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
This commit is contained in:
Sebastian Redl 2010-08-24 00:50:04 +00:00
Родитель 0ea8f7f5a4
Коммит e1dde811b3
3 изменённых файлов: 109 добавлений и 42 удалений

Просмотреть файл

@ -343,14 +343,29 @@ private:
const serialization::DeclID *LexicalDecls; const serialization::DeclID *LexicalDecls;
unsigned NumLexicalDecls; 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::SmallVector<DeclContextInfo, 1> DeclContextInfos;
typedef llvm::DenseMap<const DeclContext *, 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 /// \brief Offsets of the lexical and visible declarations for each
/// DeclContext. /// DeclContext.
DeclContextOffsetsMap DeclContextOffsets; 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> typedef llvm::DenseMap<serialization::DeclID, serialization::DeclID>
FirstLatestDeclIDMap; FirstLatestDeclIDMap;
/// \brief Map of first declarations from a chained PCH that point to the /// \brief Map of first declarations from a chained PCH that point to the

Просмотреть файл

@ -412,43 +412,6 @@ void PCHValidator::ReadCounter(unsigned Value) {
// AST reader implementation // 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 void
ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) { ASTReader::setDeserializationListener(ASTDeserializationListener *Listener) {
DeserializationListener = Listener; DeserializationListener = Listener;
@ -1770,6 +1733,22 @@ ASTReader::ReadASTBlock(PerFileData &F) {
break; 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: { case REDECLS_UPDATE_LATEST: {
assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs"); assert(Record.size() % 2 == 0 && "Expected pairs of DeclIDs");
for (unsigned i = 0, e = Record.size(); i < e; i += 2) { for (unsigned i = 0, e = Record.size(); i < e; i += 2) {
@ -3130,7 +3109,7 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) {
TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() { TranslationUnitDecl *ASTReader::GetTranslationUnitDecl() {
if (!DeclsLoaded[0]) { if (!DeclsLoaded[0]) {
ReadDeclRecord(0, 0); ReadDeclRecord(0, 1);
if (DeserializationListener) if (DeserializationListener)
DeserializationListener->DeclRead(1, DeclsLoaded[0]); DeserializationListener->DeclRead(1, DeclsLoaded[0]);
} }
@ -4084,6 +4063,63 @@ void ASTReader::FinishedDeserializing() {
--NumCurrentElementsDeserializing; --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() ASTReader::PerFileData::PerFileData()
: StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0), : StatCache(0), LocalNumSLocEntries(0), LocalNumTypes(0), TypeOffsets(0),
LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0), LocalNumDecls(0), DeclOffsets(0), LocalNumIdentifiers(0),

Просмотреть файл

@ -1402,10 +1402,26 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
if (ReadDeclContextStorage(DeclsCursor, Offsets, Info)) if (ReadDeclContextStorage(DeclsCursor, Offsets, Info))
return 0; return 0;
DeclContextInfos &Infos = DeclContextOffsets[DC]; DeclContextInfos &Infos = DeclContextOffsets[DC];
// Reading the TU will happen after reading its update blocks, so we need // Reading the TU will happen after reading its lexical update blocks,
// to make sure we insert in front. For all other contexts, the vector // so we need to make sure we insert in front. For all other contexts,
// is empty here anyway, so there's no loss in efficiency. // the vector is empty here anyway, so there's no loss in efficiency.
Infos.insert(Infos.begin(), Info); 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()); assert(Idx == Record.size());