зеркало из 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;
|
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());
|
||||||
|
|
Загрузка…
Ссылка в новой задаче