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: @_ZTVN6Test161AIcEE = external unnamed_addr constant
30 // CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
31 // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
32 
33 namespace Test1 {
34   // CHECK: define hidden void @_ZN5Test11fEv
35   void HIDDEN f() { }
36 
37 }
38 
39 namespace 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 
49 namespace 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 
61 namespace 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 
77 namespace 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>
93 namespace 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 
110 namespace 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 
127 namespace 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
140 namespace 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
156 namespace 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
169 namespace 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.
188 namespace 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.
205 namespace 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.
222 namespace 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
231 namespace 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 
244 namespace 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 
258 namespace 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 
293 namespace 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 
347 namespace 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.
361 namespace 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
416 namespace 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 
426 // rdar://problem/9616154
427 // Visibility on explicit specializations should take precedence.
428 namespace test22 {
429   class A1 {};
430   class A2 {};
431 
432   template <class T> struct B {};
433   template <> struct DEFAULT B<A1> {
434     static void foo();
435     static void bar() {}
436   };
437   template <> struct B<A2> {
438     static void foo();
439     static void bar() {}
440   };
441 
442   void test() {
443     B<A1>::foo();
444     B<A1>::bar();
445     B<A2>::foo();
446     B<A2>::bar();
447   }
448   // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv()
449   // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
450   // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv()
451   // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv()
452   // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv()
453   // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv()
454   // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv()
455   // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv()
456 }
457