visibility.cpp revision 20831e21ae00ee10e9d9d906f565a66f9fe1d2d1
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
3
4#define HIDDEN __attribute__((visibility("hidden")))
5#define PROTECTED __attribute__((visibility("protected")))
6#define DEFAULT __attribute__((visibility("default")))
7
8namespace 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
22namespace 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
37namespace test28 {
38  class DEFAULT foo {
39  };
40  foo myvec;
41  // CHECK: @_ZN6test285myvecE = global
42  // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global
43}
44
45namespace 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
57namespace 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
69namespace 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
82// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
83// CHECK: @_ZN5Test71aE = hidden global
84// CHECK: @_ZN5Test71bE = global
85// CHECK: @test9_var = global
86// CHECK-HIDDEN: @test9_var = global
87// 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
97// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
98// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
99
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
119// 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
123// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
124// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
125// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
126
127namespace 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}
185
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}
203
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}
232
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}
248
249// PR8478
250namespace Test10 {
251  struct A;
252
253  class DEFAULT B {
254    void foo(A*);
255  };
256
257  // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
258  // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
259  void B::foo(A*) {}
260}
261
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}
280
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}
323
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}
337
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}
351
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}
440
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}
453
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
500  // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
501  void test5() {
502    B<A<2> >::test5();
503  }
504}
505
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}
516
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}
548
549namespace PR10113 {
550  namespace foo DEFAULT {
551    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
559
560  struct zed {
561  };
562  template class foo::bar<zed>;
563  // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
564
565  // FIXME: This should be hidden as zed is hidden.
566  // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
567}
568
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
577
578  template<class T> void Method() {}
579  template  DEFAULT void Method<char>();
580  // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv
581  // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv
582}
583
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
597
598  // FIXME: This should be hidden as baz is hidden.
599  // CHECK-HIDDEN: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
600}
601
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}
663
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}
676
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}
688
689namespace test33 {
690  template<typename T>
691  class foo {
692    void bar() {}
693  };
694  struct HIDDEN zed {
695  };
696  template class DEFAULT foo<zed>;
697  // CHECK: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
698  // CHECK-HIDDEN: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
699}
700
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}
710
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}
728
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}
740
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}
792
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}
808
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}
821
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}
835
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}
852