// 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; // dllimport implies a declaration. __declspec(dllimport) int GlobalDecl; // Not allowed on definitions. __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}} // Declare, then reject definition. __declspec(dllimport) extern int ExternGlobalDeclInit; int ExternGlobalDeclInit = 1; // expected-error{{definition of dllimport data}} // Redeclarations __declspec(dllimport) extern int GlobalRedecl1; __declspec(dllimport) extern int GlobalRedecl1; // Import in local scope. void functionScope() { __declspec(dllimport) int LocalVarDecl; __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}} __declspec(dllimport) extern int ExternLocalVarDecl; __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}} } //===----------------------------------------------------------------------===// // 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(); __declspec(dllimport) void redecl3(); void redecl3() {} // expected-warning{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} //===----------------------------------------------------------------------===// // Function templates //===----------------------------------------------------------------------===// // Import function template declaration. Check different placements. template __declspec(dllimport) void funcTmplDecl1(); template void __declspec(dllimport) funcTmplDecl2(); // Redeclarations template __declspec(dllimport) void funcTmplRedecl1(); template __declspec(dllimport) void funcTmplRedecl1(); template __declspec(dllimport) void funcTmplRedecl2(); template void funcTmplRedecl2(); template __declspec(dllimport) void funcTmplRedecl3(); template void funcTmplRedecl3() {} // expected-warning{{'funcTmplRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} template void funcTmpl() {} template __declspec(dllimport) void importedFuncTmpl(); // Import specialization of an imported function template. A definition must be // declared inline. template<> __declspec(dllimport) void importedFuncTmpl(); template<> __declspec(dllimport) void importedFuncTmpl() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}} template<> __declspec(dllimport) inline void importedFuncTmpl() {} // expected-warning{{'dllimport' attribute ignored}} // Not importing specialization of an imported function template without // explicit dllimport. template<> void importedFuncTmpl() {} // Import explicit instantiation declaration of a non-imported function template. extern template __declspec(dllimport) void funcTmpl(); // Import specialization of a non-imported function template. A definition must // be declared inline. template<> __declspec(dllimport) void funcTmpl(); template<> __declspec(dllimport) void funcTmpl() {} // expected-error{{'dllimport' attribute can be applied only to symbol declaration}} template<> __declspec(dllimport) inline void funcTmpl() {} // expected-warning{{'dllimport' attribute ignored}}