1// 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
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  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 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
82namespace 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
101// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
102// CHECK: @_ZN5Test71aE = hidden global
103// CHECK: @_ZN5Test71bE = global
104// CHECK: @test9_var = global
105// CHECK-HIDDEN: @test9_var = global
106// 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
116// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
117// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
118
119namespace test27 {
120  template<typename T>
121  class C {
122    class DEFAULT D {
123      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
138// 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
142// CHECK: @_ZZN6test681fC1EvE4test = linkonce_odr global
143// CHECK: @_ZGVZN6test681fC1EvE4test = linkonce_odr global
144// CHECK-HIDDEN: @_ZZN6test681fC1EvE4test = linkonce_odr hidden global
145// CHECK-HIDDEN: @_ZGVZN6test681fC1EvE4test = linkonce_odr hidden global
146// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
147// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
148// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
149
150namespace Test1 {
151  // CHECK-LABEL: define hidden void @_ZN5Test11fEv
152  void HIDDEN f() { }
153
154}
155
156namespace Test2 {
157  struct HIDDEN A {
158    void f();
159  };
160
161  // A::f is a member function of a hidden class.
162  // CHECK-LABEL: define hidden void @_ZN5Test21A1fEv
163  void A::f() { }
164}
165
166namespace Test3 {
167  struct HIDDEN A {
168    struct B {
169      void f();
170    };
171  };
172
173  // B is a nested class where its parent class is hidden.
174  // CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv
175  void A::B::f() { }
176}
177
178namespace Test4 HIDDEN {
179  int VariableInHiddenNamespace = 10;
180
181  // Test4::g is in a hidden namespace.
182  // CHECK-LABEL: define hidden void @_ZN5Test41gEv
183  void g() { }
184
185  struct DEFAULT A {
186    void f();
187  };
188
189  // A has default visibility.
190  // CHECK-LABEL: define void @_ZN5Test41A1fEv
191  void A::f() { }
192}
193
194namespace Test5 {
195
196  namespace NS HIDDEN {
197    // f is in NS which is hidden.
198    // CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv()
199    void f() { }
200  }
201
202  namespace NS {
203    // g is in NS, but this NS decl is not hidden.
204    // CHECK-LABEL: define void @_ZN5Test52NS1gEv
205    void g() { }
206  }
207}
208
209// <rdar://problem/8091955>
210namespace Test6 {
211  struct HIDDEN foo {
212    foo() { }
213    void bonk();
214    virtual void bar() = 0;
215
216    virtual void zonk() {}
217  };
218
219  struct barc : public foo {
220    barc();
221    virtual void bar();
222  };
223
224  barc::barc() {}
225}
226
227namespace Test7 {
228  class HIDDEN A {};
229  A a; // top of file
230
231  template <A&> struct Aref {
232    static void foo() {}
233  };
234
235  class B : public A {};
236  B b; // top of file
237
238  // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
239  void test() {
240    Aref<a>::foo();
241  }
242}
243
244namespace Test8 {
245  void foo();
246  void bar() {}
247  // CHECK-HIDDEN-LABEL: define hidden void @_ZN5Test83barEv()
248  // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
249
250  void test() {
251    foo();
252    bar();
253  }
254}
255
256// PR8457
257namespace Test9 {
258  extern "C" {
259    struct A { int field; };
260    void DEFAULT test9_fun(struct A *a) { }
261    struct A DEFAULT test9_var; // above
262  }
263  // CHECK-LABEL: define void @test9_fun(
264  // CHECK-HIDDEN-LABEL: define void @test9_fun(
265
266  void test() {
267    A a = test9_var;
268    test9_fun(&a);
269  }
270}
271
272// PR8478
273namespace Test10 {
274  struct A;
275
276  class DEFAULT B {
277    void foo(A*);
278  };
279
280  // CHECK-LABEL: define void @_ZN6Test101B3fooEPNS_1AE(
281  // CHECK-HIDDEN-LABEL: define void @_ZN6Test101B3fooEPNS_1AE(
282  void B::foo(A*) {}
283}
284
285// PR8492
286namespace Test11 {
287  struct A {
288    void foo() {}
289    void DEFAULT bar() {}
290  };
291
292  void test() {
293    A a;
294    a.foo();
295    a.bar();
296  }
297
298  // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3fooEv(
299  // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3barEv(
300  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
301  // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6Test111A3barEv(
302}
303
304// Tested at top of file.
305namespace Test12 {
306  struct A {
307    // This is hidden in all cases: the explicit attribute takes
308    // priority over -fvisibility on the parent.
309    static int hidden HIDDEN;
310
311    // This is default in all cases because it's only a declaration.
312    static int visible;
313  };
314
315  void test() {
316    A::hidden = 0;
317    A::visible = 0;
318  }
319}
320
321// Tested at top of file.
322namespace Test13 {
323  struct HIDDEN A {};
324
325  // Should be hidden in all cases.
326  struct B {
327    static A a;
328  };
329  A B::a;
330
331  // Should be default in all cases.
332  struct DEFAULT C {
333    static A a;
334  };
335  A C::a;
336};
337
338// Tested at top of file.
339namespace Test14 {
340  // Neither the visibility of the type nor -fvisibility=hidden should
341  // apply to declarations.
342  extern struct A *var;
343
344  struct A *test() { return var; }
345}
346
347// rdar://problem/8613093
348namespace Test15 {
349  struct A {};
350  template <class T> struct Temp {
351    struct Inner {
352      static char buffer[0];
353    };
354  };
355
356  char *test() {
357    return Temp<A>::Inner::buffer;
358  }
359}
360
361namespace Test16 {
362  struct Base1 { virtual void foo(); };
363  struct Base2 : virtual Base1 { virtual void foo(); };
364  template <class T> struct A : virtual Base1, Base2 {
365    virtual void foo();
366  };
367  extern template struct A<char>;
368
369  void test() {
370    A<char> a;
371    a.foo();
372  }
373}
374
375namespace Test17 {
376  struct HIDDEN A {
377    static void foo();
378    static void DEFAULT bar();
379    static void HIDDEN baz();
380
381    struct DEFAULT B {
382      static void foo();
383      static void DEFAULT bar();
384      static void HIDDEN baz();
385    };
386  };
387
388  void test() {
389    A::foo();
390    A::bar();
391    A::baz();
392    A::B::foo();
393    A::B::bar();
394    A::B::baz();
395  }
396  // CHECK: declare hidden void @_ZN6Test171A3fooEv()
397  // CHECK: declare void @_ZN6Test171A3barEv()
398  // CHECK: declare hidden void @_ZN6Test171A3bazEv()
399  // CHECK: declare void @_ZN6Test171A1B3fooEv()
400  // CHECK: declare void @_ZN6Test171A1B3barEv()
401  // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
402  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
403  // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
404  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
405  // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
406  // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
407  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
408}
409
410namespace Test18 {
411  template <class T> struct HIDDEN A {
412    static void foo();
413    static void DEFAULT bar();
414    static void HIDDEN baz();
415
416    struct DEFAULT B {
417      static void foo();
418      static void DEFAULT bar();
419      static void HIDDEN baz();
420    };
421  };
422  struct HIDDEN H;
423
424  void test() {
425    A<int>::foo();
426    A<int>::bar();
427    A<int>::baz();
428    A<int>::B::foo();
429    A<int>::B::bar();
430    A<int>::B::baz();
431    A<H>::foo();
432    A<H>::bar();
433    A<H>::baz();
434    A<H>::B::foo();
435    A<H>::B::bar();
436    A<H>::B::baz();
437  }
438  // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
439  // CHECK: declare void @_ZN6Test181AIiE3barEv()
440  // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
441  // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
442  // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
443  // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
444  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
445  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
446  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
447  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
448  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
449  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
450  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
451  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
452  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
453  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
454  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
455  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
456  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
457  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
458  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
459  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
460  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
461  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
462}
463
464namespace Test19 {
465  struct A { A(); ~A(); };
466
467  // Tested at top of file.
468  template <class T> void foo() {
469    static A a;
470  }
471
472  void test() {
473    foo<int>();
474  }
475}
476
477// Various things with class template specializations.
478namespace Test20 {
479  template <unsigned> struct HIDDEN A {};
480
481  // An explicit specialization inherits the explicit visibility of
482  // the template.
483  template <> struct A<0> {
484    static void test0();
485    static void test1();
486  };
487
488  // CHECK-LABEL: define hidden void @_ZN6Test201AILj0EE5test0Ev()
489  void A<0>::test0() {}
490
491  // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
492  void test1() {
493    A<0>::test1();
494  }
495
496  // ...unless that's explicitly overridden.
497  template <> struct DEFAULT A<1> {
498    static void test2();
499    static void test3();
500  };
501
502  // CHECK-LABEL: define void @_ZN6Test201AILj1EE5test2Ev()
503  void A<1>::test2() {}
504
505  // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
506  void test3() {
507    A<1>::test3();
508  }
509
510  // <rdar://problem/8778497>
511  // But we should assume that an unknown specialization has the
512  // explicit visibility settings of the template.
513  template <class T> struct B {
514    static void test4() {}
515    static void test5();
516  };
517
518  // CHECK-LABEL: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
519  void test4() {
520    B<A<2> >::test4();
521  }
522
523  // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
524  void test5() {
525    B<A<2> >::test5();
526  }
527}
528
529// PR9371
530namespace test21 {
531  enum En { en };
532  template<En> struct A {
533    DEFAULT void foo() {}
534  };
535
536  // CHECK-LABEL: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
537  template void A<en>::foo();
538}
539
540// rdar://problem/9616154
541// Visibility on explicit specializations should take precedence.
542namespace test22 {
543  class A1 {};
544  class A2 {};
545
546  template <class T> struct B {};
547  template <> struct DEFAULT B<A1> {
548    static void foo();
549    static void bar() {}
550  };
551  template <> struct B<A2> {
552    static void foo();
553    static void bar() {}
554  };
555
556  void test() {
557    B<A1>::foo();
558    B<A1>::bar();
559    B<A2>::foo();
560    B<A2>::bar();
561  }
562  // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
563  // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
564  // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
565  // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
566  // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
567  // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
568  // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
569  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
570}
571
572namespace PR10113 {
573  namespace foo DEFAULT {
574    template<typename T>
575      class bar {
576      void zed() {}
577    };
578  }
579  template class foo::bar<char>;
580  // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
581  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
582
583  struct zed {
584  };
585  template class foo::bar<zed>;
586  // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
587  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv
588}
589
590namespace PR11690 {
591  template<class T> struct Class {
592    void size() const {
593    }
594  };
595  template class DEFAULT Class<char>;
596  // CHECK-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
597  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
598
599  template<class T> void Method() {}
600  template  DEFAULT void Method<char>();
601  // CHECK-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv
602  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv
603}
604
605namespace PR11690_2 {
606  namespace foo DEFAULT {
607    class bar;
608    template<typename T1, typename T2 = bar>
609    class zed {
610      void bar() {
611      }
612    };
613  }
614  struct baz {
615  };
616  template class foo::zed<baz>;
617  // CHECK-LABEL: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
618  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
619}
620
621namespace test23 {
622  // Having a template argument that is explicitly visible should not make
623  // the template instantiation visible.
624  template <typename T>
625  struct X {
626    static void f() {
627    }
628  };
629
630  class DEFAULT A;
631
632  void g() {
633    X<A> y;
634    y.f();
635  }
636  // CHECK-LABEL: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv
637  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv
638}
639
640namespace PR12001 {
641  template <typename P1>
642  void Bind(const P1& p1) {
643  }
644
645  class DEFAULT Version { };
646
647  void f() {
648    Bind(Version());
649  }
650  // CHECK-LABEL: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_
651  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_
652}
653
654namespace test24 {
655  class DEFAULT A { };
656
657  struct S {
658    template <typename T>
659    void mem() {}
660  };
661
662  void test() {
663    S s;
664    s.mem<A>();
665  }
666  // CHECK-LABEL: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv
667  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv
668}
669
670namespace test26 {
671  template<typename T>
672  class C {
673    DEFAULT  void f();
674  };
675
676  template<>
677  void C<int>::f() { }
678
679  // CHECK-LABEL: define void @_ZN6test261CIiE1fEv
680  // CHECK-HIDDEN-LABEL: define void @_ZN6test261CIiE1fEv
681}
682
683namespace test31 {
684  struct A {
685    struct HIDDEN B {
686      static void DEFAULT baz();
687    };
688  };
689  void f() {
690    A::B::baz();
691  }
692  // CHECK: declare void @_ZN6test311A1B3bazEv()
693  // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv()
694}
695
696namespace test32 {
697  struct HIDDEN A {
698    struct DEFAULT B {
699      void DEFAULT baz();
700    };
701  };
702  void A::B::baz() {
703  }
704  // CHECK-LABEL: define void @_ZN6test321A1B3bazEv
705  // CHECK-HIDDEN-LABEL: define void @_ZN6test321A1B3bazEv
706}
707
708namespace test33 {
709  template<typename T>
710  class foo {
711    void bar() {}
712  };
713  struct HIDDEN zed {
714  };
715  template class DEFAULT foo<zed>;
716  // CHECK-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
717  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv
718}
719
720namespace test34 {
721  struct foo {
722  };
723  template<class T>
724  void bar() {}
725  template DEFAULT void bar<foo>();
726  // CHECK-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv
727  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv
728}
729
730namespace test35 {
731  // This is a really ugly testcase. GCC propagates the DEFAULT in zed's
732  // definition. It's not really clear what we can do here, because we
733  // produce the symbols before even seeing the DEFAULT definition of zed.
734  // FIXME: Maybe the best thing to do here is error?  It's certainly hard
735  // to argue that this ought to be valid.
736  template<typename T>
737  struct DEFAULT foo {
738    void bar() {}
739  };
740  class zed;
741  template class foo<zed>;
742  class DEFAULT zed {
743  };
744  // CHECK-LABEL: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv
745  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test353fooINS_3zedEE3barEv
746}
747
748namespace test36 {
749  template<typename T1, typename T2>
750  class foo {
751    void bar() {}
752  };
753  class DEFAULT S1 {};
754  struct HIDDEN S2 {};
755  template class foo<S1, S2>;
756  // CHECK-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
757  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv
758}
759
760namespace test37 {
761  struct HIDDEN foo {
762  };
763  template<class T>
764  DEFAULT void bar() {}
765  template DEFAULT void bar<foo>();
766  // CHECK-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv
767  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv
768}
769
770namespace test38 {
771  template<typename T>
772  class DEFAULT foo {
773    void bar() {}
774  };
775  struct HIDDEN zed {
776  };
777  template class foo<zed>;
778  // CHECK-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
779  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv
780}
781
782namespace test39 {
783  class DEFAULT default_t;
784  class HIDDEN hidden_t;
785  template <class T> class A {
786    template <class U> class B {
787      HIDDEN void hidden() {}
788      void noattr() {}
789      template <class V> void temp() {}
790    };
791  };
792  template class DEFAULT A<hidden_t>;
793  template class DEFAULT A<hidden_t>::B<hidden_t>;
794  template void A<hidden_t>::B<hidden_t>::temp<default_t>();
795  template void A<hidden_t>::B<hidden_t>::temp<hidden_t>();
796
797  // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
798  // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
799  // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
800
801  // GCC produces a default for this one. Why?
802  // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
803
804  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv
805  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv
806  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv
807
808  // GCC produces a default for this one. Why?
809  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv
810}
811
812namespace test42 {
813  struct HIDDEN foo {
814  };
815  template <class P>
816  struct bar {
817  };
818  template <>
819  struct HIDDEN bar<foo> {
820    DEFAULT static void zed();
821  };
822  void bar<foo>::zed() {
823  }
824  // CHECK-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv
825  // CHECK-HIDDEN-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv
826}
827
828namespace test43 {
829  struct HIDDEN foo {
830  };
831  template <class P>
832  void bar() {
833  }
834  template <>
835  DEFAULT void bar<foo>() {
836  }
837  // CHECK-LABEL: define void @_ZN6test433barINS_3fooEEEvv
838  // CHECK-HIDDEN-LABEL: define void @_ZN6test433barINS_3fooEEEvv
839}
840
841namespace test44 {
842  template <typename T>
843  struct foo {
844    foo() {}
845  };
846  namespace {
847    struct bar;
848  }
849  template struct DEFAULT foo<bar>;
850  foo<bar> x;
851  // CHECK-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
852  // CHECK-HIDDEN-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev
853}
854
855namespace test45 {
856  template <typename T>
857  struct foo {
858    template <typename T2>
859    struct bar {
860      bar() {};
861    };
862  };
863  namespace {
864    struct zed;
865  }
866  template struct DEFAULT foo<int>::bar<zed>;
867  foo<int>::bar<zed> x;
868  // CHECK-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
869  // CHECK-HIDDEN-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev
870}
871
872namespace test46 {
873  template <typename T>
874  void foo() {
875  }
876  namespace {
877    struct bar;
878  }
879  template DEFAULT void foo<bar>();
880  void zed() {
881    foo<bar>();
882  }
883  // CHECK-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
884  // CHECK-HIDDEN-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv
885}
886
887namespace test47 {
888  struct foo {
889    template <typename T>
890    static void bar() {
891    }
892  };
893  namespace {
894    struct zed;
895  }
896  template DEFAULT void foo::bar<zed>();
897  void baz() {
898    foo::bar<zed>();
899  }
900  // CHECK-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
901  // CHECK-HIDDEN-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv
902}
903
904namespace test49 {
905  // Test that we use the visibility of struct foo when instantiating the
906  // template. Note that is a case where we disagree with gcc, it produces
907  // a default symbol.
908
909  struct HIDDEN foo {
910  };
911
912  DEFAULT foo x;
913
914  struct bar {
915    template<foo *z>
916    void zed() {
917    }
918  };
919
920  template void bar::zed<&x>();
921  // CHECK-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
922  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv
923}
924
925namespace test50 {
926  // Test that we use the visibility of struct foo when instantiating the
927  // template. Note that is a case where we disagree with gcc, it produces
928  // a default symbol.
929
930  struct HIDDEN foo {
931  };
932  DEFAULT foo x;
933  template<foo *z>
934  struct DEFAULT bar {
935    void zed() {
936    }
937  };
938  template void bar<&x>::zed();
939  // CHECK-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
940  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv
941}
942
943namespace test51 {
944  // Test that we use the visibility of struct foo when instantiating the
945  // template. Note that is a case where we disagree with gcc, it produces
946  // a default symbol.
947
948  struct HIDDEN foo {
949  };
950  DEFAULT foo x;
951  template<foo *z>
952  void DEFAULT zed() {
953  }
954  template void zed<&x>();
955  // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
956  // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv
957}
958
959namespace test52 {
960  // Test that we use the linkage of struct foo when instantiating the
961  // template. Note that is a case where we disagree with gcc, it produces
962  // an external symbol.
963
964  namespace {
965    struct foo {
966    };
967  }
968  template<foo *x>
969  void zed() {
970  }
971  void f() {
972    zed<nullptr>();
973  }
974  // CHECK-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
975  // CHECK-HIDDEN-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv
976}
977
978namespace test53 {
979  template<typename _Tp > struct vector   {
980    static void       _M_fill_insert();
981  };
982#pragma GCC visibility push(hidden)
983  // GCC doesn't seem to use the visibility of enums at all, we do.
984  enum zed {v1};
985
986  // GCC fails to mark this specialization hidden, we mark it.
987  template<>
988  struct vector<int> {
989    static void       _M_fill_insert();
990  };
991  void foo() {
992    vector<unsigned>::_M_fill_insert();
993    vector<int>::_M_fill_insert();
994    vector<zed>::_M_fill_insert();
995  }
996#pragma GCC visibility pop
997  // CHECK: declare void @_ZN6test536vectorIjE14_M_fill_insertEv
998  // CHECK-HIDDEN: declare void @_ZN6test536vectorIjE14_M_fill_insertEv
999  // CHECK: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv
1000  // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv
1001  // CHECK: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv
1002  // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv
1003}
1004
1005namespace test54 {
1006  template <class T>
1007  struct foo {
1008    static void bar();
1009  };
1010#pragma GCC visibility push(hidden)
1011  class zed {
1012    zed(const zed &);
1013  };
1014  void bah() {
1015    foo<zed>::bar();
1016  }
1017#pragma GCC visibility pop
1018  // CHECK: declare hidden void @_ZN6test543fooINS_3zedEE3barEv
1019  // CHECK-HIDDEN: declare hidden void @_ZN6test543fooINS_3zedEE3barEv
1020}
1021
1022namespace test55 {
1023  template <class T>
1024  struct HIDDEN foo {
1025    static void bar();
1026  };
1027  template <class T> struct foo;
1028  void foobar() {
1029    foo<int>::bar();
1030  }
1031  // CHECK: declare hidden void @_ZN6test553fooIiE3barEv
1032  // CHECK-HIDDEN: declare hidden void @_ZN6test553fooIiE3barEv
1033}
1034
1035namespace test56 {
1036  template <class T> struct foo;
1037  template <class T>
1038  struct HIDDEN foo {
1039    static void bar();
1040  };
1041  void foobar() {
1042    foo<int>::bar();
1043  }
1044  // CHECK: declare hidden void @_ZN6test563fooIiE3barEv
1045  // CHECK-HIDDEN: declare hidden void @_ZN6test563fooIiE3barEv
1046}
1047
1048namespace test57 {
1049#pragma GCC visibility push(hidden)
1050  template <class T>
1051  struct foo;
1052  void bar(foo<int>*);
1053  template <class T>
1054  struct foo {
1055    static void zed();
1056  };
1057  void bah() {
1058    foo<int>::zed();
1059  }
1060#pragma GCC visibility pop
1061  // CHECK: declare hidden void @_ZN6test573fooIiE3zedEv
1062  // CHECK-HIDDEN: declare hidden void @_ZN6test573fooIiE3zedEv
1063}
1064
1065namespace test58 {
1066#pragma GCC visibility push(hidden)
1067  struct foo;
1068  template<typename T>
1069  struct DEFAULT bar {
1070    static void zed() {
1071    }
1072  };
1073  void bah() {
1074    bar<foo>::zed();
1075  }
1076#pragma GCC visibility pop
1077  // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
1078  // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv
1079}
1080
1081namespace test59 {
1082  DEFAULT int f();
1083  HIDDEN int g();
1084  typedef int (*foo)();
1085  template<foo x, foo y>
1086  void test() {}
1087  void use() {
1088    test<&g, &f>();
1089    // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
1090    // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv
1091
1092    test<&f, &g>();
1093    // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
1094    // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv
1095  }
1096}
1097
1098namespace test60 {
1099  template<int i>
1100  class HIDDEN a {};
1101  template<int i>
1102  class DEFAULT b {};
1103  template<template<int> class x, template<int> class y>
1104  void test() {}
1105  void use() {
1106    test<a, b>();
1107    // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
1108    // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv
1109
1110    test<b, a>();
1111    // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
1112    // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv
1113  }
1114}
1115
1116namespace test61 {
1117  template <typename T1>
1118  struct Class1
1119  {
1120    void f1() { f2(); }
1121    inline void f2();
1122  };
1123  template<>
1124  inline void Class1<int>::f2()
1125  {
1126  }
1127  void g(Class1<int> *x) {
1128    x->f1();
1129  }
1130}
1131namespace test61 {
1132  // Just test that we don't crash. Currently we apply this attribute. Current
1133  // gcc issues a warning about it being unused since "the type is already
1134  // defined". We should probably do the same.
1135  template class HIDDEN Class1<int>;
1136}
1137
1138namespace test62 {
1139  template <typename T1>
1140  struct Class1
1141  {
1142    void f1() { f2(); }
1143    inline void f2() {}
1144  };
1145  template<>
1146  inline void Class1<int>::f2()
1147  {
1148  }
1149  void g(Class1<int> *x) {
1150    x->f2();
1151  }
1152}
1153namespace test62 {
1154  template class HIDDEN Class1<int>;
1155  // Just test that we don't crash. Currently we apply this attribute. Current
1156  // gcc issues a warning about it being unused since "the type is already
1157  // defined". We should probably do the same.
1158}
1159
1160namespace test63 {
1161  enum HIDDEN E { E0 };
1162  struct A {
1163    template <E> static void foo() {}
1164
1165    template <E> struct B {
1166      static void foo() {}
1167    };
1168  };
1169
1170  void test() {
1171    A::foo<E0>();
1172    A::B<E0>::foo();
1173  }
1174  // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A3fooILNS_1EE0EEEvv()
1175  // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A1BILNS_1EE0EE3fooEv()
1176}
1177
1178// Don't ignore the visibility of template arguments just because we
1179// explicitly instantiated something.
1180namespace test64 {
1181  struct HIDDEN A {};
1182  template <class P> struct B {
1183    static DEFAULT void foo() {}
1184  };
1185
1186  template class B<A>;
1187  // CHECK-LABEL: define weak_odr hidden void @_ZN6test641BINS_1AEE3fooEv()
1188}
1189
1190namespace test65 {
1191  class HIDDEN A {};
1192  template <class T> struct B {
1193    static void func();
1194    template <class U> static void funcT1();
1195    template <class U> static void funcT2();
1196    class Inner {};
1197    template <class U> class InnerT {};
1198  };
1199  template <template <class T> class Temp> struct C {
1200    static void foo() {}
1201  };
1202
1203  // CHECK-LABEL: define void @_ZN6test651BINS_1AEE4funcEv()
1204  template <> DEFAULT void B<A>::func() {}
1205
1206  // CHECK-LABEL: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv()
1207  template <> template <> DEFAULT void B<A>::funcT2<A>() {}
1208
1209  // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6funcT1IiEEvv()
1210  // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6funcT1IS1_EEvv()
1211  template <> template <class T> DEFAULT void B<A>::funcT1() {}
1212
1213  // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE5Inner3fooEv()
1214  template <> struct DEFAULT B<A>::Inner {
1215    static void foo() {}
1216  };
1217
1218  // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6InnerTIiE3fooEv()
1219  // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6InnerTIS1_E3fooEv()
1220  template <> template <class U> struct DEFAULT B<A>::InnerT {
1221    static void foo() {}
1222  };
1223
1224  void test() {
1225    B<A>::funcT1<int>();
1226    B<A>::funcT1<A>();
1227    B<A>::Inner::foo();
1228    B<A>::InnerT<int>::foo();
1229    B<A>::InnerT<A>::foo();
1230  }
1231
1232  template class C<B<A>::InnerT>;
1233}
1234
1235namespace test66 {
1236  template <typename T>
1237  struct DEFAULT barT {
1238    static void zed() {}
1239  };
1240  class foo;
1241  class DEFAULT foo;
1242  template struct barT<foo>;
1243  // CHECK-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv
1244  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv
1245
1246  template <int* I>
1247  struct DEFAULT barI {
1248    static void zed() {}
1249  };
1250  extern int I;
1251  extern int I DEFAULT;
1252  template struct barI<&I>;
1253  // CHECK-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv
1254  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv
1255
1256  typedef void (*fType)(void);
1257  template<fType F>
1258  struct DEFAULT barF {
1259    static void zed() {}
1260  };
1261  void F();
1262  void F() DEFAULT;
1263  template struct barF<F>;
1264  // CHECK-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv
1265  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv
1266}
1267
1268namespace test67 {
1269  template <typename T>
1270  struct DEFAULT bar {
1271    static void zed() {}
1272  };
1273
1274  class foo;
1275  class compute {
1276    void f(foo *rootfoo);
1277  };
1278  class DEFAULT foo;
1279
1280  template struct bar<foo>;
1281  // CHECK-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv
1282  // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv
1283}
1284
1285namespace test68 {
1286  class A { public: ~A(); };
1287  class f {
1288  public:
1289    f() {
1290      static A test;
1291    }
1292  };
1293  void g() {
1294    f a;
1295  }
1296  // Check lines at top of file.
1297}
1298
1299namespace test69 {
1300  // PR18174
1301  namespace foo {
1302    void f();
1303  }
1304  namespace foo {
1305    void f() {};
1306  }
1307  namespace foo __attribute__((visibility("hidden"))) {
1308  }
1309  // CHECK-LABEL: define void @_ZN6test693foo1fEv
1310  // CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv
1311}
1312