Fix the clang-wpa example.
[clang.git] / test / CodeGenCXX / visibility.cpp
blob931465060b6204b4f0382a7daa7819a21846e7cf
1 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2 // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
4 #define HIDDEN __attribute__((visibility("hidden")))
5 #define PROTECTED __attribute__((visibility("protected")))
6 #define DEFAULT __attribute__((visibility("default")))
8 // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
9 // CHECK: @_ZN5Test71aE = hidden global
10 // CHECK: @_ZN5Test71bE = global
11 // CHECK: @test9_var = global
12 // CHECK-HIDDEN: @test9_var = global
13 // CHECK: @_ZN6Test121A6hiddenE = external hidden global
14 // CHECK: @_ZN6Test121A7visibleE = external global
15 // CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
16 // CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
17 // CHECK: @_ZN6Test131B1aE = hidden global
18 // CHECK: @_ZN6Test131C1aE = global
19 // CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
20 // CHECK-HIDDEN: @_ZN6Test131C1aE = global
21 // CHECK: @_ZN6Test143varE = external global
22 // CHECK-HIDDEN: @_ZN6Test143varE = external global
23 // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
24 // CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
25 // CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
26 // CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
27 // CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
28 // CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
29 // CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
30 // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
31 // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
33 namespace Test1 {
34 // CHECK: define hidden void @_ZN5Test11fEv
35 void HIDDEN f() { }
39 namespace Test2 {
40 struct HIDDEN A {
41 void f();
44 // A::f is a member function of a hidden class.
45 // CHECK: define hidden void @_ZN5Test21A1fEv
46 void A::f() { }
49 namespace Test3 {
50 struct HIDDEN A {
51 struct B {
52 void f();
56 // B is a nested class where its parent class is hidden.
57 // CHECK: define hidden void @_ZN5Test31A1B1fEv
58 void A::B::f() { }
61 namespace Test4 HIDDEN {
62 int VariableInHiddenNamespace = 10;
64 // Test4::g is in a hidden namespace.
65 // CHECK: define hidden void @_ZN5Test41gEv
66 void g() { }
68 struct DEFAULT A {
69 void f();
72 // A has default visibility.
73 // CHECK: define void @_ZN5Test41A1fEv
74 void A::f() { }
77 namespace Test5 {
79 namespace NS HIDDEN {
80 // f is in NS which is hidden.
81 // CHECK: define hidden void @_ZN5Test52NS1fEv()
82 void f() { }
85 namespace NS {
86 // g is in NS, but this NS decl is not hidden.
87 // CHECK: define void @_ZN5Test52NS1gEv
88 void g() { }
92 // <rdar://problem/8091955>
93 namespace Test6 {
94 struct HIDDEN foo {
95 foo() { }
96 void bonk();
97 virtual void bar() = 0;
99 virtual void zonk() {}
102 struct barc : public foo {
103 barc();
104 virtual void bar();
107 barc::barc() {}
110 namespace Test7 {
111 class HIDDEN A {};
112 A a; // top of file
114 template <A&> struct Aref {
115 static void foo() {}
118 class B : public A {};
119 B b; // top of file
121 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
122 void test() {
123 Aref<a>::foo();
127 namespace Test8 {
128 void foo();
129 void bar() {}
130 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
131 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
133 void test() {
134 foo();
135 bar();
139 // PR8457
140 namespace Test9 {
141 extern "C" {
142 struct A { int field; };
143 void DEFAULT test9_fun(struct A *a) { }
144 struct A DEFAULT test9_var; // above
146 // CHECK: define void @test9_fun(
147 // CHECK-HIDDEN: define void @test9_fun(
149 void test() {
150 A a = test9_var;
151 test9_fun(&a);
155 // PR8478
156 namespace Test10 {
157 struct A;
159 DEFAULT class B {
160 void foo(A*);
163 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
164 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
165 void B::foo(A*) {}
168 // PR8492
169 namespace Test11 {
170 struct A {
171 void foo() {}
172 void DEFAULT bar() {}
175 void test() {
176 A a;
177 a.foo();
178 a.bar();
181 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
182 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
183 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
184 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
187 // Tested at top of file.
188 namespace Test12 {
189 struct A {
190 // This is hidden in all cases: the explicit attribute takes
191 // priority over -fvisibility on the parent.
192 static int hidden HIDDEN;
194 // This is default in all cases because it's only a declaration.
195 static int visible;
198 void test() {
199 A::hidden = 0;
200 A::visible = 0;
204 // Tested at top of file.
205 namespace Test13 {
206 struct HIDDEN A {};
208 // Should be hidden in all cases.
209 struct B {
210 static A a;
212 A B::a;
214 // Should be default in all cases.
215 struct DEFAULT C {
216 static A a;
218 A C::a;
221 // Tested at top of file.
222 namespace Test14 {
223 // Neither the visibility of the type nor -fvisibility=hidden should
224 // apply to declarations.
225 extern struct A *var;
227 struct A *test() { return var; }
230 // rdar://problem/8613093
231 namespace Test15 {
232 struct A {};
233 template <class T> struct Temp {
234 struct Inner {
235 static char buffer[0];
239 char *test() {
240 return Temp<A>::Inner::buffer;
244 namespace Test16 {
245 struct Base1 { virtual void foo(); };
246 struct Base2 : virtual Base1 { virtual void foo(); };
247 template <class T> struct A : virtual Base1, Base2 {
248 virtual void foo();
250 extern template struct A<char>;
252 void test() {
253 A<char> a;
254 a.foo();
258 namespace Test17 {
259 struct HIDDEN A {
260 static void foo();
261 static void DEFAULT bar();
262 static void HIDDEN baz();
264 struct DEFAULT B {
265 static void foo();
266 static void DEFAULT bar();
267 static void HIDDEN baz();
271 void test() {
272 A::foo();
273 A::bar();
274 A::baz();
275 A::B::foo();
276 A::B::bar();
277 A::B::baz();
279 // CHECK: declare hidden void @_ZN6Test171A3fooEv()
280 // CHECK: declare void @_ZN6Test171A3barEv()
281 // CHECK: declare hidden void @_ZN6Test171A3bazEv()
282 // CHECK: declare void @_ZN6Test171A1B3fooEv()
283 // CHECK: declare void @_ZN6Test171A1B3barEv()
284 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
285 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
286 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
287 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
288 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
289 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
290 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
293 namespace Test18 {
294 template <class T> struct HIDDEN A {
295 static void foo();
296 static void DEFAULT bar();
297 static void HIDDEN baz();
299 struct DEFAULT B {
300 static void foo();
301 static void DEFAULT bar();
302 static void HIDDEN baz();
305 struct HIDDEN H;
307 void test() {
308 A<int>::foo();
309 A<int>::bar();
310 A<int>::baz();
311 A<int>::B::foo();
312 A<int>::B::bar();
313 A<int>::B::baz();
314 A<H>::foo();
315 A<H>::bar();
316 A<H>::baz();
317 A<H>::B::foo();
318 A<H>::B::bar();
319 A<H>::B::baz();
321 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
322 // CHECK: declare void @_ZN6Test181AIiE3barEv()
323 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
324 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
325 // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
326 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
327 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
328 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
329 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
330 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
331 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
332 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
333 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
334 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
335 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
336 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
337 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
338 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
339 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
340 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
341 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
342 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
343 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
344 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
347 namespace Test19 {
348 struct A { A(); ~A(); };
350 // Tested at top of file.
351 template <class T> void foo() {
352 static A a;
355 void test() {
356 foo<int>();
360 // Various things with class template specializations.
361 namespace Test20 {
362 template <unsigned> struct HIDDEN A {};
364 // An explicit specialization inherits the explicit visibility of
365 // the template.
366 template <> struct A<0> {
367 static void test0();
368 static void test1();
371 // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
372 void A<0>::test0() {}
374 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
375 void test1() {
376 A<0>::test1();
379 // ...unless that's explicitly overridden.
380 template <> struct DEFAULT A<1> {
381 static void test2();
382 static void test3();
385 // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
386 void A<1>::test2() {}
388 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
389 void test3() {
390 A<1>::test3();
393 // <rdar://problem/8778497>
394 // But we should assume that an unknown specialization has the
395 // explicit visibility settings of the template.
396 template <class T> struct B {
397 static void test4() {}
398 static void test5();
401 // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
402 void test4() {
403 B<A<2> >::test4();
406 // CHECK: declare void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
407 // (but explicit visibility on a template argument doesn't count as
408 // explicit visibility for the template for purposes of deciding
409 // whether an external symbol gets visibility)
410 void test5() {
411 B<A<2> >::test5();