visibility.cpp revision af14603ca61757cf4361b583b45639a04c57e651
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-HIDDEN: @_ZTTN6Test161AIcEE = external constant
26// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external constant
27// CHECK: @_ZTVN5Test63fooE = weak_odr hidden constant
28
29namespace Test1 {
30  // CHECK: define hidden void @_ZN5Test11fEv
31  void HIDDEN f() { }
32
33}
34
35namespace Test2 {
36  struct HIDDEN A {
37    void f();
38  };
39
40  // A::f is a member function of a hidden class.
41  // CHECK: define hidden void @_ZN5Test21A1fEv
42  void A::f() { }
43}
44
45namespace Test3 {
46  struct HIDDEN A {
47    struct B {
48      void f();
49    };
50  };
51
52  // B is a nested class where its parent class is hidden.
53  // CHECK: define hidden void @_ZN5Test31A1B1fEv
54  void A::B::f() { }
55}
56
57namespace Test4 HIDDEN {
58  int VariableInHiddenNamespace = 10;
59
60  // Test4::g is in a hidden namespace.
61  // CHECK: define hidden void @_ZN5Test41gEv
62  void g() { }
63
64  struct DEFAULT A {
65    void f();
66  };
67
68  // A has default visibility.
69  // CHECK: define void @_ZN5Test41A1fEv
70  void A::f() { }
71}
72
73namespace Test5 {
74
75  namespace NS HIDDEN {
76    // f is in NS which is hidden.
77    // CHECK: define hidden void @_ZN5Test52NS1fEv()
78    void f() { }
79  }
80
81  namespace NS {
82    // g is in NS, but this NS decl is not hidden.
83    // CHECK: define void @_ZN5Test52NS1gEv
84    void g() { }
85  }
86}
87
88// <rdar://problem/8091955>
89namespace Test6 {
90  struct HIDDEN foo {
91    foo() { }
92    void bonk();
93    virtual void bar() = 0;
94
95    virtual void zonk() {}
96  };
97
98  struct barc : public foo {
99    barc();
100    virtual void bar();
101  };
102
103  barc::barc() {}
104}
105
106namespace Test7 {
107  class HIDDEN A {};
108  A a; // top of file
109
110  template <A&> struct Aref {
111    static void foo() {}
112  };
113
114  class B : public A {};
115  B b; // top of file
116
117  // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv()
118  void test() {
119    Aref<a>::foo();
120  }
121}
122
123namespace Test8 {
124  void foo();
125  void bar() {}
126  // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv()
127  // CHECK-HIDDEN: declare void @_ZN5Test83fooEv()
128
129  void test() {
130    foo();
131    bar();
132  }
133}
134
135// PR8457
136namespace Test9 {
137  extern "C" {
138    struct A { int field; };
139    void DEFAULT test9_fun(struct A *a) { }
140    struct A DEFAULT test9_var; // above
141  }
142  // CHECK: define void @test9_fun(
143  // CHECK-HIDDEN: define void @test9_fun(
144
145  void test() {
146    A a = test9_var;
147    test9_fun(&a);
148  }
149}
150
151// PR8478
152namespace Test10 {
153  struct A;
154
155  DEFAULT class B {
156    void foo(A*);
157  };
158
159  // CHECK: define void @_ZN6Test101B3fooEPNS_1AE(
160  // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE(
161  void B::foo(A*) {}
162}
163
164// PR8492
165namespace Test11 {
166  struct A {
167    void foo() {}
168    void DEFAULT bar() {}
169  };
170
171  void test() {
172    A a;
173    a.foo();
174    a.bar();
175  }
176
177  // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv(
178  // CHECK: define linkonce_odr void @_ZN6Test111A3barEv(
179  // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv(
180  // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv(
181}
182
183// Tested at top of file.
184namespace Test12 {
185  struct A {
186    // This is hidden in all cases: the explicit attribute takes
187    // priority over -fvisibility on the parent.
188    static int hidden HIDDEN;
189
190    // This is default in all cases because it's only a declaration.
191    static int visible;
192  };
193
194  void test() {
195    A::hidden = 0;
196    A::visible = 0;
197  }
198}
199
200// Tested at top of file.
201namespace Test13 {
202  struct HIDDEN A {};
203
204  // Should be hidden in all cases.
205  struct B {
206    static A a;
207  };
208  A B::a;
209
210  // Should be default in all cases.
211  struct DEFAULT C {
212    static A a;
213  };
214  A C::a;
215};
216
217// Tested at top of file.
218namespace Test14 {
219  // Neither the visibility of the type nor -fvisibility=hidden should
220  // apply to declarations.
221  extern struct A *var;
222
223  struct A *test() { return var; }
224}
225
226// rdar://problem/8613093
227namespace Test15 {
228  struct A {};
229  template <class T> struct Temp {
230    struct Inner {
231      static char buffer[0];
232    };
233  };
234
235  char *test() {
236    return Temp<A>::Inner::buffer;
237  }
238}
239
240namespace Test16 {
241  struct Base1 { virtual void foo(); };
242  struct Base2 : virtual Base1 { virtual void foo(); };
243  template <class T> struct A : virtual Base1, Base2 {
244    virtual void foo();
245  };
246  extern template struct A<char>;
247
248  void test() {
249    A<char> a;
250    a.foo();
251  }
252}
253