зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
0ea8f7f5a4
Коммит
e1dde811b3
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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());
|
||||
|
|
Загрузка…
Ссылка в новой задаче