diff options
-rw-r--r-- | clang/include/clang/AST/Mangle.h | 3 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 9 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 28 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 7 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-static-initializers.cpp | 8 |
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 } |