Don't dllimport/export destructor variants implemented by thunks.
authorHans Wennborg <hans@hanshq.net>
Wed, 28 May 2014 01:52:23 +0000 (01:52 +0000)
committerHans Wennborg <hans@hanshq.net>
Wed, 28 May 2014 01:52:23 +0000 (01:52 +0000)
MSVC doesn't export these functions, so trying to import them doesnt' work.
Also, don't let any dll attributes on the CXXDestructorDecl influence the
thunk's linkage -- they should always be linkonce_odr.

This takes care of the FIXME's for this in Nico's tests.

Differential Revision: http://reviews.llvm.org/D3930

llvm-svn: 209706

clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/CodeGen/CodeGenModule.h
clang/test/CodeGenCXX/dllimport-members.cpp

index 9e8401d..c55e231 100644 (file)
@@ -561,13 +561,16 @@ CodeGenModule::getFunctionLinkage(GlobalDecl GD) {
 
   GVALinkage Linkage = getContext().GetGVALinkageForFunction(D);
 
-  bool UseThunkForDtorVariant =
-      isa<CXXDestructorDecl>(D) &&
+  if (isa<CXXDestructorDecl>(D) &&
       getCXXABI().useThunkForDtorVariant(cast<CXXDestructorDecl>(D),
-                                         GD.getDtorType());
+                                         GD.getDtorType())) {
+    // Destructor variants in the Microsoft C++ ABI are always internal or
+    // linkonce_odr thunks emitted on an as-needed basis.
+    return Linkage == GVA_Internal ? llvm::GlobalValue::InternalLinkage
+                                   : llvm::GlobalValue::LinkOnceODRLinkage;
+  }
 
-  return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false,
-                                     UseThunkForDtorVariant);
+  return getLLVMLinkageForDeclarator(D, Linkage, /*isConstantVariable=*/false);
 }
 
 void CodeGenModule::setFunctionDefinitionAttributes(const FunctionDecl *D,
@@ -780,6 +783,13 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
 
   setLinkageAndVisibilityForGV(F, FD);
 
+  if (const auto *Dtor = dyn_cast_or_null<CXXDestructorDecl>(FD)) {
+    if (getCXXABI().useThunkForDtorVariant(Dtor, GD.getDtorType())) {
+      // Don't dllexport/import destructor thunks.
+      F->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+    }
+  }
+
   if (const SectionAttr *SA = FD->getAttr<SectionAttr>())
     F->setSection(SA->getName());
 
@@ -1914,8 +1924,7 @@ static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
 }
 
 llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
-    const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable,
-    bool UseThunkForDtorVariant) {
+    const DeclaratorDecl *D, GVALinkage Linkage, bool IsConstantVariable) {
   if (Linkage == GVA_Internal)
     return llvm::Function::InternalLinkage;
 
@@ -1954,11 +1963,6 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
     return !Context.getLangOpts().AppleKext ? llvm::Function::WeakODRLinkage
                                             : llvm::Function::ExternalLinkage;
 
-  // Destructor variants in the Microsoft C++ ABI are always linkonce_odr thunks
-  // emitted on an as-needed basis.
-  if (UseThunkForDtorVariant)
-    return llvm::GlobalValue::LinkOnceODRLinkage;
-
   // If required by the ABI, give definitions of static data members with inline
   // initializers at least linkonce_odr linkage.
   if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
@@ -1987,8 +1991,7 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
 llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageVarDefinition(
     const VarDecl *VD, bool IsConstant) {
   GVALinkage Linkage = getContext().GetGVALinkageForVariable(VD);
-  return getLLVMLinkageForDeclarator(VD, Linkage, IsConstant,
-                                     /*UseThunkForDtorVariant=*/false);
+  return getLLVMLinkageForDeclarator(VD, Linkage, IsConstant);
 }
 
 /// Replace the uses of a function that was declared with a non-proto type.
index 9e58351..c54f6de 100644 (file)
@@ -975,8 +975,7 @@ public:
   /// Returns LLVM linkage for a declarator.
   llvm::GlobalValue::LinkageTypes
   getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage,
-                              bool IsConstantVariable,
-                              bool UseThunkForDtorVariant);
+                              bool IsConstantVariable);
 
   /// Returns LLVM linkage for a declarator.
   llvm::GlobalValue::LinkageTypes
index 63ce989..7fe48a7 100644 (file)
@@ -422,9 +422,8 @@ struct ImportSpecials {
   // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsC1Ev(%struct.ImportSpecials*)
   __declspec(dllimport) ImportSpecials();
 
-  // FIXME: MSVC emits ??1ImportSpecials@@{{QAE|QEAA}}@XZ here.
-  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportSpecials@@QAE@XZ"(%struct.ImportSpecials*)
-  // M64-DAG: declare dllimport                void @"\01??_DImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportSpecials@@QAE@XZ"(%struct.ImportSpecials*)
+  // M64-DAG: declare dllimport                void @"\01??1ImportSpecials@@QEAA@XZ"(%struct.ImportSpecials*)
   // G32-DAG: declare dllimport x86_thiscallcc void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
   // G64-DAG: declare dllimport                void                    @_ZN14ImportSpecialsD1Ev(%struct.ImportSpecials*)
   __declspec(dllimport) ~ImportSpecials() {}
@@ -466,12 +465,11 @@ struct ImportInlineSpecials {
   // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsC1Ev(
   __declspec(dllimport) ImportInlineSpecials() {}
 
-  // FIXME: MSVC emits ??1ImportInlineSpecials@@{{QAE|QEAA}}@XZ here.
-  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials*)
-  // M64-DAG: declare dllimport                void @"\01??_DImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportInlineSpecials@@QAE@XZ"(%struct.ImportInlineSpecials*)
+  // M64-DAG: declare dllimport                void @"\01??1ImportInlineSpecials@@QEAA@XZ"(%struct.ImportInlineSpecials*)
   // G32-DAG: declare dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*)
   // G64-DAG: declare dllimport                void @_ZN20ImportInlineSpecialsD1Ev(%struct.ImportInlineSpecials*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportInlineSpecials@@QAE@XZ"(
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1ImportInlineSpecials@@QAE@XZ"(
   // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN20ImportInlineSpecialsD1Ev(
   __declspec(dllimport) ~ImportInlineSpecials() {}
 
@@ -522,11 +520,11 @@ struct ImportDefaulted {
   // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedC1Ev(%struct.ImportDefaulted* %this)
   __declspec(dllimport) ImportDefaulted() = default;
 
-  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted*)
-  // M64-DAG: declare dllimport                void @"\01??_DImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted*)
+  // M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted*)
+  // M64-DAG: declare dllimport                void @"\01??1ImportDefaulted@@QEAA@XZ"(%struct.ImportDefaulted*)
   // G32-DAG: declare dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*)
   // G64-DAG: declare dllimport                void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted*)
-  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??_DImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* %this)
+  // MO1-DAG: define available_externally dllimport x86_thiscallcc void @"\01??1ImportDefaulted@@QAE@XZ"(%struct.ImportDefaulted* %this)
   // GO1-DAG: define available_externally dllimport x86_thiscallcc void @_ZN15ImportDefaultedD1Ev(%struct.ImportDefaulted* %this)
   __declspec(dllimport) ~ImportDefaulted() = default;
 
@@ -585,9 +583,8 @@ struct ImportDefaultedDefs {
 // G64-DAG: declare dllimport                void                         @_ZN19ImportDefaultedDefsC1Ev(%struct.ImportDefaultedDefs*)
 __declspec(dllimport) ImportDefaultedDefs::ImportDefaultedDefs() = default;
 
-// FIXME: MSVC emits ??1ImportDefaultedDefs@@{{QAE|QEAA}}@XZ here.
-// M32-DAG: declare dllimport x86_thiscallcc void @"\01??_DImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs*)
-// M64-DAG: declare dllimport                void @"\01??_DImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs*)
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??1ImportDefaultedDefs@@QAE@XZ"(%struct.ImportDefaultedDefs*)
+// M64-DAG: declare dllimport                void @"\01??1ImportDefaultedDefs@@QEAA@XZ"(%struct.ImportDefaultedDefs*)
 // G32-DAG: declare dllimport x86_thiscallcc void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*)
 // G64-DAG: declare dllimport                void @_ZN19ImportDefaultedDefsD1Ev(%struct.ImportDefaultedDefs*)
 __declspec(dllimport) ImportDefaultedDefs::~ImportDefaultedDefs() = default;