aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Serialization/ASTReader.cpp221
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp24
2 files changed, 126 insertions, 119 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 7a6a6039f3..8264a7421c 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -918,7 +918,8 @@ public:
typedef OnDiskChainedHashTable<ASTDeclContextNameLookupTrait>
ASTDeclContextNameLookupTable;
-bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
+bool ASTReader::ReadDeclContextStorage(Module &M,
+ llvm::BitstreamCursor &Cursor,
const std::pair<uint64_t, uint64_t> &Offsets,
DeclContextInfo &Info) {
SavedStreamPosition SavedPosition(Cursor);
@@ -938,9 +939,6 @@ bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair*>(Blob);
Info.NumLexicalDecls = BlobLen / sizeof(KindDeclIDPair);
- } else {
- Info.LexicalDecls = 0;
- Info.NumLexicalDecls = 0;
}
// Now the lookup table.
@@ -960,9 +958,7 @@ bool ASTReader::ReadDeclContextStorage(llvm::BitstreamCursor &Cursor,
= ASTDeclContextNameLookupTable::Create(
(const unsigned char *)Blob + Record[0],
(const unsigned char *)Blob,
- ASTDeclContextNameLookupTrait(*this, *Info.F));
- } else {
- Info.NameLookupTableData = 0;
+ ASTDeclContextNameLookupTrait(*this, M));
}
return false;
@@ -2108,15 +2104,11 @@ ASTReader::ReadASTBlock(Module &F) {
}
case TU_UPDATE_LEXICAL: {
- DeclContextInfo Info = {
- &F,
- /* No visible information */ 0,
- reinterpret_cast<const KindDeclIDPair *>(BlobStart),
- static_cast<unsigned int>(BlobLen / sizeof(KindDeclIDPair))
- };
-
DeclContext *TU = Context ? Context->getTranslationUnitDecl() : 0;
- DeclContextOffsets[TU].push_back(Info);
+ DeclContextInfo &Info = F.DeclContextInfos[TU];
+ Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair *>(BlobStart);
+ Info.NumLexicalDecls
+ = static_cast<unsigned int>(BlobLen / sizeof(KindDeclIDPair));
if (TU)
TU->setHasExternalLexicalStorage(true);
@@ -2130,14 +2122,9 @@ ASTReader::ReadASTBlock(Module &F) {
(const unsigned char *)BlobStart + Record[Idx++],
(const unsigned char *)BlobStart,
ASTDeclContextNameLookupTrait(*this, F));
- // FIXME: Complete hack to check for the TU
if (ID == PREDEF_DECL_TRANSLATION_UNIT_ID && Context) { // Is it the TU?
- DeclContextInfo Info = {
- &F, Table, /* No lexical information */ 0, 0
- };
-
DeclContext *TU = Context->getTranslationUnitDecl();
- DeclContextOffsets[TU].push_back(Info);
+ F.DeclContextInfos[TU].NameLookupTableData = Table;
TU->setHasExternalVisibleStorage(true);
} else
PendingVisibleUpdates[ID].push_back(std::make_pair(Table, &F));
@@ -2954,16 +2941,19 @@ void ASTReader::InitializeContext(ASTContext &Ctx) {
PP->getIdentifierTable().setExternalIdentifierLookup(this);
PP->setExternalSource(this);
- // If we have an update block for the TU waiting, we have to add it before
- // deserializing the decl.
+ // If we have any update blocks for the TU waiting, we have to add
+ // them before we deserialize anything.
TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
- DeclContextOffsetsMap::iterator DCU = DeclContextOffsets.find(0);
- if (DCU != DeclContextOffsets.end()) {
- // Insertion could invalidate map, so grab vector.
- DeclContextInfos T;
- T.swap(DCU->second);
- DeclContextOffsets.erase(DCU);
- DeclContextOffsets[TU].swap(T);
+ for (ModuleIterator M = ModuleMgr.begin(), MEnd = ModuleMgr.end();
+ M != MEnd; ++M) {
+ Module::DeclContextInfosMap::iterator DCU
+ = (*M)->DeclContextInfos.find(0);
+ if (DCU != (*M)->DeclContextInfos.end()) {
+ // Insertion could invalidate map, so grab value first.
+ DeclContextInfo Info = DCU->second;
+ (*M)->DeclContextInfos.erase(DCU);
+ (*M)->DeclContextInfos[TU] = Info;
+ }
}
// If there's a listener, notify them that we "read" the translation unit.
@@ -4277,24 +4267,26 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) {
ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
bool (*isKindWeWant)(Decl::Kind),
SmallVectorImpl<Decl*> &Decls) {
- // There might be lexical decls in multiple parts of the chain, for the TU
- // at least.
- // DeclContextOffsets might reallocate as we load additional decls below,
- // so make a copy of the vector.
- DeclContextInfos Infos = DeclContextOffsets[DC];
- for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
- I != E; ++I) {
- // IDs can be 0 if this context doesn't contain declarations.
- if (!I->LexicalDecls)
+ // There might be lexical decls in multiple modules, for the TU at
+ // least.
+ // FIXME: We might want a faster way to zero
+ // FIXME: Going backwards through the chain does the right thing for
+ // chained PCH; for modules, it isn't clear what the right thing is.
+ for (ModuleReverseIterator M = ModuleMgr.rbegin(), MEnd = ModuleMgr.rend();
+ M != MEnd; ++M) {
+ Module::DeclContextInfosMap::iterator Info
+ = (*M)->DeclContextInfos.find(DC);
+ if (Info == (*M)->DeclContextInfos.end() || !Info->second.LexicalDecls)
continue;
// Load all of the declaration IDs
- for (const KindDeclIDPair *ID = I->LexicalDecls,
- *IDE = ID + I->NumLexicalDecls; ID != IDE; ++ID) {
+ for (const KindDeclIDPair *ID = Info->second.LexicalDecls,
+ *IDE = ID + Info->second.NumLexicalDecls;
+ ID != IDE; ++ID) {
if (isKindWeWant && !isKindWeWant((Decl::Kind)ID->first))
continue;
- Decl *D = GetLocalDecl(*I->F, ID->second);
+ Decl *D = GetLocalDecl(**M, ID->second);
assert(D && "Null decl in lexical decls");
Decls.push_back(D);
}
@@ -4304,6 +4296,63 @@ ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
return ELR_Success;
}
+namespace {
+ /// \brief Module visitor used to perform name lookup into a
+ /// declaration context.
+ class DeclContextNameLookupVisitor {
+ ASTReader &Reader;
+ const DeclContext *DC;
+ DeclarationName Name;
+ SmallVectorImpl<NamedDecl *> &Decls;
+
+ public:
+ DeclContextNameLookupVisitor(ASTReader &Reader,
+ const DeclContext *DC, DeclarationName Name,
+ SmallVectorImpl<NamedDecl *> &Decls)
+ : Reader(Reader), DC(DC), Name(Name), Decls(Decls) { }
+
+ static bool visit(Module &M, void *UserData) {
+ DeclContextNameLookupVisitor *This
+ = static_cast<DeclContextNameLookupVisitor *>(UserData);
+
+ // Check whether we have any visible declaration information for
+ // this context in this module.
+ Module::DeclContextInfosMap::iterator Info
+ = M.DeclContextInfos.find(This->DC);
+ if (Info == M.DeclContextInfos.end() || !Info->second.NameLookupTableData)
+ return false;
+
+ // Look for this name within this module.
+ ASTDeclContextNameLookupTable *LookupTable =
+ (ASTDeclContextNameLookupTable*)Info->second.NameLookupTableData;
+ ASTDeclContextNameLookupTable::iterator Pos
+ = LookupTable->find(This->Name);
+ if (Pos == LookupTable->end())
+ return false;
+
+ bool FoundAnything = false;
+ ASTDeclContextNameLookupTrait::data_type Data = *Pos;
+ for (; Data.first != Data.second; ++Data.first) {
+ NamedDecl *ND = This->Reader.GetLocalDeclAs<NamedDecl>(M, *Data.first);
+ if (!ND)
+ continue;
+
+ if (ND->getDeclName() != This->Name) {
+ assert(!This->Name.getCXXNameType().isNull() &&
+ "Name mismatch without a type");
+ continue;
+ }
+
+ // Record this declaration.
+ FoundAnything = true;
+ This->Decls.push_back(ND);
+ }
+
+ return FoundAnything;
+ }
+ };
+}
+
DeclContext::lookup_result
ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
@@ -4314,49 +4363,9 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclContext::lookup_iterator(0));
SmallVector<NamedDecl *, 64> Decls;
- // There might be visible decls in multiple parts of the chain, for the TU
- // and namespaces. For any given name, the last available results replace
- // all earlier ones. For this reason, we walk in reverse.
- // Copy the DeclContextInfos vector instead of using a reference to the
- // vector stored in the map, because DeclContextOffsets can change while
- // we load declarations with GetLocalDeclAs.
- DeclContextInfos Infos = DeclContextOffsets[DC];
- for (DeclContextInfos::reverse_iterator I = Infos.rbegin(), E = Infos.rend();
- I != E; ++I) {
- if (!I->NameLookupTableData)
- continue;
-
- ASTDeclContextNameLookupTable *LookupTable =
- (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
- ASTDeclContextNameLookupTable::iterator Pos = LookupTable->find(Name);
- if (Pos == LookupTable->end())
- continue;
-
- ASTDeclContextNameLookupTrait::data_type Data = *Pos;
- for (; Data.first != Data.second; ++Data.first) {
- NamedDecl *ND = GetLocalDeclAs<NamedDecl>(*I->F, *Data.first);
- if (!ND)
- continue;
-
- if (ND->getDeclName() != Name) {
- assert(!Name.getCXXNameType().isNull() &&
- "Name mismatch without a type");
- continue;
- }
-
- Decls.push_back(ND);
- }
-
- // If we rejected all of the declarations we found, e.g., because the
- // name didn't actually match, continue looking through DeclContexts.
- if (Decls.empty())
- continue;
-
- break;
- }
-
+ DeclContextNameLookupVisitor Visitor(*this, DC, Name, Decls);
+ ModuleMgr.visit(&DeclContextNameLookupVisitor::visit, &Visitor);
++NumVisibleDeclContextsRead;
-
SetExternalVisibleDeclsForName(DC, Name, Decls);
return const_cast<DeclContext*>(DC)->lookup(Name);
}
@@ -4368,14 +4377,23 @@ void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
SmallVector<NamedDecl *, 64> Decls;
// There might be visible decls in multiple parts of the chain, for the TU
// and namespaces.
- DeclContextInfos &Infos = DeclContextOffsets[DC];
- for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
- I != E; ++I) {
- if (!I->NameLookupTableData)
+ // There might be lexical decls in multiple modules, for the TU at
+ // least.
+ // FIXME: We might want a faster way to zero
+ // FIXME: Going backwards through the chain does the right thing for
+ // chained PCH; for modules, it isn't clear what the right thing is.
+ for (ModuleReverseIterator M = ModuleMgr.rbegin(), MEnd = ModuleMgr.rend();
+ M != MEnd; ++M) {
+ Module::DeclContextInfosMap::iterator Info
+ = (*M)->DeclContextInfos.find(DC);
+ if (Info == (*M)->DeclContextInfos.end() || !Info->second.LexicalDecls)
+ continue;
+
+ if (!Info->second.NameLookupTableData)
continue;
ASTDeclContextNameLookupTable *LookupTable =
- (ASTDeclContextNameLookupTable*)I->NameLookupTableData;
+ (ASTDeclContextNameLookupTable*)Info->second.NameLookupTableData;
for (ASTDeclContextNameLookupTable::item_iterator
ItemI = LookupTable->item_begin(),
ItemEnd = LookupTable->item_end() ; ItemI != ItemEnd; ++ItemI) {
@@ -4383,8 +4401,10 @@ void ASTReader::MaterializeVisibleDecls(const DeclContext *DC) {
= *ItemI;
ASTDeclContextNameLookupTrait::data_type Data = Val.second;
Decls.clear();
- for (; Data.first != Data.second; ++Data.first)
- Decls.push_back(GetLocalDeclAs<NamedDecl>(*I->F, *Data.first));
+ for (; Data.first != Data.second; ++Data.first) {
+ if (NamedDecl *ND = GetLocalDeclAs<NamedDecl>(**M, *Data.first))
+ Decls.push_back(ND);
+ }
MaterializeVisibleDeclsForName(DC, Val.first, Decls);
}
}
@@ -5608,17 +5628,6 @@ ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
}
ASTReader::~ASTReader() {
- // Delete all visible decl lookup tables
- for (DeclContextOffsetsMap::iterator I = DeclContextOffsets.begin(),
- E = DeclContextOffsets.end();
- I != E; ++I) {
- for (DeclContextInfos::iterator J = I->second.begin(), F = I->second.end();
- J != F; ++J) {
- if (J->NameLookupTableData)
- delete static_cast<ASTDeclContextNameLookupTable*>(
- J->NameLookupTableData);
- }
- }
for (DeclContextVisibleUpdatesPending::iterator
I = PendingVisibleUpdates.begin(),
E = PendingVisibleUpdates.end();
@@ -5653,6 +5662,14 @@ Module::Module(ModuleKind Kind)
{}
Module::~Module() {
+ for (DeclContextInfosMap::iterator I = DeclContextInfos.begin(),
+ E = DeclContextInfos.end();
+ I != E; ++I) {
+ if (I->second.NameLookupTableData)
+ delete static_cast<ASTDeclContextNameLookupTable*>(
+ I->second.NameLookupTableData);
+ }
+
delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
delete static_cast<ASTSelectorLookupTable *>(SelectorLookupTable);
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 0c29b34b6f..ab46e0a096 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1698,17 +1698,13 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
std::pair<uint64_t, uint64_t> Offsets = Reader.VisitDeclContext(DC);
if (Offsets.first || Offsets.second) {
- DC->setHasExternalLexicalStorage(Offsets.first != 0);
- DC->setHasExternalVisibleStorage(Offsets.second != 0);
- DeclContextInfo Info;
- Info.F = Loc.F;
- if (ReadDeclContextStorage(DeclsCursor, Offsets, Info))
+ if (Offsets.first != 0)
+ DC->setHasExternalLexicalStorage(true);
+ if (Offsets.second != 0)
+ DC->setHasExternalVisibleStorage(true);
+ if (ReadDeclContextStorage(*Loc.F, DeclsCursor, Offsets,
+ Loc.F->DeclContextInfos[DC]))
return 0;
- DeclContextInfos &Infos = DeclContextOffsets[DC];
- // Reading the TU will happen after reading its lexical update blocks,
- // so we need to make sure we insert in front. For all other contexts,
- // the vector is empty here anyway, so there's no loss in efficiency.
- Infos.insert(Infos.begin(), Info);
}
// Now add the pending visible updates for this decl context, if it has any.
@@ -1719,15 +1715,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) {
// storage, even if the original stored version didn't.
DC->setHasExternalVisibleStorage(true);
DeclContextVisibleUpdates &U = I->second;
- DeclContextInfos &Infos = DeclContextOffsets[DC];
- DeclContextInfo Info;
- Info.LexicalDecls = 0;
- Info.NumLexicalDecls = 0;
for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
UI != UE; ++UI) {
- Info.NameLookupTableData = UI->first;
- Info.F = UI->second;
- Infos.push_back(Info);
+ UI->second->DeclContextInfos[DC].NameLookupTableData = UI->first;
}
PendingVisibleUpdates.erase(I);
}