hans created this revision.

This matches MSVC's behaviour, and we already do it for class templates since 
r270897.


https://reviews.llvm.org/D40621

Files:
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCXX/dllimport.cpp


Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -579,7 +579,7 @@
 // MSC-DAG: declare dllimport void 
@"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
 // GNU-DAG: define weak_odr void 
@_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
-// MO1-DAG: define available_externally dllimport void 
@"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: declare dllimport void 
@"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
 // MO1-DAG: define available_externally dllimport void 
@"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
 // GO1-DAG: define available_externally dllimport void 
@_Z8funcTmplI21ExplicitInst_ImportedEvv()
 // GO1-DAG: define weak_odr void 
@_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
@@ -609,6 +609,15 @@
 template<> __declspec(dllimport) inline void 
funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
 
+#ifdef MSABI
+namespace pr35435 {
+struct X;
+template <typename T> struct __declspec(dllimport) S {
+  void foo(T *t) { t->problem(); }
+};
+template void S<X>::foo(X*); // Cannot be instantiated because X is 
incomplete; dllimport means it's treated as an instantiation decl.
+}
+#endif
 
 
 
//===----------------------------------------------------------------------===//
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -9239,10 +9239,18 @@
       return (Decl*) nullptr;
   }
 
-  Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
 
+  // In MSVC mode, dllimported explicit instantiation definitions are treated 
as
+  // instantiation declarations.
+  if (TSK == TSK_ExplicitInstantiationDefinition &&
+      Specialization->hasAttr<DLLImportAttr>() &&
+      Context.getTargetInfo().getCXXABI().isMicrosoft())
+    TSK = TSK_ExplicitInstantiationDeclaration;
+
+  Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
+
   if (Specialization->isDefined()) {
     // Let the ASTConsumer know that this function has been explicitly
     // instantiated now, and its linkage might have changed.


Index: test/CodeGenCXX/dllimport.cpp
===================================================================
--- test/CodeGenCXX/dllimport.cpp
+++ test/CodeGenCXX/dllimport.cpp
@@ -579,7 +579,7 @@
 // MSC-DAG: declare dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
 // GNU-DAG: declare dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
 // GNU-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
-// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
+// MO1-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitInst_Imported@@@@YAXXZ"()
 // MO1-DAG: define available_externally dllimport void @"\01??$inlineFuncTmpl@UExplicitInst_Imported@@@@YAXXZ"()
 // GO1-DAG: define available_externally dllimport void @_Z8funcTmplI21ExplicitInst_ImportedEvv()
 // GO1-DAG: define weak_odr void @_Z14inlineFuncTmplI21ExplicitInst_ImportedEvv()
@@ -609,6 +609,15 @@
 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
 USE(funcTmpl<ExplicitSpec_InlineDef_Imported>)
 
+#ifdef MSABI
+namespace pr35435 {
+struct X;
+template <typename T> struct __declspec(dllimport) S {
+  void foo(T *t) { t->problem(); }
+};
+template void S<X>::foo(X*); // Cannot be instantiated because X is incomplete; dllimport means it's treated as an instantiation decl.
+}
+#endif
 
 
 //===----------------------------------------------------------------------===//
Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -9239,10 +9239,18 @@
       return (Decl*) nullptr;
   }
 
-  Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
 
+  // In MSVC mode, dllimported explicit instantiation definitions are treated as
+  // instantiation declarations.
+  if (TSK == TSK_ExplicitInstantiationDefinition &&
+      Specialization->hasAttr<DLLImportAttr>() &&
+      Context.getTargetInfo().getCXXABI().isMicrosoft())
+    TSK = TSK_ExplicitInstantiationDeclaration;
+
+  Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
+
   if (Specialization->isDefined()) {
     // Let the ASTConsumer know that this function has been explicitly
     // instantiated now, and its linkage might have changed.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to