[clang] [Serialization] No transitive change for MacroID and PreprocessedEntityID (#166346)
Similar to previous no transitive changes to decls, types, identifiers and source locations ( https://github.com/llvm/llvm-project/pull/92083 https://github.com/llvm/llvm-project/pull/92085 https://github.com/llvm/llvm-project/pull/92511 https://github.com/llvm/llvm-project/pull/86912 ) This patch does the same thing for MacroID and PreprocessedEntityID. --- ### Some background Previously we record different IDs linearly. That is, when writing a module, if we have 17 decls in imported modules, the ID of decls in the module will start from 18. This makes the contents of the BMI changes if the we add/remove any decls, types, identifiers and source locations in the imported modules. This makes it hard for us to reduce recompilations with modules. We want to skip recompilations as we think the modules can help us to remove fake dependencies. This can be done by split the ID into <ModuleIndex, LocalIndex> pairs. This is ALREADY done for several different ID above. We call it non-casacading changes (https://clang.llvm.org/docs/StandardCPlusPlusModules.html#experimental-non-cascading-changes). Our internal users have already used this feature and it works well for years. Now we want to extend this to MacroID and PreprocessedEntityID. This is helpful for us in the downstream as we allowed named modules to export macros. But I believe this is also helpful for header-like modules if you'd like to explore the area. And also I think this is a nice cleanup too. --- Given the use of MacroID and PreprocessedEntityID are not as complicated as other IDs in the above series, I feel the patch itself should be good. I hope the vendors can test the patch to make sure it won't affect existing users.
This commit is contained in:
parent
61218267a5
commit
3cda32d590
@ -151,14 +151,14 @@ struct UnsafeQualTypeDenseMapInfo {
|
||||
};
|
||||
|
||||
/// An ID number that refers to a macro in an AST file.
|
||||
using MacroID = uint32_t;
|
||||
using MacroID = uint64_t;
|
||||
|
||||
/// A global ID number that refers to a macro in an AST file.
|
||||
using GlobalMacroID = uint32_t;
|
||||
using GlobalMacroID = uint64_t;
|
||||
|
||||
/// A local to a module ID number that refers to a macro in an
|
||||
/// AST file.
|
||||
using LocalMacroID = uint32_t;
|
||||
using LocalMacroID = uint64_t;
|
||||
|
||||
/// The number of predefined macro IDs.
|
||||
const unsigned int NUM_PREDEF_MACRO_IDS = 1;
|
||||
@ -179,7 +179,7 @@ using CXXCtorInitializersID = uint32_t;
|
||||
|
||||
/// An ID number that refers to an entity in the detailed
|
||||
/// preprocessing record.
|
||||
using PreprocessedEntityID = uint32_t;
|
||||
using PreprocessedEntityID = uint64_t;
|
||||
|
||||
/// An ID number that refers to a submodule in a module file.
|
||||
using SubmoduleID = uint32_t;
|
||||
|
||||
@ -800,14 +800,6 @@ private:
|
||||
/// files.
|
||||
llvm::DenseSet<LoadedMacroInfo> LoadedUndefs;
|
||||
|
||||
using GlobalMacroMapType =
|
||||
ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>;
|
||||
|
||||
/// Mapping from global macro IDs to the module in which the
|
||||
/// macro resides along with the offset that should be added to the
|
||||
/// global macro ID to produce a local ID.
|
||||
GlobalMacroMapType GlobalMacroMap;
|
||||
|
||||
/// A vector containing submodules that have already been loaded.
|
||||
///
|
||||
/// This vector is indexed by the Submodule ID (-1). NULL submodule entries
|
||||
@ -1655,8 +1647,7 @@ private:
|
||||
|
||||
/// Returns the first preprocessed entity ID that begins or ends after
|
||||
/// \arg Loc.
|
||||
serialization::PreprocessedEntityID
|
||||
findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const;
|
||||
unsigned findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const;
|
||||
|
||||
/// Find the next module that contains entities and return the ID
|
||||
/// of the first entry.
|
||||
@ -1664,9 +1655,8 @@ private:
|
||||
/// \param SLocMapI points at a chunk of a module that contains no
|
||||
/// preprocessed entities or the entities it contains are not the
|
||||
/// ones we are looking for.
|
||||
serialization::PreprocessedEntityID
|
||||
findNextPreprocessedEntity(
|
||||
GlobalSLocOffsetMapType::const_iterator SLocMapI) const;
|
||||
unsigned findNextPreprocessedEntity(
|
||||
GlobalSLocOffsetMapType::const_iterator SLocMapI) const;
|
||||
|
||||
/// Returns (ModuleFile, Local index) pair for \p GlobalIndex of a
|
||||
/// preprocessed entity.
|
||||
@ -1748,6 +1738,14 @@ private:
|
||||
std::pair<ModuleFile *, unsigned>
|
||||
translateIdentifierIDToIndex(serialization::IdentifierID ID) const;
|
||||
|
||||
/// Translate an \param MacroID ID to the index of MacrosLoaded
|
||||
/// array and the corresponding module file.
|
||||
std::pair<ModuleFile *, unsigned>
|
||||
translateMacroIDToIndex(serialization::MacroID ID) const;
|
||||
|
||||
unsigned translatePreprocessedEntityIDToIndex(
|
||||
serialization::PreprocessedEntityID ID) const;
|
||||
|
||||
/// Translate an \param TypeID ID to the index of TypesLoaded
|
||||
/// array and the corresponding module file.
|
||||
std::pair<ModuleFile *, unsigned>
|
||||
@ -2163,6 +2161,14 @@ public:
|
||||
LocalDeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M,
|
||||
GlobalDeclID GlobalID);
|
||||
|
||||
/// Reads a macro ID from the given position in a record in the
|
||||
/// given module.
|
||||
///
|
||||
/// \returns The declaration ID read from the record, adjusted to a global
|
||||
/// Macro ID.
|
||||
serialization::MacroID
|
||||
ReadMacroID(ModuleFile &F, const RecordDataImpl &Record, unsigned &Idx);
|
||||
|
||||
/// Reads a declaration ID from the given position in a record in the
|
||||
/// given module.
|
||||
///
|
||||
@ -2388,7 +2394,8 @@ public:
|
||||
|
||||
/// Retrieve the global macro ID corresponding to the given local
|
||||
/// ID within the given module file.
|
||||
serialization::MacroID getGlobalMacroID(ModuleFile &M, unsigned LocalID);
|
||||
serialization::MacroID getGlobalMacroID(ModuleFile &M,
|
||||
serialization::MacroID LocalID);
|
||||
|
||||
/// Read the source location entry with index ID.
|
||||
bool ReadSLocEntry(int ID) override;
|
||||
@ -2572,8 +2579,8 @@ public:
|
||||
|
||||
/// Determine the global preprocessed entity ID that corresponds to
|
||||
/// the given local ID within the given module.
|
||||
serialization::PreprocessedEntityID
|
||||
getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const;
|
||||
serialization::PreprocessedEntityID getGlobalPreprocessedEntityID(
|
||||
ModuleFile &M, serialization::PreprocessedEntityID LocalID) const;
|
||||
|
||||
/// Add a macro to deserialize its macro directive history.
|
||||
///
|
||||
|
||||
@ -782,6 +782,10 @@ public:
|
||||
void AddLookupOffsets(const LookupBlockOffsets &Offsets,
|
||||
RecordDataImpl &Record);
|
||||
|
||||
/// Emit a reference to a macro.
|
||||
void AddMacroRef(MacroInfo *MI, const IdentifierInfo *Name,
|
||||
RecordDataImpl &Record);
|
||||
|
||||
/// Emit a reference to a declaration.
|
||||
void AddDeclRef(const Decl *D, RecordDataImpl &Record);
|
||||
// Emit a reference to a declaration if the declaration was emitted.
|
||||
|
||||
@ -353,9 +353,6 @@ public:
|
||||
/// Base macro ID for macros local to this module.
|
||||
serialization::MacroID BaseMacroID = 0;
|
||||
|
||||
/// Remapping table for macro IDs in this module.
|
||||
ContinuousRangeMap<uint32_t, int, 2> MacroRemap;
|
||||
|
||||
/// The offset of the start of the set of defined macros.
|
||||
uint64_t MacroStartOffset = 0;
|
||||
|
||||
@ -372,9 +369,6 @@ public:
|
||||
/// this module.
|
||||
serialization::PreprocessedEntityID BasePreprocessedEntityID = 0;
|
||||
|
||||
/// Remapping table for preprocessed entity IDs in this module.
|
||||
ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
|
||||
|
||||
const PPEntityOffset *PreprocessedEntityOffsets = nullptr;
|
||||
unsigned NumPreprocessedEntities = 0;
|
||||
|
||||
|
||||
@ -2228,9 +2228,10 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
|
||||
// We have a macro definition. Register the association
|
||||
PreprocessedEntityID
|
||||
GlobalID = getGlobalPreprocessedEntityID(F, Record[NextIndex]);
|
||||
unsigned Index = translatePreprocessedEntityIDToIndex(GlobalID);
|
||||
PreprocessingRecord &PPRec = *PP.getPreprocessingRecord();
|
||||
PreprocessingRecord::PPEntityID PPID =
|
||||
PPRec.getPPEntityID(GlobalID - 1, /*isLoaded=*/true);
|
||||
PPRec.getPPEntityID(Index, /*isLoaded=*/true);
|
||||
MacroDefinitionRecord *PPDef = cast_or_null<MacroDefinitionRecord>(
|
||||
PPRec.getPreprocessedEntity(PPID));
|
||||
if (PPDef)
|
||||
@ -2261,16 +2262,22 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
|
||||
|
||||
PreprocessedEntityID
|
||||
ASTReader::getGlobalPreprocessedEntityID(ModuleFile &M,
|
||||
unsigned LocalID) const {
|
||||
PreprocessedEntityID LocalID) const {
|
||||
if (!M.ModuleOffsetMap.empty())
|
||||
ReadModuleOffsetMap(M);
|
||||
|
||||
ContinuousRangeMap<uint32_t, int, 2>::const_iterator
|
||||
I = M.PreprocessedEntityRemap.find(LocalID - NUM_PREDEF_PP_ENTITY_IDS);
|
||||
assert(I != M.PreprocessedEntityRemap.end()
|
||||
&& "Invalid index into preprocessed entity index remap");
|
||||
unsigned ModuleFileIndex = LocalID >> 32;
|
||||
LocalID &= llvm::maskTrailingOnes<PreprocessedEntityID>(32);
|
||||
ModuleFile *MF =
|
||||
ModuleFileIndex ? M.TransitiveImports[ModuleFileIndex - 1] : &M;
|
||||
assert(MF && "malformed identifier ID encoding?");
|
||||
|
||||
return LocalID + I->second;
|
||||
if (!ModuleFileIndex) {
|
||||
assert(LocalID >= NUM_PREDEF_PP_ENTITY_IDS);
|
||||
LocalID -= NUM_PREDEF_PP_ENTITY_IDS;
|
||||
}
|
||||
|
||||
return (static_cast<PreprocessedEntityID>(MF->Index + 1) << 32) | LocalID;
|
||||
}
|
||||
|
||||
OptionalFileEntryRef
|
||||
@ -2547,6 +2554,13 @@ void ASTReader::markIdentifierUpToDate(const IdentifierInfo *II) {
|
||||
IdentifierGeneration[II] = getGeneration();
|
||||
}
|
||||
|
||||
MacroID ASTReader::ReadMacroID(ModuleFile &F, const RecordDataImpl &Record,
|
||||
unsigned &Idx) {
|
||||
uint64_t ModuleFileIndex = Record[Idx++] << 32;
|
||||
uint64_t LocalIndex = Record[Idx++];
|
||||
return getGlobalMacroID(F, (ModuleFileIndex | LocalIndex));
|
||||
}
|
||||
|
||||
void ASTReader::resolvePendingMacro(IdentifierInfo *II,
|
||||
const PendingMacroInfo &PMInfo) {
|
||||
ModuleFile &M = *PMInfo.M;
|
||||
@ -2597,9 +2611,10 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II,
|
||||
case PP_MODULE_MACRO: {
|
||||
ModuleMacros.push_back(ModuleMacroRecord());
|
||||
auto &Info = ModuleMacros.back();
|
||||
Info.SubModID = getGlobalSubmoduleID(M, Record[0]);
|
||||
Info.MI = getMacro(getGlobalMacroID(M, Record[1]));
|
||||
for (int I = 2, N = Record.size(); I != N; ++I)
|
||||
unsigned Idx = 0;
|
||||
Info.SubModID = getGlobalSubmoduleID(M, Record[Idx++]);
|
||||
Info.MI = getMacro(ReadMacroID(M, Record, Idx));
|
||||
for (int I = Idx, N = Record.size(); I != N; ++I)
|
||||
Info.Overrides.push_back(getGlobalSubmoduleID(M, Record[I]));
|
||||
continue;
|
||||
}
|
||||
@ -4111,8 +4126,6 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
assert(Blob.size() % sizeof(PPEntityOffset) == 0);
|
||||
F.NumPreprocessedEntities = Blob.size() / sizeof(PPEntityOffset);
|
||||
|
||||
unsigned LocalBasePreprocessedEntityID = Record[0];
|
||||
|
||||
unsigned StartingID;
|
||||
if (!PP.getPreprocessingRecord())
|
||||
PP.createPreprocessingRecord();
|
||||
@ -4127,12 +4140,6 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
// Introduce the global -> local mapping for preprocessed entities in
|
||||
// this module.
|
||||
GlobalPreprocessedEntityMap.insert(std::make_pair(StartingID, &F));
|
||||
|
||||
// Introduce the local -> global mapping for preprocessed entities in
|
||||
// this module.
|
||||
F.PreprocessedEntityRemap.insertOrReplace(
|
||||
std::make_pair(LocalBasePreprocessedEntityID,
|
||||
F.BasePreprocessedEntityID - LocalBasePreprocessedEntityID));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -4343,21 +4350,11 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
|
||||
"duplicate MACRO_OFFSET record in AST file");
|
||||
F.MacroOffsets = (const uint32_t *)Blob.data();
|
||||
F.LocalNumMacros = Record[0];
|
||||
unsigned LocalBaseMacroID = Record[1];
|
||||
F.MacroOffsetsBase = Record[2] + F.ASTBlockStartOffset;
|
||||
F.MacroOffsetsBase = Record[1] + F.ASTBlockStartOffset;
|
||||
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));
|
||||
|
||||
if (F.LocalNumMacros > 0)
|
||||
MacrosLoaded.resize(MacrosLoaded.size() + F.LocalNumMacros);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -4463,8 +4460,6 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
|
||||
F.ModuleOffsetMap = StringRef();
|
||||
|
||||
using RemapBuilder = ContinuousRangeMap<uint32_t, int, 2>::Builder;
|
||||
RemapBuilder MacroRemap(F.MacroRemap);
|
||||
RemapBuilder PreprocessedEntityRemap(F.PreprocessedEntityRemap);
|
||||
RemapBuilder SubmoduleRemap(F.SubmoduleRemap);
|
||||
RemapBuilder SelectorRemap(F.SelectorRemap);
|
||||
|
||||
@ -4494,10 +4489,6 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
|
||||
|
||||
ImportedModuleVector.push_back(OM);
|
||||
|
||||
uint32_t MacroIDOffset =
|
||||
endian::readNext<uint32_t, llvm::endianness::little>(Data);
|
||||
uint32_t PreprocessedEntityIDOffset =
|
||||
endian::readNext<uint32_t, llvm::endianness::little>(Data);
|
||||
uint32_t SubmoduleIDOffset =
|
||||
endian::readNext<uint32_t, llvm::endianness::little>(Data);
|
||||
uint32_t SelectorIDOffset =
|
||||
@ -4511,9 +4502,6 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const {
|
||||
static_cast<int>(BaseOffset - Offset)));
|
||||
};
|
||||
|
||||
mapOffset(MacroIDOffset, OM->BaseMacroID, MacroRemap);
|
||||
mapOffset(PreprocessedEntityIDOffset, OM->BasePreprocessedEntityID,
|
||||
PreprocessedEntityRemap);
|
||||
mapOffset(SubmoduleIDOffset, OM->BaseSubmoduleID, SubmoduleRemap);
|
||||
mapOffset(SelectorIDOffset, OM->BaseSelectorID, SelectorRemap);
|
||||
}
|
||||
@ -6725,11 +6713,23 @@ SourceRange ASTReader::ReadSkippedRange(unsigned GlobalIndex) {
|
||||
return Range;
|
||||
}
|
||||
|
||||
unsigned
|
||||
ASTReader::translatePreprocessedEntityIDToIndex(PreprocessedEntityID ID) const {
|
||||
unsigned ModuleFileIndex = ID >> 32;
|
||||
assert(ModuleFileIndex && "not translating loaded MacroID?");
|
||||
assert(getModuleManager().size() > ModuleFileIndex - 1);
|
||||
ModuleFile &MF = getModuleManager()[ModuleFileIndex - 1];
|
||||
|
||||
ID &= llvm::maskTrailingOnes<PreprocessedEntityID>(32);
|
||||
return MF.BasePreprocessedEntityID + ID;
|
||||
}
|
||||
|
||||
PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
|
||||
PreprocessedEntityID PPID = Index+1;
|
||||
std::pair<ModuleFile *, unsigned> PPInfo = getModulePreprocessedEntity(Index);
|
||||
ModuleFile &M = *PPInfo.first;
|
||||
unsigned LocalIndex = PPInfo.second;
|
||||
PreprocessedEntityID PPID =
|
||||
(static_cast<PreprocessedEntityID>(M.Index + 1) << 32) | LocalIndex;
|
||||
const PPEntityOffset &PPOffs = M.PreprocessedEntityOffsets[LocalIndex];
|
||||
|
||||
if (!PP.getPreprocessingRecord()) {
|
||||
@ -6777,8 +6777,9 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
|
||||
else {
|
||||
PreprocessedEntityID GlobalID =
|
||||
getGlobalPreprocessedEntityID(M, Record[1]);
|
||||
Def = cast<MacroDefinitionRecord>(
|
||||
PPRec.getLoadedPreprocessedEntity(GlobalID - 1));
|
||||
unsigned Index = translatePreprocessedEntityIDToIndex(GlobalID);
|
||||
Def =
|
||||
cast<MacroDefinitionRecord>(PPRec.getLoadedPreprocessedEntity(Index));
|
||||
}
|
||||
|
||||
MacroExpansion *ME;
|
||||
@ -6831,8 +6832,8 @@ PreprocessedEntity *ASTReader::ReadPreprocessedEntity(unsigned Index) {
|
||||
/// \param SLocMapI points at a chunk of a module that contains no
|
||||
/// preprocessed entities or the entities it contains are not the ones we are
|
||||
/// looking for.
|
||||
PreprocessedEntityID ASTReader::findNextPreprocessedEntity(
|
||||
GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
|
||||
unsigned ASTReader::findNextPreprocessedEntity(
|
||||
GlobalSLocOffsetMapType::const_iterator SLocMapI) const {
|
||||
++SLocMapI;
|
||||
for (GlobalSLocOffsetMapType::const_iterator
|
||||
EndI = GlobalSLocOffsetMap.end(); SLocMapI != EndI; ++SLocMapI) {
|
||||
@ -6875,8 +6876,8 @@ struct PPEntityComp {
|
||||
|
||||
} // namespace
|
||||
|
||||
PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc,
|
||||
bool EndsAfter) const {
|
||||
unsigned ASTReader::findPreprocessedEntity(SourceLocation Loc,
|
||||
bool EndsAfter) const {
|
||||
if (SourceMgr.isLocalSourceLocation(Loc))
|
||||
return getTotalNumPreprocessedEntities();
|
||||
|
||||
@ -6936,9 +6937,8 @@ std::pair<unsigned, unsigned>
|
||||
return std::make_pair(0,0);
|
||||
assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
|
||||
|
||||
PreprocessedEntityID BeginID =
|
||||
findPreprocessedEntity(Range.getBegin(), false);
|
||||
PreprocessedEntityID EndID = findPreprocessedEntity(Range.getEnd(), true);
|
||||
unsigned BeginID = findPreprocessedEntity(Range.getBegin(), false);
|
||||
unsigned EndID = findPreprocessedEntity(Range.getEnd(), true);
|
||||
return std::make_pair(BeginID, EndID);
|
||||
}
|
||||
|
||||
@ -8963,7 +8963,6 @@ LLVM_DUMP_METHOD void ASTReader::dump() {
|
||||
llvm::errs() << "*** PCH/ModuleFile Remappings:\n";
|
||||
dumpModuleIDMap("Global bit offset map", GlobalBitOffsetsMap);
|
||||
dumpModuleIDMap("Global source location entry map", GlobalSLocEntryMap);
|
||||
dumpModuleIDMap("Global macro map", GlobalMacroMap);
|
||||
dumpModuleIDMap("Global submodule map", GlobalSubmoduleMap);
|
||||
dumpModuleIDMap("Global selector map", GlobalSelectorMap);
|
||||
dumpModuleIDMap("Global preprocessed entity map",
|
||||
@ -9746,6 +9745,21 @@ IdentifierID ASTReader::getGlobalIdentifierID(ModuleFile &M, uint64_t LocalID) {
|
||||
return ((IdentifierID)(MF->Index + 1) << 32) | LocalID;
|
||||
}
|
||||
|
||||
std::pair<ModuleFile *, unsigned>
|
||||
ASTReader::translateMacroIDToIndex(MacroID ID) const {
|
||||
if (ID == 0)
|
||||
return {nullptr, 0};
|
||||
|
||||
unsigned ModuleFileIndex = ID >> 32;
|
||||
assert(ModuleFileIndex && "not translating loaded MacroID?");
|
||||
assert(getModuleManager().size() > ModuleFileIndex - 1);
|
||||
ModuleFile &MF = getModuleManager()[ModuleFileIndex - 1];
|
||||
|
||||
unsigned LocalID = ID & llvm::maskTrailingOnes<MacroID>(32);
|
||||
assert(LocalID < MF.LocalNumMacros);
|
||||
return {&MF, MF.BaseMacroID + LocalID};
|
||||
}
|
||||
|
||||
MacroInfo *ASTReader::getMacro(MacroID ID) {
|
||||
if (ID == 0)
|
||||
return nullptr;
|
||||
@ -9755,36 +9769,40 @@ MacroInfo *ASTReader::getMacro(MacroID ID) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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;
|
||||
MacrosLoaded[ID] =
|
||||
ReadMacroRecord(*M, M->MacroOffsetsBase + M->MacroOffsets[Index]);
|
||||
auto [M, Index] = translateMacroIDToIndex(ID);
|
||||
if (!MacrosLoaded[Index]) {
|
||||
assert(M != nullptr && "Untranslated Macro ID?");
|
||||
assert(Index >= M->BaseMacroID);
|
||||
unsigned LocalIndex = Index - M->BaseMacroID;
|
||||
uint64_t DataOffset = M->MacroOffsetsBase + M->MacroOffsets[LocalIndex];
|
||||
MacrosLoaded[Index] = ReadMacroRecord(*M, DataOffset);
|
||||
|
||||
if (DeserializationListener)
|
||||
DeserializationListener->MacroRead(ID + NUM_PREDEF_MACRO_IDS,
|
||||
MacrosLoaded[ID]);
|
||||
DeserializationListener->MacroRead(ID, MacrosLoaded[Index]);
|
||||
}
|
||||
|
||||
return MacrosLoaded[ID];
|
||||
return MacrosLoaded[Index];
|
||||
}
|
||||
|
||||
MacroID ASTReader::getGlobalMacroID(ModuleFile &M, unsigned LocalID) {
|
||||
MacroID ASTReader::getGlobalMacroID(ModuleFile &M, MacroID LocalID) {
|
||||
if (LocalID < NUM_PREDEF_MACRO_IDS)
|
||||
return LocalID;
|
||||
|
||||
if (!M.ModuleOffsetMap.empty())
|
||||
ReadModuleOffsetMap(M);
|
||||
|
||||
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");
|
||||
unsigned ModuleFileIndex = LocalID >> 32;
|
||||
LocalID &= llvm::maskTrailingOnes<MacroID>(32);
|
||||
ModuleFile *MF =
|
||||
ModuleFileIndex ? M.TransitiveImports[ModuleFileIndex - 1] : &M;
|
||||
assert(MF && "malformed identifier ID encoding?");
|
||||
|
||||
return LocalID + I->second;
|
||||
if (!ModuleFileIndex) {
|
||||
assert(LocalID >= NUM_PREDEF_MACRO_IDS);
|
||||
LocalID -= NUM_PREDEF_MACRO_IDS;
|
||||
}
|
||||
|
||||
return (static_cast<MacroID>(MF->Index + 1) << 32) | LocalID;
|
||||
}
|
||||
|
||||
serialization::SubmoduleID
|
||||
|
||||
@ -2691,7 +2691,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
||||
Record.push_back(VisMD->isPublic());
|
||||
}
|
||||
ModuleMacroRecord.push_back(getSubmoduleID(WritingModule));
|
||||
ModuleMacroRecord.push_back(getMacroRef(MD->getMacroInfo(), Name));
|
||||
AddMacroRef(MD->getMacroInfo(), Name, ModuleMacroRecord);
|
||||
Stream.EmitRecord(PP_MODULE_MACRO, ModuleMacroRecord);
|
||||
ModuleMacroRecord.clear();
|
||||
EmittedModuleMacros = true;
|
||||
@ -2720,7 +2720,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
||||
|
||||
// Emit a record indicating this submodule exports this macro.
|
||||
ModuleMacroRecord.push_back(getSubmoduleID(Macro->getOwningModule()));
|
||||
ModuleMacroRecord.push_back(getMacroRef(Macro->getMacroInfo(), Name));
|
||||
AddMacroRef(Macro->getMacroInfo(), Name, ModuleMacroRecord);
|
||||
for (auto *M : Macro->overrides())
|
||||
ModuleMacroRecord.push_back(getSubmoduleID(M->getOwningModule()));
|
||||
|
||||
@ -2819,14 +2819,12 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
|
||||
auto Abbrev = std::make_shared<BitCodeAbbrev>();
|
||||
Abbrev->Add(BitCodeAbbrevOp(MACRO_OFFSET));
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of macros
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // base offset
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
||||
|
||||
unsigned MacroOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
|
||||
{
|
||||
RecordData::value_type Record[] = {MACRO_OFFSET, MacroOffsets.size(),
|
||||
FirstMacroID - NUM_PREDEF_MACRO_IDS,
|
||||
MacroOffsetsBase - ASTBlockStartOffset};
|
||||
Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, bytes(MacroOffsets));
|
||||
}
|
||||
@ -2859,9 +2857,7 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec,
|
||||
InclusionAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
|
||||
}
|
||||
|
||||
unsigned FirstPreprocessorEntityID
|
||||
= (Chain ? PPRec.getNumLoadedPreprocessedEntities() : 0)
|
||||
+ NUM_PREDEF_PP_ENTITY_IDS;
|
||||
unsigned FirstPreprocessorEntityID = NUM_PREDEF_PP_ENTITY_IDS;
|
||||
unsigned NextPreprocessorEntityID = FirstPreprocessorEntityID;
|
||||
RecordData Record;
|
||||
for (PreprocessingRecord::iterator E = PPRec.local_begin(),
|
||||
@ -2925,13 +2921,10 @@ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec,
|
||||
|
||||
auto Abbrev = std::make_shared<BitCodeAbbrev>();
|
||||
Abbrev->Add(BitCodeAbbrevOp(PPD_ENTITIES_OFFSETS));
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first pp entity
|
||||
Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));
|
||||
unsigned PPEOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
|
||||
|
||||
RecordData::value_type Record[] = {PPD_ENTITIES_OFFSETS,
|
||||
FirstPreprocessorEntityID -
|
||||
NUM_PREDEF_PP_ENTITY_IDS};
|
||||
RecordData::value_type Record[] = {PPD_ENTITIES_OFFSETS};
|
||||
Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record,
|
||||
bytes(PreprocessedEntityOffsets));
|
||||
}
|
||||
@ -6100,9 +6093,6 @@ ASTFileSignature ASTWriter::WriteASTCore(Sema *SemaPtr, StringRef isysroot,
|
||||
|
||||
// These values should be unique within a chain, since they will be read
|
||||
// as keys into ContinuousRangeMaps.
|
||||
writeBaseIDOrNone(M.BaseMacroID, M.LocalNumMacros);
|
||||
writeBaseIDOrNone(M.BasePreprocessedEntityID,
|
||||
M.NumPreprocessedEntities);
|
||||
writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
|
||||
writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
|
||||
}
|
||||
@ -6903,6 +6893,13 @@ void ASTWriter::AddLookupOffsets(const LookupBlockOffsets &Offsets,
|
||||
Record.push_back(Offsets.TULocalOffset);
|
||||
}
|
||||
|
||||
void ASTWriter::AddMacroRef(MacroInfo *MI, const IdentifierInfo *Name,
|
||||
RecordDataImpl &Record) {
|
||||
MacroID MacroRef = getMacroRef(MI, Name);
|
||||
Record.push_back(MacroRef >> 32);
|
||||
Record.push_back(MacroRef & llvm::maskTrailingOnes<MacroID>(32));
|
||||
}
|
||||
|
||||
void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) {
|
||||
if (!wasDeclEmitted(D))
|
||||
return;
|
||||
@ -7383,12 +7380,8 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) {
|
||||
|
||||
Chain = Reader;
|
||||
|
||||
// Note, this will get called multiple times, once one the reader starts up
|
||||
// and again each time it's done reading a PCH or module.
|
||||
FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros();
|
||||
FirstSubmoduleID = NUM_PREDEF_SUBMODULE_IDS + Chain->getTotalNumSubmodules();
|
||||
FirstSelectorID = NUM_PREDEF_SELECTOR_IDS + Chain->getTotalNumSelectors();
|
||||
NextMacroID = FirstMacroID;
|
||||
NextSelectorID = FirstSelectorID;
|
||||
NextSubmoduleID = FirstSubmoduleID;
|
||||
}
|
||||
@ -7416,6 +7409,14 @@ void ASTWriter::IdentifierRead(IdentifierID ID, IdentifierInfo *II) {
|
||||
void ASTWriter::MacroRead(serialization::MacroID ID, MacroInfo *MI) {
|
||||
// Always keep the highest ID. See \p TypeRead() for more information.
|
||||
MacroID &StoredID = MacroIDs[MI];
|
||||
unsigned OriginalModuleFileIndex = StoredID >> 32;
|
||||
|
||||
// Always keep the local macro ID. See \p TypeRead() for more information.
|
||||
if (OriginalModuleFileIndex == 0 && StoredID)
|
||||
return;
|
||||
|
||||
// Otherwise, keep the highest ID since the module file comes later has
|
||||
// higher module file indexes.
|
||||
if (ID > StoredID)
|
||||
StoredID = ID;
|
||||
}
|
||||
|
||||
@ -65,7 +65,6 @@ LLVM_DUMP_METHOD void ModuleFile::dump() {
|
||||
|
||||
llvm::errs() << " Base macro ID: " << BaseMacroID << '\n'
|
||||
<< " Number of macros: " << LocalNumMacros << '\n';
|
||||
dumpLocalRemap("Macro ID local -> global map", MacroRemap);
|
||||
|
||||
llvm::errs() << " Base submodule ID: " << BaseSubmoduleID << '\n'
|
||||
<< " Number of submodules: " << LocalNumSubmodules << '\n';
|
||||
@ -79,8 +78,6 @@ LLVM_DUMP_METHOD void ModuleFile::dump() {
|
||||
<< '\n'
|
||||
<< " Number of preprocessed entities: "
|
||||
<< NumPreprocessedEntities << '\n';
|
||||
dumpLocalRemap("Preprocessed entity ID local -> global map",
|
||||
PreprocessedEntityRemap);
|
||||
|
||||
llvm::errs() << " Base type index: " << BaseTypeIndex << '\n'
|
||||
<< " Number of types: " << LocalNumTypes << '\n';
|
||||
|
||||
23
clang/test/Modules/no-transitive-macro-change.cpp
Normal file
23
clang/test/Modules/no-transitive-macro-change.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
//
|
||||
// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header \
|
||||
// RUN: %t/a.h -o %t/a.pcm
|
||||
// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header \
|
||||
// RUN: %t/b.h -o %t/b.pcm -fmodule-file=%t/a.pcm
|
||||
// RUN: echo "#define A2 44" >> %t/a.h
|
||||
// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header \
|
||||
// RUN: %t/a.h -o %t/a.v1.pcm
|
||||
// RUN: %clang_cc1 -std=c++20 -emit-header-unit -xc++-user-header \
|
||||
// RUN: %t/b.h -o %t/b.v1.pcm -fmodule-file=%t/a.v1.pcm
|
||||
// RUN: not diff %t/b.pcm %t/b.v1.pcm &> /dev/null
|
||||
|
||||
//--- a.h
|
||||
#pragma once
|
||||
#define A 43
|
||||
|
||||
//--- b.h
|
||||
#pragma once
|
||||
import "a.h";
|
||||
#define B 43
|
||||
const int a = A;
|
||||
Loading…
x
Reference in New Issue
Block a user