diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/DeclBase.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/AST/DeclBase.cpp | 136 |
1 files changed, 102 insertions, 34 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp index 6b3c13ff206d..c4e948a38e26 100644 --- a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp +++ b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp @@ -71,21 +71,20 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { #include "clang/AST/DeclNodes.inc" void *Decl::operator new(std::size_t Size, const ASTContext &Context, - unsigned ID, std::size_t Extra) { + GlobalDeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. - static_assert(sizeof(unsigned) * 2 >= alignof(Decl), - "Decl won't be misaligned"); + static_assert(sizeof(uint64_t) >= alignof(Decl), "Decl won't be misaligned"); void *Start = Context.Allocate(Size + Extra + 8); void *Result = (char*)Start + 8; - unsigned *PrefixPtr = (unsigned *)Result - 2; + uint64_t *PrefixPtr = (uint64_t *)Result - 1; - // Zero out the first 4 bytes; this is used to store the owning module ID. - PrefixPtr[0] = 0; + *PrefixPtr = ID.getRawValue(); - // Store the global declaration ID in the second 4 bytes. - PrefixPtr[1] = ID; + // We leave the upper 16 bits to store the module IDs. 48 bits should be + // sufficient to store a declaration ID. + assert(*PrefixPtr < llvm::maskTrailingOnes<uint64_t>(48)); return Result; } @@ -111,6 +110,29 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, return ::operator new(Size + Extra, Ctx); } +GlobalDeclID Decl::getGlobalID() const { + if (!isFromASTFile()) + return GlobalDeclID(); + // See the comments in `Decl::operator new` for details. + uint64_t ID = *((const uint64_t *)this - 1); + return GlobalDeclID(ID & llvm::maskTrailingOnes<uint64_t>(48)); +} + +unsigned Decl::getOwningModuleID() const { + if (!isFromASTFile()) + return 0; + + uint64_t ID = *((const uint64_t *)this - 1); + return ID >> 48; +} + +void Decl::setOwningModuleID(unsigned ID) { + assert(isFromASTFile() && "Only works on a deserialized declaration"); + uint64_t *IDAddress = (uint64_t *)this - 1; + *IDAddress &= llvm::maskTrailingOnes<uint64_t>(48); + *IDAddress |= (uint64_t)ID << 48; +} + Module *Decl::getOwningModuleSlow() const { assert(isFromASTFile() && "Not from AST file?"); return getASTContext().getExternalSource()->getModule(getOwningModuleID()); @@ -402,7 +424,7 @@ bool Decl::isInAnonymousNamespace() const { bool Decl::isInStdNamespace() const { const DeclContext *DC = getDeclContext(); - return DC && DC->isStdNamespace(); + return DC && DC->getNonTransparentContext()->isStdNamespace(); } bool Decl::isFileContextDecl() const { @@ -666,12 +688,29 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, // Make sure that this declaration has already been introduced. if (!A->getIntroduced().empty() && EnclosingVersion < A->getIntroduced()) { - if (Message) { - Message->clear(); - llvm::raw_string_ostream Out(*Message); - VersionTuple VTI(A->getIntroduced()); - Out << "introduced in " << PrettyPlatformName << ' ' - << VTI << HintMessage; + IdentifierInfo *IIEnv = A->getEnvironment(); + StringRef TargetEnv = + Context.getTargetInfo().getTriple().getEnvironmentName(); + StringRef EnvName = llvm::Triple::getEnvironmentTypeName( + Context.getTargetInfo().getTriple().getEnvironment()); + // Matching environment or no environment on attribute + if (!IIEnv || (!TargetEnv.empty() && IIEnv->getName() == TargetEnv)) { + if (Message) { + Message->clear(); + llvm::raw_string_ostream Out(*Message); + VersionTuple VTI(A->getIntroduced()); + Out << "introduced in " << PrettyPlatformName << " " << VTI << " " + << EnvName << HintMessage; + } + } + // Non-matching environment or no environment on target + else { + if (Message) { + Message->clear(); + llvm::raw_string_ostream Out(*Message); + Out << "not available on " << PrettyPlatformName << " " << EnvName + << HintMessage; + } } return A->getStrict() ? AR_Unavailable : AR_NotYetIntroduced; @@ -1077,7 +1116,7 @@ bool Decl::isInExportDeclContext() const { while (DC && !isa<ExportDecl>(DC)) DC = DC->getLexicalParent(); - return DC && isa<ExportDecl>(DC); + return isa_and_nonnull<ExportDecl>(DC); } bool Decl::isInAnotherModuleUnit() const { @@ -1086,25 +1125,48 @@ bool Decl::isInAnotherModuleUnit() const { if (!M) return false; + // FIXME or NOTE: maybe we need to be clear about the semantics + // of clang header modules. e.g., if this lives in a clang header + // module included by the current unit, should we return false + // here? + // + // This is clear for header units as the specification says the + // header units live in a synthesised translation unit. So we + // can return false here. M = M->getTopLevelModule(); - // FIXME: It is problematic if the header module lives in another module - // unit. Consider to fix this by techniques like - // ExternalASTSource::hasExternalDefinitions. - if (M->isHeaderLikeModule()) + if (!M->isNamedModule()) return false; - // A global module without parent implies that we're parsing the global - // module. So it can't be in another module unit. - if (M->isGlobalModule()) + return M != getASTContext().getCurrentNamedModule(); +} + +bool Decl::isInCurrentModuleUnit() const { + auto *M = getOwningModule(); + + if (!M || !M->isNamedModule()) return false; - assert(M->isNamedModule() && "New module kind?"); - return M != getASTContext().getCurrentNamedModule(); + return M == getASTContext().getCurrentNamedModule(); +} + +bool Decl::shouldEmitInExternalSource() const { + ExternalASTSource *Source = getASTContext().getExternalSource(); + if (!Source) + return false; + + return Source->hasExternalDefinitions(this) == ExternalASTSource::EK_Always; +} + +bool Decl::isFromExplicitGlobalModule() const { + return getOwningModule() && getOwningModule()->isExplicitGlobalModule(); } -bool Decl::shouldSkipCheckingODR() const { - return getASTContext().getLangOpts().SkipODRCheckInGMF && getOwningModule() && - getOwningModule()->isExplicitGlobalModule(); +bool Decl::isFromGlobalModule() const { + return getOwningModule() && getOwningModule()->isGlobalModule(); +} + +bool Decl::isInNamedModule() const { + return getOwningModule() && getOwningModule()->isNamedModule(); } static Decl::Kind getKind(const Decl *D) { return D->getKind(); } @@ -1116,7 +1178,9 @@ int64_t Decl::getID() const { const FunctionType *Decl::getFunctionType(bool BlocksToo) const { QualType Ty; - if (const auto *D = dyn_cast<ValueDecl>(this)) + if (isa<BindingDecl>(this)) + return nullptr; + else if (const auto *D = dyn_cast<ValueDecl>(this)) Ty = D->getType(); else if (const auto *D = dyn_cast<TypedefNameDecl>(this)) Ty = D->getUnderlyingType(); @@ -1357,6 +1421,7 @@ DeclContext *DeclContext::getPrimaryContext() { case Decl::ExternCContext: case Decl::LinkageSpec: case Decl::Export: + case Decl::TopLevelStmt: case Decl::Block: case Decl::Captured: case Decl::OMPDeclareReduction: @@ -1377,8 +1442,7 @@ DeclContext *DeclContext::getPrimaryContext() { case Decl::TranslationUnit: return static_cast<TranslationUnitDecl *>(this)->getFirstDecl(); case Decl::Namespace: - // The original namespace is our primary context. - return static_cast<NamespaceDecl *>(this)->getOriginalNamespace(); + return static_cast<NamespaceDecl *>(this)->getFirstDecl(); case Decl::ObjCMethod: return this; @@ -1847,9 +1911,9 @@ DeclContext::lookup(DeclarationName Name) const { DeclContext::lookup_result DeclContext::noload_lookup(DeclarationName Name) { - assert(getDeclKind() != Decl::LinkageSpec && - getDeclKind() != Decl::Export && - "should not perform lookups into transparent contexts"); + // For transparent DeclContext, we should lookup in their enclosing context. + if (getDeclKind() == Decl::LinkageSpec || getDeclKind() == Decl::Export) + return getParent()->noload_lookup(Name); DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) @@ -2145,3 +2209,7 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, return DD; } + +unsigned DeclIDBase::getLocalDeclIndex() const { + return ID & llvm::maskTrailingOnes<DeclID>(32); +} |