forked from OSchip/llvm-project
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:
parent
fac440cfb6
commit
5c415f3e32
|
@ -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());
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue