aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-08-24 00:50:04 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-08-24 00:50:04 +0000
commite1dde811b38e779894150cb1093d57f8411a84f7 (patch)
treeaaf08f23e8aa559ac49315f7f09dcc1d0fc97fcc
parent0ea8f7f5a4eba47ae226dd47c6dce39eef0c554c (diff)
Read the UPDATE_VISIBLE record, and add its visible decls to the lookup tables. Also, free the lookup tables when destructing the ASTReader.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111880 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Serialization/ASTReader.h17
-rw-r--r--lib/Serialization/ASTReader.cpp112
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp22
3 files changed, 109 insertions, 42 deletions
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 8b5790fc9c..889605e34d 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -343,14 +343,29 @@ private:
const serialization::DeclID *LexicalDecls;
unsigned NumLexicalDecls;
};
+ // In a full chain, there could be multiple updates to every decl context,
+ // so this is a vector. However, typically a chain is only two elements long,
+ // with only one file containing updates, so there will be only one update
+ // per decl context.
typedef llvm::SmallVector<DeclContextInfo, 1> DeclContextInfos;
typedef llvm::DenseMap<const DeclContext *, DeclContextInfos>
- DeclContextOffsetsMap;
+ DeclContextOffsetsMap;
+ // Updates for visible decls can occur for other contexts than just the
+ // TU, and when we read those update records, the actual context will not
+ // be available yet (unless it's the TU), so have this pending map using the
+ // ID as a key. It will be realized when the context is actually loaded.
+ typedef llvm::SmallVector<void *, 1> DeclContextVisibleUpdates;
+ typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates>
+ DeclContextVisibleUpdatesPending;
/// \brief Offsets of the lexical and visible declarations for each
/// DeclContext.
DeclContextOffsetsMap DeclContextOffsets;
+ /// \brief Updates to the visible declarations of declaration contexts that
+ /// haven't been loaded yet.
+ DeclContextVisibleUpdatesPending PendingVisibleUpdates;
+
typedef llvm::DenseMap<serialization::DeclID, serialization::DeclID>
FirstLatestDeclIDMap;
/// \brief Map of first declarations from a chained PCH that point to the
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 2a5a9ac1d9..8167a0f5fa 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -412,43 +412,6 @@ void PCHValidator::ReadCounter(unsigned Value) {
// AST reader implementation
//===----------------------------------------------------------------------===//
-ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
- const char *isysroot, bool DisableValidation)
- : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
- SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
- Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
- Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
- NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
- TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
- NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
- NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
- TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
- TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
- TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
- RelocatablePCH = false;
-}
-
-ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
- Diagnostic &Diags, const char *isysroot,
- bool DisableValidation)
- : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
- Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
- isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
- NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
- NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
- TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
- NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
- NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
- NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
- NumCurrentElementsDeserializing(0) {
- RelocatablePCH = false;
-}
-
-ASTReader::~ASTReader() {
- for (unsigned i = 0, e = Chain.size(); i != e; ++i)
- delete Chain[e - i - 1];
-}
-
void
ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
DeserializationListener = Listener;
@@ -1770,6 +1733,22 @@ ASTReader::ReadASTBlock(PerFileData &F) {
break;
}
+ case UPDATE_VISIBLE: {
+ serialization::DeclID ID = Record[0];
+ void *Table = ASTDeclContextNameLookupTable::Create(
+ (const unsigned char *)BlobStart + Record[1],
+ (const unsigned char *)BlobStart,
+ ASTDeclContextNameLookupTrait(*this));
+ if (ID == 1) { // Is it the TU?
+ DeclContextInfo Info = {
+ Table, /* No lexical inforamtion */ 0, 0
+ };
+ DeclContextOffsets[Context->getTranslationUnitDecl()].push_back(Info);
+ } else
+ PendingVisibleUpdates[ID].push_back(Table);
+ break;
+ }
+
case REDECLS_UPDATE_LATEST: {
assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
@@ -3130,7 +3109,7 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) {
TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
if (!DeclsLoaded[0]) {
- ReadDeclRecord(0, 0);
+ ReadDeclRecord(0, 1);
if (DeserializationListener)
DeserializationListener->DeclRead(1, DeclsLoaded[0]);
}
@@ -4084,6 +4063,63 @@ void ASTReader::FinishedDeserializing() {
--NumCurrentElementsDeserializing;
}
+ASTReader::ASTReader(Preprocessor &PP, ASTContext *Context,
+ const char *isysroot, bool DisableValidation)
+ : Listener(new PCHValidator(PP, *this)), DeserializationListener(0),
+ SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
+ Diags(PP.getDiagnostics()), SemaObj(0), PP(&PP), Context(Context),
+ Consumer(0), isysroot(isysroot), DisableValidation(DisableValidation),
+ NumStatHits(0), NumStatMisses(0), NumSLocEntriesRead(0),
+ TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
+ NumMacrosRead(0), TotalNumMacros(0), NumSelectorsRead(0),
+ NumMethodPoolEntriesRead(0), NumMethodPoolMisses(0),
+ TotalNumMethodPoolEntries(0), NumLexicalDeclContextsRead(0),
+ TotalLexicalDeclContexts(0), NumVisibleDeclContextsRead(0),
+ TotalVisibleDeclContexts(0), NumCurrentElementsDeserializing(0) {
+ RelocatablePCH = false;
+}
+
+ASTReader::ASTReader(SourceManager &SourceMgr, FileManager &FileMgr,
+ Diagnostic &Diags, const char *isysroot,
+ bool DisableValidation)
+ : DeserializationListener(0), SourceMgr(SourceMgr), FileMgr(FileMgr),
+ Diags(Diags), SemaObj(0), PP(0), Context(0), Consumer(0),
+ isysroot(isysroot), DisableValidation(DisableValidation), NumStatHits(0),
+ NumStatMisses(0), NumSLocEntriesRead(0), TotalNumSLocEntries(0),
+ NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0),
+ TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0),
+ NumMethodPoolMisses(0), TotalNumMethodPoolEntries(0),
+ NumLexicalDeclContextsRead(0), TotalLexicalDeclContexts(0),
+ NumVisibleDeclContextsRead(0), TotalVisibleDeclContexts(0),
+ NumCurrentElementsDeserializing(0) {
+ RelocatablePCH = false;
+}
+
+ASTReader::~ASTReader() {
+ for (unsigned i = 0, e = Chain.size(); i != e; ++i)
+ delete Chain[e - i - 1];
+ // 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();
+ I != E; ++I) {
+ for (DeclContextVisibleUpdates::iterator J = I->second.begin(),
+ F = I->second.end();
+ J != F; ++J)
+ delete static_cast<ASTDeclContextNameLookupTable*>(*J);
+ }
+}
+
ASTReader::PerFileData::PerFileData()
: StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0),
LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0),
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 0ee8c83183..d2fb408e56 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1402,10 +1402,26 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
if (ReadDeclContextStorage(DeclsCursor, Offsets, Info))
return 0;
DeclContextInfos &Infos = DeclContextOffsets[DC];
- // Reading the TU will happen after reading its 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.
+ // 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.
+ DeclContextVisibleUpdatesPending::iterator I =
+ PendingVisibleUpdates.find(ID);
+ if (I != PendingVisibleUpdates.end()) {
+ DeclContextVisibleUpdates &U = I->second;
+ Info.LexicalDecls = 0;
+ Info.NumLexicalDecls = 0;
+ for (DeclContextVisibleUpdates::iterator UI = U.begin(), UE = U.end();
+ UI != UE; ++UI) {
+ Info.NameLookupTableData = *UI;
+ Infos.push_back(Info);
+ }
+ PendingVisibleUpdates.erase(I);
+ }
}
}
assert(Idx == Record.size());