diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/DeclBase.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/AST/DeclBase.cpp | 214 |
1 files changed, 126 insertions, 88 deletions
diff --git a/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp b/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp index a46787f..70bd16f 100644 --- a/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp +++ b/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp @@ -66,6 +66,12 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, void *Decl::operator new(std::size_t Size, const ASTContext &Ctx, DeclContext *Parent, std::size_t Extra) { assert(!Parent || &Parent->getParentASTContext() == &Ctx); + // With local visibility enabled, we track the owning module even for local + // declarations. + if (Ctx.getLangOpts().ModulesLocalVisibility) { + void *Buffer = ::operator new(sizeof(Module *) + Size + Extra, Ctx); + return new (Buffer) Module*(nullptr) + 1; + } return ::operator new(Size + Extra, Ctx); } @@ -74,6 +80,10 @@ Module *Decl::getOwningModuleSlow() const { return getASTContext().getExternalSource()->getModule(getOwningModuleID()); } +bool Decl::hasLocalOwningModuleStorage() const { + return getASTContext().getLangOpts().ModulesLocalVisibility; +} + const char *Decl::getDeclKindName() const { switch (DeclKind) { default: llvm_unreachable("Declaration not in DeclNodes.inc!"); @@ -336,20 +346,34 @@ bool Decl::isReferenced() const { static AvailabilityResult CheckAvailability(ASTContext &Context, const AvailabilityAttr *A, std::string *Message) { - StringRef TargetPlatform = Context.getTargetInfo().getPlatformName(); - StringRef PrettyPlatformName - = AvailabilityAttr::getPrettyPlatformName(TargetPlatform); - if (PrettyPlatformName.empty()) - PrettyPlatformName = TargetPlatform; + VersionTuple TargetMinVersion = + Context.getTargetInfo().getPlatformMinVersion(); - VersionTuple TargetMinVersion = Context.getTargetInfo().getPlatformMinVersion(); if (TargetMinVersion.empty()) return AR_Available; + // Check if this is an App Extension "platform", and if so chop off + // the suffix for matching with the actual platform. + StringRef ActualPlatform = A->getPlatform()->getName(); + StringRef RealizedPlatform = ActualPlatform; + if (Context.getLangOpts().AppExt) { + size_t suffix = RealizedPlatform.rfind("_app_extension"); + if (suffix != StringRef::npos) + RealizedPlatform = RealizedPlatform.slice(0, suffix); + } + + StringRef TargetPlatform = Context.getTargetInfo().getPlatformName(); + // Match the platform name. - if (A->getPlatform()->getName() != TargetPlatform) + if (RealizedPlatform != TargetPlatform) return AR_Available; - + + StringRef PrettyPlatformName + = AvailabilityAttr::getPrettyPlatformName(ActualPlatform); + + if (PrettyPlatformName.empty()) + PrettyPlatformName = ActualPlatform; + std::string HintMessage; if (!A->getMessage().empty()) { HintMessage = " - "; @@ -583,6 +607,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case Block: case Captured: case TranslationUnit: + case ExternCContext: case UsingDirective: case ClassTemplateSpecialization: @@ -846,6 +871,10 @@ bool DeclContext::isDependentContext() const { return getLexicalParent()->isDependentContext(); } + // FIXME: A variable template is a dependent context, but is not a + // DeclContext. A context within it (such as a lambda-expression) + // should be considered dependent. + return getParent() && getParent()->isDependentContext(); } @@ -889,6 +918,7 @@ bool DeclContext::Encloses(const DeclContext *DC) const { DeclContext *DeclContext::getPrimaryContext() { switch (DeclKind) { case Decl::TranslationUnit: + case Decl::ExternCContext: case Decl::LinkageSpec: case Decl::Block: case Decl::Captured: @@ -991,23 +1021,24 @@ DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls, /// built a lookup map. For every name in the map, pull in the new names from /// the external storage. void DeclContext::reconcileExternalVisibleStorage() const { - assert(NeedToReconcileExternalVisibleStorage && LookupPtr.getPointer()); + assert(NeedToReconcileExternalVisibleStorage && LookupPtr); NeedToReconcileExternalVisibleStorage = false; - for (auto &Lookup : *LookupPtr.getPointer()) + for (auto &Lookup : *LookupPtr) Lookup.second.setHasExternalDecls(); } /// \brief Load the declarations within this lexical storage from an /// external source. -void +/// \return \c true if any declarations were added. +bool DeclContext::LoadLexicalDeclsFromExternalStorage() const { ExternalASTSource *Source = getParentASTContext().getExternalSource(); assert(hasExternalLexicalStorage() && Source && "No external storage?"); // Notify that we have a DeclContext that is initializing. ExternalASTSource::Deserializing ADeclContext(Source); - + // Load the external declarations, if any. SmallVector<Decl*, 64> Decls; ExternalLexicalStorage = false; @@ -1017,11 +1048,11 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { case ELR_Failure: case ELR_AlreadyLoaded: - return; + return false; } if (Decls.empty()) - return; + return false; // We may have already loaded just the fields of this record, in which case // we need to ignore them. @@ -1038,6 +1069,7 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { FirstDecl = ExternalFirst; if (!LastDecl) LastDecl = ExternalLast; + return true; } DeclContext::lookup_result @@ -1045,7 +1077,7 @@ ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name) { ASTContext &Context = DC->getParentASTContext(); StoredDeclsMap *Map; - if (!(Map = DC->LookupPtr.getPointer())) + if (!(Map = DC->LookupPtr)) Map = DC->CreateStoredDeclsMap(Context); if (DC->NeedToReconcileExternalVisibleStorage) DC->reconcileExternalVisibleStorage(); @@ -1061,7 +1093,7 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, ArrayRef<NamedDecl*> Decls) { ASTContext &Context = DC->getParentASTContext(); StoredDeclsMap *Map; - if (!(Map = DC->LookupPtr.getPointer())) + if (!(Map = DC->LookupPtr)) Map = DC->CreateStoredDeclsMap(Context); if (DC->NeedToReconcileExternalVisibleStorage) DC->reconcileExternalVisibleStorage(); @@ -1078,7 +1110,7 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, // first. llvm::SmallVector<unsigned, 8> Skip; for (unsigned I = 0, N = Decls.size(); I != N; ++I) - if (List.HandleRedeclaration(Decls[I])) + if (List.HandleRedeclaration(Decls[I], /*IsKnownNewer*/false)) Skip.push_back(I); Skip.push_back(Decls.size()); @@ -1155,7 +1187,7 @@ void DeclContext::removeDecl(Decl *D) { // Remove only decls that have a name if (!ND->getDeclName()) return; - StoredDeclsMap *Map = getPrimaryContext()->LookupPtr.getPointer(); + StoredDeclsMap *Map = getPrimaryContext()->LookupPtr; if (!Map) return; StoredDeclsMap::iterator Pos = Map->find(ND->getDeclName()); @@ -1243,32 +1275,38 @@ static bool shouldBeHidden(NamedDecl *D) { StoredDeclsMap *DeclContext::buildLookup() { assert(this == getPrimaryContext() && "buildLookup called on non-primary DC"); - // FIXME: Should we keep going if hasExternalVisibleStorage? - if (!LookupPtr.getInt()) - return LookupPtr.getPointer(); + if (!HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups) + return LookupPtr; SmallVector<DeclContext *, 2> Contexts; collectAllContexts(Contexts); - for (unsigned I = 0, N = Contexts.size(); I != N; ++I) - buildLookupImpl<&DeclContext::decls_begin, - &DeclContext::decls_end>(Contexts[I]); + + if (HasLazyExternalLexicalLookups) { + HasLazyExternalLexicalLookups = false; + for (auto *DC : Contexts) { + if (DC->hasExternalLexicalStorage()) + HasLazyLocalLexicalLookups |= + DC->LoadLexicalDeclsFromExternalStorage(); + } + + if (!HasLazyLocalLexicalLookups) + return LookupPtr; + } + + for (auto *DC : Contexts) + buildLookupImpl(DC, hasExternalVisibleStorage()); // We no longer have any lazy decls. - LookupPtr.setInt(false); - return LookupPtr.getPointer(); + HasLazyLocalLexicalLookups = false; + return LookupPtr; } /// buildLookupImpl - Build part of the lookup data structure for the /// declarations contained within DCtx, which will either be this /// DeclContext, a DeclContext linked to it, or a transparent context /// nested within it. -template<DeclContext::decl_iterator (DeclContext::*Begin)() const, - DeclContext::decl_iterator (DeclContext::*End)() const> -void DeclContext::buildLookupImpl(DeclContext *DCtx) { - for (decl_iterator I = (DCtx->*Begin)(), E = (DCtx->*End)(); - I != E; ++I) { - Decl *D = *I; - +void DeclContext::buildLookupImpl(DeclContext *DCtx, bool Internal) { + for (Decl *D : DCtx->noload_decls()) { // Insert this declaration into the lookup structure, but only if // it's semantically within its decl context. Any other decls which // should be found in this context are added eagerly. @@ -1282,39 +1320,46 @@ void DeclContext::buildLookupImpl(DeclContext *DCtx) { (!ND->isFromASTFile() || (isTranslationUnit() && !getParentASTContext().getLangOpts().CPlusPlus))) - makeDeclVisibleInContextImpl(ND, false); + makeDeclVisibleInContextImpl(ND, Internal); // If this declaration is itself a transparent declaration context // or inline namespace, add the members of this declaration of that // context (recursively). if (DeclContext *InnerCtx = dyn_cast<DeclContext>(D)) if (InnerCtx->isTransparentContext() || InnerCtx->isInlineNamespace()) - buildLookupImpl<Begin, End>(InnerCtx); + buildLookupImpl(InnerCtx, Internal); } } +NamedDecl *const DeclContextLookupResult::SingleElementDummyList = nullptr; + DeclContext::lookup_result -DeclContext::lookup(DeclarationName Name) { +DeclContext::lookup(DeclarationName Name) const { assert(DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"); - DeclContext *PrimaryContext = getPrimaryContext(); + const DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->lookup(Name); - // If this is a namespace, ensure that any later redeclarations of it have - // been loaded, since they may add names to the result of this lookup. - if (auto *ND = dyn_cast<NamespaceDecl>(this)) - (void)ND->getMostRecentDecl(); + // If we have an external source, ensure that any later redeclarations of this + // context have been loaded, since they may add names to the result of this + // lookup (or add external visible storage). + ExternalASTSource *Source = getParentASTContext().getExternalSource(); + if (Source) + (void)cast<Decl>(this)->getMostRecentDecl(); if (hasExternalVisibleStorage()) { + assert(Source && "external visible storage but no external source?"); + if (NeedToReconcileExternalVisibleStorage) reconcileExternalVisibleStorage(); - StoredDeclsMap *Map = LookupPtr.getPointer(); + StoredDeclsMap *Map = LookupPtr; - if (LookupPtr.getInt()) - Map = buildLookup(); + if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups) + // FIXME: Make buildLookup const? + Map = const_cast<DeclContext*>(this)->buildLookup(); if (!Map) Map = CreateStoredDeclsMap(getParentASTContext()); @@ -1325,28 +1370,27 @@ DeclContext::lookup(DeclarationName Name) { if (!R.second && !R.first->second.hasExternalDecls()) return R.first->second.getLookupResult(); - ExternalASTSource *Source = getParentASTContext().getExternalSource(); if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) { - if (StoredDeclsMap *Map = LookupPtr.getPointer()) { + if (StoredDeclsMap *Map = LookupPtr) { StoredDeclsMap::iterator I = Map->find(Name); if (I != Map->end()) return I->second.getLookupResult(); } } - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); } - StoredDeclsMap *Map = LookupPtr.getPointer(); - if (LookupPtr.getInt()) - Map = buildLookup(); + StoredDeclsMap *Map = LookupPtr; + if (HasLazyLocalLexicalLookups || HasLazyExternalLexicalLookups) + Map = const_cast<DeclContext*>(this)->buildLookup(); if (!Map) - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); StoredDeclsMap::iterator I = Map->find(Name); if (I == Map->end()) - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); return I->second.getLookupResult(); } @@ -1355,40 +1399,29 @@ DeclContext::lookup_result DeclContext::noload_lookup(DeclarationName Name) { assert(DeclKind != Decl::LinkageSpec && "Should not perform lookups into linkage specs!"); - if (!hasExternalVisibleStorage()) - return lookup(Name); DeclContext *PrimaryContext = getPrimaryContext(); if (PrimaryContext != this) return PrimaryContext->noload_lookup(Name); - StoredDeclsMap *Map = LookupPtr.getPointer(); - if (LookupPtr.getInt()) { - // Carefully build the lookup map, without deserializing anything. + // If we have any lazy lexical declarations not in our lookup map, add them + // now. Don't import any external declarations, not even if we know we have + // some missing from the external visible lookups. + if (HasLazyLocalLexicalLookups) { SmallVector<DeclContext *, 2> Contexts; collectAllContexts(Contexts); for (unsigned I = 0, N = Contexts.size(); I != N; ++I) - buildLookupImpl<&DeclContext::noload_decls_begin, - &DeclContext::noload_decls_end>(Contexts[I]); - - // We no longer have any lazy decls. - LookupPtr.setInt(false); - - // There may now be names for which we have local decls but are - // missing the external decls. FIXME: Just set the hasExternalDecls - // flag on those names that have external decls. - NeedToReconcileExternalVisibleStorage = true; - - Map = LookupPtr.getPointer(); + buildLookupImpl(Contexts[I], hasExternalVisibleStorage()); + HasLazyLocalLexicalLookups = false; } + StoredDeclsMap *Map = LookupPtr; if (!Map) - return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr)); + return lookup_result(); StoredDeclsMap::iterator I = Map->find(Name); return I != Map->end() ? I->second.getLookupResult() - : lookup_result(lookup_iterator(nullptr), - lookup_iterator(nullptr)); + : lookup_result(); } void DeclContext::localUncachedLookup(DeclarationName Name, @@ -1404,8 +1437,9 @@ void DeclContext::localUncachedLookup(DeclarationName Name, } // If we have a lookup table, check there first. Maybe we'll get lucky. - if (Name && !LookupPtr.getInt()) { - if (StoredDeclsMap *Map = LookupPtr.getPointer()) { + // FIXME: Should we be checking these flags on the primary context? + if (Name && !HasLazyLocalLexicalLookups && !HasLazyExternalLexicalLookups) { + if (StoredDeclsMap *Map = LookupPtr) { StoredDeclsMap::iterator Pos = Map->find(Name); if (Pos != Map->end()) { Results.insert(Results.end(), @@ -1418,6 +1452,8 @@ void DeclContext::localUncachedLookup(DeclarationName Name, // Slow case: grovel through the declarations in our chain looking for // matches. + // FIXME: If we have lazy external declarations, this will not find them! + // FIXME: Should we CollectAllContexts and walk them all here? for (Decl *D = FirstDecl; D; D = D->getNextDeclInContext()) { if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) if (ND->getDeclName() == Name) @@ -1498,7 +1534,7 @@ void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, // FIXME: As a performance hack, don't add such decls into the translation // unit unless we're in C++, since qualified lookup into the TU is never // performed. - if (LookupPtr.getPointer() || hasExternalVisibleStorage() || + if (LookupPtr || hasExternalVisibleStorage() || ((!Recoverable || D->getDeclContext() != D->getLexicalDeclContext()) && (getParentASTContext().getLangOpts().CPlusPlus || !isTranslationUnit()))) { @@ -1508,7 +1544,7 @@ void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, buildLookup(); makeDeclVisibleInContextImpl(D, Internal); } else { - LookupPtr.setInt(true); + HasLazyLocalLexicalLookups = true; } // If we are a transparent context or inline namespace, insert into our @@ -1526,7 +1562,7 @@ void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { // Find or create the stored declaration map. - StoredDeclsMap *Map = LookupPtr.getPointer(); + StoredDeclsMap *Map = LookupPtr; if (!Map) { ASTContext *C = &getParentASTContext(); Map = CreateStoredDeclsMap(*C); @@ -1555,12 +1591,12 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { return; } - else if (DeclNameEntries.isNull()) { + if (DeclNameEntries.isNull()) { DeclNameEntries.setOnlyValue(D); return; } - if (DeclNameEntries.HandleRedeclaration(D)) { + if (DeclNameEntries.HandleRedeclaration(D, /*IsKnownNewer*/!Internal)) { // This declaration has replaced an existing one for which // declarationReplaces returns true. return; @@ -1570,15 +1606,17 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) { DeclNameEntries.AddSubsequentDecl(D); } +UsingDirectiveDecl *DeclContext::udir_iterator::operator*() const { + return cast<UsingDirectiveDecl>(*I); +} + /// Returns iterator range [First, Last) of UsingDirectiveDecls stored within /// this context. DeclContext::udir_range DeclContext::using_directives() const { // FIXME: Use something more efficient than normal lookup for using // directives. In C++, using directives are looked up more than anything else. - lookup_const_result Result = lookup(UsingDirectiveDecl::getName()); - return udir_range( - reinterpret_cast<UsingDirectiveDecl *const *>(Result.begin()), - reinterpret_cast<UsingDirectiveDecl *const *>(Result.end())); + lookup_result Result = lookup(UsingDirectiveDecl::getName()); + return udir_range(Result.begin(), Result.end()); } //===----------------------------------------------------------------------===// @@ -1586,7 +1624,7 @@ DeclContext::udir_range DeclContext::using_directives() const { //===----------------------------------------------------------------------===// StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const { - assert(!LookupPtr.getPointer() && "context already has a decls map"); + assert(!LookupPtr && "context already has a decls map"); assert(getPrimaryContext() == this && "creating decls map on non-primary context"); @@ -1598,7 +1636,7 @@ StoredDeclsMap *DeclContext::CreateStoredDeclsMap(ASTContext &C) const { M = new StoredDeclsMap(); M->Previous = C.LastSDM; C.LastSDM = llvm::PointerIntPair<StoredDeclsMap*,1>(M, Dependent); - LookupPtr.setPointer(M); + LookupPtr = M; return M; } @@ -1630,11 +1668,11 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C, assert(Parent->isDependentContext() && "cannot iterate dependent diagnostics of non-dependent context"); Parent = Parent->getPrimaryContext(); - if (!Parent->LookupPtr.getPointer()) + if (!Parent->LookupPtr) Parent->CreateStoredDeclsMap(C); - DependentStoredDeclsMap *Map - = static_cast<DependentStoredDeclsMap*>(Parent->LookupPtr.getPointer()); + DependentStoredDeclsMap *Map = + static_cast<DependentStoredDeclsMap *>(Parent->LookupPtr); // Allocate the copy of the PartialDiagnostic via the ASTContext's // BumpPtrAllocator, rather than the ASTContext itself. |