diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-05 23:24:12 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-03-05 23:24:12 +0000 |
commit | fe620d26ea10980f56f87db68c9e63c4a7832aa0 (patch) | |
tree | 62ab35d2b491c70ce7219678f87041d6bacd6378 /clang/lib/Serialization/ASTWriter.cpp | |
parent | 6fb4915bd6a751f9d52aceae72186c11f30b830c (diff) | |
download | bcm5719-llvm-fe620d26ea10980f56f87db68c9e63c4a7832aa0.tar.gz bcm5719-llvm-fe620d26ea10980f56f87db68c9e63c4a7832aa0.zip |
[modules] Rework merging of redeclaration chains on module import.
We used to save out and eagerly load a (potentially huge) table of merged
formerly-canonical declarations when we loaded each module. This was extremely
inefficient in the presence of large amounts of merging, and didn't actually
save any merging lookup work, because we still needed to perform name lookup to
check that our merged declaration lists were complete. This also resulted in a
loss of laziness -- even if we only needed an early declaration of an entity, we
would eagerly pull in all declarations that had been merged into it regardless.
We now store the relevant fragments of the table within the declarations
themselves. In detail:
* The first declaration of each entity within a module stores a list of first
declarations from imported modules that are merged into it.
* Loading that declaration pre-loads those other entities, so that they appear
earlier within the redeclaration chain.
* The name lookup tables list the most recent local lookup result, if there
is one, or all directly-imported lookup results if not.
llvm-svn: 231424
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 49 |
1 files changed, 17 insertions, 32 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index e04c46ed982..29ed5c366cd 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -924,7 +924,6 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(OBJC_CATEGORIES_MAP); RECORD(FILE_SORTED_DECLS); RECORD(IMPORTED_MODULES); - RECORD(MERGED_DECLARATIONS); RECORD(LOCAL_REDECLARATIONS); RECORD(OBJC_CATEGORIES); RECORD(MACRO_OFFSET); @@ -3115,7 +3114,7 @@ static NamedDecl *getDeclForLocalLookup(const LangOptions &LangOpts, for (; Redecl; Redecl = Redecl->getPreviousDecl()) { if (!Redecl->isFromASTFile()) return cast<NamedDecl>(Redecl); - // If we come up a decl from a (chained-)PCH stop since we won't find a + // If we find a decl from a (chained-)PCH stop since we won't find a // local one. if (D->getOwningModuleID() == 0) break; @@ -3671,14 +3670,24 @@ void ASTWriter::visitLocalLookupResults(const DeclContext *ConstDC, SmallVector<DeclarationName, 16> ExternalNames; for (auto &Lookup : *DC->buildLookup()) { - // If there are no local declarations in our lookup result, we don't - // need to write an entry for the name at all unless we're rewriting - // the decl context. - if (!Lookup.second.hasLocalDecls() && !isRewritten(cast<Decl>(DC))) - continue; - if (Lookup.second.hasExternalDecls() || DC->NeedToReconcileExternalVisibleStorage) { + // If there are no local declarations in our lookup result, we don't + // need to write an entry for the name at all unless we're rewriting + // the decl context. If we can't write out a lookup set without + // performing more deserialization, just skip this entry. + if (!isRewritten(cast<Decl>(DC))) { + bool AllFromASTFile = true; + for (auto *D : Lookup.second.getLookupResult()) { + AllFromASTFile &= + getDeclForLocalLookup(getLangOpts(), D)->isFromASTFile(); + if (!AllFromASTFile) + break; + } + if (AllFromASTFile) + continue; + } + // We don't know for sure what declarations are found by this name, // because the external source might have a different set from the set // that are in the lookup map, and we can't update it now without @@ -3898,10 +3907,6 @@ void ASTWriter::WriteRedeclarations() { if (Prev->isFromASTFile()) FirstFromAST = Prev; } - - // FIXME: Do we need to do this for the first declaration from each - // redeclaration chain that was merged into this one? - Chain->MergedDecls[FirstFromAST].push_back(getDeclID(First)); } LocalRedeclChains[Offset] = Size; @@ -3998,25 +4003,6 @@ void ASTWriter::WriteObjCCategories() { Stream.EmitRecord(OBJC_CATEGORIES, Categories); } -void ASTWriter::WriteMergedDecls() { - if (!Chain || Chain->MergedDecls.empty()) - return; - - RecordData Record; - for (ASTReader::MergedDeclsMap::iterator I = Chain->MergedDecls.begin(), - IEnd = Chain->MergedDecls.end(); - I != IEnd; ++I) { - DeclID CanonID = I->first->isFromASTFile()? I->first->getGlobalID() - : GetDeclRef(I->first); - assert(CanonID && "Merged declaration not known?"); - - Record.push_back(CanonID); - Record.push_back(I->second.size()); - Record.append(I->second.begin(), I->second.end()); - } - Stream.EmitRecord(MERGED_DECLARATIONS, Record); -} - void ASTWriter::WriteLateParsedTemplates(Sema &SemaRef) { Sema::LateParsedTemplateMapT &LPTMap = SemaRef.LateParsedTemplateMap; @@ -4699,7 +4685,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, WriteDeclReplacementsBlock(); WriteRedeclarations(); - WriteMergedDecls(); WriteObjCCategories(); WriteLateParsedTemplates(SemaRef); if(!WritingModule) |