[clang] [ExtractAPI] Deterministically emit macros (PR #215381)

Prajwal Nadig via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 10 13:10:23 PDT 2026


https://github.com/snprajwal created https://github.com/llvm/llvm-project/pull/215381

Macros are processed by iterating over the preprocessor's stored `DenseMap`, which is pointer-keyed with `IdentifierInfo`. This map is not ordered, leading to the contents of the symbol graph changing across runs with identical inputs. Sort macros lexicographically by name to ensure consistent output.

rdar://184545768

>From 67a334e0b537fb9f85b2865446075ca1f65fbca9 Mon Sep 17 00:00:00 2001
From: Prajwal Nadig <pnadig at apple.com>
Date: Mon, 10 Aug 2026 21:04:48 +0100
Subject: [PATCH] [ExtractAPI] Deterministically emit macros

Macros are processed by iterating over the preprocessor's stored
`DenseMap`, which is pointer-keyed with `IdentifierInfo`. This map is
not ordered, leading to the contents of the symbol graph changing across
runs with identical inputs. Sort macros lexicographically by name to
ensure consistent output.

rdar://184545768
---
 clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | 11 +++++++++--
 clang/test/ExtractAPI/macros.c              |  8 ++++++++
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index 85da480fb67a6..4b3d6993acce5 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -287,8 +287,15 @@ class MacroCallback : public PPCallbacks {
       : Ctx(Ctx), SM(SM), API(API), PP(PP) {}
 
   void EndOfMainFile() override {
-    for (const auto &M : PP.macros()) {
-      auto *II = M.getFirst();
+    SmallVector<const IdentifierInfo *> Macros;
+    for (const auto &M : PP.macros())
+      Macros.push_back(M.getFirst());
+    llvm::sort(Macros,
+               [](const IdentifierInfo *LHS, const IdentifierInfo *RHS) {
+                 return LHS->getName() < RHS->getName();
+               });
+
+    for (const auto *II : Macros) {
       auto MD = PP.getMacroDefinition(II);
       auto *MI = MD.getMacroInfo();
 
diff --git a/clang/test/ExtractAPI/macros.c b/clang/test/ExtractAPI/macros.c
index 15eb5f6a7f66f..cb0b018fd5390 100644
--- a/clang/test/ExtractAPI/macros.c
+++ b/clang/test/ExtractAPI/macros.c
@@ -354,5 +354,13 @@
 // FUNGNU-NEXT:   "FUNGNU"
 // FUNGNU-NEXT: ]
 
+// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix ORDER
+// ORDER: "!testLabel": "c:@macro at FUN"
+// ORDER: "!testLabel": "c:@macro at FUNC99"
+// ORDER: "!testLabel": "c:@macro at FUNGNU"
+// ORDER: "!testLabel": "c:@macro at HELLO"
+// ORDER: "!testLabel": "c:@macro at MACRO_FUN"
+// ORDER: "!testLabel": "c:@macro at WORLD"
+
 // expected-no-diagnostics
 



More information about the cfe-commits mailing list