1*67e74705SXin Li // RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c99 %s 2*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c11 %s 3*67e74705SXin Li // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c11 %s 4*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 %s 5*67e74705SXin Li 6*67e74705SXin Li // Invalid usage. 7*67e74705SXin Li __declspec(dllexport) typedef int typedef1; // expected-warning{{'dllexport' attribute only applies to variables and functions}} 8*67e74705SXin Li typedef __declspec(dllexport) int typedef2; // expected-warning{{'dllexport' attribute only applies to variables and functions}} 9*67e74705SXin Li typedef int __declspec(dllexport) typedef3; // expected-warning{{'dllexport' attribute only applies to variables and functions}} 10*67e74705SXin Li typedef __declspec(dllexport) void (*FunTy)(); // expected-warning{{'dllexport' attribute only applies to variables and functions}} 11*67e74705SXin Li enum __declspec(dllexport) Enum { EnumVal }; // expected-warning{{'dllexport' attribute only applies to variables and functions}} 12*67e74705SXin Li struct __declspec(dllexport) Record {}; // expected-warning{{'dllexport' attribute only applies to variables and functions}} 13*67e74705SXin Li 14*67e74705SXin Li 15*67e74705SXin Li 16*67e74705SXin Li //===----------------------------------------------------------------------===// 17*67e74705SXin Li // Globals 18*67e74705SXin Li //===----------------------------------------------------------------------===// 19*67e74705SXin Li 20*67e74705SXin Li // Export declaration. 21*67e74705SXin Li __declspec(dllexport) extern int ExternGlobalDecl; 22*67e74705SXin Li 23*67e74705SXin Li // dllexport implies a definition. 24*67e74705SXin Li __declspec(dllexport) int GlobalDef; 25*67e74705SXin Li 26*67e74705SXin Li // Export definition. 27*67e74705SXin Li __declspec(dllexport) int GlobalInit1 = 1; 28*67e74705SXin Li int __declspec(dllexport) GlobalInit2 = 1; 29*67e74705SXin Li 30*67e74705SXin Li // Declare, then export definition. 31*67e74705SXin Li __declspec(dllexport) extern int GlobalDeclInit; 32*67e74705SXin Li int GlobalDeclInit = 1; 33*67e74705SXin Li 34*67e74705SXin Li // Redeclarations 35*67e74705SXin Li __declspec(dllexport) extern int GlobalRedecl1; 36*67e74705SXin Li __declspec(dllexport) int GlobalRedecl1; 37*67e74705SXin Li 38*67e74705SXin Li __declspec(dllexport) extern int GlobalRedecl2; 39*67e74705SXin Li int GlobalRedecl2; 40*67e74705SXin Li 41*67e74705SXin Li extern int GlobalRedecl3; // expected-note{{previous declaration is here}} useGlobalRedecl3()42*67e74705SXin Liint useGlobalRedecl3() { return GlobalRedecl3; } 43*67e74705SXin Li __declspec(dllexport) extern int GlobalRedecl3; // expected-error{{redeclaration of 'GlobalRedecl3' cannot add 'dllexport' attribute}} 44*67e74705SXin Li 45*67e74705SXin Li extern int GlobalRedecl4; // expected-note{{previous declaration is here}} 46*67e74705SXin Li __declspec(dllexport) extern int GlobalRedecl4; // expected-warning{{redeclaration of 'GlobalRedecl4' should not add 'dllexport' attribute}} 47*67e74705SXin Li 48*67e74705SXin Li 49*67e74705SXin Li // External linkage is required. 50*67e74705SXin Li __declspec(dllexport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllexport'}} 51*67e74705SXin Li 52*67e74705SXin Li // Thread local variables are invalid. 53*67e74705SXin Li __declspec(dllexport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllexport'}} 54*67e74705SXin Li 55*67e74705SXin Li // Export in local scope. functionScope()56*67e74705SXin Livoid functionScope() { 57*67e74705SXin Li __declspec(dllexport) int LocalVarDecl; // expected-error{{'LocalVarDecl' must have external linkage when declared 'dllexport'}} 58*67e74705SXin Li __declspec(dllexport) int LocalVarDef = 1; // expected-error{{'LocalVarDef' must have external linkage when declared 'dllexport'}} 59*67e74705SXin Li __declspec(dllexport) extern int ExternLocalVarDecl; 60*67e74705SXin Li __declspec(dllexport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllexport'}} 61*67e74705SXin Li } 62*67e74705SXin Li 63*67e74705SXin Li 64*67e74705SXin Li 65*67e74705SXin Li //===----------------------------------------------------------------------===// 66*67e74705SXin Li // Functions 67*67e74705SXin Li //===----------------------------------------------------------------------===// 68*67e74705SXin Li 69*67e74705SXin Li // Export function declaration. Check different placements. 70*67e74705SXin Li __attribute__((dllexport)) void decl1A(); // Sanity check with __attribute__ 71*67e74705SXin Li __declspec(dllexport) void decl1B(); 72*67e74705SXin Li 73*67e74705SXin Li void __attribute__((dllexport)) decl2A(); 74*67e74705SXin Li void __declspec(dllexport) decl2B(); 75*67e74705SXin Li 76*67e74705SXin Li // Export function definition. def()77*67e74705SXin Li__declspec(dllexport) void def() {} 78*67e74705SXin Li 79*67e74705SXin Li // Export inline function. inlineFunc1()80*67e74705SXin Li__declspec(dllexport) inline void inlineFunc1() {} 81*67e74705SXin Li extern void inlineFunc1(); 82*67e74705SXin Li inlineFunc2()83*67e74705SXin Liinline void __attribute__((dllexport)) inlineFunc2() {} 84*67e74705SXin Li extern void inlineFunc2(); 85*67e74705SXin Li 86*67e74705SXin Li // Redeclarations 87*67e74705SXin Li __declspec(dllexport) void redecl1(); 88*67e74705SXin Li __declspec(dllexport) void redecl1(); 89*67e74705SXin Li 90*67e74705SXin Li __declspec(dllexport) void redecl2(); 91*67e74705SXin Li void redecl2(); 92*67e74705SXin Li 93*67e74705SXin Li __declspec(dllexport) void redecl3(); redecl3()94*67e74705SXin Li void redecl3() {} 95*67e74705SXin Li 96*67e74705SXin Li void redecl4(); // expected-note{{previous declaration is here}} useRedecl4()97*67e74705SXin Livoid useRedecl4() { redecl4(); } 98*67e74705SXin Li __declspec(dllexport) void redecl4(); // expected-error{{redeclaration of 'redecl4' cannot add 'dllexport' attribute}} 99*67e74705SXin Li 100*67e74705SXin Li void redecl5(); // expected-note{{previous declaration is here}} useRedecl5()101*67e74705SXin Livoid useRedecl5() { redecl5(); } redecl5()102*67e74705SXin Li__declspec(dllexport) inline void redecl5() {} // expected-error{{redeclaration of 'redecl5' cannot add 'dllexport' attribute}} 103*67e74705SXin Li 104*67e74705SXin Li // Allow with a warning if the decl hasn't been used yet. 105*67e74705SXin Li void redecl6(); // expected-note{{previous declaration is here}} 106*67e74705SXin Li __declspec(dllexport) void redecl6(); // expected-warning{{redeclaration of 'redecl6' should not add 'dllexport' attribute}} 107*67e74705SXin Li 108*67e74705SXin Li 109*67e74705SXin Li // External linkage is required. 110*67e74705SXin Li __declspec(dllexport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllexport'}} 111*67e74705SXin Li 112*67e74705SXin Li // Static locals don't count as having external linkage. staticLocalFunc()113*67e74705SXin Livoid staticLocalFunc() { 114*67e74705SXin Li __declspec(dllexport) static int staticLocal; // expected-error{{'staticLocal' must have external linkage when declared 'dllexport'}} 115*67e74705SXin Li } 116*67e74705SXin Li 117*67e74705SXin Li 118*67e74705SXin Li 119*67e74705SXin Li //===----------------------------------------------------------------------===// 120*67e74705SXin Li // Precedence 121*67e74705SXin Li //===----------------------------------------------------------------------===// 122*67e74705SXin Li 123*67e74705SXin Li // dllexport takes precedence over dllimport if both are specified. 124*67e74705SXin Li __attribute__((dllimport, dllexport)) extern int PrecedenceExternGlobal1A; // expected-warning{{'dllimport' attribute ignored}} 125*67e74705SXin Li __declspec(dllimport) __declspec(dllexport) extern int PrecedenceExternGlobal1B; // expected-warning{{'dllimport' attribute ignored}} 126*67e74705SXin Li 127*67e74705SXin Li __attribute__((dllexport, dllimport)) extern int PrecedenceExternGlobal2A; // expected-warning{{'dllimport' attribute ignored}} 128*67e74705SXin Li __declspec(dllexport) __declspec(dllimport) extern int PrecedenceExternGlobal2B; // expected-warning{{'dllimport' attribute ignored}} 129*67e74705SXin Li 130*67e74705SXin Li __attribute__((dllimport, dllexport)) int PrecedenceGlobal1A; // expected-warning{{'dllimport' attribute ignored}} 131*67e74705SXin Li __declspec(dllimport) __declspec(dllexport) int PrecedenceGlobal1B; // expected-warning{{'dllimport' attribute ignored}} 132*67e74705SXin Li 133*67e74705SXin Li __attribute__((dllexport, dllimport)) int PrecedenceGlobal2A; // expected-warning{{'dllimport' attribute ignored}} 134*67e74705SXin Li __declspec(dllexport) __declspec(dllimport) int PrecedenceGlobal2B; // expected-warning{{'dllimport' attribute ignored}} 135*67e74705SXin Li 136*67e74705SXin Li __declspec(dllexport) extern int PrecedenceExternGlobalRedecl1; 137*67e74705SXin Li __declspec(dllimport) extern int PrecedenceExternGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}} 138*67e74705SXin Li 139*67e74705SXin Li __declspec(dllimport) extern int PrecedenceExternGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}} 140*67e74705SXin Li __declspec(dllexport) extern int PrecedenceExternGlobalRedecl2; 141*67e74705SXin Li 142*67e74705SXin Li __declspec(dllexport) extern int PrecedenceGlobalRedecl1; 143*67e74705SXin Li __declspec(dllimport) int PrecedenceGlobalRedecl1; // expected-warning{{'dllimport' attribute ignored}} 144*67e74705SXin Li 145*67e74705SXin Li __declspec(dllimport) extern int PrecedenceGlobalRedecl2; // expected-warning{{'dllimport' attribute ignored}} 146*67e74705SXin Li __declspec(dllexport) int PrecedenceGlobalRedecl2; 147*67e74705SXin Li precedence1A()148*67e74705SXin Livoid __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}} precedence1B()149*67e74705SXin Livoid __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}} 150*67e74705SXin Li precedence2A()151*67e74705SXin Livoid __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}} precedence2B()152*67e74705SXin Livoid __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}} 153*67e74705SXin Li 154*67e74705SXin Li void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}} precedenceRedecl1()155*67e74705SXin Livoid __declspec(dllexport) precedenceRedecl1() {} 156*67e74705SXin Li 157*67e74705SXin Li void __declspec(dllexport) precedenceRedecl2(); precedenceRedecl2()158*67e74705SXin Livoid __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}} 159