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