[PATCH] D26657: [Sema] Respect DLL attributes more faithfully

Shoaib Meenai via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 14 19:15:45 PST 2016


smeenai created this revision.
smeenai added reviewers: compnerd, hans.
smeenai added a subscriber: cfe-commits.

On MSVC, if an implicit instantiation already exists and an explicit
instantiation definition with a DLL attribute is created, the DLL
attribute still takes effect. Make clang match this behavior.


https://reviews.llvm.org/D26657

Files:
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCXX/dllexport.cpp
  test/CodeGenCXX/dllimport.cpp
  test/CodeGenCXX/windows-itanium-dllexport.cpp


Index: test/CodeGenCXX/windows-itanium-dllexport.cpp
===================================================================
--- test/CodeGenCXX/windows-itanium-dllexport.cpp
+++ test/CodeGenCXX/windows-itanium-dllexport.cpp
@@ -23,3 +23,8 @@
 // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcEaSERKS0_
 // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIcE1fEv
 
+c<double> g;
+template class __declspec(dllexport) c<double>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdEaSERKS0_
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv
Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -814,6 +814,13 @@
 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate at H@@QAEXXZ"
 // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefImportedTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefImportedTemplate at H@@QAE at XZ"
 
+template <typename T> struct ImplicitInstantiationExplicitInstantiationDefImportedTemplate { void f() {} };
+ImplicitInstantiationExplicitInstantiationDefImportedTemplate<int> ImplicitInstantiationExplicitInstantiationDefImportedTemplateInstance;
+template class __declspec(dllimport) ImplicitInstantiationExplicitInstantiationDefImportedTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExplicitInstantiationDefImportedTemplate<int>, f);
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefImportedTemplate at H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExplicitInstantiationDefImportedTemplateIiE1fEv
+
 template <typename T> struct PR23770BaseTemplate { void f() {} };
 template <typename T> struct PR23770DerivedTemplate : PR23770BaseTemplate<int> {};
 extern template struct PR23770DerivedTemplate<int>;
Index: test/CodeGenCXX/dllexport.cpp
===================================================================
--- test/CodeGenCXX/dllexport.cpp
+++ test/CodeGenCXX/dllexport.cpp
@@ -771,6 +771,13 @@
 // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.ExplicitInstantiationDeclExportedDefTemplate* @"\01??0?$ExplicitInstantiationDeclExportedDefTemplate at H@@QAE at XZ"
 // G32-DAG: define weak_odr x86_thiscallcc void @_ZN44ExplicitInstantiationDeclExportedDefTemplateIiE1fEv
 
+template <typename T> struct ImplicitInstantiationExplicitInstantiationDefExportedTemplate { void f() {} };
+ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int> ImplicitInstantiationExplicitInstantiationDefExportedTemplateInstance;
+template class __declspec(dllexport) ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>;
+USEMEMFUNC(ImplicitInstantiationExplicitInstantiationDefExportedTemplate<int>, f);
+// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ImplicitInstantiationExplicitInstantiationDefExportedTemplate at H@@QAEXXZ"
+// G32-DAG: define weak_odr x86_thiscallcc void @_ZN61ImplicitInstantiationExplicitInstantiationDefExportedTemplateIiE1fEv
+
 namespace { struct InternalLinkageType {}; }
 struct __declspec(dllexport) PR23308 {
   void f(InternalLinkageType*);
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -7665,20 +7665,22 @@
                                        Specialization->getDefinition());
   if (Def) {
     TemplateSpecializationKind Old_TSK = Def->getTemplateSpecializationKind();
-    // Fix a TSK_ExplicitInstantiationDeclaration followed by a
-    // TSK_ExplicitInstantiationDefinition
-    if (Old_TSK == TSK_ExplicitInstantiationDeclaration &&
+    // Fix a TSK_ExplicitInstantiationDeclaration or a TSK_ImplicitInstantiation
+    // followed by a TSK_ExplicitInstantiationDefinition
+    if ((Old_TSK == TSK_ExplicitInstantiationDeclaration ||
+         Old_TSK == TSK_ImplicitInstantiation) &&
         (TSK == TSK_ExplicitInstantiationDefinition ||
          DLLImportExplicitInstantiationDef)) {
       // FIXME: Need to notify the ASTMutationListener that we did this.
       Def->setTemplateSpecializationKind(TSK);
 
-      if (!getDLLAttr(Def) && getDLLAttr(Specialization) &&
+      if (getDLLAttr(Specialization) &&
+          (!getDLLAttr(Def) || Old_TSK == TSK_ImplicitInstantiation) &&
           (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
            Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
         // In the MS ABI, an explicit instantiation definition can add a dll
-        // attribute to a template with a previous instantiation declaration.
-        // MinGW doesn't allow this.
+        // attribute to a template with a previous instantiation declaration
+        // or implicit instantiation. MinGW doesn't allow this.
         auto *A = cast<InheritableAttr>(
             getDLLAttr(Specialization)->clone(getASTContext()));
         A->setInherited(true);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D26657.77939.patch
Type: text/x-patch
Size: 5111 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161115/e0d2e127/attachment.bin>


More information about the cfe-commits mailing list