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