visibility.cpp revision 1a0918ade0a3490c7aff243f9cd519156dfcb0bd
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
3
4#define HIDDEN __attribute__((visibility("hidden")))
5#define PROTECTED __attribute__((visibility("protected")))
6#define DEFAULT __attribute__((visibility("default")))
7
8// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
9// CHECK: @_ZN5Test71aE = hidden global
10// CHECK: @_ZN5Test71bE = global
11// CHECK: @test9_var = global
12// CHECK-HIDDEN: @test9_var = global
13// CHECK: @_ZN6Test121A6hiddenE = external hidden global
14// CHECK: @_ZN6Test121A7visibleE = external global
15// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
16// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
17// CHECK: @_ZN6Test131B1aE = hidden global
18// CHECK: @_ZN6Test131C1aE = global
19// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
20// CHECK-HIDDEN: @_ZN6Test131C1aE = global
21// CHECK: @_ZN6Test143varE = external global
22// CHECK-HIDDEN: @_ZN6Test143varE = external global
23// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
24// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
25// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
26// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
27// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
28// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
29// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
30// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
31// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
32
33namespace Test1 {
34  // CHECK: define hidden void @_ZN5Test11fEv
35  void HIDDEN f() { }
36
37}
38
39namespace Test2 {
40  struct HIDDEN A {
41    void f();
42  };
43
44  // A::f is a member function of a hidden class.
45  // CHECK: define hidden void @_ZN5Test21A1fEv
46  void A::f() { }
47}
48
49namespace Test3 {
50  struct HIDDEN A {
51    struct B {
52      void f();
53    };
54  };
55
56  // B is a nested class where its parent class is hidden.
57  // CHECK: define hidden void @_ZN5Test31A1B1fEv
58  void A::B::f() { }
59}
60
61namespace Test4 HIDDEN {
62  int VariableInHiddenNamespace = 10;
63
64  // Test4::g is in a hidden namespace.
65  // CHECK: define hidden void @_ZN5Test41gEv
66  void g() { }
67
68  struct DEFAULT A {
69    void f();
70  };
71
72  // A has default visibility.
73  // CHECK: define void @_ZN5Test41A1fEv
74  void A::f() { }
75}
76
77namespace Test5 {
78
79  namespace NS HIDDEN {
80    // f is in NS which is hidden.
81    // CHECK: define hidden void @_ZN5Test52NS1fEv()
82    void f() { }
83  }
84
85  namespace NS {
86    // g is in NS, but this NS decl is not hidden.
87    // CHECK: define void @_ZN5Test52NS1gEv
88    void g() { }
89  }
90}
91
92// <rdar://problem/8091955>
93namespace Test6 {
94  struct HIDDEN foo {
95    foo() { }
96    void bonk();
97    virtual void bar() = 0;
98
99    virtual void zonk() {}
100  };
101
102  struct barc : public foo {
103    barc();
104    virtual void bar();
105  };
106
107  barc::barc() {}
108}
109
110namespace Test7 {
111  class HIDDEN A {};
112  A a; // top of file
113
114  template <A&> struct Aref {
115    static void foo() {}
116  };
117
118  class B : public A {};
119  B b; // top of file
120
121  // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
122  void test() {
123    Aref<a>::foo();
124  }
125}
126
127namespace Test8 {
128  void foo();
129  void bar() {}
130  // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
131  // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
132
133  void test() {
134    foo();
135    bar();
136  }
137}
138
139// PR8457
140namespace Test9 {
141  extern "C" {
142    struct A { int field; };
143    void DEFAULT test9_fun(struct A *a) { }
144    struct A DEFAULT test9_var; // above
145  }
146  // CHECK: define void @test9_fun(
147  // CHECK-HIDDEN: define void @test9_fun(
148
149  void test() {
150    A a = test9_var;
151    test9_fun(&a);
152  }
153}
154
155// PR8478
156namespace Test10 {
157  struct A;
158
159  DEFAULT class B {
160    void foo(A*);
161  };
162
163  // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
164  // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
165  void B::foo(A*) {}
166}
167
168// PR8492
169namespace Test11 {
170  struct A {
171    void foo() {}
172    void DEFAULT bar() {}
173  };
174
175  void test() {
176    A a;
177    a.foo();
178    a.bar();
179  }
180
181  // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
182  // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
183  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
184  // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
185}
186
187// Tested at top of file.
188namespace Test12 {
189  struct A {
190    // This is hidden in all cases: the explicit attribute takes
191    // priority over -fvisibility on the parent.
192    static int hidden HIDDEN;
193
194    // This is default in all cases because it's only a declaration.
195    static int visible;
196  };
197
198  void test() {
199    A::hidden = 0;
200    A::visible = 0;
201  }
202}
203
204// Tested at top of file.
205namespace Test13 {
206  struct HIDDEN A {};
207
208  // Should be hidden in all cases.
209  struct B {
210    static A a;
211  };
212  A B::a;
213
214  // Should be default in all cases.
215  struct DEFAULT C {
216    static A a;
217  };
218  A C::a;
219};
220
221// Tested at top of file.
222namespace Test14 {
223  // Neither the visibility of the type nor -fvisibility=hidden should
224  // apply to declarations.
225  extern struct A *var;
226
227  struct A *test() { return var; }
228}
229
230// rdar://problem/8613093
231namespace Test15 {
232  struct A {};
233  template <class T> struct Temp {
234    struct Inner {
235      static char buffer[0];
236    };
237  };
238
239  char *test() {
240    return Temp<A>::Inner::buffer;
241  }
242}
243
244namespace Test16 {
245  struct Base1 { virtual void foo(); };
246  struct Base2 : virtual Base1 { virtual void foo(); };
247  template <class T> struct A : virtual Base1, Base2 {
248    virtual void foo();
249  };
250  extern template struct A<char>;
251
252  void test() {
253    A<char> a;
254    a.foo();
255  }
256}
257
258namespace Test17 {
259  struct HIDDEN A {
260    static void foo();
261    static void DEFAULT bar();
262    static void HIDDEN baz();
263
264    struct DEFAULT B {
265      static void foo();
266      static void DEFAULT bar();
267      static void HIDDEN baz();
268    };
269  };
270
271  void test() {
272    A::foo();
273    A::bar();
274    A::baz();
275    A::B::foo();
276    A::B::bar();
277    A::B::baz();
278  }
279  // CHECK: declare hidden void @_ZN6Test171A3fooEv()
280  // CHECK: declare void @_ZN6Test171A3barEv()
281  // CHECK: declare hidden void @_ZN6Test171A3bazEv()
282  // CHECK: declare void @_ZN6Test171A1B3fooEv()
283  // CHECK: declare void @_ZN6Test171A1B3barEv()
284  // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
285  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
286  // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
287  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
288  // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
289  // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
290  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
291}
292
293namespace Test18 {
294  template <class T> struct HIDDEN A {
295    static void foo();
296    static void DEFAULT bar();
297    static void HIDDEN baz();
298
299    struct DEFAULT B {
300      static void foo();
301      static void DEFAULT bar();
302      static void HIDDEN baz();
303    };
304  };
305  struct HIDDEN H;
306
307  void test() {
308    A<int>::foo();
309    A<int>::bar();
310    A<int>::baz();
311    A<int>::B::foo();
312    A<int>::B::bar();
313    A<int>::B::baz();
314    A<H>::foo();
315    A<H>::bar();
316    A<H>::baz();
317    A<H>::B::foo();
318    A<H>::B::bar();
319    A<H>::B::baz();
320  }
321  // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
322  // CHECK: declare void @_ZN6Test181AIiE3barEv()
323  // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
324  // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
325  // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
326  // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
327  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
328  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
329  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
330  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
331  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
332  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
333  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
334  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
335  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
336  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
337  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
338  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
339  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
340  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
341  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
342  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
343  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
344  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
345}
346
347namespace Test19 {
348  struct A { A(); ~A(); };
349
350  // Tested at top of file.
351  template <class T> void foo() {
352    static A a;
353  }
354
355  void test() {
356    foo<int>();
357  }
358}
359
360// Various things with class template specializations.
361namespace Test20 {
362  template <unsigned> struct HIDDEN A {};
363
364  // An explicit specialization inherits the explicit visibility of
365  // the template.
366  template <> struct A<0> {
367    static void test0();
368    static void test1();
369  };
370
371  // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
372  void A<0>::test0() {}
373
374  // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
375  void test1() {
376    A<0>::test1();
377  }
378
379  // ...unless that's explicitly overridden.
380  template <> struct DEFAULT A<1> {
381    static void test2();
382    static void test3();
383  };
384
385  // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
386  void A<1>::test2() {}
387
388  // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
389  void test3() {
390    A<1>::test3();
391  }
392
393  // <rdar://problem/8778497>
394  // But we should assume that an unknown specialization has the
395  // explicit visibility settings of the template.
396  template <class T> struct B {
397    static void test4() {}
398    static void test5();
399  };
400
401  // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
402  void test4() {
403    B<A<2> >::test4();
404  }
405
406  // CHECK: declare void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
407  // (but explicit visibility on a template argument doesn't count as
408  //  explicit visibility for the template for purposes of deciding
409  //  whether an external symbol gets visibility)
410  void test5() {
411    B<A<2> >::test5();
412  }
413}
414
415// PR9371
416namespace test21 {
417  enum En { en };
418  template<En> struct A {
419    __attribute__((visibility("default"))) void foo() {}
420  };
421
422  // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
423  template void A<en>::foo();
424}
425