[clang] [clang] [Serialization] No transitive change for MacroID and PreprocessedEntityID (PR #166346)
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 9 19:19:21 PST 2025
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/166346
>From 5c491d055d679981141787d9a8401f30608305b3 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Tue, 4 Nov 2025 17:41:04 +0800
Subject: [PATCH] [clang] [Serialization] No transitive change for MacroID and
PreprocessedEntityID
---
.../include/clang/Serialization/ASTBitCodes.h | 8 +-
clang/include/clang/Serialization/ASTReader.h | 39 +++--
clang/include/clang/Serialization/ASTWriter.h | 4 +
.../include/clang/Serialization/ModuleFile.h | 6 -
clang/lib/Serialization/ASTReader.cpp | 152 ++++++++++--------
clang/lib/Serialization/ASTWriter.cpp | 37 ++---
clang/lib/Serialization/ModuleFile.cpp | 3 -
.../Modules/no-transitive-macro-change.cpp | 23 +++
8 files changed, 158 insertions(+), 114 deletions(-)
create mode 100644 clang/test/Modules/no-transitive-macro-change.cpp
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 5d09d5536e5ab..d7d429eacd67a 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -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;
diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h
index af856a8097ab1..4d6fa585ebd45 100644
--- a/clang/include/clang/Serialization/ASTReader.h
+++ b/clang/include/clang/Serialization/ASTReader.h
@@ -800,14 +800,6 @@ class ASTReader
/// 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 @@ class ASTReader
/// 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 @@ class ASTReader
/// \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 @@ class ASTReader
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 @@ class ASTReader
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 @@ class ASTReader
/// 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 @@ class ASTReader
/// 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.
///
diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index 28c3e55864057..c77c98dffc39f 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -782,6 +782,10 @@ class ASTWriter : public ASTDeserializationListener,
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.
diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h
index f20cb2f9f35ae..783e2ba7a1f94 100644
--- a/clang/include/clang/Serialization/ModuleFile.h
+++ b/clang/include/clang/Serialization/ModuleFile.h
@@ -353,9 +353,6 @@ class ModuleFile {
/// 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 @@ class ModuleFile {
/// 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;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index e3106f8d8e13c..c8f50b309e375 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -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;
}
@@ -4107,8 +4122,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();
@@ -4123,12 +4136,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;
@@ -4339,21 +4346,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;
}
@@ -4459,8 +4456,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);
@@ -4490,10 +4485,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 =
@@ -4507,9 +4498,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);
}
@@ -6718,11 +6706,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()) {
@@ -6770,8 +6770,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;
@@ -6824,8 +6825,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) {
@@ -6868,8 +6869,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();
@@ -6929,9 +6930,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);
}
@@ -8956,7 +8956,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",
@@ -9739,6 +9738,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;
@@ -9748,36 +9762,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
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 3ac338e013deb..d1ec8bb70f79f 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -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));
}
@@ -6099,9 +6092,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);
}
@@ -6902,6 +6892,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;
@@ -7382,12 +7379,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;
}
@@ -7415,6 +7408,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;
}
diff --git a/clang/lib/Serialization/ModuleFile.cpp b/clang/lib/Serialization/ModuleFile.cpp
index 4858cdbda5545..7f631eafcaf35 100644
--- a/clang/lib/Serialization/ModuleFile.cpp
+++ b/clang/lib/Serialization/ModuleFile.cpp
@@ -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';
diff --git a/clang/test/Modules/no-transitive-macro-change.cpp b/clang/test/Modules/no-transitive-macro-change.cpp
new file mode 100644
index 0000000000000..fced26490c27f
--- /dev/null
+++ b/clang/test/Modules/no-transitive-macro-change.cpp
@@ -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;
More information about the cfe-commits
mailing list