summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-03-05 23:24:12 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-03-05 23:24:12 +0000
commitfe620d26ea10980f56f87db68c9e63c4a7832aa0 (patch)
tree62ab35d2b491c70ce7219678f87041d6bacd6378 /clang/lib/Serialization/ASTReader.cpp
parent6fb4915bd6a751f9d52aceae72186c11f30b830c (diff)
downloadbcm5719-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/ASTReader.cpp')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp78
1 files changed, 43 insertions, 35 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 78c44d17887..930b651f9ef 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -3316,16 +3316,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
break;
}
- case MERGED_DECLARATIONS: {
- for (unsigned Idx = 0; Idx < Record.size(); /* increment in loop */) {
- GlobalDeclID CanonID = getGlobalDeclID(F, Record[Idx++]);
- SmallVectorImpl<GlobalDeclID> &Decls = StoredMergedDecls[CanonID];
- for (unsigned N = Record[Idx++]; N > 0; --N)
- Decls.push_back(getGlobalDeclID(F, Record[Idx++]));
- }
- break;
- }
-
case MACRO_OFFSET: {
if (F.LocalNumMacros != 0) {
Error("duplicate MACRO_OFFSET record in AST file");
@@ -6227,6 +6217,10 @@ ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const {
bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID,
ModuleFile &M) const {
+ // Predefined decls aren't from any module.
+ if (ID < NUM_PREDEF_DECL_IDS)
+ return false;
+
GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(ID);
assert(I != GlobalDeclMap.end() && "Corrupted global declaration map");
return &M == I->second;
@@ -6259,39 +6253,51 @@ SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) {
return ReadSourceLocation(*Rec.F, RawLocation);
}
-Decl *ASTReader::GetExistingDecl(DeclID ID) {
- if (ID < NUM_PREDEF_DECL_IDS) {
- switch ((PredefinedDeclIDs)ID) {
- case PREDEF_DECL_NULL_ID:
- return nullptr;
+static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) {
+ switch (ID) {
+ case PREDEF_DECL_NULL_ID:
+ return nullptr;
- case PREDEF_DECL_TRANSLATION_UNIT_ID:
- return Context.getTranslationUnitDecl();
+ case PREDEF_DECL_TRANSLATION_UNIT_ID:
+ return Context.getTranslationUnitDecl();
- case PREDEF_DECL_OBJC_ID_ID:
- return Context.getObjCIdDecl();
+ case PREDEF_DECL_OBJC_ID_ID:
+ return Context.getObjCIdDecl();
- case PREDEF_DECL_OBJC_SEL_ID:
- return Context.getObjCSelDecl();
+ case PREDEF_DECL_OBJC_SEL_ID:
+ return Context.getObjCSelDecl();
- case PREDEF_DECL_OBJC_CLASS_ID:
- return Context.getObjCClassDecl();
+ case PREDEF_DECL_OBJC_CLASS_ID:
+ return Context.getObjCClassDecl();
- case PREDEF_DECL_OBJC_PROTOCOL_ID:
- return Context.getObjCProtocolDecl();
+ case PREDEF_DECL_OBJC_PROTOCOL_ID:
+ return Context.getObjCProtocolDecl();
- case PREDEF_DECL_INT_128_ID:
- return Context.getInt128Decl();
+ case PREDEF_DECL_INT_128_ID:
+ return Context.getInt128Decl();
- case PREDEF_DECL_UNSIGNED_INT_128_ID:
- return Context.getUInt128Decl();
+ case PREDEF_DECL_UNSIGNED_INT_128_ID:
+ return Context.getUInt128Decl();
- case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
- return Context.getObjCInstanceTypeDecl();
+ case PREDEF_DECL_OBJC_INSTANCETYPE_ID:
+ return Context.getObjCInstanceTypeDecl();
+
+ case PREDEF_DECL_BUILTIN_VA_LIST_ID:
+ return Context.getBuiltinVaListDecl();
+ }
+}
- case PREDEF_DECL_BUILTIN_VA_LIST_ID:
- return Context.getBuiltinVaListDecl();
+Decl *ASTReader::GetExistingDecl(DeclID ID) {
+ if (ID < NUM_PREDEF_DECL_IDS) {
+ Decl *D = getPredefinedDecl(Context, (PredefinedDeclIDs)ID);
+ if (D) {
+ // Track that we have merged the declaration with ID \p ID into the
+ // pre-existing predefined declaration \p D.
+ auto &Merged = MergedDecls[D->getCanonicalDecl()];
+ if (Merged.empty())
+ Merged.push_back(ID);
}
+ return D;
}
unsigned Index = ID - NUM_PREDEF_DECL_IDS;
@@ -8302,9 +8308,11 @@ void ASTReader::finishPendingActions() {
PendingIncompleteDeclChains.clear();
// Load pending declaration chains.
- for (unsigned I = 0; I != PendingDeclChains.size(); ++I)
+ for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
loadPendingDeclChain(PendingDeclChains[I]);
- PendingDeclChainsKnown.clear();
+ PendingDeclChainsKnown.erase(PendingDeclChains[I]);
+ }
+ assert(PendingDeclChainsKnown.empty());
PendingDeclChains.clear();
// Make the most recent of the top-level declarations visible.
OpenPOWER on IntegriCloud