visibility.cpp revision a77e0726341a4afbe9c25b05cf944edf17f64543
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
2// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
3
4#define HIDDEN __attribute__((visibility("hidden")))
5#define PROTECTED __attribute__((visibility("protected")))
6#define DEFAULT __attribute__((visibility("default")))
7
8namespace test30 {
9  // When H is hidden, it should make X hidden, even if the template argument
10  // is not.
11  struct H {
12  };
13  template<H *T>
14  struct X {
15  };
16  H DEFAULT a;
17  X<&a> b;
18  // CHECK: _ZN6test301bE = global
19  // CHECK-HIDDEN: _ZN6test301bE = hidden global
20}
21
22namespace test25 {
23  template<typename T>
24  struct X {
25    template<typename U>
26    struct definition {
27    };
28  };
29
30  class DEFAULT A { };
31
32  X<int>::definition<A> a;
33  // CHECK: @_ZN6test251aE = global
34  // CHECK-HIDDEN: @_ZN6test251aE = hidden global
35}
36
37namespace test28 {
38  class DEFAULT foo {
39  };
40  foo myvec;
41  // CHECK: @_ZN6test285myvecE = global
42  // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global
43}
44
45namespace test29 {
46#pragma GCC visibility push(hidden)
47  struct RECT {
48    int top;
49  };
50  __attribute__ ((visibility ("default"))) extern RECT data_rect;
51  RECT data_rect = { -1};
52#pragma GCC visibility pop
53  // CHECK: @_ZN6test299data_rectE = global
54  // CHECK-HIDDEN: @_ZN6test299data_rectE = global
55}
56
57// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10
58// CHECK: @_ZN5Test71aE = hidden global
59// CHECK: @_ZN5Test71bE = global
60// CHECK: @test9_var = global
61// CHECK-HIDDEN: @test9_var = global
62// CHECK: @_ZN6Test121A6hiddenE = external hidden global
63// CHECK: @_ZN6Test121A7visibleE = external global
64// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global
65// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global
66// CHECK: @_ZN6Test131B1aE = hidden global
67// CHECK: @_ZN6Test131C1aE = global
68// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global
69// CHECK-HIDDEN: @_ZN6Test131C1aE = global
70// CHECK: @_ZN6Test143varE = external global
71// CHECK-HIDDEN: @_ZN6Test143varE = external global
72// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
73// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
74
75namespace test27 {
76  template<typename T>
77  class C {
78    class __attribute__((visibility("default"))) D {
79      void f();
80    };
81  };
82
83  template<>
84  class C<int>::D {
85    virtual void g();
86  };
87
88  void C<int>::D::g() {
89  }
90  // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant
91  // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant
92}
93
94// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global
95// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64
96// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global
97// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64
98// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
99// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
100// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
101
102namespace Test1 {
103  // CHECK: define hidden void @_ZN5Test11fEv
104  void HIDDEN f() { }
105
106}
107
108namespace Test2 {
109  struct HIDDEN A {
110    void f();
111  };
112
113  // A::f is a member function of a hidden class.
114  // CHECK: define hidden void @_ZN5Test21A1fEv
115  void A::f() { }
116}
117
118namespace Test3 {
119  struct HIDDEN A {
120    struct B {
121      void f();
122    };
123  };
124
125  // B is a nested class where its parent class is hidden.
126  // CHECK: define hidden void @_ZN5Test31A1B1fEv
127  void A::B::f() { }
128}
129
130namespace Test4 HIDDEN {
131  int VariableInHiddenNamespace = 10;
132
133  // Test4::g is in a hidden namespace.
134  // CHECK: define hidden void @_ZN5Test41gEv
135  void g() { }
136
137  struct DEFAULT A {
138    void f();
139  };
140
141  // A has default visibility.
142  // CHECK: define void @_ZN5Test41A1fEv
143  void A::f() { }
144}
145
146namespace Test5 {
147
148  namespace NS HIDDEN {
149    // f is in NS which is hidden.
150    // CHECK: define hidden void @_ZN5Test52NS1fEv()
151    void f() { }
152  }
153
154  namespace NS {
155    // g is in NS, but this NS decl is not hidden.
156    // CHECK: define void @_ZN5Test52NS1gEv
157    void g() { }
158  }
159}
160
161// <rdar://problem/8091955>
162namespace Test6 {
163  struct HIDDEN foo {
164    foo() { }
165    void bonk();
166    virtual void bar() = 0;
167
168    virtual void zonk() {}
169  };
170
171  struct barc : public foo {
172    barc();
173    virtual void bar();
174  };
175
176  barc::barc() {}
177}
178
179namespace Test7 {
180  class HIDDEN A {};
181  A a; // top of file
182
183  template <A&> struct Aref {
184    static void foo() {}
185  };
186
187  class B : public A {};
188  B b; // top of file
189
190  // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
191  void test() {
192    Aref<a>::foo();
193  }
194}
195
196namespace Test8 {
197  void foo();
198  void bar() {}
199  // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
200  // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
201
202  void test() {
203    foo();
204    bar();
205  }
206}
207
208// PR8457
209namespace Test9 {
210  extern "C" {
211    struct A { int field; };
212    void DEFAULT test9_fun(struct A *a) { }
213    struct A DEFAULT test9_var; // above
214  }
215  // CHECK: define void @test9_fun(
216  // CHECK-HIDDEN: define void @test9_fun(
217
218  void test() {
219    A a = test9_var;
220    test9_fun(&a);
221  }
222}
223
224// PR8478
225namespace Test10 {
226  struct A;
227
228  class DEFAULT B {
229    void foo(A*);
230  };
231
232  // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
233  // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
234  void B::foo(A*) {}
235}
236
237// PR8492
238namespace Test11 {
239  struct A {
240    void foo() {}
241    void DEFAULT bar() {}
242  };
243
244  void test() {
245    A a;
246    a.foo();
247    a.bar();
248  }
249
250  // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
251  // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
252  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
253  // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
254}
255
256// Tested at top of file.
257namespace Test12 {
258  struct A {
259    // This is hidden in all cases: the explicit attribute takes
260    // priority over -fvisibility on the parent.
261    static int hidden HIDDEN;
262
263    // This is default in all cases because it's only a declaration.
264    static int visible;
265  };
266
267  void test() {
268    A::hidden = 0;
269    A::visible = 0;
270  }
271}
272
273// Tested at top of file.
274namespace Test13 {
275  struct HIDDEN A {};
276
277  // Should be hidden in all cases.
278  struct B {
279    static A a;
280  };
281  A B::a;
282
283  // Should be default in all cases.
284  struct DEFAULT C {
285    static A a;
286  };
287  A C::a;
288};
289
290// Tested at top of file.
291namespace Test14 {
292  // Neither the visibility of the type nor -fvisibility=hidden should
293  // apply to declarations.
294  extern struct A *var;
295
296  struct A *test() { return var; }
297}
298
299// rdar://problem/8613093
300namespace Test15 {
301  struct A {};
302  template <class T> struct Temp {
303    struct Inner {
304      static char buffer[0];
305    };
306  };
307
308  char *test() {
309    return Temp<A>::Inner::buffer;
310  }
311}
312
313namespace Test16 {
314  struct Base1 { virtual void foo(); };
315  struct Base2 : virtual Base1 { virtual void foo(); };
316  template <class T> struct A : virtual Base1, Base2 {
317    virtual void foo();
318  };
319  extern template struct A<char>;
320
321  void test() {
322    A<char> a;
323    a.foo();
324  }
325}
326
327namespace Test17 {
328  struct HIDDEN A {
329    static void foo();
330    static void DEFAULT bar();
331    static void HIDDEN baz();
332
333    struct DEFAULT B {
334      static void foo();
335      static void DEFAULT bar();
336      static void HIDDEN baz();
337    };
338  };
339
340  void test() {
341    A::foo();
342    A::bar();
343    A::baz();
344    A::B::foo();
345    A::B::bar();
346    A::B::baz();
347  }
348  // CHECK: declare hidden void @_ZN6Test171A3fooEv()
349  // CHECK: declare void @_ZN6Test171A3barEv()
350  // CHECK: declare hidden void @_ZN6Test171A3bazEv()
351  // CHECK: declare void @_ZN6Test171A1B3fooEv()
352  // CHECK: declare void @_ZN6Test171A1B3barEv()
353  // CHECK: declare hidden void @_ZN6Test171A1B3bazEv()
354  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv()
355  // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv()
356  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv()
357  // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv()
358  // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv()
359  // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv()
360}
361
362namespace Test18 {
363  template <class T> struct HIDDEN A {
364    static void foo();
365    static void DEFAULT bar();
366    static void HIDDEN baz();
367
368    struct DEFAULT B {
369      static void foo();
370      static void DEFAULT bar();
371      static void HIDDEN baz();
372    };
373  };
374  struct HIDDEN H;
375
376  void test() {
377    A<int>::foo();
378    A<int>::bar();
379    A<int>::baz();
380    A<int>::B::foo();
381    A<int>::B::bar();
382    A<int>::B::baz();
383    A<H>::foo();
384    A<H>::bar();
385    A<H>::baz();
386    A<H>::B::foo();
387    A<H>::B::bar();
388    A<H>::B::baz();
389  }
390  // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv()
391  // CHECK: declare void @_ZN6Test181AIiE3barEv()
392  // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv()
393  // CHECK: declare void @_ZN6Test181AIiE1B3fooEv()
394  // CHECK: declare void @_ZN6Test181AIiE1B3barEv()
395  // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv()
396  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
397  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
398  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
399  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
400  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
401  // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
402  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv()
403  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv()
404  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv()
405  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv()
406  // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv()
407  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv()
408  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv()
409  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv()
410  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv()
411  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv()
412  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv()
413  // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv()
414}
415
416namespace Test19 {
417  struct A { A(); ~A(); };
418
419  // Tested at top of file.
420  template <class T> void foo() {
421    static A a;
422  }
423
424  void test() {
425    foo<int>();
426  }
427}
428
429// Various things with class template specializations.
430namespace Test20 {
431  template <unsigned> struct HIDDEN A {};
432
433  // An explicit specialization inherits the explicit visibility of
434  // the template.
435  template <> struct A<0> {
436    static void test0();
437    static void test1();
438  };
439
440  // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev()
441  void A<0>::test0() {}
442
443  // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev()
444  void test1() {
445    A<0>::test1();
446  }
447
448  // ...unless that's explicitly overridden.
449  template <> struct DEFAULT A<1> {
450    static void test2();
451    static void test3();
452  };
453
454  // CHECK: define void @_ZN6Test201AILj1EE5test2Ev()
455  void A<1>::test2() {}
456
457  // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev()
458  void test3() {
459    A<1>::test3();
460  }
461
462  // <rdar://problem/8778497>
463  // But we should assume that an unknown specialization has the
464  // explicit visibility settings of the template.
465  template <class T> struct B {
466    static void test4() {}
467    static void test5();
468  };
469
470  // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev()
471  void test4() {
472    B<A<2> >::test4();
473  }
474
475  // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
476  void test5() {
477    B<A<2> >::test5();
478  }
479}
480
481// PR9371
482namespace test21 {
483  enum En { en };
484  template<En> struct A {
485    __attribute__((visibility("default"))) void foo() {}
486  };
487
488  // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv(
489  template void A<en>::foo();
490}
491
492// rdar://problem/9616154
493// Visibility on explicit specializations should take precedence.
494namespace test22 {
495  class A1 {};
496  class A2 {};
497
498  template <class T> struct B {};
499  template <> struct DEFAULT B<A1> {
500    static void foo();
501    static void bar() {}
502  };
503  template <> struct B<A2> {
504    static void foo();
505    static void bar() {}
506  };
507
508  void test() {
509    B<A1>::foo();
510    B<A1>::bar();
511    B<A2>::foo();
512    B<A2>::bar();
513  }
514  // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
515  // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
516  // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
517  // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
518  // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
519  // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
520  // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
521  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
522}
523
524namespace PR10113 {
525  namespace foo DEFAULT {
526    template<typename T>
527      class bar {
528      void zed() {}
529    };
530  }
531  template class foo::bar<char>;
532  // CHECK: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
533  // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv
534
535  struct zed {
536  };
537  template class foo::bar<zed>;
538  // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv
539  // CHECK-HIDDEN: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv
540}
541
542namespace PR11690 {
543  template<class T> struct Class {
544    void size() const {
545    }
546  };
547  template class DEFAULT Class<char>;
548  // CHECK: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
549  // CHECK-HIDDEN: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv
550
551  template<class T> void Method() {}
552  template  DEFAULT void Method<char>();
553  // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv
554  // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv
555}
556
557namespace PR11690_2 {
558  namespace foo DEFAULT {
559    class bar;
560    template<typename T1, typename T2 = bar>
561    class zed {
562      void bar() {
563      }
564    };
565  }
566  struct baz {
567  };
568  template class foo::zed<baz>;
569  // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
570  // CHECK-HIDDEN: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv
571}
572
573namespace test23 {
574  // Having a template argument that is explicitly visible should not make
575  // the template instantiation visible.
576  template <typename T>
577  struct X {
578    static void f() {
579    }
580  };
581
582  class DEFAULT A;
583
584  void g() {
585    X<A> y;
586    y.f();
587  }
588  // CHECK: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv
589  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv
590}
591
592namespace PR12001 {
593  template <typename P1>
594  void Bind(const P1& p1) {
595  }
596
597  class DEFAULT Version { };
598
599  void f() {
600    Bind(Version());
601  }
602  // CHECK: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_
603  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_
604}
605
606namespace test24 {
607  class DEFAULT A { };
608
609  struct S {
610    template <typename T>
611    void mem() {}
612  };
613
614  void test() {
615    S s;
616    s.mem<A>();
617  }
618  // CHECK: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv
619  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv
620}
621
622namespace test26 {
623  template<typename T>
624  class C {
625    __attribute__((visibility("default")))  void f();
626  };
627
628  template<>
629  void C<int>::f() { }
630
631  // CHECK: define void @_ZN6test261CIiE1fEv
632  // CHECK-HIDDEN: define void @_ZN6test261CIiE1fEv
633}
634
635namespace test31 {
636  struct A {
637    struct HIDDEN B {
638      static void DEFAULT baz();
639    };
640  };
641  void f() {
642    A::B::baz();
643  }
644  // CHECK: declare void @_ZN6test311A1B3bazEv()
645  // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv()
646}
647
648namespace test32 {
649  struct HIDDEN A {
650    struct DEFAULT B {
651      void DEFAULT baz();
652    };
653  };
654  void A::B::baz() {
655  }
656  // CHECK: define void @_ZN6test321A1B3bazEv
657  // CHECK-HIDDEN: define void @_ZN6test321A1B3bazEv
658}
659