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