summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/AST/DeclBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/AST/DeclBase.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/AST/DeclBase.cpp214
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.
OpenPOWER on IntegriCloud