[clang] [Modules] Make -module-file-info print macro names in deterministic order (PR #161332)

Hans Wennborg via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 30 00:56:38 PDT 2025


https://github.com/zmodem created https://github.com/llvm/llvm-project/pull/161332

Developers reported non-deterministic output from `-module-file-info`, thinking this reflected non-determinism in the .pcm files themselves. However, it turned out it was the printing that was non-deterministic:

```
$ cat /tmp/a.h
#define FOO 1
#define BAR 2

$ build/bin/clang -cc1 -std=c++20 -x c++ -emit-header-unit /tmp/a.h -o /tmp/a.pcm

$ build/bin/clang -cc1 -module-file-info /tmp/a.pcm | grep -A2 Definitions
   Macro Definitions:
     FOO
     BAR

$ build/bin/clang -cc1 -module-file-info /tmp/a.pcm | grep -A2 Definitions
   Macro Definitions:
     BAR
     FOO
```

Making the output deterministic also simplifies the test.

This is a follow-up to 360c5fe54c0758c73bf85453fd2913f371adc7d5

>From fdb864a0720817a31e68992ca843ba5b86d96798 Mon Sep 17 00:00:00 2001
From: Hans Wennborg <hans at chromium.org>
Date: Tue, 30 Sep 2025 09:51:51 +0200
Subject: [PATCH] [Modules] Make -module-file-info print macro names in
 deterministic order

---
 clang/lib/Frontend/FrontendActions.cpp        | 19 ++++++++++--------
 .../Modules/cxx20-module-file-info-macros.cpp | 20 +++++++++----------
 2 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 7424958d46612..d7d56b8166350 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -971,14 +971,17 @@ void DumpModuleInfoAction::ExecuteAction() {
     // Emit the macro definitions in the module file so that we can know how
     // much definitions in the module file quickly.
     // TODO: Emit the macro definition bodies completely.
-    if (auto FilteredMacros = llvm::make_filter_range(
-            R->getPreprocessor().macros(),
-            [](const auto &Macro) { return Macro.first->isFromAST(); });
-        !FilteredMacros.empty()) {
-      Out << "   Macro Definitions:\n";
-      for (/*<IdentifierInfo *, MacroState> pair*/ const auto &Macro :
-           FilteredMacros)
-        Out << "     " << Macro.first->getName() << "\n";
+    {
+      std::vector<StringRef> MacroNames;
+      for (const auto &M : R->getPreprocessor().macros()) {
+        if (M.first->isFromAST())
+          MacroNames.push_back(M.first->getName());
+      }
+      llvm::sort(MacroNames);
+      if (!MacroNames.empty())
+        Out << "   Macro Definitions:\n";
+      for (StringRef Name : MacroNames)
+        Out << "     " << Name << "\n";
     }
 
     // Now let's print out any modules we did not see as part of the Primary.
diff --git a/clang/test/Modules/cxx20-module-file-info-macros.cpp b/clang/test/Modules/cxx20-module-file-info-macros.cpp
index 3b67e9b9acd41..431c967fbbccd 100644
--- a/clang/test/Modules/cxx20-module-file-info-macros.cpp
+++ b/clang/test/Modules/cxx20-module-file-info-macros.cpp
@@ -36,28 +36,28 @@
 #define REDEFINE
 
 // CHECK: Macro Definitions:
-// CHECK-DAG: REDEFINE
-// CHECK-DAG: FUNC_Macro
-// CHECK-DAG: CONSTANT
-// CHECK-DAG: FOO
+// CHECK: CONSTANT
+// CHECK: FOO
+// CHECK: FUNC_Macro
+// CHECK: REDEFINE
 // CHECK-NEXT: ===
 
 //--- include_foo.h
 #include "foo.h"
 #undef REDEFINE
 // CHECK: Macro Definitions:
-// CHECK-DAG: CONSTANT
-// CHECK-DAG: FUNC_Macro
-// CHECK-DAG: FOO
+// CHECK: CONSTANT
+// CHECK: FOO
+// CHECK: FUNC_Macro
 // CHECK-NEXT: ===
 
 //--- import_foo.h
 import "foo.h";
 #undef REDEFINE
 // CHECK: Macro Definitions:
-// CHECK-DAG: CONSTANT
-// CHECK-DAG: FUNC_Macro
-// CHECK-DAG: FOO
+// CHECK: CONSTANT
+// CHECK: FOO
+// CHECK: FUNC_Macro
 // CHECK-NEXT: ===
 
 //--- named_module.cppm



More information about the cfe-commits mailing list