On 29.05.2014 23:25, Richard Smith wrote:
> I find it a bit weird that we care in CodeGen whether a dllimport function
> is marked as 'inline'. I would expect that either Sema should detect the
> attribute has no effect and discard it, or it should keep it (and in the
> latter case, CodeGen should respect it and not care whether the function is
> marked 'inline'). Is there some reason that doesn't work?

The first patch is bit backwards and unnecessarily complex. MSVC emits
non-imported specializations with ODR linkage.

So a simpler way to deal with this would be to just do what this mail's
subject says and make such a specialization implictly inline which
resolves correctly to available_externally without doing anything
further. New patch attached.

-Nico
>From 7d68a4c2567dc47d69616c01bc3f04257a168cb5 Mon Sep 17 00:00:00 2001
From: Nico Rieck <[email protected]>
Date: Fri, 30 May 2014 00:23:45 +0200
Subject: [PATCH] MS ABI: Treat dllimport explicit specializations as inline

---
 lib/Sema/SemaDecl.cpp                 |  7 +++++++
 test/CodeGenCXX/dllimport-members.cpp | 28 ++++++++++++++--------------
 test/CodeGenCXX/dllimport.cpp         | 24 ++++++++++++------------
 test/SemaCXX/dllimport.cpp            | 27 +++++++++++++++++++--------
 4 files changed, 52 insertions(+), 34 deletions(-)

diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 075b399..d280561 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -7437,6 +7437,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
       checkIsValidOpenCLKernelParameter(*this, D, Param, ValidTypes);
   }
 
+  // MSVC treats dllimported explicit specializations as inline.
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+      NewFD->hasAttr<DLLImportAttr>() &&
+      NewFD->getTemplatedKind() != FunctionDecl::TK_MemberSpecialization &&
+      NewFD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+    NewFD->setImplicitlyInline();
+
   MarkUnusedFileScopedDecl(NewFD);
 
   if (getLangOpts().CUDA)
diff --git a/test/CodeGenCXX/dllimport-members.cpp b/test/CodeGenCXX/dllimport-members.cpp
index 8eab9d4..a024df6 100644
--- a/test/CodeGenCXX/dllimport-members.cpp
+++ b/test/CodeGenCXX/dllimport-members.cpp
@@ -704,11 +704,11 @@ USE(MemFunTmpl::importedStatic<ExplicitInst_Imported>)
 template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Imported>();
 USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Imported>)
 
-// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
-// M64-DAG-FIXME: declare dllimport                void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$importedNormal@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
 #ifdef MSABI
-//template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {}
-//USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Def_Imported>)
+template<> __declspec(dllimport) void MemFunTmpl::importedNormal<ExplicitSpec_Def_Imported>() {}
+USEMF(MemFunTmpl, importedNormal<ExplicitSpec_Def_Imported>)
 #endif
 
 // M32-DAG: declare dllimport x86_thiscallcc void @"\01??$importedNormal@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
@@ -724,10 +724,10 @@ USEMF(MemFunTmpl, importedNormal<ExplicitSpec_InlineDef_Imported>)
 template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Imported>();
 USE(MemFunTmpl::importedStatic<ExplicitSpec_Imported>)
 
-// MSC-DAG-FIXME: declare dllimport                void @"\01??$importedStatic@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+// MSC-DAG: declare dllimport                void @"\01??$importedStatic@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
 #ifdef MSABI
-//template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {}
-//USE(MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>)
+template<> __declspec(dllimport) void MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>() {}
+USE(MemFunTmpl::importedStatic<ExplicitSpec_Def_Imported>)
 #endif
 
 // MSC-DAG: declare dllimport                void @"\01??$importedStatic@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
@@ -789,11 +789,11 @@ USE(MemFunTmpl::staticDef<ExplicitInst_Imported>)
 template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Imported>();
 USEMF(MemFunTmpl, normalDef<ExplicitSpec_Imported>)
 
-// M32-DAG-FIXME: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
-// M64-DAG-FIXME: declare dllimport                void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
+// M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
+// M64-DAG: declare dllimport                void @"\01??$normalDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@QEAAXXZ"(%struct.MemFunTmpl*)
 #ifdef MSABI
-//template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {}
-//USEMF(MemFunTmpl, normalDef<ExplicitSpec_Def_Imported>)
+template<> __declspec(dllimport) void MemFunTmpl::normalDef<ExplicitSpec_Def_Imported>() {}
+USEMF(MemFunTmpl, normalDef<ExplicitSpec_Def_Imported>)
 #endif
 
 // M32-DAG: declare dllimport x86_thiscallcc void @"\01??$normalDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@QAEXXZ"(%struct.MemFunTmpl*)
@@ -809,10 +809,10 @@ USEMF(MemFunTmpl, normalDef<ExplicitSpec_InlineDef_Imported>)
 template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Imported>();
 USE(MemFunTmpl::staticDef<ExplicitSpec_Imported>)
 
-// MSC-DAG-FIXME: declare dllimport void @"\01??$staticDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitSpec_Def_Imported@@@MemFunTmpl@@SAXXZ"()
 #ifdef MSABI
-//template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {}
-//USE(MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>)
+template<> __declspec(dllimport) void MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>() {}
+USE(MemFunTmpl::staticDef<ExplicitSpec_Def_Imported>)
 #endif
 
 // MSC-DAG: declare dllimport void @"\01??$staticDef@UExplicitSpec_InlineDef_Imported@@@MemFunTmpl@@SAXXZ"()
diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp
index 87f3c88..551229e 100644
--- a/test/CodeGenCXX/dllimport.cpp
+++ b/test/CodeGenCXX/dllimport.cpp
@@ -411,11 +411,11 @@ USE(importedFuncTmpl<ExplicitInst_Imported>)
 template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
 USE(importedFuncTmplDecl<ExplicitSpec_Imported>)
 
-// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
-// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
 #ifdef MSABI
-//template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
-//USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
+template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {}
+USE(importedFuncTmplDecl<ExplicitSpec_Def_Imported>)
 #endif
 
 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmplDecl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
@@ -431,11 +431,11 @@ USE(importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>)
 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
 USE(importedFuncTmpl<ExplicitSpec_Imported>)
 
-// MSC-DAG-FIXME: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
-// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG: define available_externally dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
 #ifdef MSABI
-//template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
-//USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {}
+USE(importedFuncTmpl<ExplicitSpec_Def_Imported>)
 #endif
 
 // MSC-DAG: declare dllimport void @"\01??$importedFuncTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
@@ -488,11 +488,11 @@ USE(inlineFuncTmpl<ExplicitInst_Imported>)
 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
 USE(funcTmpl<ExplicitSpec_Imported>)
 
-// MSC-DAG-FIXME: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
-// MO1-DAG-FIXME: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
+// MO1-DAG: define available_externally dllimport void @"\01??$funcTmpl@UExplicitSpec_Def_Imported@@@@YAXXZ"()
 #ifdef MSABI
-//template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
-//USE(funcTmpl<ExplicitSpec_Def_Imported>)
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {}
+USE(funcTmpl<ExplicitSpec_Def_Imported>)
 #endif
 
 // MSC-DAG: declare dllimport void @"\01??$funcTmpl@UExplicitSpec_InlineDef_Imported@@@@YAXXZ"()
diff --git a/test/SemaCXX/dllimport.cpp b/test/SemaCXX/dllimport.cpp
index 1f53f7a..c3871b1 100644
--- a/test/SemaCXX/dllimport.cpp
+++ b/test/SemaCXX/dllimport.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y %s
+// RUN: %clang_cc1 -triple i686-win32     -fsyntax-only -verify -std=c++11 -DMSABI %s
+// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -verify -std=c++1y -DMSABI %s
 // RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -verify -std=c++1y %s
 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
 
@@ -336,11 +336,20 @@ extern template void importedFuncTmpl<ExplicitDecl_Imported>();
 // likely a bug because an implicit instantiation is accepted.
 template void importedFuncTmpl<ExplicitInst_Imported>();
 
-// Import specialization of an imported function template. A definition must be
-// declared inline.
+// Import specialization of an imported function template.
+template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Imported>();
+template<> __declspec(dllimport) void importedFuncTmplDecl<ExplicitSpec_Def_Imported>() {} // error on mingw
+template<> __declspec(dllimport) inline void importedFuncTmplDecl<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
+
 template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) void importedFuncTmpl<ExplicitSpec_Def_Imported>() {} // error on mingw
 template<> __declspec(dllimport) inline void importedFuncTmpl<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
 
 // Not importing specialization of an imported function template without
 // explicit dllimport.
@@ -355,11 +364,13 @@ extern template __declspec(dllimport) void inlineFuncTmpl<ExplicitDecl_Imported>
 template __declspec(dllimport) void funcTmpl<ExplicitInst_Imported>();
 template __declspec(dllimport) void inlineFuncTmpl<ExplicitInst_Imported>();
 
-// Import specialization of a non-imported function template. A definition must
-// be declared inline.
+// Import specialization of a non-imported function template.
 template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Imported>();
-template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // expected-error{{dllimport cannot be applied to non-inline function definition}}
+template<> __declspec(dllimport) void funcTmpl<ExplicitSpec_Def_Imported>() {} // error on mingw
 template<> __declspec(dllimport) inline void funcTmpl<ExplicitSpec_InlineDef_Imported>() {}
+#ifndef MSABI
+// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
+#endif
 
 
 
-- 
1.9.0.msysgit.0

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to