blob: 87add446ba7b998030e252fca124f4868b355196 [file] [log] [blame]
Rafael Espindolaedb4b622012-06-11 14:29:58 +00001// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2// RUN: %clang_cc1 %s -std=c++11 -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 };
Rafael Espindolab58f8102013-02-26 23:24:59 +000050 DEFAULT extern RECT data_rect;
Rafael Espindolac7e60602012-04-19 05:50:08 +000051 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.
Rafael Espindolab58f8102013-02-26 23:24:59 +000073 struct HIDDEN foo {};
Rafael Espindola2de54fc2012-05-21 14:22:37 +000074 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
Rafael Espindolaedb4b622012-06-11 14:29:58 +000082namespace test48 {
83 // Test that we use the visibility of struct foo when instantiating the
84 // template. Note that is a case where we disagree with gcc, it produces
85 // a default symbol.
86 struct HIDDEN foo {
87 };
88 DEFAULT foo x;
89
90 struct bar {
91 template<foo *z>
92 struct zed {
93 };
94 };
95
96 bar::zed<&x> y;
97 // CHECK: _ZN6test481yE = hidden global
98 // CHECK-HIDDEN: _ZN6test481yE = hidden global
99}
100
Anders Carlsson39de84d2010-02-07 01:44:36 +0000101// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
John McCall1fb0caa2010-10-22 21:05:15 +0000102// CHECK: @_ZN5Test71aE = hidden global
103// CHECK: @_ZN5Test71bE = global
John McCallac65c622010-10-26 04:59:26 +0000104// CHECK: @test9_var = global
105// CHECK-HIDDEN: @test9_var = global
John McCall110e8e52010-10-29 22:22:43 +0000106// CHECK: @_ZN6Test121A6hiddenE = external hidden global
107// CHECK: @_ZN6Test121A7visibleE = external global
108// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
109// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
110// CHECK: @_ZN6Test131B1aE = hidden global
111// CHECK: @_ZN6Test131C1aE = global
112// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
113// CHECK-HIDDEN: @_ZN6Test131C1aE = global
114// CHECK: @_ZN6Test143varE = external global
115// CHECK-HIDDEN: @_ZN6Test143varE = external global
John McCallee301022010-10-30 09:18:49 +0000116// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
117// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
Rafael Espindola860097c2012-02-23 04:17:32 +0000118
119namespace test27 {
120 template<typename T>
121 class C {
Rafael Espindolab58f8102013-02-26 23:24:59 +0000122 class DEFAULT D {
Rafael Espindola860097c2012-02-23 04:17:32 +0000123 void f();
124 };
125 };
126
127 template<>
128 class C<int>::D {
129 virtual void g();
130 };
131
132 void C<int>::D::g() {
133 }
134 // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
135 // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
136}
137
John McCall112c9672010-11-02 21:04:24 +0000138// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
139// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
140// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
141// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
Rafael Espindolacd3ac4b2011-01-15 08:23:14 +0000142// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
Peter Collingbournebf1c5ae2011-09-26 01:56:36 +0000143// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
Anders Carlssonf502d932011-01-24 00:46:19 +0000144// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
John McCall1fb0caa2010-10-22 21:05:15 +0000145
Anders Carlsson39de84d2010-02-07 01:44:36 +0000146namespace Test1 {
147 // CHECK: define hidden void @_ZN5Test11fEv
148 void HIDDEN f() { }
149
150}
151
152namespace Test2 {
153 struct HIDDEN A {
154 void f();
155 };
156
157 // A::f is a member function of a hidden class.
158 // CHECK: define hidden void @_ZN5Test21A1fEv
159 void A::f() { }
160}
161
162namespace Test3 {
163 struct HIDDEN A {
164 struct B {
165 void f();
166 };
167 };
168
169 // B is a nested class where its parent class is hidden.
170 // CHECK: define hidden void @_ZN5Test31A1B1fEv
171 void A::B::f() { }
172}
173
174namespace Test4 HIDDEN {
175 int VariableInHiddenNamespace = 10;
176
177 // Test4::g is in a hidden namespace.
178 // CHECK: define hidden void @_ZN5Test41gEv
179 void g() { }
180
181 struct DEFAULT A {
182 void f();
183 };
184
185 // A has default visibility.
186 // CHECK: define void @_ZN5Test41A1fEv
187 void A::f() { }
188}
189
190namespace Test5 {
191
192 namespace NS HIDDEN {
193 // f is in NS which is hidden.
194 // CHECK: define hidden void @_ZN5Test52NS1fEv()
195 void f() { }
196 }
197
198 namespace NS {
199 // g is in NS, but this NS decl is not hidden.
200 // CHECK: define void @_ZN5Test52NS1gEv
201 void g() { }
202 }
203}
Douglas Gregorc66bcfd2010-06-14 23:41:45 +0000204
205// <rdar://problem/8091955>
206namespace Test6 {
207 struct HIDDEN foo {
208 foo() { }
209 void bonk();
210 virtual void bar() = 0;
211
212 virtual void zonk() {}
213 };
214
215 struct barc : public foo {
216 barc();
217 virtual void bar();
218 };
219
220 barc::barc() {}
221}
John McCall1fb0caa2010-10-22 21:05:15 +0000222
223namespace Test7 {
224 class HIDDEN A {};
225 A a; // top of file
226
227 template <A&> struct Aref {
228 static void foo() {}
229 };
230
231 class B : public A {};
232 B b; // top of file
233
234 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
235 void test() {
236 Aref<a>::foo();
237 }
238}
239
240namespace Test8 {
241 void foo();
242 void bar() {}
243 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
244 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
245
246 void test() {
247 foo();
248 bar();
249 }
250}
John McCallac65c622010-10-26 04:59:26 +0000251
252// PR8457
253namespace Test9 {
254 extern "C" {
255 struct A { int field; };
256 void DEFAULT test9_fun(struct A *a) { }
257 struct A DEFAULT test9_var; // above
258 }
259 // CHECK: define void @test9_fun(
260 // CHECK-HIDDEN: define void @test9_fun(
261
262 void test() {
263 A a = test9_var;
264 test9_fun(&a);
265 }
266}
John McCall67fa6d52010-10-28 07:07:52 +0000267
268// PR8478
269namespace Test10 {
270 struct A;
271
Eli Friedmanfc038e92011-12-17 00:36:09 +0000272 class DEFAULT B {
John McCall67fa6d52010-10-28 07:07:52 +0000273 void foo(A*);
274 };
275
276 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
277 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
278 void B::foo(A*) {}
279}
John McCall0df95872010-10-29 00:29:13 +0000280
281// PR8492
282namespace Test11 {
283 struct A {
284 void foo() {}
285 void DEFAULT bar() {}
286 };
287
288 void test() {
289 A a;
290 a.foo();
291 a.bar();
292 }
293
294 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
295 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
296 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
297 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
298}
John McCall110e8e52010-10-29 22:22:43 +0000299
300// Tested at top of file.
301namespace Test12 {
302 struct A {
303 // This is hidden in all cases: the explicit attribute takes
304 // priority over -fvisibility on the parent.
305 static int hidden HIDDEN;
306
307 // This is default in all cases because it's only a declaration.
308 static int visible;
309 };
310
311 void test() {
312 A::hidden = 0;
313 A::visible = 0;
314 }
315}
316
317// Tested at top of file.
318namespace Test13 {
319 struct HIDDEN A {};
320
321 // Should be hidden in all cases.
322 struct B {
323 static A a;
324 };
325 A B::a;
326
327 // Should be default in all cases.
328 struct DEFAULT C {
329 static A a;
330 };
331 A C::a;
332};
333
334// Tested at top of file.
335namespace Test14 {
336 // Neither the visibility of the type nor -fvisibility=hidden should
337 // apply to declarations.
338 extern struct A *var;
339
340 struct A *test() { return var; }
341}
John McCallee301022010-10-30 09:18:49 +0000342
343// rdar://problem/8613093
344namespace Test15 {
345 struct A {};
346 template <class T> struct Temp {
347 struct Inner {
348 static char buffer[0];
349 };
350 };
351
352 char *test() {
353 return Temp<A>::Inner::buffer;
354 }
355}
John McCallaf146032010-10-30 11:50:40 +0000356
357namespace Test16 {
358 struct Base1 { virtual void foo(); };
359 struct Base2 : virtual Base1 { virtual void foo(); };
360 template <class T> struct A : virtual Base1, Base2 {
361 virtual void foo();
362 };
363 extern template struct A<char>;
364
365 void test() {
366 A<char> a;
367 a.foo();
368 }
369}
John McCall36987482010-11-02 01:45:15 +0000370
371namespace Test17 {
372 struct HIDDEN A {
373 static void foo();
374 static void DEFAULT bar();
375 static void HIDDEN baz();
376
377 struct DEFAULT B {
378 static void foo();
379 static void DEFAULT bar();
380 static void HIDDEN baz();
381 };
382 };
383
384 void test() {
385 A::foo();
386 A::bar();
387 A::baz();
388 A::B::foo();
389 A::B::bar();
390 A::B::baz();
391 }
392 // CHECK: declare hidden void @_ZN6Test171A3fooEv()
393 // CHECK: declare void @_ZN6Test171A3barEv()
394 // CHECK: declare hidden void @_ZN6Test171A3bazEv()
395 // CHECK: declare void @_ZN6Test171A1B3fooEv()
396 // CHECK: declare void @_ZN6Test171A1B3barEv()
397 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
398 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
399 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
400 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
401 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
402 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
403 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
404}
405
406namespace Test18 {
407 template <class T> struct HIDDEN A {
408 static void foo();
409 static void DEFAULT bar();
410 static void HIDDEN baz();
411
412 struct DEFAULT B {
413 static void foo();
414 static void DEFAULT bar();
415 static void HIDDEN baz();
416 };
417 };
418 struct HIDDEN H;
419
420 void test() {
421 A<int>::foo();
422 A<int>::bar();
423 A<int>::baz();
424 A<int>::B::foo();
425 A<int>::B::bar();
426 A<int>::B::baz();
427 A<H>::foo();
428 A<H>::bar();
429 A<H>::baz();
430 A<H>::B::foo();
431 A<H>::B::bar();
432 A<H>::B::baz();
433 }
434 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
435 // CHECK: declare void @_ZN6Test181AIiE3barEv()
436 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
437 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
438 // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
439 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
440 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
441 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
442 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
443 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
444 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
445 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
446 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
447 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
448 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
449 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
450 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
451 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
452 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
453 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
454 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
455 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
456 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
457 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
458}
John McCall112c9672010-11-02 21:04:24 +0000459
460namespace Test19 {
461 struct A { A(); ~A(); };
462
463 // Tested at top of file.
464 template <class T> void foo() {
465 static A a;
466 }
467
468 void test() {
469 foo<int>();
470 }
471}
John McCall7f1b9872010-12-18 03:30:47 +0000472
473// Various things with class template specializations.
474namespace Test20 {
475 template <unsigned> struct HIDDEN A {};
476
477 // An explicit specialization inherits the explicit visibility of
478 // the template.
479 template <> struct A<0> {
480 static void test0();
481 static void test1();
482 };
483
484 // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
485 void A<0>::test0() {}
486
487 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
488 void test1() {
489 A<0>::test1();
490 }
491
492 // ...unless that's explicitly overridden.
493 template <> struct DEFAULT A<1> {
494 static void test2();
495 static void test3();
496 };
497
498 // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
499 void A<1>::test2() {}
500
501 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
502 void test3() {
503 A<1>::test3();
504 }
505
506 // <rdar://problem/8778497>
507 // But we should assume that an unknown specialization has the
508 // explicit visibility settings of the template.
509 template <class T> struct B {
510 static void test4() {}
511 static void test5();
512 };
513
514 // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
515 void test4() {
516 B<A<2> >::test4();
517 }
518
Rafael Espindola093ecc92012-01-14 00:30:36 +0000519 // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
John McCall7f1b9872010-12-18 03:30:47 +0000520 void test5() {
521 B<A<2> >::test5();
522 }
523}
John McCall1a0918a2011-03-04 10:39:25 +0000524
525// PR9371
526namespace test21 {
527 enum En { en };
528 template<En> struct A {
Rafael Espindolab58f8102013-02-26 23:24:59 +0000529 DEFAULT void foo() {}
John McCall1a0918a2011-03-04 10:39:25 +0000530 };
531
532 // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
533 template void A<en>::foo();
534}
John McCall6ce51ee2011-06-27 23:06:04 +0000535
536// rdar://problem/9616154
537// Visibility on explicit specializations should take precedence.
538namespace test22 {
539 class A1 {};
540 class A2 {};
541
542 template <class T> struct B {};
543 template <> struct DEFAULT B<A1> {
544 static void foo();
545 static void bar() {}
546 };
547 template <> struct B<A2> {
548 static void foo();
549 static void bar() {}
550 };
551
552 void test() {
553 B<A1>::foo();
554 B<A1>::bar();
555 B<A2>::foo();
556 B<A2>::bar();
557 }
558 // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
559 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
560 // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
561 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
562 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
563 // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
564 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
565 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
566}
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000567
568namespace PR10113 {
Rafael Espindolab5d763d2012-01-02 06:26:22 +0000569 namespace foo DEFAULT {
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000570 template<typename T>
571 class bar {
572 void zed() {}
573 };
574 }
575 template class foo::bar<char>;
576 // CHECK: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
577 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
Rafael Espindola093ecc92012-01-14 00:30:36 +0000578
579 struct zed {
580 };
581 template class foo::bar<zed>;
582 // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
John McCall5a758de2013-02-16 00:17:33 +0000583 // CHECK-HIDDEN: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv
Rafael Espindola71cb8a22012-01-01 18:06:40 +0000584}
Rafael Espindola0257b7f2012-01-03 06:04:21 +0000585
586namespace PR11690 {
587 template<class T> struct Class {
588 void size() const {
589 }
590 };
591 template class DEFAULT Class<char>;
592 // CHECK: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
593 // CHECK-HIDDEN: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
Rafael Espindola256fc4d2012-01-04 05:40:59 +0000594
595 template<class T> void Method() {}
Rafael Espindola093ecc92012-01-14 00:30:36 +0000596 template DEFAULT void Method<char>();
Rafael Espindola256fc4d2012-01-04 05:40:59 +0000597 // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv
598 // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv
Rafael Espindola0257b7f2012-01-03 06:04:21 +0000599}
Rafael Espindola093ecc92012-01-14 00:30:36 +0000600
601namespace PR11690_2 {
602 namespace foo DEFAULT {
603 class bar;
604 template<typename T1, typename T2 = bar>
605 class zed {
606 void bar() {
607 }
608 };
609 }
610 struct baz {
611 };
612 template class foo::zed<baz>;
613 // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
John McCall5a758de2013-02-16 00:17:33 +0000614 // CHECK-HIDDEN: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
Rafael Espindola093ecc92012-01-14 00:30:36 +0000615}
Rafael Espindola860097c2012-02-23 04:17:32 +0000616
617namespace test23 {
618 // Having a template argument that is explicitly visible should not make
619 // the template instantiation visible.
620 template <typename T>
621 struct X {
622 static void f() {
623 }
624 };
625
626 class DEFAULT A;
627
628 void g() {
629 X<A> y;
630 y.f();
631 }
632 // CHECK: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv
633 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv
634}
635
636namespace PR12001 {
637 template <typename P1>
638 void Bind(const P1& p1) {
639 }
640
641 class DEFAULT Version { };
642
643 void f() {
644 Bind(Version());
645 }
646 // CHECK: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_
647 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_
648}
649
650namespace test24 {
651 class DEFAULT A { };
652
653 struct S {
654 template <typename T>
655 void mem() {}
656 };
657
658 void test() {
659 S s;
660 s.mem<A>();
661 }
662 // CHECK: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv
663 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv
664}
665
666namespace test26 {
667 template<typename T>
668 class C {
Rafael Espindolab58f8102013-02-26 23:24:59 +0000669 DEFAULT void f();
Rafael Espindola860097c2012-02-23 04:17:32 +0000670 };
671
672 template<>
673 void C<int>::f() { }
674
675 // CHECK: define void @_ZN6test261CIiE1fEv
676 // CHECK-HIDDEN: define void @_ZN6test261CIiE1fEv
677}
Rafael Espindolabc356d02012-04-22 01:22:25 +0000678
679namespace test31 {
680 struct A {
681 struct HIDDEN B {
682 static void DEFAULT baz();
683 };
684 };
685 void f() {
686 A::B::baz();
687 }
688 // CHECK: declare void @_ZN6test311A1B3bazEv()
689 // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv()
690}
Rafael Espindolaa77e0722012-04-22 02:41:22 +0000691
692namespace test32 {
693 struct HIDDEN A {
694 struct DEFAULT B {
695 void DEFAULT baz();
696 };
697 };
698 void A::B::baz() {
699 }
700 // CHECK: define void @_ZN6test321A1B3bazEv
701 // CHECK-HIDDEN: define void @_ZN6test321A1B3bazEv
702}
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000703
704namespace test33 {
705 template<typename T>
706 class foo {
707 void bar() {}
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000708 };
Rafael Espindola71776ef2012-04-22 16:03:00 +0000709 struct HIDDEN zed {
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000710 };
Rafael Espindola71776ef2012-04-22 16:03:00 +0000711 template class DEFAULT foo<zed>;
Rafael Espindolaf6a8b9c2012-04-22 15:31:59 +0000712 // CHECK: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
713 // CHECK-HIDDEN: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
714}
Rafael Espindolaa5416bd2012-04-22 22:31:25 +0000715
716namespace test34 {
717 struct foo {
718 };
719 template<class T>
720 void bar() {}
721 template DEFAULT void bar<foo>();
722 // CHECK: define weak_odr void @_ZN6test343barINS_3fooEEEvv
723 // CHECK-HIDDEN: define weak_odr void @_ZN6test343barINS_3fooEEEvv
724}
Rafael Espindola546ee6d2012-04-23 14:02:53 +0000725
726namespace test35 {
727 // This is a really ugly testcase. GCC propagates the DEFAULT in zed's
John McCall5a758de2013-02-16 00:17:33 +0000728 // definition. It's not really clear what we can do here, because we
729 // produce the symbols before even seeing the DEFAULT definition of zed.
730 // FIXME: Maybe the best thing to do here is error? It's certainly hard
731 // to argue that this ought to be valid.
Rafael Espindola546ee6d2012-04-23 14:02:53 +0000732 template<typename T>
733 struct DEFAULT foo {
734 void bar() {}
735 };
736 class zed;
737 template class foo<zed>;
738 class DEFAULT zed {
739 };
740 // CHECK: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv
John McCall5a758de2013-02-16 00:17:33 +0000741 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test353fooINS_3zedEE3barEv
Rafael Espindola546ee6d2012-04-23 14:02:53 +0000742}
Rafael Espindola923b0c92012-04-23 17:51:55 +0000743
744namespace test36 {
745 template<typename T1, typename T2>
746 class foo {
747 void bar() {}
748 };
749 class DEFAULT S1 {};
750 struct HIDDEN S2 {};
751 template class foo<S1, S2>;
752 // CHECK: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
753 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
754}
Rafael Espindola31c195a2012-05-15 14:09:55 +0000755
756namespace test37 {
757 struct HIDDEN foo {
758 };
759 template<class T>
760 DEFAULT void bar() {}
761 template DEFAULT void bar<foo>();
762 // CHECK: define weak_odr void @_ZN6test373barINS_3fooEEEvv
763 // CHECK-HIDDEN: define weak_odr void @_ZN6test373barINS_3fooEEEvv
764}
765
766namespace test38 {
767 template<typename T>
768 class DEFAULT foo {
769 void bar() {}
770 };
771 struct HIDDEN zed {
772 };
773 template class foo<zed>;
774 // CHECK: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
775 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
776}
777
778namespace test39 {
779 class DEFAULT default_t;
780 class HIDDEN hidden_t;
781 template <class T> class A {
782 template <class U> class B {
783 HIDDEN void hidden() {}
784 void noattr() {}
785 template <class V> void temp() {}
786 };
787 };
788 template class DEFAULT A<hidden_t>;
789 template class DEFAULT A<hidden_t>::B<hidden_t>;
790 template void A<hidden_t>::B<hidden_t>::temp<default_t>();
791 template void A<hidden_t>::B<hidden_t>::temp<hidden_t>();
792
793 // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
794 // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
795 // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
796
797 // GCC produces a default for this one. Why?
798 // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
799
800 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
801 // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
802 // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
803
804 // GCC produces a default for this one. Why?
805 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
806}
Rafael Espindola0b0ad0a2012-05-21 20:15:56 +0000807
808namespace test42 {
809 struct HIDDEN foo {
810 };
811 template <class P>
812 struct bar {
813 };
814 template <>
815 struct HIDDEN bar<foo> {
816 DEFAULT static void zed();
817 };
818 void bar<foo>::zed() {
819 }
John McCall5a758de2013-02-16 00:17:33 +0000820 // CHECK: define void @_ZN6test423barINS_3fooEE3zedEv
821 // CHECK-HIDDEN: define void @_ZN6test423barINS_3fooEE3zedEv
Rafael Espindola0b0ad0a2012-05-21 20:15:56 +0000822}
Rafael Espindolacae1c622012-05-21 20:31:27 +0000823
824namespace test43 {
825 struct HIDDEN foo {
826 };
827 template <class P>
828 void bar() {
829 }
830 template <>
831 DEFAULT void bar<foo>() {
832 }
John McCall5a758de2013-02-16 00:17:33 +0000833 // CHECK: define void @_ZN6test433barINS_3fooEEEvv
834 // CHECK-HIDDEN: define void @_ZN6test433barINS_3fooEEEvv
Rafael Espindolacae1c622012-05-21 20:31:27 +0000835}
Rafael Espindolaad359be2012-05-25 14:47:05 +0000836
837namespace test44 {
838 template <typename T>
839 struct foo {
840 foo() {}
841 };
842 namespace {
843 struct bar;
844 }
845 template struct DEFAULT foo<bar>;
846 foo<bar> x;
847 // CHECK: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
848 // CHECK-HIDDEN: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
849}
Rafael Espindola20831e22012-05-25 15:51:26 +0000850
851namespace test45 {
852 template <typename T>
853 struct foo {
854 template <typename T2>
855 struct bar {
856 bar() {};
857 };
858 };
859 namespace {
860 struct zed;
861 }
862 template struct DEFAULT foo<int>::bar<zed>;
863 foo<int>::bar<zed> x;
864 // CHECK: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
865 // CHECK-HIDDEN: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
866}
Rafael Espindola9db614f2012-05-25 16:41:35 +0000867
868namespace test46 {
869 template <typename T>
870 void foo() {
871 }
872 namespace {
873 struct bar;
874 }
875 template DEFAULT void foo<bar>();
876 void zed() {
877 foo<bar>();
878 }
879 // CHECK: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
880 // CHECK-HIDDEN: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
881}
Rafael Espindola41be8cd2012-05-25 17:22:33 +0000882
883namespace test47 {
884 struct foo {
885 template <typename T>
886 static void bar() {
887 }
888 };
889 namespace {
890 struct zed;
891 }
Rafael Espindolab58f8102013-02-26 23:24:59 +0000892 template DEFAULT void foo::bar<zed>();
Rafael Espindola41be8cd2012-05-25 17:22:33 +0000893 void baz() {
894 foo::bar<zed>();
895 }
896 // CHECK: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
897 // CHECK-HIDDEN: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
898}
Rafael Espindolaedb4b622012-06-11 14:29:58 +0000899
900namespace test49 {
901 // Test that we use the visibility of struct foo when instantiating the
902 // template. Note that is a case where we disagree with gcc, it produces
903 // a default symbol.
904
905 struct HIDDEN foo {
906 };
907
908 DEFAULT foo x;
909
910 struct bar {
911 template<foo *z>
912 void zed() {
913 }
914 };
915
916 template void bar::zed<&x>();
917 // CHECK: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
918 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
919}
920
921namespace test50 {
922 // Test that we use the visibility of struct foo when instantiating the
923 // template. Note that is a case where we disagree with gcc, it produces
924 // a default symbol.
925
926 struct HIDDEN foo {
927 };
928 DEFAULT foo x;
929 template<foo *z>
930 struct DEFAULT bar {
931 void zed() {
932 }
933 };
934 template void bar<&x>::zed();
935 // CHECK: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
936 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
937}
938
939namespace test51 {
940 // Test that we use the visibility of struct foo when instantiating the
941 // template. Note that is a case where we disagree with gcc, it produces
942 // a default symbol.
943
944 struct HIDDEN foo {
945 };
946 DEFAULT foo x;
947 template<foo *z>
948 void DEFAULT zed() {
949 }
950 template void zed<&x>();
951 // CHECK: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
952 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
953}
954
955namespace test52 {
956 // Test that we use the linkage of struct foo when instantiating the
957 // template. Note that is a case where we disagree with gcc, it produces
958 // an external symbol.
959
960 namespace {
961 struct foo {
962 };
963 }
964 template<foo *x>
965 void zed() {
966 }
967 void f() {
968 zed<nullptr>();
969 }
970 // CHECK: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
971 // CHECK-HIDDEN: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
972}
Rafael Espindolaf2f15b32012-07-11 02:15:51 +0000973
974namespace test53 {
975 template<typename _Tp > struct vector {
976 static void _M_fill_insert();
977 };
978#pragma GCC visibility push(hidden)
Rafael Espindola8d719182012-07-11 18:14:09 +0000979 // GCC doesn't seem to use the visibility of enums at all, we do.
980 enum zed {v1};
981
982 // GCC fails to mark this specialization hidden, we mark it.
983 template<>
984 struct vector<int> {
985 static void _M_fill_insert();
986 };
Rafael Espindolaf2f15b32012-07-11 02:15:51 +0000987 void foo() {
988 vector<unsigned>::_M_fill_insert();
Rafael Espindola8d719182012-07-11 18:14:09 +0000989 vector<int>::_M_fill_insert();
990 vector<zed>::_M_fill_insert();
Rafael Espindolaf2f15b32012-07-11 02:15:51 +0000991 }
992#pragma GCC visibility pop
993 // CHECK: declare void @_ZN6test536vectorIjE14_M_fill_insertEv
994 // CHECK-HIDDEN: declare void @_ZN6test536vectorIjE14_M_fill_insertEv
Rafael Espindola8d719182012-07-11 18:14:09 +0000995 // CHECK: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv
996 // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv
997 // CHECK: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv
998 // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv
Rafael Espindolaf2f15b32012-07-11 02:15:51 +0000999}
Rafael Espindola5e065292012-07-12 04:47:34 +00001000
1001namespace test54 {
1002 template <class T>
1003 struct foo {
1004 static void bar();
1005 };
1006#pragma GCC visibility push(hidden)
1007 class zed {
1008 zed(const zed &);
1009 };
1010 void bah() {
1011 foo<zed>::bar();
1012 }
1013#pragma GCC visibility pop
1014 // CHECK: declare hidden void @_ZN6test543fooINS_3zedEE3barEv
1015 // CHECK-HIDDEN: declare hidden void @_ZN6test543fooINS_3zedEE3barEv
1016}
Rafael Espindola23458202012-07-12 20:05:04 +00001017
1018namespace test55 {
1019 template <class T>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001020 struct HIDDEN foo {
Rafael Espindola23458202012-07-12 20:05:04 +00001021 static void bar();
1022 };
1023 template <class T> struct foo;
1024 void foobar() {
1025 foo<int>::bar();
1026 }
1027 // CHECK: declare hidden void @_ZN6test553fooIiE3barEv
1028 // CHECK-HIDDEN: declare hidden void @_ZN6test553fooIiE3barEv
1029}
Rafael Espindolad3d02dd2012-07-13 01:19:08 +00001030
1031namespace test56 {
1032 template <class T> struct foo;
1033 template <class T>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001034 struct HIDDEN foo {
Rafael Espindolad3d02dd2012-07-13 01:19:08 +00001035 static void bar();
1036 };
1037 void foobar() {
1038 foo<int>::bar();
1039 }
1040 // CHECK: declare hidden void @_ZN6test563fooIiE3barEv
1041 // CHECK-HIDDEN: declare hidden void @_ZN6test563fooIiE3barEv
1042}
Rafael Espindola6b603702012-07-13 18:04:45 +00001043
1044namespace test57 {
1045#pragma GCC visibility push(hidden)
1046 template <class T>
1047 struct foo;
1048 void bar(foo<int>*);
1049 template <class T>
1050 struct foo {
1051 static void zed();
1052 };
1053 void bah() {
1054 foo<int>::zed();
1055 }
1056#pragma GCC visibility pop
1057 // CHECK: declare hidden void @_ZN6test573fooIiE3zedEv
1058 // CHECK-HIDDEN: declare hidden void @_ZN6test573fooIiE3zedEv
1059}
Rafael Espindolabecfc232012-07-17 04:22:25 +00001060
1061namespace test58 {
1062#pragma GCC visibility push(hidden)
1063 struct foo;
1064 template<typename T>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001065 struct DEFAULT bar {
Rafael Espindolabecfc232012-07-17 04:22:25 +00001066 static void zed() {
1067 }
1068 };
1069 void bah() {
1070 bar<foo>::zed();
1071 }
1072#pragma GCC visibility pop
1073 // CHECK: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
1074 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
1075}
Rafael Espindola6d4a40e2012-07-28 02:51:03 +00001076
1077namespace test59 {
1078 DEFAULT int f();
1079 HIDDEN int g();
1080 typedef int (*foo)();
1081 template<foo x, foo y>
1082 void test() {}
1083 void use() {
1084 test<&g, &f>();
1085 // CHECK: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
1086 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
1087
1088 test<&f, &g>();
1089 // CHECK: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
1090 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
1091 }
1092}
Rafael Espindola98499012012-07-31 19:02:02 +00001093
1094namespace test60 {
1095 template<int i>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001096 class HIDDEN a {};
Rafael Espindola98499012012-07-31 19:02:02 +00001097 template<int i>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001098 class DEFAULT b {};
Rafael Espindola98499012012-07-31 19:02:02 +00001099 template<template<int> class x, template<int> class y>
1100 void test() {}
1101 void use() {
1102 test<a, b>();
1103 // CHECK: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
1104 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
1105
1106 test<b, a>();
1107 // CHECK: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
1108 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
1109 }
1110}
Rafael Espindola838dc592013-01-12 06:42:30 +00001111
1112namespace test61 {
1113 template <typename T1>
1114 struct Class1
1115 {
1116 void f1() { f2(); }
1117 inline void f2();
1118 };
1119 template<>
1120 inline void Class1<int>::f2()
1121 {
1122 }
1123 void g(Class1<int> *x) {
1124 x->f1();
1125 }
1126}
1127namespace test61 {
1128 // Just test that we don't crash. Currently we apply this attribute. Current
1129 // gcc issues a warning about it being unused since "the type is already
1130 // defined". We should probably do the same.
Rafael Espindolab58f8102013-02-26 23:24:59 +00001131 template class HIDDEN Class1<int>;
Rafael Espindola838dc592013-01-12 06:42:30 +00001132}
1133
1134namespace test62 {
1135 template <typename T1>
1136 struct Class1
1137 {
1138 void f1() { f2(); }
1139 inline void f2() {}
1140 };
1141 template<>
1142 inline void Class1<int>::f2()
1143 {
1144 }
1145 void g(Class1<int> *x) {
1146 x->f2();
1147 }
1148}
1149namespace test62 {
Rafael Espindolab58f8102013-02-26 23:24:59 +00001150 template class HIDDEN Class1<int>;
Rafael Espindola838dc592013-01-12 06:42:30 +00001151 // Just test that we don't crash. Currently we apply this attribute. Current
1152 // gcc issues a warning about it being unused since "the type is already
1153 // defined". We should probably do the same.
1154}
John McCall5a758de2013-02-16 00:17:33 +00001155
1156namespace test63 {
1157 enum HIDDEN E { E0 };
1158 struct A {
1159 template <E> static void foo() {}
1160
1161 template <E> struct B {
1162 static void foo() {}
1163 };
1164 };
1165
1166 void test() {
1167 A::foo<E0>();
1168 A::B<E0>::foo();
1169 }
1170 // CHECK: define linkonce_odr hidden void @_ZN6test631A3fooILNS_1EE0EEEvv()
1171 // CHECK: define linkonce_odr hidden void @_ZN6test631A1BILNS_1EE0EE3fooEv()
1172}
John McCalld4c3d662013-02-20 01:54:26 +00001173
1174// Don't ignore the visibility of template arguments just because we
1175// explicitly instantiated something.
1176namespace test64 {
1177 struct HIDDEN A {};
1178 template <class P> struct B {
1179 static DEFAULT void foo() {}
1180 };
1181
1182 template class B<A>;
1183 // CHECK: define weak_odr hidden void @_ZN6test641BINS_1AEE3fooEv()
1184}
John McCall3892d022013-02-21 23:42:58 +00001185
1186namespace test65 {
1187 class HIDDEN A {};
1188 template <class T> struct B {
1189 static void func();
1190 template <class U> static void funcT1();
1191 template <class U> static void funcT2();
1192 class Inner {};
1193 template <class U> class InnerT {};
1194 };
1195 template <template <class T> class Temp> struct C {
1196 static void foo() {}
1197 };
1198
1199 // CHECK: define void @_ZN6test651BINS_1AEE4funcEv()
1200 template <> DEFAULT void B<A>::func() {}
1201
1202 // CHECK: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv()
1203 template <> template <> DEFAULT void B<A>::funcT2<A>() {}
1204
1205 // CHECK: define linkonce_odr void @_ZN6test651BINS_1AEE6funcT1IiEEvv()
1206 // CHECK: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6funcT1IS1_EEvv()
1207 template <> template <class T> DEFAULT void B<A>::funcT1() {}
1208
1209 // CHECK: define linkonce_odr void @_ZN6test651BINS_1AEE5Inner3fooEv()
1210 template <> struct DEFAULT B<A>::Inner {
1211 static void foo() {}
1212 };
1213
1214 // CHECK: define linkonce_odr void @_ZN6test651BINS_1AEE6InnerTIiE3fooEv()
1215 // CHECK: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6InnerTIS1_E3fooEv()
1216 template <> template <class U> struct DEFAULT B<A>::InnerT {
1217 static void foo() {}
1218 };
1219
1220 void test() {
1221 B<A>::funcT1<int>();
1222 B<A>::funcT1<A>();
1223 B<A>::Inner::foo();
1224 B<A>::InnerT<int>::foo();
1225 B<A>::InnerT<A>::foo();
1226 }
1227
1228 template class C<B<A>::InnerT>;
1229}
Rafael Espindolad3b2f0a2013-02-26 19:33:14 +00001230
1231namespace test66 {
1232 template <typename T>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001233 struct DEFAULT barT {
Rafael Espindolad3b2f0a2013-02-26 19:33:14 +00001234 static void zed() {}
1235 };
1236 class foo;
Rafael Espindolab58f8102013-02-26 23:24:59 +00001237 class DEFAULT foo;
Rafael Espindolad3b2f0a2013-02-26 19:33:14 +00001238 template struct barT<foo>;
1239 // CHECK: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv
1240 // CHECK-HIDDEN: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv
1241
1242 template <int* I>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001243 struct DEFAULT barI {
Rafael Espindolad3b2f0a2013-02-26 19:33:14 +00001244 static void zed() {}
1245 };
1246 extern int I;
Rafael Espindolab58f8102013-02-26 23:24:59 +00001247 extern int I DEFAULT;
Rafael Espindolad3b2f0a2013-02-26 19:33:14 +00001248 template struct barI<&I>;
1249 // CHECK: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv
1250 // CHECK-HIDDEN: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv
1251
1252 typedef void (*fType)(void);
1253 template<fType F>
Rafael Espindolab58f8102013-02-26 23:24:59 +00001254 struct DEFAULT barF {
Rafael Espindolad3b2f0a2013-02-26 19:33:14 +00001255 static void zed() {}
1256 };
1257 void F();
Rafael Espindolab58f8102013-02-26 23:24:59 +00001258 void F() DEFAULT;
Rafael Espindolad3b2f0a2013-02-26 19:33:14 +00001259 template struct barF<F>;
1260 // CHECK: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv
1261 // CHECK-HIDDEN: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv
1262}
Rafael Espindolaa2bb8922013-02-27 04:15:01 +00001263
1264namespace test67 {
1265 template <typename T>
1266 struct DEFAULT bar {
1267 static void zed() {}
1268 };
1269
1270 class foo;
1271 class compute {
1272 void f(foo *rootfoo);
1273 };
1274 class DEFAULT foo;
1275
1276 template struct bar<foo>;
1277 // CHECK: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv
1278 // CHECK-HIDDEN: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv
1279}