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
