MS ABI: Treat explicit instantiation definitions of dllimport function templates as explicit instantiation decls (PR35435)

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

Differential revision: https://reviews.llvm.org/D40621

llvm-svn: 319386
This commit is contained in:
Hans Wennborg 2017-11-29 23:44:11 +00:00
parent e10568364e
commit b8304a6aed
2 changed files with 19 additions and 2 deletions

View File

@ -9239,10 +9239,18 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
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.

View File

@ -579,7 +579,7 @@ USE(inlineFuncTmpl<ExplicitDecl_Imported>)
// 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 @@ USE(funcTmpl<ExplicitSpec_Imported>)
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
//===----------------------------------------------------------------------===//