Allow loading macros from any file in the chain. WIP
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109048 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index 19e9842..c3dce5d 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -573,6 +573,7 @@
namespace {
class PCHIdentifierLookupTrait {
PCHReader &Reader;
+ llvm::BitstreamCursor &Stream;
// If we know the IdentifierInfo in advance, it is here and we will
// not build a new one. Used when deserializing information about an
@@ -586,8 +587,9 @@
typedef external_key_type internal_key_type;
- explicit PCHIdentifierLookupTrait(PCHReader &Reader, IdentifierInfo *II = 0)
- : Reader(Reader), KnownII(II) { }
+ PCHIdentifierLookupTrait(PCHReader &Reader, llvm::BitstreamCursor &Stream,
+ IdentifierInfo *II = 0)
+ : Reader(Reader), Stream(Stream), KnownII(II) { }
static bool EqualKey(const internal_key_type& a,
const internal_key_type& b) {
@@ -676,7 +678,7 @@
// definition.
if (hasMacroDefinition) {
uint32_t Offset = ReadUnalignedLE32(d);
- Reader.ReadMacroRecord(Offset);
+ Reader.ReadMacroRecord(Stream, Offset);
DataLen -= 4;
}
@@ -1114,11 +1116,9 @@
}
}
-void PCHReader::ReadMacroRecord(uint64_t Offset) {
+void PCHReader::ReadMacroRecord(llvm::BitstreamCursor &Stream, uint64_t Offset){
assert(PP && "Forgot to set Preprocessor ?");
- llvm::BitstreamCursor &Stream = Chain[0]->Stream;
-
// Keep track of where we are in the stream, then jump back there
// after reading this macro.
SavedStreamPosition SavedPosition(Stream);
@@ -1288,64 +1288,68 @@
}
void PCHReader::ReadDefinedMacros() {
- llvm::BitstreamCursor &MacroCursor = Chain[0]->MacroCursor;
+ for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+ llvm::BitstreamCursor &MacroCursor = Chain[N - I - 1]->MacroCursor;
- // If there was no preprocessor block, do nothing.
- if (!MacroCursor.getBitStreamReader())
- return;
+ // If there was no preprocessor block, skip this file.
+ if (!MacroCursor.getBitStreamReader())
+ continue;
- llvm::BitstreamCursor Cursor = MacroCursor;
- if (Cursor.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID)) {
- Error("malformed preprocessor block record in PCH file");
- return;
- }
-
- RecordData Record;
- while (true) {
- unsigned Code = Cursor.ReadCode();
- if (Code == llvm::bitc::END_BLOCK) {
- if (Cursor.ReadBlockEnd())
- Error("error at end of preprocessor block in PCH file");
+ llvm::BitstreamCursor Cursor = MacroCursor;
+ if (Cursor.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID)) {
+ Error("malformed preprocessor block record in PCH file");
return;
}
- if (Code == llvm::bitc::ENTER_SUBBLOCK) {
- // No known subblocks, always skip them.
- Cursor.ReadSubBlockID();
- if (Cursor.SkipBlock()) {
- Error("malformed block record in PCH file");
- return;
+ RecordData Record;
+ while (true) {
+ unsigned Code = Cursor.ReadCode();
+ if (Code == llvm::bitc::END_BLOCK) {
+ if (Cursor.ReadBlockEnd()) {
+ Error("error at end of preprocessor block in PCH file");
+ return;
+ }
+ break;
}
- continue;
- }
- if (Code == llvm::bitc::DEFINE_ABBREV) {
- Cursor.ReadAbbrevRecord();
- continue;
- }
+ if (Code == llvm::bitc::ENTER_SUBBLOCK) {
+ // No known subblocks, always skip them.
+ Cursor.ReadSubBlockID();
+ if (Cursor.SkipBlock()) {
+ Error("malformed block record in PCH file");
+ return;
+ }
+ continue;
+ }
- // Read a record.
- const char *BlobStart;
- unsigned BlobLen;
- Record.clear();
- switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
- default: // Default behavior: ignore.
- break;
+ if (Code == llvm::bitc::DEFINE_ABBREV) {
+ Cursor.ReadAbbrevRecord();
+ continue;
+ }
- case pch::PP_MACRO_OBJECT_LIKE:
- case pch::PP_MACRO_FUNCTION_LIKE:
- DecodeIdentifierInfo(Record[0]);
- break;
+ // Read a record.
+ const char *BlobStart;
+ unsigned BlobLen;
+ Record.clear();
+ switch (Cursor.ReadRecord(Code, Record, &BlobStart, &BlobLen)) {
+ default: // Default behavior: ignore.
+ break;
- case pch::PP_TOKEN:
- // Ignore tokens.
- break;
+ case pch::PP_MACRO_OBJECT_LIKE:
+ case pch::PP_MACRO_FUNCTION_LIKE:
+ DecodeIdentifierInfo(Record[0]);
+ break;
+
+ case pch::PP_TOKEN:
+ // Ignore tokens.
+ break;
- case pch::PP_MACRO_INSTANTIATION:
- case pch::PP_MACRO_DEFINITION:
- // Read the macro record.
- ReadMacroRecord(Cursor.GetCurrentBitNo());
- break;
+ case pch::PP_MACRO_INSTANTIATION:
+ case pch::PP_MACRO_DEFINITION:
+ // Read the macro record.
+ ReadMacroRecord(Chain[N - I - 1]->Stream, Cursor.GetCurrentBitNo());
+ break;
+ }
}
}
}
@@ -1353,10 +1357,20 @@
MacroDefinition *PCHReader::getMacroDefinition(pch::IdentID ID) {
if (ID == 0 || ID >= MacroDefinitionsLoaded.size())
return 0;
-
- if (!MacroDefinitionsLoaded[ID])
- ReadMacroRecord(Chain[0]->MacroDefinitionOffsets[ID]);
-
+
+ if (!MacroDefinitionsLoaded[ID]) {
+ unsigned Index = ID;
+ for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+ PerFileData &F = *Chain[N - I - 1];
+ if (Index < F.LocalNumMacroDefinitions) {
+ ReadMacroRecord(F.Stream, F.MacroDefinitionOffsets[Index]);
+ break;
+ }
+ Index -= F.LocalNumMacroDefinitions;
+ }
+ assert(MacroDefinitionsLoaded[ID] && "Broken chain");
+ }
+
return MacroDefinitionsLoaded[ID];
}
@@ -1533,7 +1547,7 @@
= PCHIdentifierLookupTable::Create(
(const unsigned char *)F.IdentifierTableData + Record[0],
(const unsigned char *)F.IdentifierTableData,
- PCHIdentifierLookupTrait(*this));
+ PCHIdentifierLookupTrait(*this, F.Stream));
if (PP)
PP->getIdentifierTable().setExternalIdentifierLookup(this);
}
@@ -1768,7 +1782,7 @@
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
- PCHIdentifierLookupTrait Info(*this, II);
+ PCHIdentifierLookupTrait Info(*this, Chain[J]->Stream, II);
std::pair<const char*,unsigned> Key(II->getNameStart(),II->getLength());
PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);
if (Pos == IdTable->end())
@@ -3092,18 +3106,23 @@
}
IdentifierInfo* PCHReader::get(const char *NameStart, const char *NameEnd) {
- // Try to find this name within our on-disk hash table
- PCHIdentifierLookupTable *IdTable
- = (PCHIdentifierLookupTable *)Chain[0]->IdentifierLookupTable;
- std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
- PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
- if (Pos == IdTable->end())
- return 0;
+ // Try to find this name within our on-disk hash tables. We need to aggregate
+ // the info from all of them.
+ IdentifierInfo *II = 0;
+ for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
+ PCHIdentifierLookupTable *IdTable
+ = (PCHIdentifierLookupTable *)Chain[N - I - 1]->IdentifierLookupTable;
+ std::pair<const char*, unsigned> Key(NameStart, NameEnd - NameStart);
+ PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key);
+ if (Pos == IdTable->end())
+ continue;
- // Dereferencing the iterator has the effect of building the
- // IdentifierInfo node and populating it with the various
- // declarations it needs.
- return *Pos;
+ // Dereferencing the iterator has the effect of building the
+ // IdentifierInfo node and populating it with the various
+ // declarations it needs.
+ II = *Pos;
+ }
+ return II;
}
std::pair<ObjCMethodList, ObjCMethodList>