aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r--lib/Serialization/ASTReader.cpp151
1 files changed, 128 insertions, 23 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index b7266ebbba..cdb9646758 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -573,7 +573,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
// definition.
if (hadMacroDefinition) {
// FIXME: Check for conflicts?
- uint32_t Offset = ReadUnalignedLE32(d);
+ uint32_t LocalID = ReadUnalignedLE32(d);
unsigned LocalSubmoduleID = ReadUnalignedLE32(d);
// Determine whether this macro definition should be visible now, or
@@ -594,7 +594,8 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k,
}
}
- Reader.setIdentifierIsMacro(II, F, Offset, Visible && hasMacroDefinition);
+ Reader.setIdentifierIsMacro(II, Reader.getGlobalMacroID(F, LocalID),
+ Visible && hasMacroDefinition);
DataLen -= 8;
}
@@ -1314,10 +1315,19 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
return;
}
- unsigned NextIndex = 1;
+ unsigned GlobalID = getGlobalMacroID(F, Record[1]);
+
+ // If this macro has already been loaded, don't do so again.
+ if (MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS])
+ return;
+
+ unsigned NextIndex = 2;
SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);
MacroInfo *MI = PP.AllocateMacroInfo(Loc);
+ // Record this macro.
+ MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS] = MI;
+
SourceLocation UndefLoc = ReadSourceLocation(F, Record, NextIndex);
if (UndefLoc.isValid())
MI->setUndefLoc(UndefLoc);
@@ -1345,6 +1355,20 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
PP.getPreprocessorAllocator());
}
+ if (DeserializationListener)
+ DeserializationListener->MacroRead(GlobalID, MI);
+
+ // If an update record marked this as undefined, do so now.
+ MacroUpdatesMap::iterator Update = MacroUpdates.find(GlobalID);
+ if (Update != MacroUpdates.end()) {
+ if (MI->getUndefLoc().isInvalid()) {
+ MI->setUndefLoc(Update->second.UndefLoc);
+ if (PPMutationListener *Listener = PP.getPPMutationListener())
+ Listener->UndefinedMacro(MI);
+ }
+ MacroUpdates.erase(Update);
+ }
+
// Finally, install the macro.
PP.setMacroInfo(II, MI, /*LoadedFromAST=*/true);
@@ -1455,17 +1479,18 @@ HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d,
return HFI;
}
-void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, ModuleFile &F,
- uint64_t LocalOffset, bool Visible) {
+void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, MacroID ID,
+ bool Visible) {
if (Visible) {
// Note that this identifier has a macro definition.
II->setHasMacroDefinition(true);
} else {
II->setHadMacroDefinition(true);
}
-
- // Adjust the offset to a global offset.
- UnreadMacroRecordOffsets[II] = F.GlobalBitOffset + LocalOffset;
+
+ // FIXME: This could end up overwriting a previously recording macro
+ // definition here, which is not cool at all.
+ UnreadMacroIDs[II] = ID;
}
void ASTReader::ReadDefinedMacros() {
@@ -1522,23 +1547,21 @@ void ASTReader::ReadDefinedMacros() {
}
// Drain the unread macro-record offsets map.
- while (!UnreadMacroRecordOffsets.empty())
- LoadMacroDefinition(UnreadMacroRecordOffsets.begin());
+ while (!UnreadMacroIDs.empty())
+ LoadMacroDefinition(UnreadMacroIDs.begin());
}
void ASTReader::LoadMacroDefinition(
- llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos) {
- assert(Pos != UnreadMacroRecordOffsets.end() && "Unknown macro definition");
- uint64_t Offset = Pos->second;
- UnreadMacroRecordOffsets.erase(Pos);
-
- RecordLocation Loc = getLocalBitOffset(Offset);
- ReadMacroRecord(*Loc.F, Loc.Offset);
+ llvm::DenseMap<IdentifierInfo *, MacroID>::iterator Pos) {
+ assert(Pos != UnreadMacroIDs.end() && "Unknown macro definition");
+ uint64_t GlobalID = Pos->second;
+ UnreadMacroIDs.erase(Pos);
+ getMacro(GlobalID);
}
void ASTReader::LoadMacroDefinition(IdentifierInfo *II) {
- llvm::DenseMap<IdentifierInfo *, uint64_t>::iterator Pos
- = UnreadMacroRecordOffsets.find(II);
+ llvm::DenseMap<IdentifierInfo *, MacroID>::iterator Pos
+ = UnreadMacroIDs.find(II);
LoadMacroDefinition(Pos);
}
@@ -1959,7 +1982,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
}
break;
}
-
+
case EXTERNAL_DEFINITIONS:
for (unsigned I = 0, N = Record.size(); I != N; ++I)
ExternalDefinitions.push_back(getGlobalDeclID(F, Record[I]));
@@ -2109,7 +2132,9 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
ContinuousRangeMap<uint32_t, int, 2>::Builder SLocRemap(F.SLocRemap);
ContinuousRangeMap<uint32_t, int, 2>::Builder
IdentifierRemap(F.IdentifierRemap);
- ContinuousRangeMap<uint32_t, int, 2>::Builder
+ ContinuousRangeMap<uint32_t, int, 2>::Builder
+ MacroRemap(F.MacroRemap);
+ ContinuousRangeMap<uint32_t, int, 2>::Builder
PreprocessedEntityRemap(F.PreprocessedEntityRemap);
ContinuousRangeMap<uint32_t, int, 2>::Builder
SubmoduleRemap(F.SubmoduleRemap);
@@ -2130,6 +2155,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
uint32_t SLocOffset = io::ReadUnalignedLE32(Data);
uint32_t IdentifierIDOffset = io::ReadUnalignedLE32(Data);
+ uint32_t MacroIDOffset = io::ReadUnalignedLE32(Data);
uint32_t PreprocessedEntityIDOffset = io::ReadUnalignedLE32(Data);
uint32_t SubmoduleIDOffset = io::ReadUnalignedLE32(Data);
uint32_t SelectorIDOffset = io::ReadUnalignedLE32(Data);
@@ -2142,6 +2168,8 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
IdentifierRemap.insert(
std::make_pair(IdentifierIDOffset,
OM->BaseIdentifierID - IdentifierIDOffset));
+ MacroRemap.insert(std::make_pair(MacroIDOffset,
+ OM->BaseMacroID - MacroIDOffset));
PreprocessedEntityRemap.insert(
std::make_pair(PreprocessedEntityIDOffset,
OM->BasePreprocessedEntityID - PreprocessedEntityIDOffset));
@@ -2458,6 +2486,41 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
}
break;
}
+
+ case MACRO_OFFSET: {
+ if (F.LocalNumMacros != 0) {
+ Error("duplicate MACRO_OFFSET record in AST file");
+ return Failure;
+ }
+ F.MacroOffsets = (const uint32_t *)BlobStart;
+ F.LocalNumMacros = Record[0];
+ unsigned LocalBaseMacroID = Record[1];
+ F.BaseMacroID = getTotalNumMacros();
+
+ if (F.LocalNumMacros > 0) {
+ // Introduce the global -> local mapping for macros within this module.
+ GlobalMacroMap.insert(std::make_pair(getTotalNumMacros() + 1, &F));
+
+ // Introduce the local -> global mapping for macros within this module.
+ F.MacroRemap.insertOrReplace(
+ std::make_pair(LocalBaseMacroID,
+ F.BaseMacroID - LocalBaseMacroID));
+
+ MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros);
+ }
+ break;
+ }
+
+ case MACRO_UPDATES: {
+ for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
+ MacroID ID = getGlobalMacroID(F, Record[I++]);
+ if (I == N)
+ break;
+
+ MacroUpdates[ID].UndefLoc = ReadSourceLocation(F, Record, I);
+ }
+ break;
+ }
}
}
Error("premature end of bitstream in AST file");
@@ -5195,6 +5258,10 @@ void ASTReader::PrintStats() {
= IdentifiersLoaded.size() - std::count(IdentifiersLoaded.begin(),
IdentifiersLoaded.end(),
(IdentifierInfo *)0);
+ unsigned NumMacrosLoaded
+ = MacrosLoaded.size() - std::count(MacrosLoaded.begin(),
+ MacrosLoaded.end(),
+ (MacroInfo *)0);
unsigned NumSelectorsLoaded
= SelectorsLoaded.size() - std::count(SelectorsLoaded.begin(),
SelectorsLoaded.end(),
@@ -5218,6 +5285,10 @@ void ASTReader::PrintStats() {
std::fprintf(stderr, " %u/%u identifiers read (%f%%)\n",
NumIdentifiersLoaded, (unsigned)IdentifiersLoaded.size(),
((float)NumIdentifiersLoaded/IdentifiersLoaded.size() * 100));
+ if (!MacrosLoaded.empty())
+ std::fprintf(stderr, " %u/%u macros read (%f%%)\n",
+ NumMacrosLoaded, (unsigned)MacrosLoaded.size(),
+ ((float)NumMacrosLoaded/MacrosLoaded.size() * 100));
if (!SelectorsLoaded.empty())
std::fprintf(stderr, " %u/%u selectors read (%f%%)\n",
NumSelectorsLoaded, (unsigned)SelectorsLoaded.size(),
@@ -5276,6 +5347,7 @@ void ASTReader::dump() {
dumpModuleIDMap("Global type map", GlobalTypeMap);
dumpModuleIDMap("Global declaration map", GlobalDeclMap);
dumpModuleIDMap("Global identifier map", GlobalIdentifierMap);
+ dumpModuleIDMap("Global macro map", GlobalMacroMap);
dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
dumpModuleIDMap("Global selector map", GlobalSelectorMap);
dumpModuleIDMap("Global preprocessed entity map",
@@ -5746,6 +5818,39 @@ IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, unsigned LocalID) {
return LocalID + I->second;
}
+MacroInfo *ASTReader::getMacro(MacroID ID) {
+ if (ID == 0)
+ return 0;
+
+ if (MacrosLoaded.empty()) {
+ Error("no macro table in AST file");
+ return 0;
+ }
+
+ ID -= NUM_PREDEF_MACRO_IDS;
+ if (!MacrosLoaded[ID]) {
+ GlobalMacroMapType::iterator I
+ = GlobalMacroMap.find(ID + NUM_PREDEF_MACRO_IDS);
+ assert(I != GlobalMacroMap.end() && "Corrupted global macro map");
+ ModuleFile *M = I->second;
+ unsigned Index = ID - M->BaseMacroID;
+ ReadMacroRecord(*M, M->MacroOffsets[Index]);
+ }
+
+ return MacrosLoaded[ID];
+}
+
+MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) {
+ if (LocalID < NUM_PREDEF_MACRO_IDS)
+ return LocalID;
+
+ ContinuousRangeMap<uint32_t, int, 2>::iterator I
+ = M.MacroRemap.find(LocalID - NUM_PREDEF_MACRO_IDS);
+ assert(I != M.MacroRemap.end() && "Invalid index into macro index remap");
+
+ return LocalID + I->second;
+}
+
bool ASTReader::ReadSLocEntry(int ID) {
return ReadSLocEntryRecord(ID) != Success;
}
@@ -5758,7 +5863,7 @@ ASTReader::getGlobalSubmoduleID(ModuleFile &M, unsigned LocalID) {
ContinuousRangeMap<uint32_t, int, 2>::iterator I
= M.SubmoduleRemap.find(LocalID - NUM_PREDEF_SUBMODULE_IDS);
assert(I != M.SubmoduleRemap.end()
- && "Invalid index into identifier index remap");
+ && "Invalid index into submodule index remap");
return LocalID + I->second;
}
@@ -5823,7 +5928,7 @@ ASTReader::getGlobalSelectorID(ModuleFile &M, unsigned LocalID) const {
ContinuousRangeMap<uint32_t, int, 2>::iterator I
= M.SelectorRemap.find(LocalID - NUM_PREDEF_SELECTOR_IDS);
assert(I != M.SelectorRemap.end()
- && "Invalid index into identifier index remap");
+ && "Invalid index into selector index remap");
return LocalID + I->second;
}