diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclBase.cpp | 47 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 15 |
2 files changed, 48 insertions, 14 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 52ecdeb318..3039c95462 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -913,6 +913,24 @@ DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls, return std::make_pair(FirstNewDecl, PrevDecl); } +/// \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() { + assert(NeedToReconcileExternalVisibleStorage); + if (!LookupPtr.getPointer()) + return; + + NeedToReconcileExternalVisibleStorage = false; + + StoredDeclsMap &Map = *LookupPtr.getPointer(); + ExternalASTSource *Source = getParentASTContext().getExternalSource(); + for (StoredDeclsMap::iterator I = Map.begin(); I != Map.end(); ++I) { + I->second.removeExternalDecls(); + Source->FindExternalVisibleDeclsByName(this, I->first); + } +} + /// \brief Load the declarations within this lexical storage from an /// external source. void @@ -963,9 +981,8 @@ ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC, if (!(Map = DC->LookupPtr.getPointer())) Map = DC->CreateStoredDeclsMap(Context); - StoredDeclsList &List = (*Map)[Name]; - assert(List.isNull()); - (void) List; + // Add an entry to the map for this name, if it's not already present. + (*Map)[Name]; return DeclContext::lookup_result(); } @@ -975,7 +992,6 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef<NamedDecl*> Decls) { ASTContext &Context = DC->getParentASTContext(); - StoredDeclsMap *Map; if (!(Map = DC->LookupPtr.getPointer())) Map = DC->CreateStoredDeclsMap(Context); @@ -986,6 +1002,7 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC, if (List.isNull()) List.setOnlyValue(*I); else + // FIXME: Need declarationReplaces handling for redeclarations in modules. List.AddSubsequentDecl(*I); } @@ -1145,6 +1162,10 @@ StoredDeclsMap *DeclContext::buildLookup() { /// DeclContext, a DeclContext linked to it, or a transparent context /// nested within it. void DeclContext::buildLookupImpl(DeclContext *DCtx) { + // FIXME: If buildLookup is supposed to return a complete map, we should not + // bail out in buildLookup if hasExternalVisibleStorage. If it is not required + // to include names from PCH and modules, we should use the noload_ iterators + // here. for (decl_iterator I = DCtx->decls_begin(), E = DCtx->decls_end(); I != E; ++I) { Decl *D = *I; @@ -1175,11 +1196,17 @@ DeclContext::lookup(DeclarationName Name) { return PrimaryContext->lookup(Name); if (hasExternalVisibleStorage()) { - // If a PCH has a result for this name, and we have a local declaration, we - // will have imported the PCH result when adding the local declaration. - // FIXME: For modules, we could have had more declarations added by module - // imoprts since we saw the declaration of the local name. - if (StoredDeclsMap *Map = LookupPtr.getPointer()) { + if (NeedToReconcileExternalVisibleStorage) + reconcileExternalVisibleStorage(); + + StoredDeclsMap *Map = LookupPtr.getPointer(); + if (LookupPtr.getInt()) + Map = buildLookup(); + + // If a PCH/module has a result for this name, and we have a local + // declaration, we will have imported the PCH/module result when adding the + // local declaration or when reconciling the module. + if (Map) { StoredDeclsMap::iterator I = Map->find(Name); if (I != Map->end()) return I->second.getLookupResult(); @@ -1224,7 +1251,7 @@ void DeclContext::localUncachedLookup(DeclarationName Name, } // If we have a lookup table, check there first. Maybe we'll get lucky. - if (Name) { + if (Name && !LookupPtr.getInt()) { if (StoredDeclsMap *Map = LookupPtr.getPointer()) { StoredDeclsMap::iterator Pos = Map->find(Name); if (Pos != Map->end()) { diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 469b3938ee..c2ace30782 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -2122,12 +2122,18 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // If this declaration is also a declaration context, get the // offsets for its tables of lexical and visible declarations. if (DeclContext *DC = dyn_cast<DeclContext>(D)) { + // FIXME: This should really be + // DeclContext *LookupDC = DC->getPrimaryContext(); + // but that can walk the redeclaration chain, which might not work yet. + DeclContext *LookupDC = DC; + if (isa<NamespaceDecl>(DC)) + LookupDC = DC->getPrimaryContext(); std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC); if (Offsets.first || Offsets.second) { if (Offsets.first != 0) DC->setHasExternalLexicalStorage(true); if (Offsets.second != 0) - DC->setHasExternalVisibleStorage(true); + LookupDC->setHasExternalVisibleStorage(true); if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets, Loc.F->DeclContextInfos[DC])) return 0; @@ -2139,7 +2145,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { if (I != PendingVisibleUpdates.end()) { // There are updates. This means the context has external visible // storage, even if the original stored version didn't. - DC->setHasExternalVisibleStorage(true); + LookupDC->setHasExternalVisibleStorage(true); DeclContextVisibleUpdates &U = I->second; for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end(); UI != UE; ++UI) { @@ -2150,8 +2156,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { PendingVisibleUpdates.erase(I); } - if (!DC->hasExternalVisibleStorage() && DC->hasExternalLexicalStorage()) - DC->setMustBuildLookupTable(); + if (!LookupDC->hasExternalVisibleStorage() && + DC->hasExternalLexicalStorage()) + LookupDC->setMustBuildLookupTable(); } assert(Idx == Record.size()); |