blob: 59fd7c26f0d5cf71b28a9ba0c8c250e62b37233e [file] [log] [blame]
Anders Carlsson39de84d2010-02-07 01:44:36 +00001// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
John McCall1fb0caa2010-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 Carlsson39de84d2010-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 Espindola860097c2012-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 Espindola2f47c362012-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
Anders Carlsson39de84d2010-02-07 01:44:36 +000031// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
John McCall1fb0caa2010-10-22 21:05:15 +000032// CHECK: @_ZN5Test71aE = hidden global
33// CHECK: @_ZN5Test71bE = global
John McCallac65c622010-10-26 04:59:26 +000034// CHECK: @test9_var = global
35// CHECK-HIDDEN: @test9_var = global
John McCall110e8e52010-10-29 22:22:43 +000036// CHECK: @_ZN6Test121A6hiddenE = external hidden global
37// CHECK: @_ZN6Test121A7visibleE = external global
38// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
39// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
40// CHECK: @_ZN6Test131B1aE = hidden global
41// CHECK: @_ZN6Test131C1aE = global
42// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
43// CHECK-HIDDEN: @_ZN6Test131C1aE = global
44// CHECK: @_ZN6Test143varE = external global
45// CHECK-HIDDEN: @_ZN6Test143varE = external global
John McCallee301022010-10-30 09:18:49 +000046// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
47// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
Rafael Espindola860097c2012-02-23 04:17:32 +000048
49namespace test27 {
50 template<typename T>
51 class C {
52 class __attribute__((visibility("default"))) D {
53 void f();
54 };
55 };
56
57 template<>
58 class C<int>::D {
59 virtual void g();
60 };
61
62 void C<int>::D::g() {
63 }
64 // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
65 // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
66}
67
John McCall112c9672010-11-02 21:04:24 +000068// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
69// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
70// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
71// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
Rafael Espindolacd3ac4b2011-01-15 08:23:14 +000072// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
Peter Collingbournebf1c5ae2011-09-26 01:56:36 +000073// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
Anders Carlssonf502d932011-01-24 00:46:19 +000074// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
John McCall1fb0caa2010-10-22 21:05:15 +000075
Anders Carlsson39de84d2010-02-07 01:44:36 +000076namespace Test1 {
77 // CHECK: define hidden void @_ZN5Test11fEv
78 void HIDDEN f() { }
79
80}
81
82namespace Test2 {
83 struct HIDDEN A {
84 void f();
85 };
86
87 // A::f is a member function of a hidden class.
88 // CHECK: define hidden void @_ZN5Test21A1fEv
89 void A::f() { }
90}
91
92namespace Test3 {
93 struct HIDDEN A {
94 struct B {
95 void f();
96 };
97 };
98
99 // B is a nested class where its parent class is hidden.
100 // CHECK: define hidden void @_ZN5Test31A1B1fEv
101 void A::B::f() { }
102}
103
104namespace Test4 HIDDEN {
105 int VariableInHiddenNamespace = 10;
106
107 // Test4::g is in a hidden namespace.
108 // CHECK: define hidden void @_ZN5Test41gEv
109 void g() { }
110
111 struct DEFAULT A {
112 void f();
113 };
114
115 // A has default visibility.
116 // CHECK: define void @_ZN5Test41A1fEv
117 void A::f() { }
118}
119
120namespace Test5 {
121
122 namespace NS HIDDEN {
123 // f is in NS which is hidden.
124 // CHECK: define hidden void @_ZN5Test52NS1fEv()
125 void f() { }
126 }
127
128 namespace NS {
129 // g is in NS, but this NS decl is not hidden.
130 // CHECK: define void @_ZN5Test52NS1gEv
131 void g() { }
132 }
133}
Douglas Gregorc66bcfd2010-06-14 23:41:45 +0000134
135// <rdar://problem/8091955>
136namespace Test6 {
137 struct HIDDEN foo {
138 foo() { }
139 void bonk();
140 virtual void bar() = 0;
141
142 virtual void zonk() {}
143 };
144
145 struct barc : public foo {
146 barc();
147 virtual void bar();
148 };
149
150 barc::barc() {}
151}
John McCall1fb0caa2010-10-22 21:05:15 +0000152
153namespace Test7 {
154 class HIDDEN A {};
155 A a; // top of file
156
157 template <A&> struct Aref {
158 static void foo() {}
159 };
160
161 class B : public A {};
162 B b; // top of file
163
164 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
165 void test() {
166 Aref<a>::foo();
167 }
168}
169
170namespace Test8 {
171 void foo();
172 void bar() {}
173 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
174 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
175
176 void test() {
177 foo();
178 bar();
179 }
180}
John McCallac65c622010-10-26 04:59:26 +0000181
182// PR8457
183namespace Test9 {
184 extern "C" {
185 struct A { int field; };
186 void DEFAULT test9_fun(struct A *a) { }
187 struct A DEFAULT test9_var; // above
188 }
189 // CHECK: define void @test9_fun(
190 // CHECK-HIDDEN: define void @test9_fun(
191
192 void test() {
193 A a = test9_var;
194 test9_fun(&a);
195 }
196}
John McCall67fa6d52010-10-28 07:07:52 +0000197
198// PR8478
199namespace Test10 {
200 struct A;
201
Eli Friedmanfc038e92011-12-17 00:36:09 +0000202 class DEFAULT B {
John McCall67fa6d52010-10-28 07:07:52 +0000203 void foo(A*);
204 };
205
206 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
207 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
208 void B::foo(A*) {}
209}
John McCall0df95872010-10-29 00:29:13 +0000210
211// PR8492
212namespace Test11 {
213 struct A {
214 void foo() {}
215 void DEFAULT bar() {}
216 };
217
218 void test() {
219 A a;
220 a.foo();
221 a.bar();
222 }
223
224 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
225 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
226 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
227 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
228}
John McCall110e8e52010-10-29 22:22:43 +0000229
230// Tested at top of file.
231namespace Test12 {
232 struct A {
233 // This is hidden in all cases: the explicit attribute takes
234 // priority over -fvisibility on the parent.
235 static int hidden HIDDEN;
236
237 // This is default in all cases because it's only a declaration.
238 static int visible;
239 };
240
241 void test() {
242 A::hidden = 0;
243 A::visible = 0;
244 }
245}
246
247// Tested at top of file.
248namespace Test13 {
249 struct HIDDEN A {};
250
251 // Should be hidden in all cases.
252 struct B {
253 static A a;
254 };
255 A B::a;
256
257 // Should be default in all cases.
258 struct DEFAULT C {
259 static A a;
260 };
261 A C::a;
262};
263
264// Tested at top of file.
265namespace Test14 {
266 // Neither the visibility of the type nor -fvisibility=hidden should
267 // apply to declarations.
268 extern struct A *var;
269
270 struct A *test() { return var; }
271}
John McCallee301022010-10-30 09:18:49 +0000272
273// rdar://problem/8613093
274namespace Test15 {
275 struct A {};
276 template <class T> struct Temp {
277 struct Inner {
278 static char buffer[0];
279 };
280 };
281
282 char *test() {
283 return Temp<A>::Inner::buffer;
284 }
285}
John McCallaf146032010-10-30 11:50:40 +0000286
287namespace Test16 {
288 struct Base1 { virtual void foo(); };
289 struct Base2 : virtual Base1 { virtual void foo(); };
290 template <class T> struct A : virtual Base1, Base2 {
291 virtual void foo();
292 };
293 extern template struct A<char>;
294
295 void test() {
296 A<char> a;
297 a.foo();
298 }
299}
John McCall36987482010-11-02 01:45:15 +0000300
301namespace Test17 {
302 struct HIDDEN A {
303 static void foo();
304 static void DEFAULT bar();
305 static void HIDDEN baz();
306
307 struct DEFAULT B {
308 static void foo();
309 static void DEFAULT bar();
310 static void HIDDEN baz();
311 };
312 };
313
314 void test() {
315 A::foo();
316 A::bar();
317 A::baz();
318 A::B::foo();
319 A::B::bar();
320 A::B::baz();
321 }
322 // CHECK: declare hidden void @_ZN6Test171A3fooEv()
323 // CHECK: declare void @_ZN6Test171A3barEv()
324 // CHECK: declare hidden void @_ZN6Test171A3bazEv()
325 // CHECK: declare void @_ZN6Test171A1B3fooEv()
326 // CHECK: declare void @_ZN6Test171A1B3barEv()
327 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
328 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
329 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
330 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
331 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
332 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
333 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
334}
335
336namespace Test18 {
337 template <class T> struct HIDDEN A {
338 static void foo();
339 static void DEFAULT bar();
340 static void HIDDEN baz();
341
342 struct DEFAULT B {
343 static void foo();
344 static void DEFAULT bar();
345 static void HIDDEN baz();
346 };
347 };
348 struct HIDDEN H;
349
350 void test() {
351 A<int>::foo();
352 A<int>::bar();
353 A<int>::baz();
354 A<int>::B::foo();
355 A<int>::B::bar();
356 A<int>::B::baz();
357 A<H>::foo();
358 A<H>::bar();
359 A<H>::baz();
360 A<H>::B::foo();
361 A<H>::B::bar();
362 A<H>::B::baz();
363 }
364 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
365 // CHECK: declare void @_ZN6Test181AIiE3barEv()
366 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
367 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
368 // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
369 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
370 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
371 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
372 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
373 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
374 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
375 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
376 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
377 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
378 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
379 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
380 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
381 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
382 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
383 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
384 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
385 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
386 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
387 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
388}
John McCall112c9672010-11-02 21:04:24 +0000389
390namespace Test19 {
391 struct A { A(); ~A(); };
392
393 // Tested at top of file.
394 template <class T> void foo() {
395 static A a;
396 }
397
398 void test() {
399 foo<int>();
400 }
401}
John McCall7f1b9872010-12-18 03:30:47 +0000402
403// Various things with class template specializations.
404namespace Test20 {
405 template <unsigned> struct HIDDEN A {};
406
407 // An explicit specialization inherits the explicit visibility of
408 // the template.
409 template <> struct A<0> {
410 static void test0();
411 static void test1();
412 };
413
414 // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
415 void A<0>::test0() {}
416
417 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
418 void test1() {
419 A<0>::test1();
420 }
421
422 // ...unless that's explicitly overridden.
423 template <> struct DEFAULT A<1> {
424 static void test2();
425 static void test3();
426 };
427
428 // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
429 void A<1>::test2() {}
430
431 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
432 void test3() {
433 A<1>::test3();
434 }
435
436 // <rdar://problem/8778497>
437 // But we should assume that an unknown specialization has the
438 // explicit visibility settings of the template.
439 template <class T> struct B {
440 static void test4() {}
441 static void test5();
442 };
443
444 // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
445 void test4() {
446 B<A<2> >::test4();
447 }
448
Rafael Espindola093ecc92012-01-14 00:30:36 +0000449 // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
John McCall7f1b9872010-12-18 03:30:47 +0000450 void test5() {
451 B<A<2> >::test5();
452 }
453}
John McCall1a0918a2011-03-04 10:39:25 +0000454
455// PR9371
456namespace test21 {
457 enum En { en };
458 template<En> struct A {
459 __attribute__((visibility("default"))) void foo() {}
460 };
461
462 // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
463 template void A<en>::foo();
464}
John McCall6ce51ee2011-06-27 23:06:04 +0000465
466// rdar://problem/9616154
467// Visibility on explicit specializations should take precedence.
468namespace test22 {
469 class A1 {};
470 class A2 {};
471
472 template <class T> struct B {};
473 template <> struct DEFAULT B<A1> {
474 static void foo();
475 static void bar() {}
476 };
477 template <> struct B<A2> {
478 static void foo();
479 static void bar() {}
480 };
481
482 void test() {
483 B<A1>::foo();
484 B<A1>::bar();
485 B<A2>::foo();
486 B<A2>::bar();
487 }
488 // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
489 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
490 // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
491 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
492 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
493 // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
494 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
495 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
496}
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000497
498namespace PR10113 {
Rafael Espindolab5d763d2012-01-02 06:26:22 +0000499 namespace foo DEFAULT {
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000500 template<typename T>
501 class bar {
502 void zed() {}
503 };
504 }
505 template class foo::bar<char>;
506 // CHECK: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
507 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
Rafael Espindola093ecc92012-01-14 00:30:36 +0000508
509 struct zed {
510 };
511 template class foo::bar<zed>;
512 // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
513 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000514}
Rafael Espindola0257b7f2012-01-03 06:04:21 +0000515
516namespace PR11690 {
517 template<class T> struct Class {
518 void size() const {
519 }
520 };
521 template class DEFAULT Class<char>;
522 // CHECK: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
523 // CHECK-HIDDEN: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
Rafael Espindola256fc4d2012-01-04 05:40:59 +0000524
525 template<class T> void Method() {}
Rafael Espindola093ecc92012-01-14 00:30:36 +0000526 template DEFAULT void Method<char>();
Rafael Espindola256fc4d2012-01-04 05:40:59 +0000527 // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv
528 // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv
Rafael Espindola0257b7f2012-01-03 06:04:21 +0000529}
Rafael Espindola093ecc92012-01-14 00:30:36 +0000530
531namespace PR11690_2 {
532 namespace foo DEFAULT {
533 class bar;
534 template<typename T1, typename T2 = bar>
535 class zed {
536 void bar() {
537 }
538 };
539 }
540 struct baz {
541 };
542 template class foo::zed<baz>;
543 // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
544 // CHECK-HIDDEN: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
545}
Rafael Espindola860097c2012-02-23 04:17:32 +0000546
547namespace test23 {
548 // Having a template argument that is explicitly visible should not make
549 // the template instantiation visible.
550 template <typename T>
551 struct X {
552 static void f() {
553 }
554 };
555
556 class DEFAULT A;
557
558 void g() {
559 X<A> y;
560 y.f();
561 }
562 // CHECK: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv
563 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv
564}
565
566namespace PR12001 {
567 template <typename P1>
568 void Bind(const P1& p1) {
569 }
570
571 class DEFAULT Version { };
572
573 void f() {
574 Bind(Version());
575 }
576 // CHECK: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_
577 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_
578}
579
580namespace test24 {
581 class DEFAULT A { };
582
583 struct S {
584 template <typename T>
585 void mem() {}
586 };
587
588 void test() {
589 S s;
590 s.mem<A>();
591 }
592 // CHECK: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv
593 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv
594}
595
596namespace test26 {
597 template<typename T>
598 class C {
599 __attribute__((visibility("default"))) void f();
600 };
601
602 template<>
603 void C<int>::f() { }
604
605 // CHECK: define void @_ZN6test261CIiE1fEv
606 // CHECK-HIDDEN: define void @_ZN6test261CIiE1fEv
607}