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