blob: 0f36a6a753248ae90b6a6e3420cae35486318b9c [file] [log] [blame]
Anders Carlsson39de84d2010-02-07 01:44:36 +00001// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
John McCall1fb0caa2010-10-22 21:05:15 +00002// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN
Anders Carlsson39de84d2010-02-07 01:44:36 +00003
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
John McCall1fb0caa2010-10-22 21:05:15 +00009// CHECK: @_ZN5Test71aE = hidden global
10// CHECK: @_ZN5Test71bE = global
John McCallac65c622010-10-26 04:59:26 +000011// CHECK: @test9_var = global
12// CHECK-HIDDEN: @test9_var = global
John McCall110e8e52010-10-29 22:22:43 +000013// 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
John McCallee301022010-10-30 09:18:49 +000023// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
24// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8]
John McCall112c9672010-11-02 21:04:24 +000025// 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
Rafael Espindolacd3ac4b2011-01-15 08:23:14 +000029// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant
Peter Collingbournebf1c5ae2011-09-26 01:56:36 +000030// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant
Anders Carlssonf502d932011-01-24 00:46:19 +000031// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant
John McCall1fb0caa2010-10-22 21:05:15 +000032
Anders Carlsson39de84d2010-02-07 01:44:36 +000033namespace 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}
Douglas Gregorc66bcfd2010-06-14 23:41:45 +000091
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}
John McCall1fb0caa2010-10-22 21:05:15 +0000109
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}
John McCallac65c622010-10-26 04:59:26 +0000138
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}
John McCall67fa6d52010-10-28 07:07:52 +0000154
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}
John McCall0df95872010-10-29 00:29:13 +0000167
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}
John McCall110e8e52010-10-29 22:22:43 +0000186
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}
John McCallee301022010-10-30 09:18:49 +0000229
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}
John McCallaf146032010-10-30 11:50:40 +0000243
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}
John McCall36987482010-11-02 01:45:15 +0000257
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}
John McCall112c9672010-11-02 21:04:24 +0000346
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}
John McCall7f1b9872010-12-18 03:30:47 +0000359
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
John McCall2b364a42010-12-18 03:52:04 +0000406 // CHECK: declare void @_ZN6Test201BINS_1AILj2EEEE5test5Ev()
John McCall7f1b9872010-12-18 03:30:47 +0000407 // (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}
John McCall1a0918a2011-03-04 10:39:25 +0000414
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}
John McCall6ce51ee2011-06-27 23:06:04 +0000425
426// rdar://problem/9616154
427// Visibility on explicit specializations should take precedence.
428namespace 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}