summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/Mangle.h3
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp9
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp28
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp7
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp8
5 files changed, 44 insertions, 11 deletions
diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h
index f6aa2fc9766..34864fa1929 100644
--- a/clang/include/clang/AST/Mangle.h
+++ b/clang/include/clang/AST/Mangle.h
@@ -141,6 +141,9 @@ public:
virtual void mangleStaticGuardVariable(const VarDecl *D,
raw_ostream &Out) = 0;
+
+ virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out) = 0;
+
virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) = 0;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 1d8a311c614..38a6223f788 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -153,6 +153,7 @@ public:
raw_ostream &);
void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &);
+ void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &Out);
void mangleItaniumThreadLocalInit(const VarDecl *D, raw_ostream &);
void mangleItaniumThreadLocalWrapper(const VarDecl *D, raw_ostream &);
@@ -3701,6 +3702,14 @@ void ItaniumMangleContext::mangleStaticGuardVariable(const VarDecl *D,
Mangler.mangleName(D);
}
+void ItaniumMangleContext::mangleDynamicInitializer(const VarDecl *MD,
+ raw_ostream &Out) {
+ // These symbols are internal in the Itanium ABI, so the names don't matter.
+ // Clang has traditionally used this symbol and allowed LLVM to adjust it to
+ // avoid duplicate symbols.
+ Out << "__cxx_global_var_init";
+}
+
void ItaniumMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out) {
// Prefix the mangling of D with __dtor_.
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 7e3d6c21395..3ccc2bddf6d 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -170,8 +170,12 @@ public:
raw_ostream &);
virtual void mangleReferenceTemporary(const VarDecl *, raw_ostream &);
virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out);
+ virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
raw_ostream &Out);
+
+private:
+ void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
};
}
@@ -1941,17 +1945,29 @@ void MicrosoftMangleContext::mangleStaticGuardVariable(const VarDecl *VD,
Mangler.getStream() << (Visible ? "@51" : "@4IA");
}
-void MicrosoftMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
- raw_ostream &Out) {
- // <destructor-name> ::= ?__F <postfix> YAXXZ
+void MicrosoftMangleContext::mangleInitFiniStub(const VarDecl *D,
+ raw_ostream &Out,
+ char CharCode) {
MicrosoftCXXNameMangler Mangler(*this, Out);
- Mangler.getStream() << "\01??__F";
+ Mangler.getStream() << "\01??__" << CharCode;
Mangler.mangleName(D);
- // This is the mangling of the function type of the stub, which is a global,
- // non-variadic, cdecl function that returns void and takes no args.
+ // This is the function class mangling. These stubs are global, non-variadic,
+ // cdecl functions that return void and take no args.
Mangler.getStream() << "YAXXZ";
}
+void MicrosoftMangleContext::mangleDynamicInitializer(const VarDecl *D,
+ raw_ostream &Out) {
+ // <initializer-name> ::= ?__E <name> YAXXZ
+ mangleInitFiniStub(D, Out, 'E');
+}
+
+void MicrosoftMangleContext::mangleDynamicAtExitDestructor(const VarDecl *D,
+ raw_ostream &Out) {
+ // <destructor-name> ::= ?__F <name> YAXXZ
+ mangleInitFiniStub(D, Out, 'F');
+}
+
MangleContext *clang::createMicrosoftMangleContext(ASTContext &Context,
DiagnosticsEngine &Diags) {
return new MicrosoftMangleContext(Context, Diags);
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 2417873858b..e3249aa232f 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -259,10 +259,15 @@ CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
llvm::GlobalVariable *Addr,
bool PerformInit) {
llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
+ SmallString<256> FnName;
+ {
+ llvm::raw_svector_ostream Out(FnName);
+ getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);
+ }
// Create a variable initialization function.
llvm::Function *Fn =
- CreateGlobalInitOrDestructFunction(*this, FTy, "__cxx_global_var_init");
+ CreateGlobalInitOrDestructFunction(*this, FTy, FnName.str());
CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D, Addr,
PerformInit);
diff --git a/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
index 6c4e9e72f4a..53d82f60b36 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -emit-llvm %s -o - -cxx-abi microsoft -triple=i386-pc-win32 | FileCheck %s
// CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }]
-// CHECK: [{ i32, void ()* } { i32 65535, void ()* [[INIT_foo:@.*global_var.*]] },
+// CHECK: [{ i32, void ()* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@YAXXZ" },
// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
struct S {
@@ -11,7 +11,7 @@ struct S {
S s;
-// CHECK: define internal void [[INIT_s:@.*global_var.*]] [[NUW:#[0-9]+]]
+// CHECK: define internal void @"\01??__Es@@YAXXZ"() [[NUW:#[0-9]+]]
// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ"
// CHECK: call i32 @atexit(void ()* @"\01??__Fs@@YAXXZ")
// CHECK: ret void
@@ -134,7 +134,7 @@ void force_usage() {
(void)B<int>::foo; // (void) - force usage
}
-// CHECK: define internal void [[INIT_foo]]() [[NUW]]
+// CHECK: define internal void @"\01??__Efoo@?$B@H@@YAXXZ"() [[NUW]]
// CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"
// CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@YAXXZ")
// CHECK: ret void
@@ -148,7 +148,7 @@ void force_usage() {
// CHECK: ret void
// CHECK: define internal void @_GLOBAL__I_a() [[NUW]] {
-// CHECK: call void [[INIT_s]]
+// CHECK: call void @"\01??__Es@@YAXXZ"()
// CHECK: ret void
// CHECK: attributes [[NUW]] = { nounwind }
OpenPOWER on IntegriCloud