2014-02-23 03:47:30 +08:00
// 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-mingw32 -fsyntax-only -verify -std=c++1y %s
// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -verify -std=c++11 %s
// Helper structs to make templates more expressive.
struct ImplicitInst_Imported { } ;
struct ExplicitDecl_Imported { } ;
struct ExplicitInst_Imported { } ;
struct ExplicitSpec_Imported { } ;
struct ExplicitSpec_Def_Imported { } ;
struct ExplicitSpec_InlineDef_Imported { } ;
struct ExplicitSpec_NotImported { } ;
2014-03-31 22:56:58 +08:00
namespace { struct Internal { } ; }
2014-02-23 03:47:30 +08:00
// Invalid usage.
__declspec ( dllimport ) typedef int typedef1 ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
typedef __declspec ( dllimport ) int typedef2 ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
typedef int __declspec ( dllimport ) typedef3 ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
typedef __declspec ( dllimport ) void ( * FunTy ) ( ) ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
enum __declspec ( dllimport ) Enum { } ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
# if __has_feature(cxx_strong_enums)
enum class __declspec ( dllimport ) EnumClass { } ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
# endif
//===----------------------------------------------------------------------===//
// Globals
//===----------------------------------------------------------------------===//
// Import declaration.
__declspec ( dllimport ) extern int ExternGlobalDecl ;
2014-02-27 05:27:13 +08:00
// dllimport implies a declaration.
__declspec ( dllimport ) int GlobalDecl ;
2014-03-24 05:24:01 +08:00
int * * __attribute__ ( ( dllimport ) ) * GlobalDeclChunkAttr ;
int GlobalDeclAttr __attribute__ ( ( dllimport ) ) ;
2014-02-23 03:47:30 +08:00
// Not allowed on definitions.
2014-02-27 05:27:13 +08:00
__declspec ( dllimport ) extern int ExternGlobalInit = 1 ; // expected-error{{definition of dllimport data}}
__declspec ( dllimport ) int GlobalInit1 = 1 ; // expected-error{{definition of dllimport data}}
int __declspec ( dllimport ) GlobalInit2 = 1 ; // expected-error{{definition of dllimport data}}
2014-02-23 03:47:30 +08:00
// Declare, then reject definition.
2014-03-31 22:56:15 +08:00
__declspec ( dllimport ) extern int ExternGlobalDeclInit ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
int ExternGlobalDeclInit = 1 ; // expected-warning{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
2014-02-23 03:47:30 +08:00
2014-03-31 22:56:15 +08:00
__declspec ( dllimport ) int GlobalDeclInit ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
int GlobalDeclInit = 1 ; // expected-warning{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
2014-03-24 05:24:01 +08:00
2014-03-31 22:56:15 +08:00
int * __attribute__ ( ( dllimport ) ) GlobalDeclChunkAttrInit ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
int * GlobalDeclChunkAttrInit = 0 ; // expected-warning{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
2014-03-24 05:24:01 +08:00
2014-03-31 22:56:15 +08:00
int GlobalDeclAttrInit __attribute__ ( ( dllimport ) ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
int GlobalDeclAttrInit = 1 ; // expected-warning{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
2014-03-24 05:24:01 +08:00
2014-02-23 03:47:30 +08:00
// Redeclarations
__declspec ( dllimport ) extern int GlobalRedecl1 ;
__declspec ( dllimport ) extern int GlobalRedecl1 ;
2014-03-24 05:24:01 +08:00
__declspec ( dllimport ) int GlobalRedecl2a ;
__declspec ( dllimport ) int GlobalRedecl2a ;
int * __attribute__ ( ( dllimport ) ) GlobalRedecl2b ;
int * __attribute__ ( ( dllimport ) ) GlobalRedecl2b ;
int GlobalRedecl2c __attribute__ ( ( dllimport ) ) ;
int GlobalRedecl2c __attribute__ ( ( dllimport ) ) ;
2014-03-31 22:56:15 +08:00
// NB: MSVC issues a warning and makes GlobalRedecl3 dllexport. We follow GCC
// and drop the dllimport with a warning.
__declspec ( dllimport ) extern int GlobalRedecl3 ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
extern int GlobalRedecl3 ; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
extern int GlobalRedecl4 ; // expected-note{{previous declaration is here}}
__declspec ( dllimport ) extern int GlobalRedecl4 ; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}}
2014-03-31 22:56:58 +08:00
// External linkage is required.
__declspec ( dllimport ) static int StaticGlobal ; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}}
__declspec ( dllimport ) Internal InternalTypeGlobal ; // expected-error{{'InternalTypeGlobal' must have external linkage when declared 'dllimport'}}
2014-04-02 14:18:49 +08:00
namespace { __declspec ( dllimport ) int InternalGlobal ; } // expected-error{{'(anonymous namespace)::InternalGlobal' must have external linkage when declared 'dllimport'}}
2014-03-31 22:56:58 +08:00
namespace ns { __declspec ( dllimport ) int ExternalGlobal ; }
__declspec ( dllimport ) auto InternalAutoTypeGlobal = Internal ( ) ; // expected-error{{'InternalAutoTypeGlobal' must have external linkage when declared 'dllimport'}}
// expected-error@-1{{definition of dllimport data}}
2014-02-23 03:47:30 +08:00
// Import in local scope.
2014-03-24 05:24:01 +08:00
__declspec ( dllimport ) float LocalRedecl1 ; // expected-note{{previous definition is here}}
__declspec ( dllimport ) float LocalRedecl2 ; // expected-note{{previous definition is here}}
__declspec ( dllimport ) float LocalRedecl3 ; // expected-note{{previous definition is here}}
2014-02-23 03:47:30 +08:00
void functionScope ( ) {
2014-03-24 05:24:01 +08:00
__declspec ( dllimport ) int LocalRedecl1 ; // expected-error{{redefinition of 'LocalRedecl1' with a different type: 'int' vs 'float'}}
int * __attribute__ ( ( dllimport ) ) LocalRedecl2 ; // expected-error{{redefinition of 'LocalRedecl2' with a different type: 'int *' vs 'float'}}
int LocalRedecl3 __attribute__ ( ( dllimport ) ) ; // expected-error{{redefinition of 'LocalRedecl3' with a different type: 'int' vs 'float'}}
2014-02-27 05:27:13 +08:00
__declspec ( dllimport ) int LocalVarDecl ;
__declspec ( dllimport ) int LocalVarDef = 1 ; // expected-error{{definition of dllimport data}}
2014-02-23 03:47:30 +08:00
__declspec ( dllimport ) extern int ExternLocalVarDecl ;
2014-02-27 05:27:13 +08:00
__declspec ( dllimport ) extern int ExternLocalVarDef = 1 ; // expected-error{{definition of dllimport data}}
2014-03-31 22:56:58 +08:00
__declspec ( dllimport ) static int StaticLocalVar ; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}}
2014-02-23 03:47:30 +08:00
}
2014-05-25 18:34:36 +08:00
//===----------------------------------------------------------------------===//
// Variable templates
//===----------------------------------------------------------------------===//
# if __has_feature(cxx_variable_templates)
// Import declaration.
template < typename T > __declspec ( dllimport ) extern int ExternVarTmplDecl ;
// dllimport implies a declaration.
template < typename T > __declspec ( dllimport ) int VarTmplDecl ;
// Not allowed on definitions.
template < typename T > __declspec ( dllimport ) extern int ExternVarTmplInit = 1 ; // expected-error{{definition of dllimport data}}
template < typename T > __declspec ( dllimport ) int VarTmplInit1 = 1 ; // expected-error{{definition of dllimport data}}
template < typename T > int __declspec ( dllimport ) VarTmplInit2 = 1 ; // expected-error{{definition of dllimport data}}
// Declare, then reject definition.
template < typename T > __declspec ( dllimport ) extern int ExternVarTmplDeclInit ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > int ExternVarTmplDeclInit = 1 ; // expected-warning{{'ExternVarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > __declspec ( dllimport ) int VarTmplDeclInit ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > int VarTmplDeclInit = 1 ; // expected-warning{{'VarTmplDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
// Redeclarations
template < typename T > __declspec ( dllimport ) extern int VarTmplRedecl1 ;
template < typename T > __declspec ( dllimport ) extern int VarTmplRedecl1 ;
template < typename T > __declspec ( dllimport ) int VarTmplRedecl2 ;
template < typename T > __declspec ( dllimport ) int VarTmplRedecl2 ;
template < typename T > __declspec ( dllimport ) extern int VarTmplRedecl3 ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > extern int VarTmplRedecl3 ; // expected-warning{{'VarTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > extern int VarTmplRedecl4 ; // expected-note{{previous declaration is here}}
template < typename T > __declspec ( dllimport ) extern int VarTmplRedecl4 ; // expected-error{{redeclaration of 'VarTmplRedecl4' cannot add 'dllimport' attribute}}
// External linkage is required.
template < typename T > __declspec ( dllimport ) static int StaticVarTmpl ; // expected-error{{'StaticVarTmpl' must have external linkage when declared 'dllimport'}}
template < typename T > __declspec ( dllimport ) Internal InternalTypeVarTmpl ; // expected-error{{'InternalTypeVarTmpl' must have external linkage when declared 'dllimport'}}
namespace { template < typename T > __declspec ( dllimport ) int InternalVarTmpl ; } // expected-error{{'(anonymous namespace)::InternalVarTmpl' must have external linkage when declared 'dllimport'}}
namespace ns { template < typename T > __declspec ( dllimport ) int ExternalVarTmpl ; }
template < typename T > __declspec ( dllimport ) auto InternalAutoTypeVarTmpl = Internal ( ) ; // expected-error{{definition of dllimport data}} // expected-error{{'InternalAutoTypeVarTmpl' must have external linkage when declared 'dllimport'}}
template < typename T > int VarTmpl ;
template < typename T > __declspec ( dllimport ) int ImportedVarTmpl ;
// Import implicit instantiation of an imported variable template.
int useVarTmpl ( ) { return ImportedVarTmpl < ImplicitInst_Imported > ; }
// Import explicit instantiation declaration of an imported variable template.
extern template int ImportedVarTmpl < ExplicitDecl_Imported > ;
// An explicit instantiation definition of an imported variable template cannot
// be imported because the template must be defined which is illegal.
// Import specialization of an imported variable template.
template < > __declspec ( dllimport ) int ImportedVarTmpl < ExplicitSpec_Imported > ;
template < > __declspec ( dllimport ) int ImportedVarTmpl < ExplicitSpec_Def_Imported > = 1 ; // expected-error{{definition of dllimport data}}
// Not importing specialization of an imported variable template without
// explicit dllimport.
template < > int ImportedVarTmpl < ExplicitSpec_NotImported > ;
// Import explicit instantiation declaration of a non-imported variable template.
extern template __declspec ( dllimport ) int VarTmpl < ExplicitDecl_Imported > ;
// Import explicit instantiation definition of a non-imported variable template.
template __declspec ( dllimport ) int VarTmpl < ExplicitInst_Imported > ;
// Import specialization of a non-imported variable template.
template < > __declspec ( dllimport ) int VarTmpl < ExplicitSpec_Imported > ;
template < > __declspec ( dllimport ) int VarTmpl < ExplicitSpec_Def_Imported > = 1 ; // expected-error{{definition of dllimport data}}
# endif // __has_feature(cxx_variable_templates)
2014-02-23 03:47:30 +08:00
//===----------------------------------------------------------------------===//
// Functions
//===----------------------------------------------------------------------===//
// Import function declaration. Check different placements.
__attribute__ ( ( dllimport ) ) void decl1A ( ) ; // Sanity check with __attribute__
__declspec ( dllimport ) void decl1B ( ) ;
void __attribute__ ( ( dllimport ) ) decl2A ( ) ;
void __declspec ( dllimport ) decl2B ( ) ;
// Not allowed on function definitions.
2014-05-16 06:07:49 +08:00
__declspec ( dllimport ) void def ( ) { } // expected-error{{dllimport cannot be applied to non-inline function definition}}
2014-02-23 03:47:30 +08:00
// extern "C"
2014-05-24 03:07:09 +08:00
extern " C " __declspec ( dllimport ) void externC ( ) ;
2014-02-23 03:47:30 +08:00
// Import inline function.
2014-05-16 06:07:49 +08:00
__declspec ( dllimport ) inline void inlineFunc1 ( ) { }
inline void __attribute__ ( ( dllimport ) ) inlineFunc2 ( ) { }
2014-02-23 03:47:30 +08:00
2014-05-24 03:07:49 +08:00
__declspec ( dllimport ) inline void inlineDecl ( ) ;
void inlineDecl ( ) { }
__declspec ( dllimport ) void inlineDef ( ) ;
inline void inlineDef ( ) { }
2014-02-23 03:47:30 +08:00
// Redeclarations
__declspec ( dllimport ) void redecl1 ( ) ;
__declspec ( dllimport ) void redecl1 ( ) ;
2014-03-31 22:56:15 +08:00
// NB: MSVC issues a warning and makes redecl2/redecl3 dllexport. We follow GCC
// and drop the dllimport with a warning.
__declspec ( dllimport ) void redecl2 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
void redecl2 ( ) ; // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
__declspec ( dllimport ) void redecl3 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
2014-02-23 03:47:30 +08:00
void redecl3 ( ) { } // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
2014-03-31 22:56:15 +08:00
void redecl4 ( ) ; // expected-note{{previous declaration is here}}
__declspec ( dllimport ) void redecl4 ( ) ; // expected-error{{redeclaration of 'redecl4' cannot add 'dllimport' attribute}}
2014-05-24 03:07:49 +08:00
void redecl5 ( ) ; // expected-note{{previous declaration is here}}
__declspec ( dllimport ) inline void redecl5 ( ) { } // expected-error{{redeclaration of 'redecl5' cannot add 'dllimport' attribute}}
2014-03-31 22:56:15 +08:00
// Friend functions
struct FuncFriend {
friend __declspec ( dllimport ) void friend1 ( ) ;
friend __declspec ( dllimport ) void friend2 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
friend __declspec ( dllimport ) void friend3 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
friend void friend4 ( ) ; // expected-note{{previous declaration is here}}
2014-05-24 03:07:49 +08:00
friend void friend5 ( ) ; // expected-note{{previous declaration is here}}
2014-03-31 22:56:15 +08:00
} ;
__declspec ( dllimport ) void friend1 ( ) ;
void friend2 ( ) ; // expected-warning{{'friend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
void friend3 ( ) { } // expected-warning{{'friend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
__declspec ( dllimport ) void friend4 ( ) ; // expected-error{{redeclaration of 'friend4' cannot add 'dllimport' attribute}}
2014-05-24 03:07:49 +08:00
__declspec ( dllimport ) inline void friend5 ( ) { } // expected-error{{redeclaration of 'friend5' cannot add 'dllimport' attribute}}
2014-03-31 22:56:15 +08:00
// Implicit declarations can be redeclared with dllimport.
__declspec ( dllimport ) void * operator new ( __SIZE_TYPE__ n ) ;
2014-03-31 22:56:58 +08:00
// External linkage is required.
__declspec ( dllimport ) static int staticFunc ( ) ; // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}}
__declspec ( dllimport ) Internal internalRetFunc ( ) ; // expected-error{{'internalRetFunc' must have external linkage when declared 'dllimport'}}
2014-04-02 14:18:49 +08:00
namespace { __declspec ( dllimport ) void internalFunc ( ) ; } // expected-error{{'(anonymous namespace)::internalFunc' must have external linkage when declared 'dllimport'}}
2014-03-31 22:56:58 +08:00
namespace ns { __declspec ( dllimport ) void externalFunc ( ) ; }
2014-05-30 00:51:19 +08:00
// Import deleted functions.
// FIXME: Deleted functions are definitions so a missing inline is diagnosed
// here which is irrelevant. But because the delete keyword is parsed later
// there is currently no straight-forward way to avoid this diagnostic.
__declspec ( dllimport ) void deletedFunc ( ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}} expected-error{{dllimport cannot be applied to non-inline function definition}}
__declspec ( dllimport ) inline void deletedInlineFunc ( ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
2014-02-23 03:47:30 +08:00
//===----------------------------------------------------------------------===//
// Function templates
//===----------------------------------------------------------------------===//
// Import function template declaration. Check different placements.
template < typename T > __declspec ( dllimport ) void funcTmplDecl1 ( ) ;
template < typename T > void __declspec ( dllimport ) funcTmplDecl2 ( ) ;
2014-05-24 03:07:49 +08:00
// Import function template definition.
template < typename T > __declspec ( dllimport ) void funcTmplDef ( ) { } // expected-error{{dllimport cannot be applied to non-inline function definition}}
// Import inline function template.
template < typename T > __declspec ( dllimport ) inline void inlineFuncTmpl1 ( ) { }
template < typename T > inline void __attribute__ ( ( dllimport ) ) inlineFuncTmpl2 ( ) { }
template < typename T > __declspec ( dllimport ) inline void inlineFuncTmplDecl ( ) ;
template < typename T > void inlineFuncTmplDecl ( ) { }
template < typename T > __declspec ( dllimport ) void inlineFuncTmplDef ( ) ;
template < typename T > inline void inlineFuncTmplDef ( ) { }
2014-02-23 03:47:30 +08:00
// Redeclarations
template < typename T > __declspec ( dllimport ) void funcTmplRedecl1 ( ) ;
template < typename T > __declspec ( dllimport ) void funcTmplRedecl1 ( ) ;
2014-03-31 22:56:15 +08:00
template < typename T > __declspec ( dllimport ) void funcTmplRedecl2 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > void funcTmplRedecl2 ( ) ; // expected-warning{{'funcTmplRedecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
2014-02-23 03:47:30 +08:00
2014-03-31 22:56:15 +08:00
template < typename T > __declspec ( dllimport ) void funcTmplRedecl3 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
2014-02-23 03:47:30 +08:00
template < typename T > void funcTmplRedecl3 ( ) { } // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
2014-03-31 22:56:15 +08:00
template < typename T > void funcTmplRedecl4 ( ) ; // expected-note{{previous declaration is here}}
template < typename T > __declspec ( dllimport ) void funcTmplRedecl4 ( ) ; // expected-error{{redeclaration of 'funcTmplRedecl4' cannot add 'dllimport' attribute}}
2014-05-24 03:07:49 +08:00
template < typename T > void funcTmplRedecl5 ( ) ; // expected-note{{previous declaration is here}}
template < typename T > __declspec ( dllimport ) inline void funcTmplRedecl5 ( ) { } // expected-error{{redeclaration of 'funcTmplRedecl5' cannot add 'dllimport' attribute}}
2014-03-31 22:56:15 +08:00
// Function template friends
struct FuncTmplFriend {
template < typename T > friend __declspec ( dllimport ) void funcTmplFriend1 ( ) ;
template < typename T > friend __declspec ( dllimport ) void funcTmplFriend2 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > friend __declspec ( dllimport ) void funcTmplFriend3 ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > friend void funcTmplFriend4 ( ) ; // expected-note{{previous declaration is here}}
2014-05-24 03:07:49 +08:00
template < typename T > friend __declspec ( dllimport ) inline void funcTmplFriend5 ( ) ;
2014-03-31 22:56:15 +08:00
} ;
template < typename T > __declspec ( dllimport ) void funcTmplFriend1 ( ) ;
template < typename T > void funcTmplFriend2 ( ) ; // expected-warning{{'funcTmplFriend2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > void funcTmplFriend3 ( ) { } // expected-warning{{'funcTmplFriend3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > __declspec ( dllimport ) void funcTmplFriend4 ( ) ; // expected-error{{redeclaration of 'funcTmplFriend4' cannot add 'dllimport' attribute}}
2014-05-24 03:07:49 +08:00
template < typename T > inline void funcTmplFriend5 ( ) { }
2014-03-31 22:56:15 +08:00
2014-03-31 22:56:58 +08:00
// External linkage is required.
template < typename T > __declspec ( dllimport ) static int staticFuncTmpl ( ) ; // expected-error{{'staticFuncTmpl' must have external linkage when declared 'dllimport'}}
template < typename T > __declspec ( dllimport ) Internal internalRetFuncTmpl ( ) ; // expected-error{{'internalRetFuncTmpl' must have external linkage when declared 'dllimport'}}
2014-04-02 14:18:49 +08:00
namespace { template < typename T > __declspec ( dllimport ) void internalFuncTmpl ( ) ; } // expected-error{{'(anonymous namespace)::internalFuncTmpl' must have external linkage when declared 'dllimport'}}
2014-03-31 22:56:58 +08:00
namespace ns { template < typename T > __declspec ( dllimport ) void externalFuncTmpl ( ) ; }
2014-02-23 03:47:30 +08:00
template < typename T > void funcTmpl ( ) { }
2014-05-24 03:07:49 +08:00
template < typename T > inline void inlineFuncTmpl ( ) { }
template < typename T > __declspec ( dllimport ) void importedFuncTmplDecl ( ) ;
template < typename T > __declspec ( dllimport ) inline void importedFuncTmpl ( ) { }
// Import implicit instantiation of an imported function template.
void useFunTmplDecl ( ) { importedFuncTmplDecl < ImplicitInst_Imported > ( ) ; }
void useFunTmplDef ( ) { importedFuncTmpl < ImplicitInst_Imported > ( ) ; }
// Import explicit instantiation declaration of an imported function template.
extern template void importedFuncTmpl < ExplicitDecl_Imported > ( ) ;
// Import explicit instantiation definition of an imported function template.
// NB: MSVC fails this instantiation without explicit dllimport which is most
// likely a bug because an implicit instantiation is accepted.
template void importedFuncTmpl < ExplicitInst_Imported > ( ) ;
2014-02-23 03:47:30 +08:00
// Import specialization of an imported function template. A definition must be
// declared inline.
template < > __declspec ( dllimport ) void importedFuncTmpl < ExplicitSpec_Imported > ( ) ;
2014-05-16 06:07:49 +08:00
template < > __declspec ( dllimport ) void importedFuncTmpl < ExplicitSpec_Def_Imported > ( ) { } // expected-error{{dllimport cannot be applied to non-inline function definition}}
template < > __declspec ( dllimport ) inline void importedFuncTmpl < ExplicitSpec_InlineDef_Imported > ( ) { }
2014-02-23 03:47:30 +08:00
// Not importing specialization of an imported function template without
// explicit dllimport.
template < > void importedFuncTmpl < ExplicitSpec_NotImported > ( ) { }
// Import explicit instantiation declaration of a non-imported function template.
extern template __declspec ( dllimport ) void funcTmpl < ExplicitDecl_Imported > ( ) ;
2014-05-24 03:07:49 +08:00
extern template __declspec ( dllimport ) void inlineFuncTmpl < ExplicitDecl_Imported > ( ) ;
// Import explicit instantiation definition of a non-imported function template.
template __declspec ( dllimport ) void funcTmpl < ExplicitInst_Imported > ( ) ;
template __declspec ( dllimport ) void inlineFuncTmpl < ExplicitInst_Imported > ( ) ;
2014-02-23 03:47:30 +08:00
// Import specialization of a non-imported function template. A definition must
// be declared inline.
template < > __declspec ( dllimport ) void funcTmpl < ExplicitSpec_Imported > ( ) ;
2014-05-16 06:07:49 +08:00
template < > __declspec ( dllimport ) void funcTmpl < ExplicitSpec_Def_Imported > ( ) { } // expected-error{{dllimport cannot be applied to non-inline function definition}}
template < > __declspec ( dllimport ) inline void funcTmpl < ExplicitSpec_InlineDef_Imported > ( ) { }
2014-05-25 18:35:03 +08:00
//===----------------------------------------------------------------------===//
// Class members
//===----------------------------------------------------------------------===//
// Import individual members of a class.
struct ImportMembers {
struct Nested {
__declspec ( dllimport ) void normalDecl ( ) ;
__declspec ( dllimport ) void normalDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
} ;
__declspec ( dllimport ) void normalDecl ( ) ;
__declspec ( dllimport ) void normalDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
__declspec ( dllimport ) void normalInclass ( ) { }
__declspec ( dllimport ) void normalInlineDef ( ) ;
__declspec ( dllimport ) inline void normalInlineDecl ( ) ;
__declspec ( dllimport ) virtual void virtualDecl ( ) ;
__declspec ( dllimport ) virtual void virtualDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
__declspec ( dllimport ) virtual void virtualInclass ( ) { }
__declspec ( dllimport ) virtual void virtualInlineDef ( ) ;
__declspec ( dllimport ) virtual inline void virtualInlineDecl ( ) ;
__declspec ( dllimport ) static void staticDecl ( ) ;
__declspec ( dllimport ) static void staticDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
__declspec ( dllimport ) static void staticInclass ( ) { }
__declspec ( dllimport ) static void staticInlineDef ( ) ;
__declspec ( dllimport ) static inline void staticInlineDecl ( ) ;
protected :
__declspec ( dllimport ) void protectedDecl ( ) ;
private :
__declspec ( dllimport ) void privateDecl ( ) ;
2014-05-30 00:50:20 +08:00
public :
__declspec ( dllimport ) int Field ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
__declspec ( dllimport ) static int StaticField ;
__declspec ( dllimport ) static int StaticFieldDef ; // expected-note{{attribute is here}}
__declspec ( dllimport ) static const int StaticConstField ;
__declspec ( dllimport ) static const int StaticConstFieldDef ; // expected-note{{attribute is here}}
__declspec ( dllimport ) static const int StaticConstFieldEqualInit = 1 ;
__declspec ( dllimport ) static const int StaticConstFieldBraceInit { 1 } ;
__declspec ( dllimport ) constexpr static int ConstexprField = 1 ;
__declspec ( dllimport ) constexpr static int ConstexprFieldDef = 1 ; // expected-note{{attribute is here}}
2014-05-25 18:35:03 +08:00
} ;
void ImportMembers : : Nested : : normalDef ( ) { } // expected-warning{{'ImportMembers::Nested::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
void ImportMembers : : normalDef ( ) { } // expected-warning{{'ImportMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
inline void ImportMembers : : normalInlineDef ( ) { }
void ImportMembers : : normalInlineDecl ( ) { }
void ImportMembers : : virtualDef ( ) { } // expected-warning{{'ImportMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
inline void ImportMembers : : virtualInlineDef ( ) { }
void ImportMembers : : virtualInlineDecl ( ) { }
void ImportMembers : : staticDef ( ) { } // expected-warning{{'ImportMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
inline void ImportMembers : : staticInlineDef ( ) { }
void ImportMembers : : staticInlineDecl ( ) { }
2014-05-30 00:50:20 +08:00
int ImportMembers : : StaticFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
const int ImportMembers : : StaticConstFieldDef = 1 ; // expected-error{{definition of dllimport static field not allowed}}
constexpr int ImportMembers : : ConstexprFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
2014-05-25 18:35:03 +08:00
// Import on member definitions.
struct ImportMemberDefs {
__declspec ( dllimport ) void normalDef ( ) ;
__declspec ( dllimport ) void normalInlineDef ( ) ;
__declspec ( dllimport ) inline void normalInlineDecl ( ) ;
__declspec ( dllimport ) virtual void virtualDef ( ) ;
__declspec ( dllimport ) virtual void virtualInlineDef ( ) ;
__declspec ( dllimport ) virtual inline void virtualInlineDecl ( ) ;
__declspec ( dllimport ) static void staticDef ( ) ;
__declspec ( dllimport ) static void staticInlineDef ( ) ;
__declspec ( dllimport ) static inline void staticInlineDecl ( ) ;
2014-05-30 00:50:20 +08:00
__declspec ( dllimport ) static int StaticField ;
__declspec ( dllimport ) static const int StaticConstField ;
__declspec ( dllimport ) constexpr static int ConstexprField = 1 ;
2014-05-25 18:35:03 +08:00
} ;
__declspec ( dllimport ) void ImportMemberDefs : : normalDef ( ) { } // expected-error{{dllimport cannot be applied to non-inline function definition}}
__declspec ( dllimport ) inline void ImportMemberDefs : : normalInlineDef ( ) { }
__declspec ( dllimport ) void ImportMemberDefs : : normalInlineDecl ( ) { }
__declspec ( dllimport ) void ImportMemberDefs : : virtualDef ( ) { } // expected-error{{dllimport cannot be applied to non-inline function definition}}
__declspec ( dllimport ) inline void ImportMemberDefs : : virtualInlineDef ( ) { }
__declspec ( dllimport ) void ImportMemberDefs : : virtualInlineDecl ( ) { }
__declspec ( dllimport ) void ImportMemberDefs : : staticDef ( ) { } // expected-error{{dllimport cannot be applied to non-inline function definition}}
__declspec ( dllimport ) inline void ImportMemberDefs : : staticInlineDef ( ) { }
__declspec ( dllimport ) void ImportMemberDefs : : staticInlineDecl ( ) { }
2014-05-30 00:50:20 +08:00
__declspec ( dllimport ) int ImportMemberDefs : : StaticField ; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
__declspec ( dllimport ) const int ImportMemberDefs : : StaticConstField = 1 ; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
__declspec ( dllimport ) constexpr int ImportMemberDefs : : ConstexprField ; // expected-error{{definition of dllimport static field not allowed}} expected-note{{attribute is here}}
2014-05-25 18:35:03 +08:00
// Import special member functions.
struct ImportSpecials {
__declspec ( dllimport ) ImportSpecials ( ) ;
__declspec ( dllimport ) ~ ImportSpecials ( ) ;
__declspec ( dllimport ) ImportSpecials ( const ImportSpecials & ) ;
__declspec ( dllimport ) ImportSpecials & operator = ( const ImportSpecials & ) ;
__declspec ( dllimport ) ImportSpecials ( ImportSpecials & & ) ;
__declspec ( dllimport ) ImportSpecials & operator = ( ImportSpecials & & ) ;
} ;
2014-05-30 00:51:19 +08:00
// Import deleted member functions.
struct ImportDeleted {
__declspec ( dllimport ) ImportDeleted ( ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
__declspec ( dllimport ) ~ ImportDeleted ( ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
__declspec ( dllimport ) ImportDeleted ( const ImportDeleted & ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
__declspec ( dllimport ) ImportDeleted & operator = ( const ImportDeleted & ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
__declspec ( dllimport ) ImportDeleted ( ImportDeleted & & ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
__declspec ( dllimport ) ImportDeleted & operator = ( ImportDeleted & & ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
__declspec ( dllimport ) void deleted ( ) = delete ; // expected-error{{attribute 'dllimport' cannot be applied to a deleted function}}
} ;
2014-05-25 18:35:03 +08:00
// Import allocation functions.
struct ImportAlloc {
__declspec ( dllimport ) void * operator new ( __SIZE_TYPE__ ) ;
__declspec ( dllimport ) void * operator new [ ] ( __SIZE_TYPE__ ) ;
__declspec ( dllimport ) void operator delete ( void * ) ;
__declspec ( dllimport ) void operator delete [ ] ( void * ) ;
} ;
// Import defaulted member functions.
struct ImportDefaulted {
__declspec ( dllimport ) ImportDefaulted ( ) = default ;
__declspec ( dllimport ) ~ ImportDefaulted ( ) = default ;
__declspec ( dllimport ) ImportDefaulted ( const ImportDefaulted & ) = default ;
__declspec ( dllimport ) ImportDefaulted & operator = ( const ImportDefaulted & ) = default ;
__declspec ( dllimport ) ImportDefaulted ( ImportDefaulted & & ) = default ;
__declspec ( dllimport ) ImportDefaulted & operator = ( ImportDefaulted & & ) = default ;
} ;
// Import defaulted member function definitions.
struct ImportDefaultedDefs {
__declspec ( dllimport ) ImportDefaultedDefs ( ) ;
__declspec ( dllimport ) ~ ImportDefaultedDefs ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
__declspec ( dllimport ) inline ImportDefaultedDefs ( const ImportDefaultedDefs & ) ;
__declspec ( dllimport ) ImportDefaultedDefs & operator = ( const ImportDefaultedDefs & ) ;
__declspec ( dllimport ) ImportDefaultedDefs ( ImportDefaultedDefs & & ) ;
__declspec ( dllimport ) ImportDefaultedDefs & operator = ( ImportDefaultedDefs & & ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
} ;
// Not allowed on definitions.
__declspec ( dllimport ) ImportDefaultedDefs : : ImportDefaultedDefs ( ) = default ; // expected-error{{dllimport cannot be applied to non-inline function definition}}
// dllimport cannot be dropped.
ImportDefaultedDefs : : ~ ImportDefaultedDefs ( ) = default ; // expected-warning{{'ImportDefaultedDefs::~ImportDefaultedDefs' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
// Import inline declaration and definition.
__declspec ( dllimport ) ImportDefaultedDefs : : ImportDefaultedDefs ( const ImportDefaultedDefs & ) = default ;
inline ImportDefaultedDefs & ImportDefaultedDefs : : operator = ( const ImportDefaultedDefs & ) = default ;
__declspec ( dllimport ) ImportDefaultedDefs : : ImportDefaultedDefs ( ImportDefaultedDefs & & ) = default ; // expected-error{{dllimport cannot be applied to non-inline function definition}}
ImportDefaultedDefs & ImportDefaultedDefs : : operator = ( ImportDefaultedDefs & & ) = default ; // expected-warning{{'ImportDefaultedDefs::operator=' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
// Redeclarations cannot add dllimport.
struct MemberRedecl {
void normalDef ( ) ; // expected-note{{previous declaration is here}}
void normalInlineDef ( ) ; // expected-note{{previous declaration is here}}
inline void normalInlineDecl ( ) ; // expected-note{{previous declaration is here}}
virtual void virtualDef ( ) ; // expected-note{{previous declaration is here}}
virtual void virtualInlineDef ( ) ; // expected-note{{previous declaration is here}}
virtual inline void virtualInlineDecl ( ) ; // expected-note{{previous declaration is here}}
static void staticDef ( ) ; // expected-note{{previous declaration is here}}
static void staticInlineDef ( ) ; // expected-note{{previous declaration is here}}
static inline void staticInlineDecl ( ) ; // expected-note{{previous declaration is here}}
2014-05-30 00:50:20 +08:00
static int StaticField ; // expected-note{{previous declaration is here}}
static const int StaticConstField ; // expected-note{{previous declaration is here}}
constexpr static int ConstexprField = 1 ; // expected-note{{previous declaration is here}}
2014-05-25 18:35:03 +08:00
} ;
__declspec ( dllimport ) void MemberRedecl : : normalDef ( ) { } // expected-error{{redeclaration of 'MemberRedecl::normalDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
__declspec ( dllimport ) inline void MemberRedecl : : normalInlineDef ( ) { } // expected-error{{redeclaration of 'MemberRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
__declspec ( dllimport ) void MemberRedecl : : normalInlineDecl ( ) { } // expected-error{{redeclaration of 'MemberRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
__declspec ( dllimport ) void MemberRedecl : : virtualDef ( ) { } // expected-error{{redeclaration of 'MemberRedecl::virtualDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
__declspec ( dllimport ) inline void MemberRedecl : : virtualInlineDef ( ) { } // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDef' cannot add 'dllimport' attribute}}
__declspec ( dllimport ) void MemberRedecl : : virtualInlineDecl ( ) { } // expected-error{{redeclaration of 'MemberRedecl::virtualInlineDecl' cannot add 'dllimport' attribute}}
__declspec ( dllimport ) void MemberRedecl : : staticDef ( ) { } // expected-error{{redeclaration of 'MemberRedecl::staticDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
__declspec ( dllimport ) inline void MemberRedecl : : staticInlineDef ( ) { } // expected-error{{redeclaration of 'MemberRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
__declspec ( dllimport ) void MemberRedecl : : staticInlineDecl ( ) { } // expected-error{{redeclaration of 'MemberRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
2014-05-30 00:50:20 +08:00
__declspec ( dllimport ) int MemberRedecl : : StaticField = 1 ; // expected-error{{redeclaration of 'MemberRedecl::StaticField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
__declspec ( dllimport ) const int MemberRedecl : : StaticConstField = 1 ; // expected-error{{redeclaration of 'MemberRedecl::StaticConstField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
__declspec ( dllimport ) constexpr int MemberRedecl : : ConstexprField ; // expected-error{{redeclaration of 'MemberRedecl::ConstexprField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
2014-05-25 18:35:03 +08:00
//===----------------------------------------------------------------------===//
// Class member templates
//===----------------------------------------------------------------------===//
struct ImportMemberTmpl {
template < typename T > __declspec ( dllimport ) void normalDecl ( ) ;
template < typename T > __declspec ( dllimport ) void normalDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > __declspec ( dllimport ) void normalInclass ( ) { }
template < typename T > __declspec ( dllimport ) void normalInlineDef ( ) ;
template < typename T > __declspec ( dllimport ) inline void normalInlineDecl ( ) ;
template < typename T > __declspec ( dllimport ) static void staticDecl ( ) ;
template < typename T > __declspec ( dllimport ) static void staticDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename T > __declspec ( dllimport ) static void staticInclass ( ) { }
template < typename T > __declspec ( dllimport ) static void staticInlineDef ( ) ;
template < typename T > __declspec ( dllimport ) static inline void staticInlineDecl ( ) ;
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename T > __declspec ( dllimport ) static int StaticField ;
template < typename T > __declspec ( dllimport ) static int StaticFieldDef ; // expected-note{{attribute is here}}
template < typename T > __declspec ( dllimport ) static const int StaticConstField ;
template < typename T > __declspec ( dllimport ) static const int StaticConstFieldDef ; // expected-note{{attribute is here}}
template < typename T > __declspec ( dllimport ) static const int StaticConstFieldEqualInit = 1 ;
template < typename T > __declspec ( dllimport ) static const int StaticConstFieldBraceInit { 1 } ;
template < typename T > __declspec ( dllimport ) constexpr static int ConstexprField = 1 ;
template < typename T > __declspec ( dllimport ) constexpr static int ConstexprFieldDef = 1 ; // expected-note{{attribute is here}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
} ;
template < typename T > void ImportMemberTmpl : : normalDef ( ) { } // expected-warning{{'ImportMemberTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > inline void ImportMemberTmpl : : normalInlineDef ( ) { }
template < typename T > void ImportMemberTmpl : : normalInlineDecl ( ) { }
template < typename T > void ImportMemberTmpl : : staticDef ( ) { } // expected-warning{{'ImportMemberTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > inline void ImportMemberTmpl : : staticInlineDef ( ) { }
template < typename T > void ImportMemberTmpl : : staticInlineDecl ( ) { }
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename T > int ImportMemberTmpl : : StaticFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
template < typename T > const int ImportMemberTmpl : : StaticConstFieldDef = 1 ; // expected-error{{definition of dllimport static field not allowed}}
template < typename T > constexpr int ImportMemberTmpl : : ConstexprFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
// Redeclarations cannot add dllimport.
struct MemTmplRedecl {
template < typename T > void normalDef ( ) ; // expected-note{{previous declaration is here}}
template < typename T > void normalInlineDef ( ) ; // expected-note{{previous declaration is here}}
template < typename T > inline void normalInlineDecl ( ) ; // expected-note{{previous declaration is here}}
template < typename T > static void staticDef ( ) ; // expected-note{{previous declaration is here}}
template < typename T > static void staticInlineDef ( ) ; // expected-note{{previous declaration is here}}
template < typename T > static inline void staticInlineDecl ( ) ; // expected-note{{previous declaration is here}}
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename T > static int StaticField ; // expected-note{{previous declaration is here}}
template < typename T > static const int StaticConstField ; // expected-note{{previous declaration is here}}
template < typename T > constexpr static int ConstexprField = 1 ; // expected-note{{previous declaration is here}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
} ;
template < typename T > __declspec ( dllimport ) void MemTmplRedecl : : normalDef ( ) { } // expected-error{{redeclaration of 'MemTmplRedecl::normalDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
template < typename T > __declspec ( dllimport ) inline void MemTmplRedecl : : normalInlineDef ( ) { } // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDef' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void MemTmplRedecl : : normalInlineDecl ( ) { } // expected-error{{redeclaration of 'MemTmplRedecl::normalInlineDecl' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void MemTmplRedecl : : staticDef ( ) { } // expected-error{{redeclaration of 'MemTmplRedecl::staticDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
template < typename T > __declspec ( dllimport ) inline void MemTmplRedecl : : staticInlineDef ( ) { } // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDef' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void MemTmplRedecl : : staticInlineDecl ( ) { } // expected-error{{redeclaration of 'MemTmplRedecl::staticInlineDecl' cannot add 'dllimport' attribute}}
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename T > __declspec ( dllimport ) int MemTmplRedecl : : StaticField = 1 ; // expected-error{{redeclaration of 'MemTmplRedecl::StaticField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
template < typename T > __declspec ( dllimport ) const int MemTmplRedecl : : StaticConstField = 1 ; // expected-error{{redeclaration of 'MemTmplRedecl::StaticConstField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
template < typename T > __declspec ( dllimport ) constexpr int MemTmplRedecl : : ConstexprField ; // expected-error{{redeclaration of 'MemTmplRedecl::ConstexprField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
struct MemFunTmpl {
template < typename T > void normalDef ( ) { }
template < typename T > __declspec ( dllimport ) void importedNormal ( ) { }
template < typename T > static void staticDef ( ) { }
template < typename T > __declspec ( dllimport ) static void importedStatic ( ) { }
} ;
// Import implicit instantiation of an imported member function template.
void useMemFunTmpl ( ) {
MemFunTmpl ( ) . importedNormal < ImplicitInst_Imported > ( ) ;
MemFunTmpl ( ) . importedStatic < ImplicitInst_Imported > ( ) ;
}
// Import explicit instantiation declaration of an imported member function
// template.
extern template void MemFunTmpl : : importedNormal < ExplicitDecl_Imported > ( ) ;
extern template void MemFunTmpl : : importedStatic < ExplicitDecl_Imported > ( ) ;
// Import explicit instantiation definition of an imported member function
// template.
// NB: MSVC fails this instantiation without explicit dllimport.
template void MemFunTmpl : : importedNormal < ExplicitInst_Imported > ( ) ;
template void MemFunTmpl : : importedStatic < ExplicitInst_Imported > ( ) ;
// Import specialization of an imported member function template.
template < > __declspec ( dllimport ) void MemFunTmpl : : importedNormal < ExplicitSpec_Imported > ( ) ;
template < > __declspec ( dllimport ) void MemFunTmpl : : importedNormal < ExplicitSpec_Def_Imported > ( ) { } // error on mingw
template < > __declspec ( dllimport ) inline void MemFunTmpl : : importedNormal < ExplicitSpec_InlineDef_Imported > ( ) { }
# ifndef MSABI
// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
# endif
template < > __declspec ( dllimport ) void MemFunTmpl : : importedStatic < ExplicitSpec_Imported > ( ) ;
template < > __declspec ( dllimport ) void MemFunTmpl : : importedStatic < ExplicitSpec_Def_Imported > ( ) { } // error on mingw
template < > __declspec ( dllimport ) inline void MemFunTmpl : : importedStatic < ExplicitSpec_InlineDef_Imported > ( ) { }
# ifndef MSABI
// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
# endif
// Not importing specialization of an imported member function template without
// explicit dllimport.
template < > void MemFunTmpl : : importedNormal < ExplicitSpec_NotImported > ( ) { }
template < > void MemFunTmpl : : importedStatic < ExplicitSpec_NotImported > ( ) { }
// Import explicit instantiation declaration of a non-imported member function
// template.
extern template __declspec ( dllimport ) void MemFunTmpl : : normalDef < ExplicitDecl_Imported > ( ) ;
extern template __declspec ( dllimport ) void MemFunTmpl : : staticDef < ExplicitDecl_Imported > ( ) ;
// Import explicit instantiation definition of a non-imported member function
// template.
template __declspec ( dllimport ) void MemFunTmpl : : normalDef < ExplicitInst_Imported > ( ) ;
template __declspec ( dllimport ) void MemFunTmpl : : staticDef < ExplicitInst_Imported > ( ) ;
// Import specialization of a non-imported member function template.
template < > __declspec ( dllimport ) void MemFunTmpl : : normalDef < ExplicitSpec_Imported > ( ) ;
template < > __declspec ( dllimport ) void MemFunTmpl : : normalDef < ExplicitSpec_Def_Imported > ( ) { } // error on mingw
template < > __declspec ( dllimport ) inline void MemFunTmpl : : normalDef < ExplicitSpec_InlineDef_Imported > ( ) { }
# ifndef MSABI
// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
# endif
template < > __declspec ( dllimport ) void MemFunTmpl : : staticDef < ExplicitSpec_Imported > ( ) ;
template < > __declspec ( dllimport ) void MemFunTmpl : : staticDef < ExplicitSpec_Def_Imported > ( ) { } // error on mingw
template < > __declspec ( dllimport ) inline void MemFunTmpl : : staticDef < ExplicitSpec_InlineDef_Imported > ( ) { }
# ifndef MSABI
// expected-error@-3{{dllimport cannot be applied to non-inline function definition}}
# endif
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
struct MemVarTmpl {
template < typename T > static const int StaticVar = 1 ;
template < typename T > __declspec ( dllimport ) static const int ImportedStaticVar = 1 ;
} ;
// Import implicit instantiation of an imported member variable template.
int useMemVarTmpl ( ) { return MemVarTmpl : : ImportedStaticVar < ImplicitInst_Imported > ; }
// Import explicit instantiation declaration of an imported member variable
// template.
extern template const int MemVarTmpl : : ImportedStaticVar < ExplicitDecl_Imported > ;
// An explicit instantiation definition of an imported member variable template
// cannot be imported because the template must be defined which is illegal. The
// in-class initializer does not count.
// Import specialization of an imported member variable template.
template < > __declspec ( dllimport ) const int MemVarTmpl : : ImportedStaticVar < ExplicitSpec_Imported > ;
template < > __declspec ( dllimport ) const int MemVarTmpl : : ImportedStaticVar < ExplicitSpec_Def_Imported > = 1 ;
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
// Not importing specialization of a member variable template without explicit
// dllimport.
template < > const int MemVarTmpl : : ImportedStaticVar < ExplicitSpec_NotImported > ;
// Import explicit instantiation declaration of a non-imported member variable
// template.
extern template __declspec ( dllimport ) const int MemVarTmpl : : StaticVar < ExplicitDecl_Imported > ;
// An explicit instantiation definition of a non-imported member variable template
// cannot be imported because the template must be defined which is illegal. The
// in-class initializer does not count.
// Import specialization of a non-imported member variable template.
template < > __declspec ( dllimport ) const int MemVarTmpl : : StaticVar < ExplicitSpec_Imported > ;
template < > __declspec ( dllimport ) const int MemVarTmpl : : StaticVar < ExplicitSpec_Def_Imported > = 1 ;
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
//===----------------------------------------------------------------------===//
// Class template members
//===----------------------------------------------------------------------===//
// Import individual members of a class template.
template < typename T >
struct ImportClassTmplMembers {
__declspec ( dllimport ) void normalDecl ( ) ;
__declspec ( dllimport ) void normalDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
__declspec ( dllimport ) void normalInclass ( ) { }
__declspec ( dllimport ) void normalInlineDef ( ) ;
__declspec ( dllimport ) inline void normalInlineDecl ( ) ;
__declspec ( dllimport ) virtual void virtualDecl ( ) ;
__declspec ( dllimport ) virtual void virtualDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
__declspec ( dllimport ) virtual void virtualInclass ( ) { }
__declspec ( dllimport ) virtual void virtualInlineDef ( ) ;
__declspec ( dllimport ) virtual inline void virtualInlineDecl ( ) ;
__declspec ( dllimport ) static void staticDecl ( ) ;
__declspec ( dllimport ) static void staticDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
__declspec ( dllimport ) static void staticInclass ( ) { }
__declspec ( dllimport ) static void staticInlineDef ( ) ;
__declspec ( dllimport ) static inline void staticInlineDecl ( ) ;
protected :
__declspec ( dllimport ) void protectedDecl ( ) ;
private :
__declspec ( dllimport ) void privateDecl ( ) ;
2014-05-30 00:50:20 +08:00
public :
__declspec ( dllimport ) int Field ; // expected-warning{{'dllimport' attribute only applies to variables and functions}}
__declspec ( dllimport ) static int StaticField ;
__declspec ( dllimport ) static int StaticFieldDef ; // expected-note{{attribute is here}}
__declspec ( dllimport ) static const int StaticConstField ;
__declspec ( dllimport ) static const int StaticConstFieldDef ; // expected-note{{attribute is here}}
__declspec ( dllimport ) static const int StaticConstFieldEqualInit = 1 ;
__declspec ( dllimport ) static const int StaticConstFieldBraceInit { 1 } ;
__declspec ( dllimport ) constexpr static int ConstexprField = 1 ;
__declspec ( dllimport ) constexpr static int ConstexprFieldDef = 1 ; // expected-note{{attribute is here}}
2014-05-25 18:35:03 +08:00
} ;
// NB: MSVC is inconsistent here and disallows *InlineDef on class templates,
// but allows it on classes. We allow both.
template < typename T > void ImportClassTmplMembers < T > : : normalDef ( ) { } // expected-warning{{'ImportClassTmplMembers::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > inline void ImportClassTmplMembers < T > : : normalInlineDef ( ) { }
template < typename T > void ImportClassTmplMembers < T > : : normalInlineDecl ( ) { }
template < typename T > void ImportClassTmplMembers < T > : : virtualDef ( ) { } // expected-warning{{'ImportClassTmplMembers::virtualDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > inline void ImportClassTmplMembers < T > : : virtualInlineDef ( ) { }
template < typename T > void ImportClassTmplMembers < T > : : virtualInlineDecl ( ) { }
template < typename T > void ImportClassTmplMembers < T > : : staticDef ( ) { } // expected-warning{{'ImportClassTmplMembers::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > inline void ImportClassTmplMembers < T > : : staticInlineDef ( ) { }
template < typename T > void ImportClassTmplMembers < T > : : staticInlineDecl ( ) { }
2014-05-30 00:50:20 +08:00
template < typename T > int ImportClassTmplMembers < T > : : StaticFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
template < typename T > const int ImportClassTmplMembers < T > : : StaticConstFieldDef = 1 ; // expected-error{{definition of dllimport static field not allowed}}
template < typename T > constexpr int ImportClassTmplMembers < T > : : ConstexprFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
2014-05-25 18:35:03 +08:00
// Redeclarations cannot add dllimport.
template < typename T >
struct CTMR /*ClassTmplMemberRedecl*/ {
void normalDef ( ) ; // expected-note{{previous declaration is here}}
void normalInlineDef ( ) ; // expected-note{{previous declaration is here}}
inline void normalInlineDecl ( ) ; // expected-note{{previous declaration is here}}
virtual void virtualDef ( ) ; // expected-note{{previous declaration is here}}
virtual void virtualInlineDef ( ) ; // expected-note{{previous declaration is here}}
virtual inline void virtualInlineDecl ( ) ; // expected-note{{previous declaration is here}}
static void staticDef ( ) ; // expected-note{{previous declaration is here}}
static void staticInlineDef ( ) ; // expected-note{{previous declaration is here}}
static inline void staticInlineDecl ( ) ; // expected-note{{previous declaration is here}}
2014-05-30 00:50:20 +08:00
static int StaticField ; // expected-note{{previous declaration is here}}
static const int StaticConstField ; // expected-note{{previous declaration is here}}
constexpr static int ConstexprField = 1 ; // expected-note{{previous declaration is here}}
2014-05-25 18:35:03 +08:00
} ;
template < typename T > __declspec ( dllimport ) void CTMR < T > : : normalDef ( ) { } // expected-error{{redeclaration of 'CTMR::normalDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
template < typename T > __declspec ( dllimport ) inline void CTMR < T > : : normalInlineDef ( ) { } // expected-error{{redeclaration of 'CTMR::normalInlineDef' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void CTMR < T > : : normalInlineDecl ( ) { } // expected-error{{redeclaration of 'CTMR::normalInlineDecl' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void CTMR < T > : : virtualDef ( ) { } // expected-error{{redeclaration of 'CTMR::virtualDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
template < typename T > __declspec ( dllimport ) inline void CTMR < T > : : virtualInlineDef ( ) { } // expected-error{{redeclaration of 'CTMR::virtualInlineDef' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void CTMR < T > : : virtualInlineDecl ( ) { } // expected-error{{redeclaration of 'CTMR::virtualInlineDecl' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void CTMR < T > : : staticDef ( ) { } // expected-error{{redeclaration of 'CTMR::staticDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
template < typename T > __declspec ( dllimport ) inline void CTMR < T > : : staticInlineDef ( ) { } // expected-error{{redeclaration of 'CTMR::staticInlineDef' cannot add 'dllimport' attribute}}
template < typename T > __declspec ( dllimport ) void CTMR < T > : : staticInlineDecl ( ) { } // expected-error{{redeclaration of 'CTMR::staticInlineDecl' cannot add 'dllimport' attribute}}
2014-05-30 00:50:20 +08:00
template < typename T > __declspec ( dllimport ) int CTMR < T > : : StaticField = 1 ; // expected-error{{redeclaration of 'CTMR::StaticField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
template < typename T > __declspec ( dllimport ) const int CTMR < T > : : StaticConstField = 1 ; // expected-error{{redeclaration of 'CTMR::StaticConstField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
template < typename T > __declspec ( dllimport ) constexpr int CTMR < T > : : ConstexprField ; // expected-error{{redeclaration of 'CTMR::ConstexprField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
2014-05-25 18:35:03 +08:00
//===----------------------------------------------------------------------===//
// Class template member templates
//===----------------------------------------------------------------------===//
template < typename T >
struct ImportClsTmplMemTmpl {
template < typename U > __declspec ( dllimport ) void normalDecl ( ) ;
template < typename U > __declspec ( dllimport ) void normalDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename U > __declspec ( dllimport ) void normalInclass ( ) { }
template < typename U > __declspec ( dllimport ) void normalInlineDef ( ) ;
template < typename U > __declspec ( dllimport ) inline void normalInlineDecl ( ) ;
template < typename U > __declspec ( dllimport ) static void staticDecl ( ) ;
template < typename U > __declspec ( dllimport ) static void staticDef ( ) ; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}}
template < typename U > __declspec ( dllimport ) static void staticInclass ( ) { }
template < typename U > __declspec ( dllimport ) static void staticInlineDef ( ) ;
template < typename U > __declspec ( dllimport ) static inline void staticInlineDecl ( ) ;
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename U > __declspec ( dllimport ) static int StaticField ;
template < typename U > __declspec ( dllimport ) static int StaticFieldDef ; // expected-note{{attribute is here}}
template < typename U > __declspec ( dllimport ) static const int StaticConstField ;
template < typename U > __declspec ( dllimport ) static const int StaticConstFieldDef ; // expected-note{{attribute is here}}
template < typename U > __declspec ( dllimport ) static const int StaticConstFieldEqualInit = 1 ;
template < typename U > __declspec ( dllimport ) static const int StaticConstFieldBraceInit { 1 } ;
template < typename U > __declspec ( dllimport ) constexpr static int ConstexprField = 1 ;
template < typename U > __declspec ( dllimport ) constexpr static int ConstexprFieldDef = 1 ; // expected-note{{attribute is here}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
} ;
template < typename T > template < typename U > void ImportClsTmplMemTmpl < T > : : normalDef ( ) { } // expected-warning{{'ImportClsTmplMemTmpl::normalDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > template < typename U > inline void ImportClsTmplMemTmpl < T > : : normalInlineDef ( ) { }
template < typename T > template < typename U > void ImportClsTmplMemTmpl < T > : : normalInlineDecl ( ) { }
template < typename T > template < typename U > void ImportClsTmplMemTmpl < T > : : staticDef ( ) { } // expected-warning{{'ImportClsTmplMemTmpl::staticDef' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}}
template < typename T > template < typename U > inline void ImportClsTmplMemTmpl < T > : : staticInlineDef ( ) { }
template < typename T > template < typename U > void ImportClsTmplMemTmpl < T > : : staticInlineDecl ( ) { }
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename T > template < typename U > int ImportClsTmplMemTmpl < T > : : StaticFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
template < typename T > template < typename U > const int ImportClsTmplMemTmpl < T > : : StaticConstFieldDef = 1 ; // expected-error{{definition of dllimport static field not allowed}}
template < typename T > template < typename U > constexpr int ImportClsTmplMemTmpl < T > : : ConstexprFieldDef ; // expected-error{{definition of dllimport static field not allowed}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
// Redeclarations cannot add dllimport.
template < typename T >
struct CTMTR /*ClassTmplMemberTmplRedecl*/ {
template < typename U > void normalDef ( ) ; // expected-note{{previous declaration is here}}
template < typename U > void normalInlineDef ( ) ; // expected-note{{previous declaration is here}}
template < typename U > inline void normalInlineDecl ( ) ; // expected-note{{previous declaration is here}}
template < typename U > static void staticDef ( ) ; // expected-note{{previous declaration is here}}
template < typename U > static void staticInlineDef ( ) ; // expected-note{{previous declaration is here}}
template < typename U > static inline void staticInlineDecl ( ) ; // expected-note{{previous declaration is here}}
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename U > static int StaticField ; // expected-note{{previous declaration is here}}
template < typename U > static const int StaticConstField ; // expected-note{{previous declaration is here}}
template < typename U > constexpr static int ConstexprField = 1 ; // expected-note{{previous declaration is here}}
# endif // __has_feature(cxx_variable_templates)
2014-05-25 18:35:03 +08:00
} ;
template < typename T > template < typename U > __declspec ( dllimport ) void CTMTR < T > : : normalDef ( ) { } // expected-error{{redeclaration of 'CTMTR::normalDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
template < typename T > template < typename U > __declspec ( dllimport ) inline void CTMTR < T > : : normalInlineDef ( ) { } // expected-error{{redeclaration of 'CTMTR::normalInlineDef' cannot add 'dllimport' attribute}}
template < typename T > template < typename U > __declspec ( dllimport ) void CTMTR < T > : : normalInlineDecl ( ) { } // expected-error{{redeclaration of 'CTMTR::normalInlineDecl' cannot add 'dllimport' attribute}}
template < typename T > template < typename U > __declspec ( dllimport ) void CTMTR < T > : : staticDef ( ) { } // expected-error{{redeclaration of 'CTMTR::staticDef' cannot add 'dllimport' attribute}}
// expected-error@-1{{dllimport cannot be applied to non-inline function definition}}
template < typename T > template < typename U > __declspec ( dllimport ) inline void CTMTR < T > : : staticInlineDef ( ) { } // expected-error{{redeclaration of 'CTMTR::staticInlineDef' cannot add 'dllimport' attribute}}
template < typename T > template < typename U > __declspec ( dllimport ) void CTMTR < T > : : staticInlineDecl ( ) { } // expected-error{{redeclaration of 'CTMTR::staticInlineDecl' cannot add 'dllimport' attribute}}
2014-05-30 00:50:20 +08:00
# if __has_feature(cxx_variable_templates)
template < typename T > template < typename U > __declspec ( dllimport ) int CTMTR < T > : : StaticField = 1 ; // expected-error{{redeclaration of 'CTMTR::StaticField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
template < typename T > template < typename U > __declspec ( dllimport ) const int CTMTR < T > : : StaticConstField = 1 ; // expected-error{{redeclaration of 'CTMTR::StaticConstField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
template < typename T > template < typename U > __declspec ( dllimport ) constexpr int CTMTR < T > : : ConstexprField ; // expected-error{{redeclaration of 'CTMTR::ConstexprField' cannot add 'dllimport' attribute}}
// expected-error@-1{{definition of dllimport static field not allowed}}
// expected-note@-2{{attribute is here}}
# endif // __has_feature(cxx_variable_templates)