blob: d302214df44208187703dc655f81ed32f3a7a9d1 [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 Espindola60115a02012-04-22 00:43:48 +00008namespace test30 {
9 // When H is hidden, it should make X hidden, even if the template argument
10 // is not.
11 struct H {
12 };
13 template<H *T>
14 struct X {
15 };
16 H DEFAULT a;
17 X<&a> b;
18 // CHECK: _ZN6test301bE = global
19 // CHECK-HIDDEN: _ZN6test301bE = hidden global
20}
21
Rafael Espindola860097c2012-02-23 04:17:32 +000022namespace test25 {
23 template<typename T>
24 struct X {
25 template<typename U>
26 struct definition {
27 };
28 };
29
30 class DEFAULT A { };
31
32 X<int>::definition<A> a;
33 // CHECK: @_ZN6test251aE = global
34 // CHECK-HIDDEN: @_ZN6test251aE = hidden global
35}
36
Rafael Espindola2f47c362012-03-10 13:01:40 +000037namespace test28 {
38 class DEFAULT foo {
39 };
40 foo myvec;
41 // CHECK: @_ZN6test285myvecE = global
42 // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global
43}
44
Rafael Espindolac7e60602012-04-19 05:50:08 +000045namespace test29 {
46#pragma GCC visibility push(hidden)
47 struct RECT {
48 int top;
49 };
50 __attribute__ ((visibility ("default"))) extern RECT data_rect;
51 RECT data_rect = { -1};
52#pragma GCC visibility pop
53 // CHECK: @_ZN6test299data_rectE = global
54 // CHECK-HIDDEN: @_ZN6test299data_rectE = global
55}
56
Rafael Espindola797105a2012-05-16 02:10:38 +000057namespace test40 {
58 template<typename T>
59 struct foo {
60 DEFAULT static int bar;
61 };
62 template<typename T>
63 int foo<T>::bar;
64 template struct foo<int>;
65 // CHECK: _ZN6test403fooIiE3barE = weak_odr global
66 // CHECK-HIDDEN: _ZN6test403fooIiE3barE = weak_odr global
67}
68
Rafael Espindola2de54fc2012-05-21 14:22:37 +000069namespace test41 {
70 // Unlike gcc we propagate the information that foo not only is hidden, but
71 // has been explicitly marked as so. This lets us produce a hidden undefined
72 // reference to bar.
73 struct __attribute__((visibility("hidden"))) foo {};
74 extern foo bar;
75 foo *zed() {
76 return &bar;
77 }
78 // CHECK: @_ZN6test413barE = external hidden global
79 // CHECK-HIDDEN: @_ZN6test413barE = external hidden global
80}
81
Anders Carlsson39de84d2010-02-07 01:44:36 +000082// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
John McCall1fb0caa2010-10-22 21:05:15 +000083// CHECK: @_ZN5Test71aE = hidden global
84// CHECK: @_ZN5Test71bE = global
John McCallac65c622010-10-26 04:59:26 +000085// CHECK: @test9_var = global
86// CHECK-HIDDEN: @test9_var = global
John McCall110e8e52010-10-29 22:22:43 +000087// CHECK: @_ZN6Test121A6hiddenE = external hidden global
88// CHECK: @_ZN6Test121A7visibleE = external global
89// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
90// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
91// CHECK: @_ZN6Test131B1aE = hidden global
92// CHECK: @_ZN6Test131C1aE = global
93// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
94// CHECK-HIDDEN: @_ZN6Test131C1aE = global
95// CHECK: @_ZN6Test143varE = external global
96// CHECK-HIDDEN: @_ZN6Test143varE = external global
John McCallee301022010-10-30 09:18:49 +000097// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
98// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
Rafael Espindola860097c2012-02-23 04:17:32 +000099
100namespace test27 {
101 template<typename T>
102 class C {
103 class __attribute__((visibility("default"))) D {
104 void f();
105 };
106 };
107
108 template<>
109 class C<int>::D {
110 virtual void g();
111 };
112
113 void C<int>::D::g() {
114 }
115 // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
116 // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
117}
118
John McCall112c9672010-11-02 21:04:24 +0000119// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
120// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
121// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
122// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
Rafael Espindolacd3ac4b2011-01-15 08:23:14 +0000123// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
Peter Collingbournebf1c5ae2011-09-26 01:56:36 +0000124// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
Anders Carlssonf502d932011-01-24 00:46:19 +0000125// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
John McCall1fb0caa2010-10-22 21:05:15 +0000126
Anders Carlsson39de84d2010-02-07 01:44:36 +0000127namespace Test1 {
128 // CHECK: define hidden void @_ZN5Test11fEv
129 void HIDDEN f() { }
130
131}
132
133namespace Test2 {
134 struct HIDDEN A {
135 void f();
136 };
137
138 // A::f is a member function of a hidden class.
139 // CHECK: define hidden void @_ZN5Test21A1fEv
140 void A::f() { }
141}
142
143namespace Test3 {
144 struct HIDDEN A {
145 struct B {
146 void f();
147 };
148 };
149
150 // B is a nested class where its parent class is hidden.
151 // CHECK: define hidden void @_ZN5Test31A1B1fEv
152 void A::B::f() { }
153}
154
155namespace Test4 HIDDEN {
156 int VariableInHiddenNamespace = 10;
157
158 // Test4::g is in a hidden namespace.
159 // CHECK: define hidden void @_ZN5Test41gEv
160 void g() { }
161
162 struct DEFAULT A {
163 void f();
164 };
165
166 // A has default visibility.
167 // CHECK: define void @_ZN5Test41A1fEv
168 void A::f() { }
169}
170
171namespace Test5 {
172
173 namespace NS HIDDEN {
174 // f is in NS which is hidden.
175 // CHECK: define hidden void @_ZN5Test52NS1fEv()
176 void f() { }
177 }
178
179 namespace NS {
180 // g is in NS, but this NS decl is not hidden.
181 // CHECK: define void @_ZN5Test52NS1gEv
182 void g() { }
183 }
184}
Douglas Gregorc66bcfd2010-06-14 23:41:45 +0000185
186// <rdar://problem/8091955>
187namespace Test6 {
188 struct HIDDEN foo {
189 foo() { }
190 void bonk();
191 virtual void bar() = 0;
192
193 virtual void zonk() {}
194 };
195
196 struct barc : public foo {
197 barc();
198 virtual void bar();
199 };
200
201 barc::barc() {}
202}
John McCall1fb0caa2010-10-22 21:05:15 +0000203
204namespace Test7 {
205 class HIDDEN A {};
206 A a; // top of file
207
208 template <A&> struct Aref {
209 static void foo() {}
210 };
211
212 class B : public A {};
213 B b; // top of file
214
215 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
216 void test() {
217 Aref<a>::foo();
218 }
219}
220
221namespace Test8 {
222 void foo();
223 void bar() {}
224 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
225 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
226
227 void test() {
228 foo();
229 bar();
230 }
231}
John McCallac65c622010-10-26 04:59:26 +0000232
233// PR8457
234namespace Test9 {
235 extern "C" {
236 struct A { int field; };
237 void DEFAULT test9_fun(struct A *a) { }
238 struct A DEFAULT test9_var; // above
239 }
240 // CHECK: define void @test9_fun(
241 // CHECK-HIDDEN: define void @test9_fun(
242
243 void test() {
244 A a = test9_var;
245 test9_fun(&a);
246 }
247}
John McCall67fa6d52010-10-28 07:07:52 +0000248
249// PR8478
250namespace Test10 {
251 struct A;
252
Eli Friedmanfc038e92011-12-17 00:36:09 +0000253 class DEFAULT B {
John McCall67fa6d52010-10-28 07:07:52 +0000254 void foo(A*);
255 };
256
257 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
258 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
259 void B::foo(A*) {}
260}
John McCall0df95872010-10-29 00:29:13 +0000261
262// PR8492
263namespace Test11 {
264 struct A {
265 void foo() {}
266 void DEFAULT bar() {}
267 };
268
269 void test() {
270 A a;
271 a.foo();
272 a.bar();
273 }
274
275 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
276 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
277 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
278 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
279}
John McCall110e8e52010-10-29 22:22:43 +0000280
281// Tested at top of file.
282namespace Test12 {
283 struct A {
284 // This is hidden in all cases: the explicit attribute takes
285 // priority over -fvisibility on the parent.
286 static int hidden HIDDEN;
287
288 // This is default in all cases because it's only a declaration.
289 static int visible;
290 };
291
292 void test() {
293 A::hidden = 0;
294 A::visible = 0;
295 }
296}
297
298// Tested at top of file.
299namespace Test13 {
300 struct HIDDEN A {};
301
302 // Should be hidden in all cases.
303 struct B {
304 static A a;
305 };
306 A B::a;
307
308 // Should be default in all cases.
309 struct DEFAULT C {
310 static A a;
311 };
312 A C::a;
313};
314
315// Tested at top of file.
316namespace Test14 {
317 // Neither the visibility of the type nor -fvisibility=hidden should
318 // apply to declarations.
319 extern struct A *var;
320
321 struct A *test() { return var; }
322}
John McCallee301022010-10-30 09:18:49 +0000323
324// rdar://problem/8613093
325namespace Test15 {
326 struct A {};
327 template <class T> struct Temp {
328 struct Inner {
329 static char buffer[0];
330 };
331 };
332
333 char *test() {
334 return Temp<A>::Inner::buffer;
335 }
336}
John McCallaf146032010-10-30 11:50:40 +0000337
338namespace Test16 {
339 struct Base1 { virtual void foo(); };
340 struct Base2 : virtual Base1 { virtual void foo(); };
341 template <class T> struct A : virtual Base1, Base2 {
342 virtual void foo();
343 };
344 extern template struct A<char>;
345
346 void test() {
347 A<char> a;
348 a.foo();
349 }
350}
John McCall36987482010-11-02 01:45:15 +0000351
352namespace Test17 {
353 struct HIDDEN A {
354 static void foo();
355 static void DEFAULT bar();
356 static void HIDDEN baz();
357
358 struct DEFAULT B {
359 static void foo();
360 static void DEFAULT bar();
361 static void HIDDEN baz();
362 };
363 };
364
365 void test() {
366 A::foo();
367 A::bar();
368 A::baz();
369 A::B::foo();
370 A::B::bar();
371 A::B::baz();
372 }
373 // CHECK: declare hidden void @_ZN6Test171A3fooEv()
374 // CHECK: declare void @_ZN6Test171A3barEv()
375 // CHECK: declare hidden void @_ZN6Test171A3bazEv()
376 // CHECK: declare void @_ZN6Test171A1B3fooEv()
377 // CHECK: declare void @_ZN6Test171A1B3barEv()
378 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
379 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
380 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
381 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
382 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
383 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
384 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
385}
386
387namespace Test18 {
388 template <class T> struct HIDDEN A {
389 static void foo();
390 static void DEFAULT bar();
391 static void HIDDEN baz();
392
393 struct DEFAULT B {
394 static void foo();
395 static void DEFAULT bar();
396 static void HIDDEN baz();
397 };
398 };
399 struct HIDDEN H;
400
401 void test() {
402 A<int>::foo();
403 A<int>::bar();
404 A<int>::baz();
405 A<int>::B::foo();
406 A<int>::B::bar();
407 A<int>::B::baz();
408 A<H>::foo();
409 A<H>::bar();
410 A<H>::baz();
411 A<H>::B::foo();
412 A<H>::B::bar();
413 A<H>::B::baz();
414 }
415 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
416 // CHECK: declare void @_ZN6Test181AIiE3barEv()
417 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
418 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
419 // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
420 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
421 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
422 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
423 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
424 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
425 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
426 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
427 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
428 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
429 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
430 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
431 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
432 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
433 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
434 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
435 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
436 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
437 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
438 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
439}
John McCall112c9672010-11-02 21:04:24 +0000440
441namespace Test19 {
442 struct A { A(); ~A(); };
443
444 // Tested at top of file.
445 template <class T> void foo() {
446 static A a;
447 }
448
449 void test() {
450 foo<int>();
451 }
452}
John McCall7f1b9872010-12-18 03:30:47 +0000453
454// Various things with class template specializations.
455namespace Test20 {
456 template <unsigned> struct HIDDEN A {};
457
458 // An explicit specialization inherits the explicit visibility of
459 // the template.
460 template <> struct A<0> {
461 static void test0();
462 static void test1();
463 };
464
465 // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
466 void A<0>::test0() {}
467
468 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
469 void test1() {
470 A<0>::test1();
471 }
472
473 // ...unless that's explicitly overridden.
474 template <> struct DEFAULT A<1> {
475 static void test2();
476 static void test3();
477 };
478
479 // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
480 void A<1>::test2() {}
481
482 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
483 void test3() {
484 A<1>::test3();
485 }
486
487 // <rdar://problem/8778497>
488 // But we should assume that an unknown specialization has the
489 // explicit visibility settings of the template.
490 template <class T> struct B {
491 static void test4() {}
492 static void test5();
493 };
494
495 // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
496 void test4() {
497 B<A<2> >::test4();
498 }
499
Rafael Espindola093ecc92012-01-14 00:30:36 +0000500 // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
John McCall7f1b9872010-12-18 03:30:47 +0000501 void test5() {
502 B<A<2> >::test5();
503 }
504}
John McCall1a0918a2011-03-04 10:39:25 +0000505
506// PR9371
507namespace test21 {
508 enum En { en };
509 template<En> struct A {
510 __attribute__((visibility("default"))) void foo() {}
511 };
512
513 // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
514 template void A<en>::foo();
515}
John McCall6ce51ee2011-06-27 23:06:04 +0000516
517// rdar://problem/9616154
518// Visibility on explicit specializations should take precedence.
519namespace test22 {
520 class A1 {};
521 class A2 {};
522
523 template <class T> struct B {};
524 template <> struct DEFAULT B<A1> {
525 static void foo();
526 static void bar() {}
527 };
528 template <> struct B<A2> {
529 static void foo();
530 static void bar() {}
531 };
532
533 void test() {
534 B<A1>::foo();
535 B<A1>::bar();
536 B<A2>::foo();
537 B<A2>::bar();
538 }
539 // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
540 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
541 // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
542 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
543 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
544 // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
545 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
546 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
547}
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000548
549namespace PR10113 {
Rafael Espindolab5d763d2012-01-02 06:26:22 +0000550 namespace foo DEFAULT {
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000551 template<typename T>
552 class bar {
553 void zed() {}
554 };
555 }
556 template class foo::bar<char>;
557 // CHECK: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
558 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
Rafael Espindola093ecc92012-01-14 00:30:36 +0000559
560 struct zed {
561 };
562 template class foo::bar<zed>;
563 // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
Rafael Espindola51183372012-04-22 12:37:27 +0000564
565 // FIXME: This should be hidden as zed is hidden.
566 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000567}
Rafael Espindola0257b7f2012-01-03 06:04:21 +0000568
569namespace PR11690 {
570 template<class T> struct Class {
571 void size() const {
572 }
573 };
574 template class DEFAULT Class<char>;
575 // CHECK: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
576 // CHECK-HIDDEN: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
Rafael Espindola256fc4d2012-01-04 05:40:59 +0000577
578 template<class T> void Method() {}
Rafael Espindola093ecc92012-01-14 00:30:36 +0000579 template DEFAULT void Method<char>();
Rafael Espindola256fc4d2012-01-04 05:40:59 +0000580 // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv
581 // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv
Rafael Espindola0257b7f2012-01-03 06:04:21 +0000582}
Rafael Espindola093ecc92012-01-14 00:30:36 +0000583
584namespace PR11690_2 {
585 namespace foo DEFAULT {
586 class bar;
587 template<typename T1, typename T2 = bar>
588 class zed {
589 void bar() {
590 }
591 };
592 }
593 struct baz {
594 };
595 template class foo::zed<baz>;
596 // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
Rafael Espindola51183372012-04-22 12:37:27 +0000597
598 // FIXME: This should be hidden as baz is hidden.
599 // CHECK-HIDDEN: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
Rafael Espindola093ecc92012-01-14 00:30:36 +0000600}
Rafael Espindola860097c2012-02-23 04:17:32 +0000601
602namespace test23 {
603 // Having a template argument that is explicitly visible should not make
604 // the template instantiation visible.
605 template <typename T>
606 struct X {
607 static void f() {
608 }
609 };
610
611 class DEFAULT A;
612
613 void g() {
614 X<A> y;
615 y.f();
616 }
617 // CHECK: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv
618 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv
619}
620
621namespace PR12001 {
622 template <typename P1>
623 void Bind(const P1& p1) {
624 }
625
626 class DEFAULT Version { };
627
628 void f() {
629 Bind(Version());
630 }
631 // CHECK: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_
632 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_
633}
634
635namespace test24 {
636 class DEFAULT A { };
637
638 struct S {
639 template <typename T>
640 void mem() {}
641 };
642
643 void test() {
644 S s;
645 s.mem<A>();
646 }
647 // CHECK: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv
648 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv
649}
650
651namespace test26 {
652 template<typename T>
653 class C {
654 __attribute__((visibility("default"))) void f();
655 };
656
657 template<>
658 void C<int>::f() { }
659
660 // CHECK: define void @_ZN6test261CIiE1fEv
661 // CHECK-HIDDEN: define void @_ZN6test261CIiE1fEv
662}
Rafael Espindolabc356d02012-04-22 01:22:25 +0000663
664namespace test31 {
665 struct A {
666 struct HIDDEN B {
667 static void DEFAULT baz();
668 };
669 };
670 void f() {
671 A::B::baz();
672 }
673 // CHECK: declare void @_ZN6test311A1B3bazEv()
674 // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv()
675}
Rafael Espindolaa77e0722012-04-22 02:41:22 +0000676
677namespace test32 {
678 struct HIDDEN A {
679 struct DEFAULT B {
680 void DEFAULT baz();
681 };
682 };
683 void A::B::baz() {
684 }
685 // CHECK: define void @_ZN6test321A1B3bazEv
686 // CHECK-HIDDEN: define void @_ZN6test321A1B3bazEv
687}
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000688
689namespace test33 {
690 template<typename T>
691 class foo {
692 void bar() {}
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000693 };
Rafael Espindola71776ef2012-04-22 16:03:00 +0000694 struct HIDDEN zed {
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000695 };
Rafael Espindola71776ef2012-04-22 16:03:00 +0000696 template class DEFAULT foo<zed>;
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000697 // CHECK: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
698 // CHECK-HIDDEN: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
699}
Rafael Espindolaa5416bd2012-04-22 22:31:25 +0000700
701namespace test34 {
702 struct foo {
703 };
704 template<class T>
705 void bar() {}
706 template DEFAULT void bar<foo>();
707 // CHECK: define weak_odr void @_ZN6test343barINS_3fooEEEvv
708 // CHECK-HIDDEN: define weak_odr void @_ZN6test343barINS_3fooEEEvv
709}
Rafael Espindola546ee6d2012-04-23 14:02:53 +0000710
711namespace test35 {
712 // This is a really ugly testcase. GCC propagates the DEFAULT in zed's
713 // definition. What we do instead is be conservative about merging
714 // implicit visibilities.
715 // FIXME: Maybe the best thing to do here is error? The test at least
716 // makes sure we don't produce a hidden symbol for foo<zed>::bar.
717 template<typename T>
718 struct DEFAULT foo {
719 void bar() {}
720 };
721 class zed;
722 template class foo<zed>;
723 class DEFAULT zed {
724 };
725 // CHECK: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv
726 // CHECK-HIDDEN: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv
727}
Rafael Espindola923b0c92012-04-23 17:51:55 +0000728
729namespace test36 {
730 template<typename T1, typename T2>
731 class foo {
732 void bar() {}
733 };
734 class DEFAULT S1 {};
735 struct HIDDEN S2 {};
736 template class foo<S1, S2>;
737 // CHECK: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
738 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
739}
Rafael Espindola31c195a2012-05-15 14:09:55 +0000740
741namespace test37 {
742 struct HIDDEN foo {
743 };
744 template<class T>
745 DEFAULT void bar() {}
746 template DEFAULT void bar<foo>();
747 // CHECK: define weak_odr void @_ZN6test373barINS_3fooEEEvv
748 // CHECK-HIDDEN: define weak_odr void @_ZN6test373barINS_3fooEEEvv
749}
750
751namespace test38 {
752 template<typename T>
753 class DEFAULT foo {
754 void bar() {}
755 };
756 struct HIDDEN zed {
757 };
758 template class foo<zed>;
759 // CHECK: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
760 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
761}
762
763namespace test39 {
764 class DEFAULT default_t;
765 class HIDDEN hidden_t;
766 template <class T> class A {
767 template <class U> class B {
768 HIDDEN void hidden() {}
769 void noattr() {}
770 template <class V> void temp() {}
771 };
772 };
773 template class DEFAULT A<hidden_t>;
774 template class DEFAULT A<hidden_t>::B<hidden_t>;
775 template void A<hidden_t>::B<hidden_t>::temp<default_t>();
776 template void A<hidden_t>::B<hidden_t>::temp<hidden_t>();
777
778 // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
779 // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
780 // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
781
782 // GCC produces a default for this one. Why?
783 // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
784
785 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
786 // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
787 // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
788
789 // GCC produces a default for this one. Why?
790 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
791}
Rafael Espindola0b0ad0a2012-05-21 20:15:56 +0000792
793namespace test42 {
794 struct HIDDEN foo {
795 };
796 template <class P>
797 struct bar {
798 };
799 template <>
800 struct HIDDEN bar<foo> {
801 DEFAULT static void zed();
802 };
803 void bar<foo>::zed() {
804 }
805 // CHECK: define hidden void @_ZN6test423barINS_3fooEE3zedEv
806 // CHECK-HIDDEN: define hidden void @_ZN6test423barINS_3fooEE3zedEv
807}
Rafael Espindolacae1c622012-05-21 20:31:27 +0000808
809namespace test43 {
810 struct HIDDEN foo {
811 };
812 template <class P>
813 void bar() {
814 }
815 template <>
816 DEFAULT void bar<foo>() {
817 }
818 // CHECK: define hidden void @_ZN6test433barINS_3fooEEEvv
819 // CHECK-HIDDEN: define hidden void @_ZN6test433barINS_3fooEEEvv
820}
Rafael Espindolaad359be2012-05-25 14:47:05 +0000821
822namespace test44 {
823 template <typename T>
824 struct foo {
825 foo() {}
826 };
827 namespace {
828 struct bar;
829 }
830 template struct DEFAULT foo<bar>;
831 foo<bar> x;
832 // CHECK: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
833 // CHECK-HIDDEN: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
834}
Rafael Espindola20831e22012-05-25 15:51:26 +0000835
836namespace test45 {
837 template <typename T>
838 struct foo {
839 template <typename T2>
840 struct bar {
841 bar() {};
842 };
843 };
844 namespace {
845 struct zed;
846 }
847 template struct DEFAULT foo<int>::bar<zed>;
848 foo<int>::bar<zed> x;
849 // CHECK: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
850 // CHECK-HIDDEN: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
851}
Rafael Espindola9db614f2012-05-25 16:41:35 +0000852
853namespace test46 {
854 template <typename T>
855 void foo() {
856 }
857 namespace {
858 struct bar;
859 }
860 template DEFAULT void foo<bar>();
861 void zed() {
862 foo<bar>();
863 }
864 // CHECK: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
865 // CHECK-HIDDEN: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
866}
Rafael Espindola41be8cd2012-05-25 17:22:33 +0000867
868namespace test47 {
869 struct foo {
870 template <typename T>
871 static void bar() {
872 }
873 };
874 namespace {
875 struct zed;
876 }
877 template __attribute__((visibility("default"))) void foo::bar<zed>();
878 void baz() {
879 foo::bar<zed>();
880 }
881 // CHECK: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
882 // CHECK-HIDDEN: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
883}