Read the UPDATE_VISIBLE record, and add its visible decls to the lookup tables. Also, free the lookup tables when destructing the ASTReader.

llvm-svn: 111880
This commit is contained in:
Sebastian Redl 2010-08-24 00:50:04 +00:00
parent 9d8f58b5d7
commit d7dce0a44d
3 changed files with 109 additions and 42 deletions

View File

@ -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

View File

@ -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),

View File

@ -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());