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}}
useGlobalRedecl3()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.
functionScope()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.
def()83 __declspec(dllexport) void def() {}
84
85 // Export inline function.
inlineFunc1()86 __declspec(dllexport) inline void inlineFunc1() {}
87 extern void inlineFunc1();
88
inlineFunc2()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();
redecl3()100 void redecl3() {}
101
102 void redecl4(); // expected-note{{previous declaration is here}}
useRedecl4()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}}
useRedecl5()107 void useRedecl5() { redecl5(); }
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.
staticLocalFunc()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
precedence1A()154 void __attribute__((dllimport, dllexport)) precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
precedence1B()155 void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
156
precedence2A()157 void __attribute__((dllexport, dllimport)) precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
precedence2B()158 void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
159
160 void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
precedenceRedecl1()161 void __declspec(dllexport) precedenceRedecl1() {}
162
163 void __declspec(dllexport) precedenceRedecl2();
precedenceRedecl2()164 void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
165