blob: 497039a8f42c3a45eb7eda835394b52a7d61b4df [file] [log] [blame]
Chris Lattner60e81882009-09-08 18:43:45 +00001// RUN: clang-cc -emit-llvm %s -o - -verify | FileCheck %s
2
3// CHECK: @weakvar = weak global
4// CHECK: @__weakvar_alias = common global
5// CHECK: @correct_linkage = weak global
6
7
8// CHECK: @both = alias void ()* @__both
9// CHECK: @both2 = alias void ()* @__both2
10// CHECK: @both3 = alias weak void ()* @__both3
11// CHECK: @a3 = alias weak void ()* @__a3
12// CHECK: @weakvar_alias = alias weak i32* @__weakvar_alias
13// CHECK: @foo = alias weak void ()* @__foo
14// CHECK: @foo2 = alias weak void ()* @__foo2
15// CHECK: @stutter = alias weak void ()* @__stutter
16// CHECK: @stutter2 = alias weak void ()* @__stutter2
17// CHECK: @declfirst = alias weak void ()* @__declfirst
18// CHECK: @declfirstattr = alias weak void ()* @__declfirstattr
19// CHECK: @mix2 = alias weak void ()* @__mix2
20// CHECK: @a1 = alias weak void ()* @__a1
21// CHECK: @xxx = alias weak void ()* @__xxx
22
23
24
25// CHECK: define weak void @weakdef()
26
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000027
28#pragma weak weakvar
29int weakvar;
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000030
31#pragma weak weakdef
32void weakdef(void) {}
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000033
34#pragma weak param // expected-warning {{weak identifier 'param' never declared}}
35#pragma weak correct_linkage
36void f(int param) {
37 int correct_linkage;
38}
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000039
40#pragma weak weakvar_alias = __weakvar_alias
41int __weakvar_alias;
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000042
43#pragma weak foo = __foo
44void __foo(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +000045// CHECK: define void @__foo()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000046
47
48void __foo2(void) {}
49#pragma weak foo2 = __foo2
Chris Lattner60e81882009-09-08 18:43:45 +000050// CHECK: define void @__foo2()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000051
52
53///// test errors
54
55#pragma weak unused // expected-warning {{weak identifier 'unused' never declared}}
56#pragma weak unused_alias = __unused_alias // expected-warning {{weak identifier '__unused_alias' never declared}}
57
58#pragma weak td // expected-warning {{weak identifier 'td' never declared}}
59typedef int td;
60
61#pragma weak td2 = __td2 // expected-warning {{weak identifier '__td2' never declared}}
62typedef int __td2;
63
64
65///// test weird cases
66
67// test repeats
68
69#pragma weak stutter = __stutter
70#pragma weak stutter = __stutter
71void __stutter(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +000072// CHECK: define void @__stutter()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000073
74void __stutter2(void) {}
75#pragma weak stutter2 = __stutter2
76#pragma weak stutter2 = __stutter2
Chris Lattner60e81882009-09-08 18:43:45 +000077// CHECK: define void @__stutter2()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000078
79
80// test decl/pragma weak order
81
82void __declfirst(void);
83#pragma weak declfirst = __declfirst
84void __declfirst(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +000085// CHECK: define void @__declfirst()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000086
87void __declfirstattr(void) __attribute((noinline));
88#pragma weak declfirstattr = __declfirstattr
89void __declfirstattr(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +000090// CHECK: define void @__declfirstattr()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +000091
92//// test that other attributes are preserved
93
94//// ensure that pragma weak/__attribute((weak)) play nice
95
96void mix(void);
97#pragma weak mix
98__attribute((weak)) void mix(void) { }
Chris Lattner60e81882009-09-08 18:43:45 +000099// CHECK: define weak void @mix()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000100
101// ensure following __attributes are preserved and that only a single
102// alias is generated
103#pragma weak mix2 = __mix2
104void __mix2(void) __attribute((noinline));
105void __mix2(void) __attribute((noinline));
106void __mix2(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +0000107// CHECK: define void @__mix2()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000108
109////////////// test #pragma weak/__attribute combinations
110
111// if the SAME ALIAS is already declared then it overrides #pragma weak
112// resulting in a non-weak alias in this case
113void both(void) __attribute((alias("__both")));
114#pragma weak both = __both
115void __both(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +0000116// CHECK: define void @__both()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000117
118// if the TARGET is previously declared then whichever aliasing method
119// comes first applies and subsequent aliases are discarded.
120// TODO: warn about this
121
122void __both2(void);
123void both2(void) __attribute((alias("__both2"))); // first, wins
124#pragma weak both2 = __both2
125void __both2(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +0000126// CHECK: define void @__both2()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000127
128void __both3(void);
129#pragma weak both3 = __both3 // first, wins
130void both3(void) __attribute((alias("__both3")));
131void __both3(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +0000132// CHECK: define void @__both3()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000133
134///////////// ensure that #pragma weak does not alter existing __attributes()
135
136void __a1(void) __attribute((noinline));
137#pragma weak a1 = __a1
138void __a1(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +0000139// CHECK: define void @__a1()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000140
141// attributes introduced BEFORE a combination of #pragma weak and alias()
142// hold...
143void __a3(void) __attribute((noinline));
144#pragma weak a3 = __a3
145void a3(void) __attribute((alias("__a3")));
146void __a3(void) {}
Chris Lattner60e81882009-09-08 18:43:45 +0000147// CHECK: define void @__a3()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000148
149#pragma weak xxx = __xxx
150__attribute((pure,noinline,const,fastcall)) void __xxx(void) { }
Chris Lattner60e81882009-09-08 18:43:45 +0000151// CHECK: void @__xxx()
Ryan Flynn8f6e88f2009-08-03 23:16:15 +0000152
153/// TODO: stuff that still doesn't work
154
155// due to the fact that disparate TopLevelDecls cannot affect each other
156// (due to clang's Parser and ASTConsumer behavior, and quite reasonable)
157// #pragma weak must appear before or within the same TopLevelDecl as it
158// references.
159void yyy(void){}
160void zzz(void){}
161#pragma weak yyy
162// NOTE: weak doesn't apply, not before or in same TopLevelDec(!)
Chris Lattner60e81882009-09-08 18:43:45 +0000163// CHECK: define void @yyy()
164
165int correct_linkage;