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}}
useGlobalRedecl3()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.
functionScope()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.
def()77 __declspec(dllexport) void def() {}
78 
79 // Export inline function.
inlineFunc1()80 __declspec(dllexport) inline void inlineFunc1() {}
81 extern void inlineFunc1();
82 
inlineFunc2()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();
redecl3()94                       void redecl3() {}
95 
96                       void redecl4(); // expected-note{{previous declaration is here}}
useRedecl4()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}}
useRedecl5()101 void useRedecl5() { redecl5(); }
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.
staticLocalFunc()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 
precedence1A()148 void __attribute__((dllimport, dllexport))       precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
precedence1B()149 void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
150 
precedence2A()151 void __attribute__((dllexport, dllimport))       precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
precedence2B()152 void __declspec(dllexport) __declspec(dllimport) precedence2B() {} // expected-warning{{'dllimport' attribute ignored}}
153 
154 void __declspec(dllimport) precedenceRedecl1(); // expected-warning{{'dllimport' attribute ignored}}
precedenceRedecl1()155 void __declspec(dllexport) precedenceRedecl1() {}
156 
157 void __declspec(dllexport) precedenceRedecl2();
precedenceRedecl2()158 void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
159