aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2010-07-22 17:01:13 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2010-07-22 17:01:13 +0000
commit0fa7d0b15ea2a224bfe43ac745d411f915da87dd (patch)
tree0349170c561edec5800ab425f75d9d8b37e29ba8
parent554e6aa2da082575514607c3639c246c04b3232a (diff)
Allow loading declcontext information from any file in the chain. Properly write source locations to dependent files. WIP
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109119 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Frontend/PCHReader.h14
-rw-r--r--lib/Frontend/PCHReader.cpp142
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp7
-rw-r--r--lib/Frontend/PCHWriter.cpp10
4 files changed, 106 insertions, 67 deletions
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index b88a1d2938..34712369e7 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -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());
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index c3dce5df9d..cc44c30072 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -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,32 +2879,37 @@ 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;
- }
+ // 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;
- llvm::BitstreamCursor &DeclsCursor = Chain[0]->DeclsCursor;
+ // Keep track of where we are in the stream, then jump back there
+ // after reading this context.
+ SavedStreamPosition SavedPosition(DeclsCursor);
- // Keep track of where we are in the stream, then jump back there
- // after reading this context.
- SavedStreamPosition SavedPosition(DeclsCursor);
+ // Load the record containing all of the declarations lexically in
+ // this context.
+ DeclsCursor.JumpToBit(Offset);
+ RecordData Record;
+ unsigned Code = DeclsCursor.ReadCode();
+ unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
+ if (RecCode != pch::DECL_CONTEXT_LEXICAL) {
+ Error("Expected lexical block");
+ return true;
+ }
- // Load the record containing all of the declarations lexically in
- // this context.
- DeclsCursor.JumpToBit(Offset);
- RecordData Record;
- unsigned Code = DeclsCursor.ReadCode();
- unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
- if (RecCode != pch::DECL_CONTEXT_LEXICAL) {
- Error("Expected lexical block");
- return true;
+ // Load all of the declaration IDs
+ for (RecordData::iterator J = Record.begin(), F = Record.end(); J != F; ++J)
+ Decls.push_back(GetDecl(*J));
}
- // Load all of the declaration IDs
- for (RecordData::iterator I = Record.begin(), E = Record.end(); I != E; ++I)
- Decls.push_back(GetDecl(*I));
++NumLexicalDeclContextsRead;
return false;
}
@@ -2902,48 +2919,49 @@ 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.
- SavedStreamPosition SavedPosition(DeclsCursor);
+ // Keep track of where we are in the stream, then jump back there
+ // after reading this context.
+ SavedStreamPosition SavedPosition(DeclsCursor);
- // Load the record containing all of the declarations visible in
- // this context.
- DeclsCursor.JumpToBit(Offset);
- RecordData Record;
- unsigned Code = DeclsCursor.ReadCode();
- unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
- if (RecCode != pch::DECL_CONTEXT_VISIBLE) {
- Error("Expected visible block");
- return DeclContext::lookup_result(DeclContext::lookup_iterator(),
- DeclContext::lookup_iterator());
- }
+ // Load the record containing all of the declarations visible in
+ // this context.
+ DeclsCursor.JumpToBit(Offset);
+ RecordData Record;
+ unsigned Code = DeclsCursor.ReadCode();
+ unsigned RecCode = DeclsCursor.ReadRecord(Code, Record);
+ if (RecCode != pch::DECL_CONTEXT_VISIBLE) {
+ Error("Expected visible block");
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(),
+ 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()) {
- Decls.push_back(VisibleDeclaration());
- Decls.back().Name = ReadDeclarationName(Record, Idx);
+ unsigned Idx = 0;
+ while (Idx < Record.size()) {
+ Decls.push_back(VisibleDeclaration());
+ Decls.back().Name = ReadDeclarationName(Record, Idx);
- unsigned Size = Record[Idx++];
- llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
- LoadedDecls.reserve(Size);
- for (unsigned I = 0; I < Size; ++I)
- LoadedDecls.push_back(Record[Idx++]);
+ unsigned Size = Record[Idx++];
+ llvm::SmallVector<unsigned, 4> &LoadedDecls = Decls.back().Declarations;
+ LoadedDecls.reserve(Size);
+ 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())
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index d562d6f621..7297fefcb2 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -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());
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index d8ce4e3b6e..b97aecbd8c 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -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.