[clang] d340a68 - Produce back-references for anonymous namespaces (#188843)

via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 27 09:59:04 PDT 2026


Author: Brady Hahn
Date: 2026-03-27T09:58:59-07:00
New Revision: d340a68ee01c080bdde116ef9d1c1bcab4316d52

URL: https://github.com/llvm/llvm-project/commit/d340a68ee01c080bdde116ef9d1c1bcab4316d52
DIFF: https://github.com/llvm/llvm-project/commit/d340a68ee01c080bdde116ef9d1c1bcab4316d52.diff

LOG: Produce back-references for anonymous namespaces (#188843)

The Microsoft mangle implementation does not produce back-references for
anonymous namespaces, which results in nonsensical output from both
`undname` and `llvm-undname`. Consider the following example:

```
namespace {
    struct X {};
    X foo(X, X);
}

int main() {
    foo({}, {});
}
```

Clang 22.1.0
```
?foo@?A0xC9C482F4@@YA?AUX@?A0xC9C482F4@@U1?A0xC9C482F4@@0 at Z

undname:
struct `anonymous namespace'::X __cdecl `anonymous namespace'::foo(struct `anonymous namespace'::A0xC9C482F4,struct `anonymous namespace'::A0xC9C482F4)

llvm-undname:
struct `anonymous namespace'::X __cdecl `anonymous namespace'::foo(struct `anonymous namespace'::0xC9C482F4, struct `anonymous namespace'::0xC9C482F4)
```

MSVC 19.50
```
?foo@?A0xa6a4f20e@@YA?AUX at 1@U21 at 0@Z

undname:
struct A0xa6a4f20e::X __cdecl `anonymous namespace'::foo(struct A0xa6a4f20e::X,struct A0xa6a4f20e::X)

llvm-undname:
struct 0xa6a4f20e::X __cdecl `anonymous namespace'::foo(struct 0xa6a4f20e::X, struct 0xa6a4f20e::X)
```

As seen in the undname output for Clang's mangling, not recording a name
back-reference for the anonymous namespace when mangling results in
references to the anonymous namespace's hash in-place of the struct's
name.

When recompiling the example with the changes, Clang yields
`?foo@?A0x69FA3AC2@@YA?AUX at 1@U21 at 0@Z`. Aside from the meaningless
discrepancy with the hash, this is identical to what is produced by
MSVC.

Resolves #37999

Added: 
    

Modified: 
    clang/lib/AST/MicrosoftMangle.cpp
    clang/test/CodeGenCXX/cfi-icall.cpp
    clang/test/CodeGenCXX/mangle-ms.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 1bf92d4209f9f..2c7623632b11a 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1180,7 +1180,9 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
 
       if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
         if (NS->isAnonymousNamespace()) {
-          Out << "?A0x" << Context.getAnonymousNamespaceHash() << '@';
+          llvm::SmallString<16> Name("?A0x");
+          Name += Context.getAnonymousNamespaceHash();
+          mangleSourceName(Name);
           break;
         }
       }

diff  --git a/clang/test/CodeGenCXX/cfi-icall.cpp b/clang/test/CodeGenCXX/cfi-icall.cpp
index 8493a0b877e9a..901dce5d28c46 100644
--- a/clang/test/CodeGenCXX/cfi-icall.cpp
+++ b/clang/test/CodeGenCXX/cfi-icall.cpp
@@ -21,7 +21,7 @@ void g() {
 }
 
 // ITANIUM: define internal void @_ZN12_GLOBAL__N_11fENS_1SE({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
-// MS: define internal void @"?f@?A0x{{[^@]*}}@@YAXUS@?A0x{{[^@]*}}@@@Z"({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
+// MS: define internal void @"?f@?A0x{{[^@]*}}@@YAXUS at 1@@Z"({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
 
 // CHECK: [[VOIDS1]] = distinct !{}
 // CHECK: [[TS1]] = !{i64 0, [[VOIDS1]]}

diff  --git a/clang/test/CodeGenCXX/mangle-ms.cpp b/clang/test/CodeGenCXX/mangle-ms.cpp
index cb1efc412ddd1..606aeb86ac932 100644
--- a/clang/test/CodeGenCXX/mangle-ms.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms.cpp
@@ -15,16 +15,28 @@ namespace N {
   int b;
 // CHECK-DAG: @"?b at N@@3HA"
 
+  struct O {
+    int v;
+  };
+
   namespace {
     int anonymous;
 // CHECK-DAG: @"?anonymous@?A0x{{[^@]*}}@N@@3HA"
+
+    O get() { return O(); }
+// CHECK-DAG: @"?get@?A0x{{[^@]*}}@N@@YA?AUO at 2@XZ"
+
+    namespace {
+      int nested_anonymous;
+// CHECK-DAG: @"?nested_anonymous@?A0x{{[^@]*}}@1N@@3HA"
+    }
   }
 }
 
 static int c;
 // CHECK-DAG: @c
 
-int _c(void) {return N::anonymous + c;}
+int _c(void) {return N::anonymous + N::nested_anonymous + N::get().v + c;}
 // CHECK-DAG: @"?_c@@YAHXZ"
 // X64-DAG:   @"?_c@@YAHXZ"
 


        


More information about the cfe-commits mailing list