From: Richard Smith Date: Tue, 25 Mar 2014 00:34:21 +0000 (+0000) Subject: If a DeclContext's lookups need to be reconciled, and we're given external declaratio... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dad7449abdfca3473d9a9f327201ba883c1e2ef3;p=clang If a DeclContext's lookups need to be reconciled, and we're given external declarations for a name, reconcile first. Otherwise, when we come to reconcile, we'll ask for external declarations for that name again. No functionality change intended. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@204692 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index a08f1c50a0..7e0b73d3c7 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1655,7 +1655,7 @@ public: void dumpLookups(llvm::raw_ostream &OS) const; private: - void reconcileExternalVisibleStorage(); + void reconcileExternalVisibleStorage() const; void LoadLexicalDeclsFromExternalStorage() const; /// @brief Makes a declaration visible within this context, but diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index d4c8235f8a..1de1fe21de 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -965,13 +965,12 @@ DeclContext::BuildDeclChain(ArrayRef Decls, /// \brief We have just acquired external visible storage, and we already have /// built a lookup map. For every name in the map, pull in the new names from /// the external storage. -void DeclContext::reconcileExternalVisibleStorage() { +void DeclContext::reconcileExternalVisibleStorage() const { assert(NeedToReconcileExternalVisibleStorage && LookupPtr.getPointer()); NeedToReconcileExternalVisibleStorage = false; - StoredDeclsMap &Map = *LookupPtr.getPointer(); - for (StoredDeclsMap::iterator I = Map.begin(); I != Map.end(); ++I) - I->second.setHasExternalDecls(); + for (auto &Lookup : *LookupPtr.getPointer()) + Lookup.second.setHasExternalDecls(); } /// \brief Load the declarations within this lexical storage from an @@ -1023,6 +1022,8 @@ ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC, StoredDeclsMap *Map; if (!(Map = DC->LookupPtr.getPointer())) Map = DC->CreateStoredDeclsMap(Context); + if (DC->NeedToReconcileExternalVisibleStorage) + DC->reconcileExternalVisibleStorage(); (*Map)[Name].removeExternalDecls(); @@ -1037,6 +1038,8 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, StoredDeclsMap *Map; if (!(Map = DC->LookupPtr.getPointer())) Map = DC->CreateStoredDeclsMap(Context); + if (DC->NeedToReconcileExternalVisibleStorage) + DC->reconcileExternalVisibleStorage(); StoredDeclsList &List = (*Map)[Name]; @@ -1208,6 +1211,10 @@ static bool shouldBeHidden(NamedDecl *D) { /// buildLookup - Build the lookup data structure with all of the /// declarations in this DeclContext (and any other contexts linked /// to it or transparent contexts nested within it) and return it. +/// +/// Note that the produced map may miss out declarations from an +/// external source. If it does, those entries will be marked with +/// the 'hasExternalDecls' flag. StoredDeclsMap *DeclContext::buildLookup() { assert(this == getPrimaryContext() && "buildLookup called on non-primary DC"); @@ -1223,7 +1230,6 @@ StoredDeclsMap *DeclContext::buildLookup() { // We no longer have any lazy decls. LookupPtr.setInt(false); - NeedToReconcileExternalVisibleStorage = false; return LookupPtr.getPointer(); } @@ -1272,11 +1278,13 @@ DeclContext::lookup(DeclarationName Name) { return PrimaryContext->lookup(Name); if (hasExternalVisibleStorage()) { + if (NeedToReconcileExternalVisibleStorage) + reconcileExternalVisibleStorage(); + StoredDeclsMap *Map = LookupPtr.getPointer(); + if (LookupPtr.getInt()) Map = buildLookup(); - else if (NeedToReconcileExternalVisibleStorage) - reconcileExternalVisibleStorage(); if (!Map) Map = CreateStoredDeclsMap(getParentASTContext());