]> granicus.if.org Git - clang/commitdiff
Fix ctor/dtor aliases losing 'dllexport' (for Itanium ABI)
authorDario Domizioli <dario.domizioli@gmail.com>
Fri, 19 Sep 2014 22:06:24 +0000 (22:06 +0000)
committerDario Domizioli <dario.domizioli@gmail.com>
Fri, 19 Sep 2014 22:06:24 +0000 (22:06 +0000)
This patch makes sure that the dllexport attribute is transferred to the alias when such alias is created. It only affects the Itanium ABI because for the MSVC ABI a workaround is in place to not generate aliases of dllexport ctors/dtors.
A new CodeGenModule function is provided, CodeGenModule::setAliasAttributes, to factor the code for transferring attributes to aliases.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218159 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGenCXX/dllexport-alias.cpp [new file with mode: 0644]

index 5e87fc2799c675000537b82a4f5f72a6c4c7a392..6e7da49a44d41619233c9a3b1fcc5a2d290f5a77 100644 (file)
@@ -786,6 +786,16 @@ void CodeGenModule::SetCommonAttributes(const Decl *D,
     addUsedGlobal(GV);
 }
 
+void CodeGenModule::setAliasAttributes(const Decl *D,
+                                       llvm::GlobalValue *GV) {
+  SetCommonAttributes(D, GV);
+
+  // Process the dllexport attribute based on whether the original definition
+  // (not necessarily the aliasee) was exported.
+  if (D->hasAttr<DLLExportAttr>())
+    GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass);
+}
+
 void CodeGenModule::setNonAliasAttributes(const Decl *D,
                                           llvm::GlobalObject *GO) {
   SetCommonAttributes(D, GO);
index a095c9ddbb9711a5589077d159f30d30ab2c648e..afd5b5d404f00e47018409b2cd01eb683d6cf2d1 100644 (file)
@@ -1069,6 +1069,12 @@ public:
   /// NOTE: This should only be called for definitions.
   void SetCommonAttributes(const Decl *D, llvm::GlobalValue *GV);
 
+  /// Set attributes which must be preserved by an alias. This includes common
+  /// attributes (i.e. it includes a call to SetCommonAttributes).
+  ///
+  /// NOTE: This should only be called for definitions.
+  void setAliasAttributes(const Decl *D, llvm::GlobalValue *GV);
+
   void addReplacement(StringRef Name, llvm::Constant *C);
 private:
 
index ed7b4e9dadd2f00466716bd1fb791ce0e58e16c6..84bfb6aa505e7592f339617af543c183101af814 100644 (file)
@@ -3077,7 +3077,7 @@ static void emitConstructorDestructorAlias(CodeGenModule &CGM,
   }
 
   // Finally, set up the alias with its proper name and attributes.
-  CGM.SetCommonAttributes(cast<NamedDecl>(AliasDecl.getDecl()), Alias);
+  CGM.setAliasAttributes(cast<NamedDecl>(AliasDecl.getDecl()), Alias);
 }
 
 void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,
diff --git a/test/CodeGenCXX/dllexport-alias.cpp b/test/CodeGenCXX/dllexport-alias.cpp
new file mode 100644 (file)
index 0000000..479595d
--- /dev/null
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-windows-gnu -mconstructor-aliases %s -S -emit-llvm -o - | FileCheck %s
+
+// This test assumes that the C1 constructor will be aliased to the C2
+// constructor, and the D1 destructor to the D2. It then checks that the aliases
+// are dllexport'ed.
+
+class __declspec(dllexport) A {
+public:
+    A();
+    ~A();
+};
+
+A::A() {}
+
+A::~A() {}
+
+// CHECK: @_ZN1AC1Ev = dllexport alias void (%class.A*)* @_ZN1AC2Ev
+// CHECK: @_ZN1AD1Ev = dllexport alias void (%class.A*)* @_ZN1AD2Ev