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 { } ;
// 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-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-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.
__declspec ( dllimport ) void def ( ) { } // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
// extern "C"
extern " C " __declspec ( dllexport ) void externC ( ) ;
// Import inline function.
__declspec ( dllimport ) inline void inlineFunc1 ( ) { } // expected-warning{{'dllimport' attribute ignored}}
inline void __attribute__ ( ( dllimport ) ) inlineFunc2 ( ) { } // expected-warning{{'dllimport' attribute ignored}}
// 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}}
// 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}}
} ;
__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}}
// Implicit declarations can be redeclared with dllimport.
__declspec ( dllimport ) void * operator new ( __SIZE_TYPE__ n ) ;
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 ( ) ;
// 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}}
// 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}}
} ;
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-02-23 03:47:30 +08:00
template < typename T > void funcTmpl ( ) { }
template < typename T > __declspec ( dllimport ) void importedFuncTmpl ( ) ;
// Import specialization of an imported function template. A definition must be
// declared inline.
template < > __declspec ( dllimport ) void importedFuncTmpl < ExplicitSpec_Imported > ( ) ;
template < > __declspec ( dllimport ) void importedFuncTmpl < ExplicitSpec_Def_Imported > ( ) { } // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
template < > __declspec ( dllimport ) inline void importedFuncTmpl < ExplicitSpec_InlineDef_Imported > ( ) { } // expected-warning{{'dllimport' attribute ignored}}
// 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 > ( ) ;
// Import specialization of a non-imported function template. A definition must
// be declared inline.
template < > __declspec ( dllimport ) void funcTmpl < ExplicitSpec_Imported > ( ) ;
template < > __declspec ( dllimport ) void funcTmpl < ExplicitSpec_Def_Imported > ( ) { } // expected-error{{'dllimport' attribute can be applied only to symbol declaration}}
template < > __declspec ( dllimport ) inline void funcTmpl < ExplicitSpec_InlineDef_Imported > ( ) { } // expected-warning{{'dllimport' attribute ignored}}