xref: /aosp_15_r20/external/clang/test/Sema/dllexport.c (revision 67e74705e28f6214e480b399dd47ea732279e315)
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 Li int 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 Li void 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 Li inline 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 Li void 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 Li void 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 Li void 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 Li void __attribute__((dllimport, dllexport))       precedence1A() {} // expected-warning{{'dllimport' attribute ignored}}
precedence1B()149*67e74705SXin Li void __declspec(dllimport) __declspec(dllexport) precedence1B() {} // expected-warning{{'dllimport' attribute ignored}}
150*67e74705SXin Li 
precedence2A()151*67e74705SXin Li void __attribute__((dllexport, dllimport))       precedence2A() {} // expected-warning{{'dllimport' attribute ignored}}
precedence2B()152*67e74705SXin Li void __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 Li void __declspec(dllexport) precedenceRedecl1() {}
156*67e74705SXin Li 
157*67e74705SXin Li void __declspec(dllexport) precedenceRedecl2();
precedenceRedecl2()158*67e74705SXin Li void __declspec(dllimport) precedenceRedecl2() {} // expected-warning{{'dllimport' attribute ignored}}
159