Allow loading declcontext information from any file in the chain. Properly write source locations to dependent files. WIP

llvm-svn: 109119
This commit is contained in:
Sebastian Redl 2010-07-22 17:01:13 +00:00
parent fac440cfb6
commit 5c415f3e32
4 changed files with 111 additions and 72 deletions

View File

@ -300,7 +300,14 @@ private:
/// = I + 1 has already been loaded.
std::vector<Decl *> DeclsLoaded;
typedef llvm::DenseMap<const DeclContext *, std::pair<uint64_t, uint64_t> >
/// \brief Information about the contents of a DeclContext.
struct DeclContextInfo {
llvm::BitstreamCursor *Stream;
uint64_t OffsetToLexicalDecls;
uint64_t OffsetToVisibleDecls;
};
typedef llvm::SmallVector<DeclContextInfo, 1> DeclContextInfos;
typedef llvm::DenseMap<const DeclContext *, DeclContextInfos>
DeclContextOffsetsMap;
/// \brief Offsets of the lexical and visible declarations for each
@ -644,6 +651,11 @@ public:
/// \brief Read preprocessed entities into the
virtual void ReadPreprocessedEntities();
/// \brief Returns the number of source locations found in this file.
unsigned getTotalNumSLocs() const {
return TotalNumSLocEntries;
}
/// \brief Returns the number of types found in this file.
unsigned getTotalNumTypes() const {
return static_cast<unsigned>(TypesLoaded.size());

View File

@ -1779,6 +1779,10 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {
for (unsigned J = 0, M = Chain.size(); J != M; ++J) {
PCHIdentifierLookupTable *IdTable
= (PCHIdentifierLookupTable *)Chain[J]->IdentifierLookupTable;
// Not all PCH files necessarily have identifier tables, only the useful
// ones.
if (!IdTable)
continue;
for (unsigned I = 0, N = Identifiers.size(); I != N; ++I) {
IdentifierInfo *II = Identifiers[I];
// Look in the on-disk hash tables for an entry for this identifier
@ -2856,10 +2860,18 @@ Decl *PCHReader::GetDecl(pch::DeclID ID) {
/// source each time it is called, and is meant to be used via a
/// LazyOffsetPtr (which is used by Decls for the body of functions, etc).
Stmt *PCHReader::GetExternalDeclStmt(uint64_t Offset) {
// Since we know tha this statement is part of a decl, make sure to use the
// decl cursor to read it.
Chain[0]->DeclsCursor.JumpToBit(Offset);
return ReadStmtFromStream(Chain[0]->DeclsCursor);
// Offset here is a global offset across the entire chain.
for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
PerFileData &F = *Chain[N - I - 1];
if (Offset < F.SizeInBits) {
// Since we know that this statement is part of a decl, make sure to use
// the decl cursor to read it.
F.DeclsCursor.JumpToBit(Offset);
return ReadStmtFromStream(F.DeclsCursor);
}
Offset -= F.SizeInBits;
}
llvm_unreachable("Broken chain");
}
bool PCHReader::FindExternalLexicalDecls(const DeclContext *DC,
@ -2867,13 +2879,16 @@ bool PCHReader::FindExternalLexicalDecls(const DeclContext *DC,
assert(DC->hasExternalLexicalStorage() &&
"DeclContext has no lexical decls in storage");
uint64_t Offset = DeclContextOffsets[DC].first;
if (Offset == 0) {
Error("DeclContext has no lexical decls in storage");
return true;
}
llvm::BitstreamCursor &DeclsCursor = Chain[0]->DeclsCursor;
// There might be lexical decls in multiple parts of the chain, for the TU
// at least.
DeclContextInfos &Infos = DeclContextOffsets[DC];
for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
I != E; ++I) {
uint64_t Offset = I->OffsetToLexicalDecls;
// Offset can be 0 if this file only contains visible decls.
if (Offset == 0)
continue;
llvm::BitstreamCursor &DeclsCursor = *I->Stream;
// Keep track of where we are in the stream, then jump back there
// after reading this context.
@ -2891,8 +2906,10 @@ bool PCHReader::FindExternalLexicalDecls(const DeclContext *DC,
}
// Load all of the declaration IDs
for (RecordData::iterator I = Record.begin(), E = Record.end(); I != E; ++I)
Decls.push_back(GetDecl(*I));
for (RecordData::iterator J = Record.begin(), F = Record.end(); J != F; ++J)
Decls.push_back(GetDecl(*J));
}
++NumLexicalDeclContextsRead;
return false;
}
@ -2902,14 +2919,18 @@ PCHReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclarationName Name) {
assert(DC->hasExternalVisibleStorage() &&
"DeclContext has no visible decls in storage");
uint64_t Offset = DeclContextOffsets[DC].second;
if (Offset == 0) {
Error("DeclContext has no visible decls in storage");
return DeclContext::lookup_result(DeclContext::lookup_iterator(),
DeclContext::lookup_iterator());
}
llvm::BitstreamCursor &DeclsCursor = Chain[0]->DeclsCursor;
llvm::SmallVector<VisibleDeclaration, 64> Decls;
// There might be lexical decls in multiple parts of the chain, for the TU
// and namespaces.
DeclContextInfos &Infos = DeclContextOffsets[DC];
for (DeclContextInfos::iterator I = Infos.begin(), E = Infos.end();
I != E; ++I) {
uint64_t Offset = I->OffsetToVisibleDecls;
if (Offset == 0)
continue;
llvm::BitstreamCursor &DeclsCursor = *I->Stream;
// Keep track of where we are in the stream, then jump back there
// after reading this context.
@ -2927,12 +2948,8 @@ PCHReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
DeclContext::lookup_iterator());
}
llvm::SmallVector<VisibleDeclaration, 64> Decls;
if (Record.empty()) {
SetExternalVisibleDecls(DC, Decls);
return DeclContext::lookup_result(DeclContext::lookup_iterator(),
DeclContext::lookup_iterator());
}
if (Record.empty())
continue;
unsigned Idx = 0;
while (Idx < Record.size()) {
@ -2942,9 +2959,10 @@ PCHReader::FindExternalVisibleDeclsByName(const DeclContext *DC,
unsigned Size = Record[Idx++];
llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
LoadedDecls.reserve(Size);
for (unsigned I = 0; I < Size; ++I)
for (unsigned J = 0; J < Size; ++J)
LoadedDecls.push_back(Record[Idx++]);
}
}
++NumVisibleDeclContextsRead;
@ -3112,6 +3130,8 @@ IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
PCHIdentifierLookupTable *IdTable
= (PCHIdentifierLookupTable *)Chain[N - I - 1]->IdentifierLookupTable;
if (!IdTable)
continue;
std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
if (Pos == IdTable->end())

View File

@ -1497,7 +1497,12 @@ Decl *PCHReader::ReadDeclRecord(unsigned Index) {
if (Offsets.first || Offsets.second) {
DC->setHasExternalLexicalStorage(Offsets.first != 0);
DC->setHasExternalVisibleStorage(Offsets.second != 0);
DeclContextOffsets[DC] = Offsets;
PCHReader::DeclContextInfo Info = {
Loc.first,
Offsets.first,
Offsets.second
};
DeclContextOffsets[DC].push_back(Info);
}
}
assert(Idx == Record.size());

View File

@ -1099,8 +1099,10 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// entry, which is always the same dummy entry.
std::vector<uint32_t> SLocEntryOffsets;
RecordData PreloadSLocs;
SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1);
for (unsigned I = 1, N = SourceMgr.sloc_entry_size(); I != N; ++I) {
unsigned BaseSLocID = Chain ? Chain->getTotalNumSLocs() : 0;
SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1 - BaseSLocID);
for (unsigned I = BaseSLocID + 1, N = SourceMgr.sloc_entry_size();
I != N; ++I) {
// Get this source location entry.
const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I);
@ -1157,7 +1159,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
// FIXME: For now, preload all file source locations, so that
// we get the appropriate File entries in the reader. This is
// a temporary measure.
PreloadSLocs.push_back(SLocEntryOffsets.size());
PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size());
} else {
// The source location entry is a buffer. The blob associated
// with this entry contains the contents of the buffer.
@ -1177,7 +1179,7 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,
Buffer->getBufferSize() + 1));
if (strcmp(Name, "<built-in>") == 0)
PreloadSLocs.push_back(SLocEntryOffsets.size());
PreloadSLocs.push_back(BaseSLocID + SLocEntryOffsets.size());
}
} else {
// The source location entry is an instantiation.