blob: b3c61329afe07d3412e4f6825c5e4970c7f18ee8 [file] [log] [blame]
Anders Carlsson10d369d2010-02-07 01:44:36 +00001// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
John McCall457a04e2010-10-22 21:05:15 +00002// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
Anders Carlsson10d369d2010-02-07 01:44:36 +00003
4#define HIDDEN __attribute__((visibility("hidden")))
5#define PROTECTED __attribute__((visibility("protected")))
6#define DEFAULT __attribute__((visibility("default")))
7
Rafael Espindola8093fdf2012-02-23 04:17:32 +00008namespace test25 {
9 template<typename T>
10 struct X {
11 template<typename U>
12 struct definition {
13 };
14 };
15
16 class DEFAULT A { };
17
18 X<int>::definition<A> a;
19 // CHECK: @_ZN6test251aE = global
20 // CHECK-HIDDEN: @_ZN6test251aE = hidden global
21}
22
Rafael Espindola1f71a232012-03-10 13:01:40 +000023namespace test28 {
24 class DEFAULT foo {
25 };
26 foo myvec;
27 // CHECK: @_ZN6test285myvecE = global
28 // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global
29}
30
Rafael Espindola53cf2192012-04-19 05:50:08 +000031namespace test29 {
32#pragma GCC visibility push(hidden)
33 struct RECT {
34 int top;
35 };
36 __attribute__ ((visibility ("default"))) extern RECT data_rect;
37 RECT data_rect = { -1};
38#pragma GCC visibility pop
39 // CHECK: @_ZN6test299data_rectE = global
40 // CHECK-HIDDEN: @_ZN6test299data_rectE = global
41}
42
Anders Carlsson10d369d2010-02-07 01:44:36 +000043// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
John McCall457a04e2010-10-22 21:05:15 +000044// CHECK: @_ZN5Test71aE = hidden global
45// CHECK: @_ZN5Test71bE = global
John McCall5fe84122010-10-26 04:59:26 +000046// CHECK: @test9_var = global
47// CHECK-HIDDEN: @test9_var = global
John McCall37bb6c92010-10-29 22:22:43 +000048// CHECK: @_ZN6Test121A6hiddenE = external hidden global
49// CHECK: @_ZN6Test121A7visibleE = external global
50// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
51// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
52// CHECK: @_ZN6Test131B1aE = hidden global
53// CHECK: @_ZN6Test131C1aE = global
54// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
55// CHECK-HIDDEN: @_ZN6Test131C1aE = global
56// CHECK: @_ZN6Test143varE = external global
57// CHECK-HIDDEN: @_ZN6Test143varE = external global
John McCall36cd5cc2010-10-30 09:18:49 +000058// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
59// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
Rafael Espindola8093fdf2012-02-23 04:17:32 +000060
61namespace test27 {
62 template<typename T>
63 class C {
64 class __attribute__((visibility("default"))) D {
65 void f();
66 };
67 };
68
69 template<>
70 class C<int>::D {
71 virtual void g();
72 };
73
74 void C<int>::D::g() {
75 }
76 // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
77 // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
78}
79
John McCall8e7cb6d2010-11-02 21:04:24 +000080// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
81// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
82// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
83// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
Rafael Espindolafacb7d02011-01-15 08:23:14 +000084// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
Peter Collingbourne71c26932011-09-26 01:56:36 +000085// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
Anders Carlsson571e2ad2011-01-24 00:46:19 +000086// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
John McCall457a04e2010-10-22 21:05:15 +000087
Anders Carlsson10d369d2010-02-07 01:44:36 +000088namespace Test1 {
89 // CHECK: define hidden void @_ZN5Test11fEv
90 void HIDDEN f() { }
91
92}
93
94namespace Test2 {
95 struct HIDDEN A {
96 void f();
97 };
98
99 // A::f is a member function of a hidden class.
100 // CHECK: define hidden void @_ZN5Test21A1fEv
101 void A::f() { }
102}
103
104namespace Test3 {
105 struct HIDDEN A {
106 struct B {
107 void f();
108 };
109 };
110
111 // B is a nested class where its parent class is hidden.
112 // CHECK: define hidden void @_ZN5Test31A1B1fEv
113 void A::B::f() { }
114}
115
116namespace Test4 HIDDEN {
117 int VariableInHiddenNamespace = 10;
118
119 // Test4::g is in a hidden namespace.
120 // CHECK: define hidden void @_ZN5Test41gEv
121 void g() { }
122
123 struct DEFAULT A {
124 void f();
125 };
126
127 // A has default visibility.
128 // CHECK: define void @_ZN5Test41A1fEv
129 void A::f() { }
130}
131
132namespace Test5 {
133
134 namespace NS HIDDEN {
135 // f is in NS which is hidden.
136 // CHECK: define hidden void @_ZN5Test52NS1fEv()
137 void f() { }
138 }
139
140 namespace NS {
141 // g is in NS, but this NS decl is not hidden.
142 // CHECK: define void @_ZN5Test52NS1gEv
143 void g() { }
144 }
145}
Douglas Gregor4f6e8de2010-06-14 23:41:45 +0000146
147// <rdar://problem/8091955>
148namespace Test6 {
149 struct HIDDEN foo {
150 foo() { }
151 void bonk();
152 virtual void bar() = 0;
153
154 virtual void zonk() {}
155 };
156
157 struct barc : public foo {
158 barc();
159 virtual void bar();
160 };
161
162 barc::barc() {}
163}
John McCall457a04e2010-10-22 21:05:15 +0000164
165namespace Test7 {
166 class HIDDEN A {};
167 A a; // top of file
168
169 template <A&> struct Aref {
170 static void foo() {}
171 };
172
173 class B : public A {};
174 B b; // top of file
175
176 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
177 void test() {
178 Aref<a>::foo();
179 }
180}
181
182namespace Test8 {
183 void foo();
184 void bar() {}
185 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
186 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
187
188 void test() {
189 foo();
190 bar();
191 }
192}
John McCall5fe84122010-10-26 04:59:26 +0000193
194// PR8457
195namespace Test9 {
196 extern "C" {
197 struct A { int field; };
198 void DEFAULT test9_fun(struct A *a) { }
199 struct A DEFAULT test9_var; // above
200 }
201 // CHECK: define void @test9_fun(
202 // CHECK-HIDDEN: define void @test9_fun(
203
204 void test() {
205 A a = test9_var;
206 test9_fun(&a);
207 }
208}
John McCall2efaf112010-10-28 07:07:52 +0000209
210// PR8478
211namespace Test10 {
212 struct A;
213
Eli Friedmane3217952011-12-17 00:36:09 +0000214 class DEFAULT B {
John McCall2efaf112010-10-28 07:07:52 +0000215 void foo(A*);
216 };
217
218 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
219 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
220 void B::foo(A*) {}
221}
John McCall033caa52010-10-29 00:29:13 +0000222
223// PR8492
224namespace Test11 {
225 struct A {
226 void foo() {}
227 void DEFAULT bar() {}
228 };
229
230 void test() {
231 A a;
232 a.foo();
233 a.bar();
234 }
235
236 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
237 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
238 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
239 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
240}
John McCall37bb6c92010-10-29 22:22:43 +0000241
242// Tested at top of file.
243namespace Test12 {
244 struct A {
245 // This is hidden in all cases: the explicit attribute takes
246 // priority over -fvisibility on the parent.
247 static int hidden HIDDEN;
248
249 // This is default in all cases because it's only a declaration.
250 static int visible;
251 };
252
253 void test() {
254 A::hidden = 0;
255 A::visible = 0;
256 }
257}
258
259// Tested at top of file.
260namespace Test13 {
261 struct HIDDEN A {};
262
263 // Should be hidden in all cases.
264 struct B {
265 static A a;
266 };
267 A B::a;
268
269 // Should be default in all cases.
270 struct DEFAULT C {
271 static A a;
272 };
273 A C::a;
274};
275
276// Tested at top of file.
277namespace Test14 {
278 // Neither the visibility of the type nor -fvisibility=hidden should
279 // apply to declarations.
280 extern struct A *var;
281
282 struct A *test() { return var; }
283}
John McCall36cd5cc2010-10-30 09:18:49 +0000284
285// rdar://problem/8613093
286namespace Test15 {
287 struct A {};
288 template <class T> struct Temp {
289 struct Inner {
290 static char buffer[0];
291 };
292 };
293
294 char *test() {
295 return Temp<A>::Inner::buffer;
296 }
297}
John McCallc273f242010-10-30 11:50:40 +0000298
299namespace Test16 {
300 struct Base1 { virtual void foo(); };
301 struct Base2 : virtual Base1 { virtual void foo(); };
302 template <class T> struct A : virtual Base1, Base2 {
303 virtual void foo();
304 };
305 extern template struct A<char>;
306
307 void test() {
308 A<char> a;
309 a.foo();
310 }
311}
John McCall07072662010-11-02 01:45:15 +0000312
313namespace Test17 {
314 struct HIDDEN A {
315 static void foo();
316 static void DEFAULT bar();
317 static void HIDDEN baz();
318
319 struct DEFAULT B {
320 static void foo();
321 static void DEFAULT bar();
322 static void HIDDEN baz();
323 };
324 };
325
326 void test() {
327 A::foo();
328 A::bar();
329 A::baz();
330 A::B::foo();
331 A::B::bar();
332 A::B::baz();
333 }
334 // CHECK: declare hidden void @_ZN6Test171A3fooEv()
335 // CHECK: declare void @_ZN6Test171A3barEv()
336 // CHECK: declare hidden void @_ZN6Test171A3bazEv()
337 // CHECK: declare void @_ZN6Test171A1B3fooEv()
338 // CHECK: declare void @_ZN6Test171A1B3barEv()
339 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
340 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
341 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
342 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
343 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
344 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
345 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
346}
347
348namespace Test18 {
349 template <class T> struct HIDDEN A {
350 static void foo();
351 static void DEFAULT bar();
352 static void HIDDEN baz();
353
354 struct DEFAULT B {
355 static void foo();
356 static void DEFAULT bar();
357 static void HIDDEN baz();
358 };
359 };
360 struct HIDDEN H;
361
362 void test() {
363 A<int>::foo();
364 A<int>::bar();
365 A<int>::baz();
366 A<int>::B::foo();
367 A<int>::B::bar();
368 A<int>::B::baz();
369 A<H>::foo();
370 A<H>::bar();
371 A<H>::baz();
372 A<H>::B::foo();
373 A<H>::B::bar();
374 A<H>::B::baz();
375 }
376 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
377 // CHECK: declare void @_ZN6Test181AIiE3barEv()
378 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
379 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
380 // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
381 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
382 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
383 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
384 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
385 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
386 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
387 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
388 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
389 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
390 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
391 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
392 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
393 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
394 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
395 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
396 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
397 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
398 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
399 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
400}
John McCall8e7cb6d2010-11-02 21:04:24 +0000401
402namespace Test19 {
403 struct A { A(); ~A(); };
404
405 // Tested at top of file.
406 template <class T> void foo() {
407 static A a;
408 }
409
410 void test() {
411 foo<int>();
412 }
413}
John McCall659a3372010-12-18 03:30:47 +0000414
415// Various things with class template specializations.
416namespace Test20 {
417 template <unsigned> struct HIDDEN A {};
418
419 // An explicit specialization inherits the explicit visibility of
420 // the template.
421 template <> struct A<0> {
422 static void test0();
423 static void test1();
424 };
425
426 // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
427 void A<0>::test0() {}
428
429 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
430 void test1() {
431 A<0>::test1();
432 }
433
434 // ...unless that's explicitly overridden.
435 template <> struct DEFAULT A<1> {
436 static void test2();
437 static void test3();
438 };
439
440 // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
441 void A<1>::test2() {}
442
443 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
444 void test3() {
445 A<1>::test3();
446 }
447
448 // <rdar://problem/8778497>
449 // But we should assume that an unknown specialization has the
450 // explicit visibility settings of the template.
451 template <class T> struct B {
452 static void test4() {}
453 static void test5();
454 };
455
456 // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
457 void test4() {
458 B<A<2> >::test4();
459 }
460
Rafael Espindola2f869a32012-01-14 00:30:36 +0000461 // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
John McCall659a3372010-12-18 03:30:47 +0000462 void test5() {
463 B<A<2> >::test5();
464 }
465}
John McCall8bc6d5b2011-03-04 10:39:25 +0000466
467// PR9371
468namespace test21 {
469 enum En { en };
470 template<En> struct A {
471 __attribute__((visibility("default"))) void foo() {}
472 };
473
474 // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
475 template void A<en>::foo();
476}
John McCallb8c604a2011-06-27 23:06:04 +0000477
478// rdar://problem/9616154
479// Visibility on explicit specializations should take precedence.
480namespace test22 {
481 class A1 {};
482 class A2 {};
483
484 template <class T> struct B {};
485 template <> struct DEFAULT B<A1> {
486 static void foo();
487 static void bar() {}
488 };
489 template <> struct B<A2> {
490 static void foo();
491 static void bar() {}
492 };
493
494 void test() {
495 B<A1>::foo();
496 B<A1>::bar();
497 B<A2>::foo();
498 B<A2>::bar();
499 }
500 // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
501 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
502 // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
503 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
504 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
505 // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
506 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
507 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
508}
Rafael Espindola0f960a02012-01-01 18:06:40 +0000509
510namespace PR10113 {
Rafael Espindolaeeb9d9f2012-01-02 06:26:22 +0000511 namespace foo DEFAULT {
Rafael Espindola0f960a02012-01-01 18:06:40 +0000512 template<typename T>
513 class bar {
514 void zed() {}
515 };
516 }
517 template class foo::bar<char>;
518 // CHECK: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
519 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
Rafael Espindola2f869a32012-01-14 00:30:36 +0000520
521 struct zed {
522 };
523 template class foo::bar<zed>;
524 // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
Rafael Espindola1280fe62012-04-19 05:34:51 +0000525 // CHECK-HIDDEN: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv
Rafael Espindola0f960a02012-01-01 18:06:40 +0000526}
Rafael Espindola0b062072012-01-03 06:04:21 +0000527
528namespace PR11690 {
529 template<class T> struct Class {
530 void size() const {
531 }
532 };
533 template class DEFAULT Class<char>;
534 // CHECK: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
535 // CHECK-HIDDEN: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
Rafael Espindola2aa7acf2012-01-04 05:40:59 +0000536
537 template<class T> void Method() {}
Rafael Espindola2f869a32012-01-14 00:30:36 +0000538 template DEFAULT void Method<char>();
Rafael Espindola2aa7acf2012-01-04 05:40:59 +0000539 // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv
540 // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv
Rafael Espindola0b062072012-01-03 06:04:21 +0000541}
Rafael Espindola2f869a32012-01-14 00:30:36 +0000542
543namespace PR11690_2 {
544 namespace foo DEFAULT {
545 class bar;
546 template<typename T1, typename T2 = bar>
547 class zed {
548 void bar() {
549 }
550 };
551 }
552 struct baz {
553 };
554 template class foo::zed<baz>;
555 // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
Rafael Espindola1280fe62012-04-19 05:34:51 +0000556 // CHECK-HIDDEN: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
Rafael Espindola2f869a32012-01-14 00:30:36 +0000557}
Rafael Espindola8093fdf2012-02-23 04:17:32 +0000558
559namespace test23 {
560 // Having a template argument that is explicitly visible should not make
561 // the template instantiation visible.
562 template <typename T>
563 struct X {
564 static void f() {
565 }
566 };
567
568 class DEFAULT A;
569
570 void g() {
571 X<A> y;
572 y.f();
573 }
574 // CHECK: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv
575 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv
576}
577
578namespace PR12001 {
579 template <typename P1>
580 void Bind(const P1& p1) {
581 }
582
583 class DEFAULT Version { };
584
585 void f() {
586 Bind(Version());
587 }
588 // CHECK: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_
589 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_
590}
591
592namespace test24 {
593 class DEFAULT A { };
594
595 struct S {
596 template <typename T>
597 void mem() {}
598 };
599
600 void test() {
601 S s;
602 s.mem<A>();
603 }
604 // CHECK: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv
605 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv
606}
607
608namespace test26 {
609 template<typename T>
610 class C {
611 __attribute__((visibility("default"))) void f();
612 };
613
614 template<>
615 void C<int>::f() { }
616
617 // CHECK: define void @_ZN6test261CIiE1fEv
618 // CHECK-HIDDEN: define void @_ZN6test261CIiE1fEv
619}