rnk created this revision.
rnk added reviewers: majnemer, inglorion, hans.
Herald added subscribers: dexonsmith, JDevlieghere, aprantl, mehdi_amini.

This is needed to avoid conflicts in mangled names for codeview types in
anonymous namespaces. In CodeView, types refer to each other typically
through forward declarations, which contain mangled names. These names
have to be unique, otherwise the debugger will look up the mangled name
and find the wrong definition.

Furthermore, ThinLTO will deduplicate the types, and debug info
verification can fail when the types have the wrong sizes. This is
PR38608.

Fixes PR38609.


https://reviews.llvm.org/D50877

Files:
  clang/lib/AST/MicrosoftMangle.cpp
  clang/test/CodeGenCXX/cfi-cross-dso.cpp
  clang/test/CodeGenCXX/cfi-icall.cpp
  clang/test/CodeGenCXX/debug-info-thunk.cpp
  clang/test/CodeGenCXX/dllexport.cpp
  clang/test/CodeGenCXX/mangle-ms.cpp
  clang/test/CodeGenCXX/microsoft-abi-structors.cpp
  clang/test/CodeGenCXX/microsoft-abi-throw.cpp
  clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
  clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
  clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
  clang/test/CodeGenCXX/msabi-swiftcall-cc.cpp
  clang/test/CodeGenCXX/pragma-init_seg.cpp
  clang/test/CodeGenCXX/type-metadata.cpp

Index: clang/test/CodeGenCXX/type-metadata.cpp
===================================================================
--- clang/test/CodeGenCXX/type-metadata.cpp
+++ clang/test/CodeGenCXX/type-metadata.cpp
@@ -82,8 +82,8 @@
 // MS: comdat($"??_7B@@6B0@@"), !type [[B8:![0-9]+]]
 // MS: comdat($"??_7B@@6BA@@@"), !type [[A8]]
 // MS: comdat($"??_7C@@6B@"), !type [[A8]]
-// MS: comdat($"??_7D@?A@@6BB@@@"), !type [[B8]], !type [[D8:![0-9]+]]
-// MS: comdat($"??_7D@?A@@6BA@@@"), !type [[A8]]
+// MS: comdat($"??_7D@?A0x{{[^@]*}}@@6BB@@@"), !type [[B8]], !type [[D8:![0-9]+]]
+// MS: comdat($"??_7D@?A0x{{[^@]*}}@@6BA@@@"), !type [[A8]]
 // MS: comdat($"??_7FA@?1??foo@@YAXXZ@6B@"), !type [[A8]], !type [[FA8:![0-9]+]]
 
 struct A {
@@ -161,7 +161,7 @@
 }
 
 // ITANIUM: define internal void @_Z3df1PN12_GLOBAL__N_11DE
-// MS: define internal void @"?df1@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?df1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
 void df1(D *d) {
   // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
   // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUA@@")
@@ -171,7 +171,7 @@
 }
 
 // ITANIUM: define internal void @_Z3dg1PN12_GLOBAL__N_11DE
-// MS: define internal void @"?dg1@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?dg1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
 void dg1(D *d) {
   // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"_ZTS1B")
   // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata !"?AUB@@")
@@ -181,7 +181,7 @@
 }
 
 // ITANIUM: define internal void @_Z3dh1PN12_GLOBAL__N_11DE
-// MS: define internal void @"?dh1@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?dh1@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
 void dh1(D *d) {
   // TT-ITANIUM: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE]])
   // TT-MS: {{%[^ ]*}} = call i1 @llvm.type.test(i8* {{%[^ ]*}}, metadata ![[DTYPE:[0-9]+]])
@@ -191,7 +191,7 @@
 }
 
 // ITANIUM: define internal void @_Z3df2PN12_GLOBAL__N_11DE
-// MS: define internal void @"?df2@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?df2@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
 __attribute__((no_sanitize("cfi")))
 void df2(D *d) {
   // CFI-NVT-NOT: call i1 @llvm.type.test
@@ -201,7 +201,7 @@
 }
 
 // ITANIUM: define internal void @_Z3df3PN12_GLOBAL__N_11DE
-// MS: define internal void @"?df3@@YAXPEAUD@?A@@@Z"
+// MS: define internal void @"?df3@@YAXPEAUD@?A0x{{[^@]*}}@@@Z"
 __attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall")))
 void df3(D *d) {
   // CFI-NVT-NOT: call i1 @llvm.type.test
Index: clang/test/CodeGenCXX/pragma-init_seg.cpp
===================================================================
--- clang/test/CodeGenCXX/pragma-init_seg.cpp
+++ clang/test/CodeGenCXX/pragma-init_seg.cpp
@@ -28,8 +28,8 @@
 namespace internal_init {
 namespace {
 int x = f();
-// CHECK: @"?x@?A@internal_init@@3HA" = internal global i32 0, align 4
-// CHECK: @__cxx_init_fn_ptr.2 = private constant void ()* @"??__Ex@?A@internal_init@@YAXXZ", section ".asdf"
+// CHECK: @"?x@?A0x{{[^@]*}}@internal_init@@3HA" = internal global i32 0, align 4
+// CHECK: @__cxx_init_fn_ptr.2 = private constant void ()* @"??__Ex@?A0x{{[^@]*}}@internal_init@@YAXXZ", section ".asdf"
 }
 }
 
Index: clang/test/CodeGenCXX/msabi-swiftcall-cc.cpp
===================================================================
--- clang/test/CodeGenCXX/msabi-swiftcall-cc.cpp
+++ clang/test/CodeGenCXX/msabi-swiftcall-cc.cpp
@@ -12,8 +12,8 @@
 namespace {
 void __attribute__((__swiftcall__)) __attribute__((__used__)) f() { }
 }
-// CHECK-DAG: @"?f@?A@@YSXXZ"
-// CHECK-64-DAG: @"?f@?A@@YSXXZ"
+// CHECK-DAG: @"?f@?A0x{{[^@]*}}@@YSXXZ"
+// CHECK-64-DAG: @"?f@?A0x{{[^@]*}}@@YSXXZ"
 
 namespace n {
 void __attribute__((__swiftcall__)) f() {}
@@ -44,8 +44,8 @@
 namespace {
 void __attribute__((__preserve_most__)) __attribute__((__used__)) g() {}
 }
-// CHECK-DAG: @"?g@?A@@YUXXZ"
-// CHECK-64-DAG: @"?g@?A@@YUXXZ"
+// CHECK-DAG: @"?g@?A0x{{[^@]*}}@@YUXXZ"
+// CHECK-64-DAG: @"?g@?A0x{{[^@]*}}@@YUXXZ"
 
 namespace n {
 void __attribute__((__preserve_most__)) g() {}
Index: clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
===================================================================
--- clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp
@@ -57,14 +57,14 @@
 // CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AE" to i8*), i8** %ptr
 // CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B3AE" to i8*), i8** %ptr2
 // CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AE" to i8*), i8** %ptr3
-// CHECK32: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A@@$BA@AE" to i8*), i8** %ptr4
+// CHECK32: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AE" to i8*), i8** %ptr4
 // CHECK32: }
 //
 // CHECK64-LABEL: define dso_local void @"?f@@YAXXZ"()
 // CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BA@AA" to i8*), i8** %ptr
 // CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$B7AA" to i8*), i8** %ptr2
 // CHECK64: store i8* bitcast (void (%struct.C*, ...)* @"??_9C@@$BBA@AA" to i8*), i8** %ptr3
-// CHECK64: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A@@$BA@AA" to i8*), i8** %ptr
+// CHECK64: store i8* bitcast (void (%"struct.(anonymous namespace)::D"*, ...)* @"??_9D@?A0x{{[^@]*}}@@$BA@AA" to i8*), i8** %ptr
 // CHECK64: }
 }
 
@@ -125,15 +125,15 @@
 // CHECK64: }
 
 // Thunk for calling the virtual function in internal class D.
-// CHECK32-LABEL: define internal x86_thiscallcc void @"??_9D@?A@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this, ...)
+// CHECK32-LABEL: define internal x86_thiscallcc void @"??_9D@?A0x{{[^@]*}}@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this, ...)
 // CHECK32: #[[ATTR]]
 // CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
 // CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
 // CHECK32: musttail call x86_thiscallcc void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...)
 // CHECK32-NEXT: ret void
 // CHECK32: }
 //
-// CHECK64-LABEL: define internal void @"??_9D@?A@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this, ...)
+// CHECK64-LABEL: define internal void @"??_9D@?A0x{{[^@]*}}@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this, ...)
 // CHECK64: #[[ATTR]]
 // CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0
 // CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]]
Index: clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
===================================================================
--- clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-vftables.cpp
@@ -36,10 +36,10 @@
   virtual ~W() {}
 } w;
 }
-// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GW@?A@@UAEPAXI@Z" to i8*)] }
-// RTTI-DAG: @"??_7W@?A@@6B@" = internal unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_W]], i32 0, i32 0, i32 1)
+// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast ({{.*}} @"??_R4W@?A0x{{[^@]*}}@@6B@" to i8*), i8* bitcast ({{.*}} @"??_GW@?A0x{{[^@]*}}@@UAEPAXI@Z" to i8*)] }
+// RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* [[VTABLE_W]], i32 0, i32 0, i32 1)
 
-// NO-RTTI-DAG: @"??_7W@?A@@6B@" = internal unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GW@?A@@UAEPAXI@Z" to i8*)] }
+// NO-RTTI-DAG: @"??_7W@?A0x{{[^@]*}}@@6B@" = internal unnamed_addr constant { [1 x i8*] } { [1 x i8*] [i8* bitcast ({{.*}} @"??_GW@?A0x{{[^@]*}}@@UAEPAXI@Z" to i8*)] }
 
 struct X {};
 template <class> struct Y : virtual X {
Index: clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
===================================================================
--- clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-thunks.cpp
@@ -160,5 +160,5 @@
 E::E() {}
 E e;
 // Class with internal linkage has internal linkage thunks.
-// CODEGEN: define internal x86_thiscallcc %struct.C* @"?goo@E@?A@@QAEPAUB@@XZ"
+// CODEGEN: define internal x86_thiscallcc %struct.C* @"?goo@E@?A0x{{[^@]*}}@@QAEPAUB@@XZ"
 }
Index: clang/test/CodeGenCXX/microsoft-abi-throw.cpp
===================================================================
--- clang/test/CodeGenCXX/microsoft-abi-throw.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-throw.cpp
@@ -22,7 +22,7 @@
 // CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @_TIU2PAPFAH = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 4, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.2* @_CTA2PAPFAH to i8*) }, section ".xdata", comdat
 // CHECK-DAG: @_CTA2PAPFAH = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0PAPFAH@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat
-// CHECK-DAG: @"_TI1?AUFoo@?A@@" = internal unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @"_CTA1?AUFoo@?A@@" to i8*) }, section ".xdata"
+// CHECK-DAG: @"_TI1?AUFoo@?A0x{{[^@]*}}@@" = internal unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @"_CTA1?AUFoo@?A0x{{[^@]*}}@@" to i8*) }, section ".xdata"
 
 
 struct N { ~N(); };
@@ -135,6 +135,6 @@
 
 void *GetExceptionInfo_test2() {
 // CHECK-LABEL: @"?GetExceptionInfo_test2@@YAPAXXZ"
-// CHECK:  ret i8* bitcast (%eh.ThrowInfo* @"_TI1?AUFoo@?A@@" to i8*)
+// CHECK:  ret i8* bitcast (%eh.ThrowInfo* @"_TI1?AUFoo@?A0x{{[^@]*}}@@" to i8*)
   return __GetExceptionInfo(foo_exc);
 }
Index: clang/test/CodeGenCXX/microsoft-abi-structors.cpp
===================================================================
--- clang/test/CodeGenCXX/microsoft-abi-structors.cpp
+++ clang/test/CodeGenCXX/microsoft-abi-structors.cpp
@@ -467,9 +467,9 @@
 void *getA() {
   return (void*)new A();
 }
-// CHECK: define internal x86_thiscallcc i8* @"??_GA@?A@@UAEPAXI@Z"
+// CHECK: define internal x86_thiscallcc i8* @"??_GA@?A0x{{[^@]*}}@@UAEPAXI@Z"
 // CHECK:               (%"struct.(anonymous namespace)::A"* %this, i32 %should_call_delete)
-// CHECK: define internal x86_thiscallcc void @"??1A@?A@@UAE@XZ"
+// CHECK: define internal x86_thiscallcc void @"??1A@?A0x{{[^@]*}}@@UAE@XZ"
 // CHECK:               (%"struct.(anonymous namespace)::A"* %this)
 
 // Check that we correctly transform __stdcall to __thiscall for ctors and
Index: clang/test/CodeGenCXX/mangle-ms.cpp
===================================================================
--- clang/test/CodeGenCXX/mangle-ms.cpp
+++ clang/test/CodeGenCXX/mangle-ms.cpp
@@ -15,7 +15,7 @@
 
   namespace {
     int anonymous;
-// CHECK-DAG: @"?anonymous@?A@N@@3HA"
+// CHECK-DAG: @"?anonymous@?A0x{{[^@]*}}@N@@3HA"
   }
 }
 
Index: clang/test/CodeGenCXX/dllexport.cpp
===================================================================
--- clang/test/CodeGenCXX/dllexport.cpp
+++ clang/test/CodeGenCXX/dllexport.cpp
@@ -797,7 +797,7 @@
 };
 void PR23308::f(InternalLinkageType*) {}
 long use(PR23308* p) { p->f(nullptr); }
-// M32-DAG: define internal x86_thiscallcc void @"?f@PR23308@@QAEXPAUInternalLinkageType@?A@@@Z"
+// M32-DAG: define internal x86_thiscallcc void @"?f@PR23308@@QAEXPAUInternalLinkageType@?A0x{{[^@]*}}@@@Z"
 
 template <typename T> struct PR23770BaseTemplate { void f() {} };
 template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
Index: clang/test/CodeGenCXX/debug-info-thunk.cpp
===================================================================
--- clang/test/CodeGenCXX/debug-info-thunk.cpp
+++ clang/test/CodeGenCXX/debug-info-thunk.cpp
@@ -86,7 +86,7 @@
     };
   }
   void C::c() {}
-// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A@Test4@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
+// CHECK-DAG: DISubprogram{{.*}}linkageName: "?f@C@?A0x{{[^@]*}}@Test4@@W7EAAXXZ"{{.*}} flags: {{.*}}DIFlagThunk
   void C::f() {}
 
   // Force C::f to be used.
Index: clang/test/CodeGenCXX/cfi-icall.cpp
===================================================================
--- clang/test/CodeGenCXX/cfi-icall.cpp
+++ clang/test/CodeGenCXX/cfi-icall.cpp
@@ -21,7 +21,7 @@
 }
 
 // ITANIUM: define internal void @_ZN12_GLOBAL__N_11fENS_1SE({{.*}} !type [[TS1:![0-9]+]] !type [[TS2:![0-9]+]]
-// MS: define internal void @"?f@?A@@YAXUS@?A@@@Z"({{.*}} !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]+]]
 
 // CHECK: [[VOIDS1]] = distinct !{}
 // CHECK: [[TS1]] = !{i64 0, [[VOIDS1]]}
Index: clang/test/CodeGenCXX/cfi-cross-dso.cpp
===================================================================
--- clang/test/CodeGenCXX/cfi-cross-dso.cpp
+++ clang/test/CodeGenCXX/cfi-cross-dso.cpp
@@ -26,7 +26,7 @@
   b.f();
 }
 
-// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"??_R4B@?A@@6B@"{{.*}}@"?f@B@?A@@UEAAXXZ"
+// MS: @[[B_VTABLE:.*]] = private unnamed_addr constant { [2 x i8*] } {{.*}}@"??_R4B@?A0x{{[^@]*}}@@6B@"{{.*}}@"?f@B@?A0x{{[^@]*}}@@UEAAXXZ"
 
 // CHECK:   %[[VT:.*]] = load void (%struct.A*)**, void (%struct.A*)***
 // CHECK:   %[[VT2:.*]] = bitcast {{.*}}%[[VT]] to i8*, !nosanitize
Index: clang/lib/AST/MicrosoftMangle.cpp
===================================================================
--- clang/lib/AST/MicrosoftMangle.cpp
+++ clang/lib/AST/MicrosoftMangle.cpp
@@ -127,10 +127,10 @@
   llvm::DenseMap<const CXXRecordDecl *, unsigned> LambdaIds;
   llvm::DenseMap<const NamedDecl *, unsigned> SEHFilterIds;
   llvm::DenseMap<const NamedDecl *, unsigned> SEHFinallyIds;
+  SmallString<16> AnonymousNamespaceHash;
 
 public:
-  MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
-      : MicrosoftMangleContext(Context, Diags) {}
+  MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags);
   bool shouldMangleCXXName(const NamedDecl *D) override;
   bool shouldMangleStringLiteral(const StringLiteral *SL) override;
   void mangleCXXName(const NamedDecl *D, raw_ostream &Out) override;
@@ -238,6 +238,12 @@
     return Result.first->second;
   }
 
+  /// Return a character sequence that is (somewhat) unique to the TU suitable
+  /// for mangling anonymous namespaces.
+  StringRef getAnonymousNamespaceHash() const {
+    return AnonymousNamespaceHash;
+  }
+
 private:
   void mangleInitFiniStub(const VarDecl *D, char CharCode, raw_ostream &Out);
 };
@@ -371,6 +377,27 @@
 };
 }
 
+MicrosoftMangleContextImpl::MicrosoftMangleContextImpl(ASTContext &Context,
+                                                       DiagnosticsEngine &Diags)
+    : MicrosoftMangleContext(Context, Diags) {
+  // Hash the path to the main source file. We'll mangle the hash into the names
+  // of things in anonymous namespaces so that they are somewhat unique between
+  // TUs. If we don't have a path to the main file, we'll just use 0.
+  SourceManager &SM = Context.getSourceManager();
+  const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID());
+  if (FE) {
+    llvm::MD5 Hasher;
+    llvm::MD5::MD5Result Hash;
+    Hasher.update(FE->getName());
+    Hasher.final(Hash);
+
+    // Take 8 hexadecimal characters. These names shouldn't be excessively long.
+    AnonymousNamespaceHash = StringRef(Hash.digest()).take_front(8);
+  } else {
+    AnonymousNamespaceHash = "0";
+  }
+}
+
 bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     LanguageLinkage L = FD->getLanguageLinkage();
@@ -785,7 +812,7 @@
 
       if (const NamespaceDecl *NS = dyn_cast<NamespaceDecl>(ND)) {
         if (NS->isAnonymousNamespace()) {
-          Out << "?A@";
+          Out << "?A0x" << Context.getAnonymousNamespaceHash() << '@';
           break;
         }
       }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to