[clang] [Modules] Fix an identifier hiding a function-like macro definition. (PR #135471)

Volodymyr Sapsai via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 14 15:05:45 PDT 2025


================
@@ -3871,7 +3874,8 @@ class ASTIdentifierTableTrait {
     if (isInterestingIdentifier(II, MacroOffset)) {
       DataLen += 2; // 2 bytes for builtin ID
       DataLen += 2; // 2 bytes for flags
-      if (MacroOffset)
+      if (MacroOffset || (II->hasMacroDefinition() &&
+                          II->hasFETokenInfoChangedSinceDeserialization()))
----------------
vsapsai wrote:

This is a really good question, thanks for noticing and asking it.

The suggested change worked correctly even before my change. In my debugging function parameter "__P" isn't emitted in MacroTransitive because that's not an "interesting" identifier. So during the module traversal it doesn't prevent us from visiting MacroDefinition and discovering the macro.

Struct "__Q" does get serialized in MacroTransitive but it has non-zero MacroOffset, so we serialize the macro definition in MacroTransitive. And MacroOffset is non-zero because we've added "__Q" to `IdentMacroDirectivesOffsetMap` and that's because in the snippet
```c++
    for (auto &Id : PP.getIdentifierTable())
      if (Id.second->hadMacroDefinition() &&
          (!Id.second->isFromAST() ||
          Id.second->hasChangedSinceDeserialization()))
        MacroIdentifiers.push_back(Id.second);
```
`hasChangedSinceDeserialization()` returns true for "__Q". Which I believe is triggered by ASTReader in
```c++
static void markIdentifierFromAST(ASTReader &Reader, IdentifierInfo &II,
                                  bool IsModule) {
  if (!II.isFromAST()) {
    II.setIsFromAST();
    if (isInterestingIdentifier(Reader, II, IsModule))
      II.setChangedSinceDeserialization();
  }
}
```

https://github.com/llvm/llvm-project/pull/135471


More information about the cfe-commits mailing list