1 | // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s |
2 | // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN |
3 | // For clang, "internal" is just an alias for "hidden". We could use it for some |
4 | // optimization purposes on 32-bit x86, but it's not worth it. |
5 | // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility internal -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN |
6 | |
7 | #define HIDDEN __attribute__((visibility("hidden"))) |
8 | #define PROTECTED __attribute__((visibility("protected"))) |
9 | #define DEFAULT __attribute__((visibility("default"))) |
10 | |
11 | namespace test30 { |
12 | // When H is hidden, it should make X hidden, even if the template argument |
13 | // is not. |
14 | struct H { |
15 | }; |
16 | template<H *T> |
17 | struct X { |
18 | }; |
19 | H DEFAULT a; |
20 | X<&a> b; |
21 | // CHECK: _ZN6test301bE = global |
22 | // CHECK-HIDDEN: _ZN6test301bE = hidden global |
23 | } |
24 | |
25 | namespace test25 { |
26 | template<typename T> |
27 | struct X { |
28 | template<typename U> |
29 | struct definition { |
30 | }; |
31 | }; |
32 | |
33 | class DEFAULT A { }; |
34 | |
35 | X<int>::definition<A> a; |
36 | // CHECK: @_ZN6test251aE = global |
37 | // CHECK-HIDDEN: @_ZN6test251aE = hidden global |
38 | } |
39 | |
40 | namespace test28 { |
41 | class DEFAULT foo { |
42 | }; |
43 | foo myvec; |
44 | // CHECK: @_ZN6test285myvecE = global |
45 | // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global |
46 | } |
47 | |
48 | namespace test29 { |
49 | #pragma GCC visibility push(hidden) |
50 | struct RECT { |
51 | int top; |
52 | }; |
53 | DEFAULT extern RECT data_rect; |
54 | RECT data_rect = { -1}; |
55 | #pragma GCC visibility pop |
56 | // CHECK: @_ZN6test299data_rectE = global |
57 | // CHECK-HIDDEN: @_ZN6test299data_rectE = global |
58 | } |
59 | |
60 | namespace test40 { |
61 | template<typename T> |
62 | struct foo { |
63 | DEFAULT static int bar; |
64 | }; |
65 | template<typename T> |
66 | int foo<T>::bar; |
67 | template struct foo<int>; |
68 | // CHECK: _ZN6test403fooIiE3barE = weak_odr global |
69 | // CHECK-HIDDEN: _ZN6test403fooIiE3barE = weak_odr global |
70 | } |
71 | |
72 | namespace test41 { |
73 | // Unlike gcc we propagate the information that foo not only is hidden, but |
74 | // has been explicitly marked as so. This lets us produce a hidden undefined |
75 | // reference to bar. |
76 | struct HIDDEN foo {}; |
77 | extern foo bar; |
78 | foo *zed() { |
79 | return &bar; |
80 | } |
81 | // CHECK: @_ZN6test413barE = external hidden global |
82 | // CHECK-HIDDEN: @_ZN6test413barE = external hidden global |
83 | } |
84 | |
85 | namespace test48 { |
86 | // Test that we use the visibility of struct foo when instantiating the |
87 | // template. Note that is a case where we disagree with gcc, it produces |
88 | // a default symbol. |
89 | struct HIDDEN foo { |
90 | }; |
91 | DEFAULT foo x; |
92 | |
93 | struct bar { |
94 | template<foo *z> |
95 | struct zed { |
96 | }; |
97 | }; |
98 | |
99 | bar::zed<&x> y; |
100 | // CHECK: _ZN6test481yE = hidden global |
101 | // CHECK-HIDDEN: _ZN6test481yE = hidden global |
102 | } |
103 | |
104 | // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 |
105 | // CHECK: @_ZN5Test71aE = hidden global |
106 | // CHECK: @_ZN5Test71bE = global |
107 | // CHECK: @test9_var = global |
108 | // CHECK-HIDDEN: @test9_var = global |
109 | // CHECK: @_ZN6Test121A6hiddenE = external hidden global |
110 | // CHECK: @_ZN6Test121A7visibleE = external global |
111 | // CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global |
112 | // CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global |
113 | // CHECK: @_ZN6Test131B1aE = hidden global |
114 | // CHECK: @_ZN6Test131C1aE = global |
115 | // CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global |
116 | // CHECK-HIDDEN: @_ZN6Test131C1aE = global |
117 | // CHECK: @_ZN6Test143varE = external global |
118 | // CHECK-HIDDEN: @_ZN6Test143varE = external global |
119 | // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] |
120 | // CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] |
121 | |
122 | namespace test27 { |
123 | template<typename T> |
124 | class C { |
125 | class DEFAULT D { |
126 | void f(); |
127 | }; |
128 | }; |
129 | |
130 | template<> |
131 | class C<int>::D { |
132 | virtual void g(); |
133 | }; |
134 | |
135 | void C<int>::D::g() { |
136 | } |
137 | // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant |
138 | // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant |
139 | } |
140 | |
141 | // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant |
142 | |
143 | // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant |
144 | // CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant |
145 | |
146 | // CHECK: @_ZZN6test681fC1EvE4test = linkonce_odr global |
147 | // CHECK-HIDDEN: @_ZZN6test681fC1EvE4test = linkonce_odr hidden global |
148 | |
149 | // CHECK: @_ZGVZN6test681fC1EvE4test = linkonce_odr global |
150 | // CHECK-HIDDEN: @_ZGVZN6test681fC1EvE4test = linkonce_odr hidden global |
151 | |
152 | // CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global |
153 | // CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global |
154 | |
155 | // CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 |
156 | // CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 |
157 | |
158 | namespace Test1 { |
159 | // CHECK-LABEL: define hidden void @_ZN5Test11fEv |
160 | void HIDDEN f() { } |
161 | |
162 | } |
163 | |
164 | namespace Test2 { |
165 | struct HIDDEN A { |
166 | void f(); |
167 | }; |
168 | |
169 | // A::f is a member function of a hidden class. |
170 | // CHECK-LABEL: define hidden void @_ZN5Test21A1fEv |
171 | void A::f() { } |
172 | } |
173 | |
174 | namespace Test3 { |
175 | struct HIDDEN A { |
176 | struct B { |
177 | void f(); |
178 | }; |
179 | }; |
180 | |
181 | // B is a nested class where its parent class is hidden. |
182 | // CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv |
183 | void A::B::f() { } |
184 | } |
185 | |
186 | namespace Test4 HIDDEN { |
187 | int VariableInHiddenNamespace = 10; |
188 | |
189 | // Test4::g is in a hidden namespace. |
190 | // CHECK-LABEL: define hidden void @_ZN5Test41gEv |
191 | void g() { } |
192 | |
193 | struct DEFAULT A { |
194 | void f(); |
195 | }; |
196 | |
197 | // A has default visibility. |
198 | // CHECK-LABEL: define void @_ZN5Test41A1fEv |
199 | void A::f() { } |
200 | } |
201 | |
202 | namespace Test5 { |
203 | |
204 | namespace NS HIDDEN { |
205 | // f is in NS which is hidden. |
206 | // CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv() |
207 | void f() { } |
208 | } |
209 | |
210 | namespace NS { |
211 | // g is in NS, but this NS decl is not hidden. |
212 | // CHECK-LABEL: define void @_ZN5Test52NS1gEv |
213 | void g() { } |
214 | } |
215 | } |
216 | |
217 | // <rdar://problem/8091955> |
218 | namespace Test6 { |
219 | struct HIDDEN foo { |
220 | foo() { } |
221 | void bonk(); |
222 | virtual void bar() = 0; |
223 | |
224 | virtual void zonk() {} |
225 | }; |
226 | |
227 | struct barc : public foo { |
228 | barc(); |
229 | virtual void bar(); |
230 | }; |
231 | |
232 | barc::barc() {} |
233 | } |
234 | |
235 | namespace Test7 { |
236 | class HIDDEN A {}; |
237 | A a; // top of file |
238 | |
239 | template <A&> struct Aref { |
240 | static void foo() {} |
241 | }; |
242 | |
243 | class B : public A {}; |
244 | B b; // top of file |
245 | |
246 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefIL_ZNS_1aEEE3fooEv() |
247 | void test() { |
248 | Aref<a>::foo(); |
249 | } |
250 | } |
251 | |
252 | namespace Test8 { |
253 | void foo(); |
254 | void bar() {} |
255 | // CHECK-HIDDEN-LABEL: define hidden void @_ZN5Test83barEv() |
256 | // CHECK-HIDDEN: declare void @_ZN5Test83fooEv() |
257 | |
258 | void test() { |
259 | foo(); |
260 | bar(); |
261 | } |
262 | } |
263 | |
264 | // PR8457 |
265 | namespace Test9 { |
266 | extern "C" { |
267 | struct A { int field; }; |
268 | void DEFAULT test9_fun(struct A *a) { } |
269 | struct A DEFAULT test9_var; // above |
270 | } |
271 | // CHECK-LABEL: define void @test9_fun( |
272 | // CHECK-HIDDEN-LABEL: define void @test9_fun( |
273 | |
274 | void test() { |
275 | A a = test9_var; |
276 | test9_fun(&a); |
277 | } |
278 | } |
279 | |
280 | // PR8478 |
281 | namespace Test10 { |
282 | struct A; |
283 | |
284 | class DEFAULT B { |
285 | void foo(A*); |
286 | }; |
287 | |
288 | // CHECK-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( |
289 | // CHECK-HIDDEN-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( |
290 | void B::foo(A*) {} |
291 | } |
292 | |
293 | // PR8492 |
294 | namespace Test11 { |
295 | struct A { |
296 | void foo() {} |
297 | void DEFAULT bar() {} |
298 | }; |
299 | |
300 | void test() { |
301 | A a; |
302 | a.foo(); |
303 | a.bar(); |
304 | } |
305 | |
306 | // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3fooEv( |
307 | // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3barEv( |
308 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6Test111A3fooEv( |
309 | // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6Test111A3barEv( |
310 | } |
311 | |
312 | // Tested at top of file. |
313 | namespace Test12 { |
314 | struct A { |
315 | // This is hidden in all cases: the explicit attribute takes |
316 | // priority over -fvisibility on the parent. |
317 | static int hidden HIDDEN; |
318 | |
319 | // This is default in all cases because it's only a declaration. |
320 | static int visible; |
321 | }; |
322 | |
323 | void test() { |
324 | A::hidden = 0; |
325 | A::visible = 0; |
326 | } |
327 | } |
328 | |
329 | // Tested at top of file. |
330 | namespace Test13 { |
331 | struct HIDDEN A {}; |
332 | |
333 | // Should be hidden in all cases. |
334 | struct B { |
335 | static A a; |
336 | }; |
337 | A B::a; |
338 | |
339 | // Should be default in all cases. |
340 | struct DEFAULT C { |
341 | static A a; |
342 | }; |
343 | A C::a; |
344 | }; |
345 | |
346 | // Tested at top of file. |
347 | namespace Test14 { |
348 | // Neither the visibility of the type nor -fvisibility=hidden should |
349 | // apply to declarations. |
350 | extern struct A *var; |
351 | |
352 | struct A *test() { return var; } |
353 | } |
354 | |
355 | // rdar://problem/8613093 |
356 | namespace Test15 { |
357 | struct A {}; |
358 | template <class T> struct Temp { |
359 | struct Inner { |
360 | static char buffer[0]; |
361 | }; |
362 | }; |
363 | |
364 | char *test() { |
365 | return Temp<A>::Inner::buffer; |
366 | } |
367 | } |
368 | |
369 | namespace Test16 { |
370 | struct Base1 { virtual void foo(); }; |
371 | struct Base2 : virtual Base1 { virtual void foo(); }; |
372 | template <class T> struct A : virtual Base1, Base2 { |
373 | virtual void foo(); |
374 | }; |
375 | extern template struct A<char>; |
376 | |
377 | void test() { |
378 | A<char> a; |
379 | a.foo(); |
380 | } |
381 | } |
382 | |
383 | namespace Test17 { |
384 | struct HIDDEN A { |
385 | static void foo(); |
386 | static void DEFAULT bar(); |
387 | static void HIDDEN baz(); |
388 | |
389 | struct DEFAULT B { |
390 | static void foo(); |
391 | static void DEFAULT bar(); |
392 | static void HIDDEN baz(); |
393 | }; |
394 | }; |
395 | |
396 | void test() { |
397 | A::foo(); |
398 | A::bar(); |
399 | A::baz(); |
400 | A::B::foo(); |
401 | A::B::bar(); |
402 | A::B::baz(); |
403 | } |
404 | // CHECK: declare hidden void @_ZN6Test171A3fooEv() |
405 | // CHECK: declare void @_ZN6Test171A3barEv() |
406 | // CHECK: declare hidden void @_ZN6Test171A3bazEv() |
407 | // CHECK: declare void @_ZN6Test171A1B3fooEv() |
408 | // CHECK: declare void @_ZN6Test171A1B3barEv() |
409 | // CHECK: declare hidden void @_ZN6Test171A1B3bazEv() |
410 | // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv() |
411 | // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv() |
412 | // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv() |
413 | // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv() |
414 | // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv() |
415 | // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv() |
416 | } |
417 | |
418 | namespace Test18 { |
419 | template <class T> struct HIDDEN A { |
420 | static void foo(); |
421 | static void DEFAULT bar(); |
422 | static void HIDDEN baz(); |
423 | |
424 | struct DEFAULT B { |
425 | static void foo(); |
426 | static void DEFAULT bar(); |
427 | static void HIDDEN baz(); |
428 | }; |
429 | }; |
430 | struct HIDDEN H; |
431 | |
432 | void test() { |
433 | A<int>::foo(); |
434 | A<int>::bar(); |
435 | A<int>::baz(); |
436 | A<int>::B::foo(); |
437 | A<int>::B::bar(); |
438 | A<int>::B::baz(); |
439 | A<H>::foo(); |
440 | A<H>::bar(); |
441 | A<H>::baz(); |
442 | A<H>::B::foo(); |
443 | A<H>::B::bar(); |
444 | A<H>::B::baz(); |
445 | } |
446 | // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv() |
447 | // CHECK: declare void @_ZN6Test181AIiE3barEv() |
448 | // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv() |
449 | // CHECK: declare void @_ZN6Test181AIiE1B3fooEv() |
450 | // CHECK: declare void @_ZN6Test181AIiE1B3barEv() |
451 | // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv() |
452 | // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() |
453 | // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv() |
454 | // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() |
455 | // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() |
456 | // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() |
457 | // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() |
458 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv() |
459 | // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv() |
460 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv() |
461 | // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv() |
462 | // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv() |
463 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv() |
464 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() |
465 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv() |
466 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() |
467 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() |
468 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() |
469 | // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() |
470 | } |
471 | |
472 | namespace Test19 { |
473 | struct A { A(); ~A(); }; |
474 | |
475 | // Tested at top of file. |
476 | template <class T> void foo() { |
477 | static A a; |
478 | } |
479 | |
480 | void test() { |
481 | foo<int>(); |
482 | } |
483 | } |
484 | |
485 | // Various things with class template specializations. |
486 | namespace Test20 { |
487 | template <unsigned> struct HIDDEN A {}; |
488 | |
489 | // An explicit specialization inherits the explicit visibility of |
490 | // the template. |
491 | template <> struct A<0> { |
492 | static void test0(); |
493 | static void test1(); |
494 | }; |
495 | |
496 | // CHECK-LABEL: define hidden void @_ZN6Test201AILj0EE5test0Ev() |
497 | void A<0>::test0() {} |
498 | |
499 | // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev() |
500 | void test1() { |
501 | A<0>::test1(); |
502 | } |
503 | |
504 | // ...unless that's explicitly overridden. |
505 | template <> struct DEFAULT A<1> { |
506 | static void test2(); |
507 | static void test3(); |
508 | }; |
509 | |
510 | // CHECK-LABEL: define void @_ZN6Test201AILj1EE5test2Ev() |
511 | void A<1>::test2() {} |
512 | |
513 | // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev() |
514 | void test3() { |
515 | A<1>::test3(); |
516 | } |
517 | |
518 | // <rdar://problem/8778497> |
519 | // But we should assume that an unknown specialization has the |
520 | // explicit visibility settings of the template. |
521 | template <class T> struct B { |
522 | static void test4() {} |
523 | static void test5(); |
524 | }; |
525 | |
526 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev() |
527 | void test4() { |
528 | B<A<2> >::test4(); |
529 | } |
530 | |
531 | // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev() |
532 | void test5() { |
533 | B<A<2> >::test5(); |
534 | } |
535 | } |
536 | |
537 | // PR9371 |
538 | namespace test21 { |
539 | enum En { en }; |
540 | template<En> struct A { |
541 | DEFAULT void foo() {} |
542 | }; |
543 | |
544 | // CHECK-LABEL: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv( |
545 | template void A<en>::foo(); |
546 | } |
547 | |
548 | // rdar://problem/9616154 |
549 | // Visibility on explicit specializations should take precedence. |
550 | namespace test22 { |
551 | class A1 {}; |
552 | class A2 {}; |
553 | |
554 | template <class T> struct B {}; |
555 | template <> struct DEFAULT B<A1> { |
556 | static void foo(); |
557 | static void bar() {} |
558 | }; |
559 | template <> struct B<A2> { |
560 | static void foo(); |
561 | static void bar() {} |
562 | }; |
563 | |
564 | void test() { |
565 | B<A1>::foo(); |
566 | B<A1>::bar(); |
567 | B<A2>::foo(); |
568 | B<A2>::bar(); |
569 | } |
570 | // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv() |
571 | // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() |
572 | // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv() |
573 | // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv() |
574 | // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv() |
575 | // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() |
576 | // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv() |
577 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv() |
578 | } |
579 | |
580 | namespace PR10113 { |
581 | namespace foo DEFAULT { |
582 | template<typename T> |
583 | class bar { |
584 | void zed() {} |
585 | }; |
586 | } |
587 | template class foo::bar<char>; |
588 | // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv |
589 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv |
590 | |
591 | struct zed { |
592 | }; |
593 | template class foo::bar<zed>; |
594 | // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv |
595 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv |
596 | } |
597 | |
598 | namespace PR11690 { |
599 | template<class T> struct Class { |
600 | void size() const { |
601 | } |
602 | }; |
603 | template class DEFAULT Class<char>; |
604 | // CHECK-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv |
605 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv |
606 | |
607 | template<class T> void Method() {} |
608 | template DEFAULT void Method<char>(); |
609 | // CHECK-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv |
610 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv |
611 | } |
612 | |
613 | namespace PR11690_2 { |
614 | namespace foo DEFAULT { |
615 | class bar; |
616 | template<typename T1, typename T2 = bar> |
617 | class zed { |
618 | void bar() { |
619 | } |
620 | }; |
621 | } |
622 | struct baz { |
623 | }; |
624 | template class foo::zed<baz>; |
625 | // CHECK-LABEL: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv |
626 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv |
627 | } |
628 | |
629 | namespace test23 { |
630 | // Having a template argument that is explicitly visible should not make |
631 | // the template instantiation visible. |
632 | template <typename T> |
633 | struct X { |
634 | static void f() { |
635 | } |
636 | }; |
637 | |
638 | class DEFAULT A; |
639 | |
640 | void g() { |
641 | X<A> y; |
642 | y.f(); |
643 | } |
644 | // CHECK-LABEL: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv |
645 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv |
646 | } |
647 | |
648 | namespace PR12001 { |
649 | template <typename P1> |
650 | void Bind(const P1& p1) { |
651 | } |
652 | |
653 | class DEFAULT Version { }; |
654 | |
655 | void f() { |
656 | Bind(Version()); |
657 | } |
658 | // CHECK-LABEL: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_ |
659 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_ |
660 | } |
661 | |
662 | namespace test24 { |
663 | class DEFAULT A { }; |
664 | |
665 | struct S { |
666 | template <typename T> |
667 | void mem() {} |
668 | }; |
669 | |
670 | void test() { |
671 | S s; |
672 | s.mem<A>(); |
673 | } |
674 | // CHECK-LABEL: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv |
675 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv |
676 | } |
677 | |
678 | namespace test26 { |
679 | template<typename T> |
680 | class C { |
681 | DEFAULT void f(); |
682 | }; |
683 | |
684 | template<> |
685 | void C<int>::f() { } |
686 | |
687 | // CHECK-LABEL: define void @_ZN6test261CIiE1fEv |
688 | // CHECK-HIDDEN-LABEL: define void @_ZN6test261CIiE1fEv |
689 | } |
690 | |
691 | namespace test31 { |
692 | struct A { |
693 | struct HIDDEN B { |
694 | static void DEFAULT baz(); |
695 | }; |
696 | }; |
697 | void f() { |
698 | A::B::baz(); |
699 | } |
700 | // CHECK: declare void @_ZN6test311A1B3bazEv() |
701 | // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv() |
702 | } |
703 | |
704 | namespace test32 { |
705 | struct HIDDEN A { |
706 | struct DEFAULT B { |
707 | void DEFAULT baz(); |
708 | }; |
709 | }; |
710 | void A::B::baz() { |
711 | } |
712 | // CHECK-LABEL: define void @_ZN6test321A1B3bazEv |
713 | // CHECK-HIDDEN-LABEL: define void @_ZN6test321A1B3bazEv |
714 | } |
715 | |
716 | namespace test33 { |
717 | template<typename T> |
718 | class foo { |
719 | void bar() {} |
720 | }; |
721 | struct HIDDEN zed { |
722 | }; |
723 | template class DEFAULT foo<zed>; |
724 | // CHECK-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv |
725 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv |
726 | } |
727 | |
728 | namespace test34 { |
729 | struct foo { |
730 | }; |
731 | template<class T> |
732 | void bar() {} |
733 | template DEFAULT void bar<foo>(); |
734 | // CHECK-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv |
735 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv |
736 | } |
737 | |
738 | namespace test35 { |
739 | // This is a really ugly testcase. GCC propagates the DEFAULT in zed's |
740 | // definition. It's not really clear what we can do here, because we |
741 | // produce the symbols before even seeing the DEFAULT definition of zed. |
742 | // FIXME: Maybe the best thing to do here is error? It's certainly hard |
743 | // to argue that this ought to be valid. |
744 | template<typename T> |
745 | struct DEFAULT foo { |
746 | void bar() {} |
747 | }; |
748 | class zed; |
749 | template class foo<zed>; |
750 | class DEFAULT zed { |
751 | }; |
752 | // CHECK-LABEL: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv |
753 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test353fooINS_3zedEE3barEv |
754 | } |
755 | |
756 | namespace test36 { |
757 | template<typename T1, typename T2> |
758 | class foo { |
759 | void bar() {} |
760 | }; |
761 | class DEFAULT S1 {}; |
762 | struct HIDDEN S2 {}; |
763 | template class foo<S1, S2>; |
764 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv |
765 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv |
766 | } |
767 | |
768 | namespace test37 { |
769 | struct HIDDEN foo { |
770 | }; |
771 | template<class T> |
772 | DEFAULT void bar() {} |
773 | template DEFAULT void bar<foo>(); |
774 | // CHECK-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv |
775 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv |
776 | } |
777 | |
778 | namespace test38 { |
779 | template<typename T> |
780 | class DEFAULT foo { |
781 | void bar() {} |
782 | }; |
783 | struct HIDDEN zed { |
784 | }; |
785 | template class foo<zed>; |
786 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv |
787 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv |
788 | } |
789 | |
790 | namespace test39 { |
791 | class DEFAULT default_t; |
792 | class HIDDEN hidden_t; |
793 | template <class T> class A { |
794 | template <class U> class B { |
795 | HIDDEN void hidden() {} |
796 | void noattr() {} |
797 | template <class V> void temp() {} |
798 | }; |
799 | }; |
800 | template class DEFAULT A<hidden_t>; |
801 | template class DEFAULT A<hidden_t>::B<hidden_t>; |
802 | template void A<hidden_t>::B<hidden_t>::temp<default_t>(); |
803 | template void A<hidden_t>::B<hidden_t>::temp<hidden_t>(); |
804 | |
805 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv |
806 | // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv |
807 | // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv |
808 | |
809 | // GCC produces a default for this one. Why? |
810 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv |
811 | |
812 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv |
813 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv |
814 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv |
815 | |
816 | // GCC produces a default for this one. Why? |
817 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv |
818 | } |
819 | |
820 | namespace test42 { |
821 | struct HIDDEN foo { |
822 | }; |
823 | template <class P> |
824 | struct bar { |
825 | }; |
826 | template <> |
827 | struct HIDDEN bar<foo> { |
828 | DEFAULT static void zed(); |
829 | }; |
830 | void bar<foo>::zed() { |
831 | } |
832 | // CHECK-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv |
833 | // CHECK-HIDDEN-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv |
834 | } |
835 | |
836 | namespace test43 { |
837 | struct HIDDEN foo { |
838 | }; |
839 | template <class P> |
840 | void bar() { |
841 | } |
842 | template <> |
843 | DEFAULT void bar<foo>() { |
844 | } |
845 | // CHECK-LABEL: define void @_ZN6test433barINS_3fooEEEvv |
846 | // CHECK-HIDDEN-LABEL: define void @_ZN6test433barINS_3fooEEEvv |
847 | } |
848 | |
849 | namespace test44 { |
850 | template <typename T> |
851 | struct foo { |
852 | foo() {} |
853 | }; |
854 | namespace { |
855 | struct bar; |
856 | } |
857 | template struct DEFAULT foo<bar>; |
858 | foo<bar> x; |
859 | // CHECK-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev |
860 | // CHECK-HIDDEN-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev |
861 | } |
862 | |
863 | namespace test45 { |
864 | template <typename T> |
865 | struct foo { |
866 | template <typename T2> |
867 | struct bar { |
868 | bar() {}; |
869 | }; |
870 | }; |
871 | namespace { |
872 | struct zed; |
873 | } |
874 | template struct DEFAULT foo<int>::bar<zed>; |
875 | foo<int>::bar<zed> x; |
876 | // CHECK-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev |
877 | // CHECK-HIDDEN-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev |
878 | } |
879 | |
880 | namespace test46 { |
881 | template <typename T> |
882 | void foo() { |
883 | } |
884 | namespace { |
885 | struct bar; |
886 | } |
887 | template DEFAULT void foo<bar>(); |
888 | void zed() { |
889 | foo<bar>(); |
890 | } |
891 | // CHECK-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv |
892 | // CHECK-HIDDEN-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv |
893 | } |
894 | |
895 | namespace test47 { |
896 | struct foo { |
897 | template <typename T> |
898 | static void bar() { |
899 | } |
900 | }; |
901 | namespace { |
902 | struct zed; |
903 | } |
904 | template DEFAULT void foo::bar<zed>(); |
905 | void baz() { |
906 | foo::bar<zed>(); |
907 | } |
908 | // CHECK-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv |
909 | // CHECK-HIDDEN-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv |
910 | } |
911 | |
912 | namespace test49 { |
913 | // Test that we use the visibility of struct foo when instantiating the |
914 | // template. Note that is a case where we disagree with gcc, it produces |
915 | // a default symbol. |
916 | |
917 | struct HIDDEN foo { |
918 | }; |
919 | |
920 | DEFAULT foo x; |
921 | |
922 | struct bar { |
923 | template<foo *z> |
924 | void zed() { |
925 | } |
926 | }; |
927 | |
928 | template void bar::zed<&x>(); |
929 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv |
930 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv |
931 | } |
932 | |
933 | namespace test50 { |
934 | // Test that we use the visibility of struct foo when instantiating the |
935 | // template. Note that is a case where we disagree with gcc, it produces |
936 | // a default symbol. |
937 | |
938 | struct HIDDEN foo { |
939 | }; |
940 | DEFAULT foo x; |
941 | template<foo *z> |
942 | struct DEFAULT bar { |
943 | void zed() { |
944 | } |
945 | }; |
946 | template void bar<&x>::zed(); |
947 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv |
948 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv |
949 | } |
950 | |
951 | namespace test51 { |
952 | // Test that we use the visibility of struct foo when instantiating the |
953 | // template. Note that is a case where we disagree with gcc, it produces |
954 | // a default symbol. |
955 | |
956 | struct HIDDEN foo { |
957 | }; |
958 | DEFAULT foo x; |
959 | template<foo *z> |
960 | void DEFAULT zed() { |
961 | } |
962 | template void zed<&x>(); |
963 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv |
964 | // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv |
965 | } |
966 | |
967 | namespace test52 { |
968 | // Test that we use the linkage of struct foo when instantiating the |
969 | // template. Note that is a case where we disagree with gcc, it produces |
970 | // an external symbol. |
971 | |
972 | namespace { |
973 | struct foo { |
974 | }; |
975 | } |
976 | template<foo *x> |
977 | void zed() { |
978 | } |
979 | void f() { |
980 | zed<nullptr>(); |
981 | } |
982 | // CHECK-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv |
983 | // CHECK-HIDDEN-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv |
984 | } |
985 | |
986 | namespace test53 { |
987 | template<typename _Tp > struct vector { |
988 | static void _M_fill_insert(); |
989 | }; |
990 | #pragma GCC visibility push(hidden) |
991 | // GCC doesn't seem to use the visibility of enums at all, we do. |
992 | enum zed {v1}; |
993 | |
994 | // GCC fails to mark this specialization hidden, we mark it. |
995 | template<> |
996 | struct vector<int> { |
997 | static void _M_fill_insert(); |
998 | }; |
999 | void foo() { |
1000 | vector<unsigned>::_M_fill_insert(); |
1001 | vector<int>::_M_fill_insert(); |
1002 | vector<zed>::_M_fill_insert(); |
1003 | } |
1004 | #pragma GCC visibility pop |
1005 | // CHECK: declare void @_ZN6test536vectorIjE14_M_fill_insertEv |
1006 | // CHECK-HIDDEN: declare void @_ZN6test536vectorIjE14_M_fill_insertEv |
1007 | // CHECK: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv |
1008 | // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv |
1009 | // CHECK: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv |
1010 | // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv |
1011 | } |
1012 | |
1013 | namespace test54 { |
1014 | template <class T> |
1015 | struct foo { |
1016 | static void bar(); |
1017 | }; |
1018 | #pragma GCC visibility push(hidden) |
1019 | class zed { |
1020 | zed(const zed &); |
1021 | }; |
1022 | void bah() { |
1023 | foo<zed>::bar(); |
1024 | } |
1025 | #pragma GCC visibility pop |
1026 | // CHECK: declare hidden void @_ZN6test543fooINS_3zedEE3barEv |
1027 | // CHECK-HIDDEN: declare hidden void @_ZN6test543fooINS_3zedEE3barEv |
1028 | } |
1029 | |
1030 | namespace test55 { |
1031 | template <class T> |
1032 | struct HIDDEN foo { |
1033 | static void bar(); |
1034 | }; |
1035 | template <class T> struct foo; |
1036 | void foobar() { |
1037 | foo<int>::bar(); |
1038 | } |
1039 | // CHECK: declare hidden void @_ZN6test553fooIiE3barEv |
1040 | // CHECK-HIDDEN: declare hidden void @_ZN6test553fooIiE3barEv |
1041 | } |
1042 | |
1043 | namespace test56 { |
1044 | template <class T> struct foo; |
1045 | template <class T> |
1046 | struct HIDDEN foo { |
1047 | static void bar(); |
1048 | }; |
1049 | void foobar() { |
1050 | foo<int>::bar(); |
1051 | } |
1052 | // CHECK: declare hidden void @_ZN6test563fooIiE3barEv |
1053 | // CHECK-HIDDEN: declare hidden void @_ZN6test563fooIiE3barEv |
1054 | } |
1055 | |
1056 | namespace test57 { |
1057 | #pragma GCC visibility push(hidden) |
1058 | template <class T> |
1059 | struct foo; |
1060 | void bar(foo<int>*); |
1061 | template <class T> |
1062 | struct foo { |
1063 | static void zed(); |
1064 | }; |
1065 | void bah() { |
1066 | foo<int>::zed(); |
1067 | } |
1068 | #pragma GCC visibility pop |
1069 | // CHECK: declare hidden void @_ZN6test573fooIiE3zedEv |
1070 | // CHECK-HIDDEN: declare hidden void @_ZN6test573fooIiE3zedEv |
1071 | } |
1072 | |
1073 | namespace test58 { |
1074 | #pragma GCC visibility push(hidden) |
1075 | struct foo; |
1076 | template<typename T> |
1077 | struct DEFAULT bar { |
1078 | static void zed() { |
1079 | } |
1080 | }; |
1081 | void bah() { |
1082 | bar<foo>::zed(); |
1083 | } |
1084 | #pragma GCC visibility pop |
1085 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv |
1086 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv |
1087 | } |
1088 | |
1089 | namespace test59 { |
1090 | DEFAULT int f(); |
1091 | HIDDEN int g(); |
1092 | typedef int (*foo)(); |
1093 | template<foo x, foo y> |
1094 | void test() {} |
1095 | void use() { |
1096 | test<&g, &f>(); |
1097 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv |
1098 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv |
1099 | |
1100 | test<&f, &g>(); |
1101 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv |
1102 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv |
1103 | } |
1104 | } |
1105 | |
1106 | namespace test60 { |
1107 | template<int i> |
1108 | class HIDDEN a {}; |
1109 | template<int i> |
1110 | class DEFAULT b {}; |
1111 | template<template<int> class x, template<int> class y> |
1112 | void test() {} |
1113 | void use() { |
1114 | test<a, b>(); |
1115 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv |
1116 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv |
1117 | |
1118 | test<b, a>(); |
1119 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv |
1120 | // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv |
1121 | } |
1122 | } |
1123 | |
1124 | namespace test61 { |
1125 | template <typename T1> |
1126 | struct Class1 |
1127 | { |
1128 | void f1() { f2(); } |
1129 | inline void f2(); |
1130 | }; |
1131 | template<> |
1132 | inline void Class1<int>::f2() |
1133 | { |
1134 | } |
1135 | void g(Class1<int> *x) { |
1136 | x->f1(); |
1137 | } |
1138 | } |
1139 | namespace test61 { |
1140 | // Just test that we don't crash. Currently we apply this attribute. Current |
1141 | // gcc issues a warning about it being unused since "the type is already |
1142 | // defined". We should probably do the same. |
1143 | template class HIDDEN Class1<int>; |
1144 | } |
1145 | |
1146 | namespace test62 { |
1147 | template <typename T1> |
1148 | struct Class1 |
1149 | { |
1150 | void f1() { f2(); } |
1151 | inline void f2() {} |
1152 | }; |
1153 | template<> |
1154 | inline void Class1<int>::f2() |
1155 | { |
1156 | } |
1157 | void g(Class1<int> *x) { |
1158 | x->f2(); |
1159 | } |
1160 | } |
1161 | namespace test62 { |
1162 | template class HIDDEN Class1<int>; |
1163 | // Just test that we don't crash. Currently we apply this attribute. Current |
1164 | // gcc issues a warning about it being unused since "the type is already |
1165 | // defined". We should probably do the same. |
1166 | } |
1167 | |
1168 | namespace test63 { |
1169 | enum HIDDEN E { E0 }; |
1170 | struct A { |
1171 | template <E> static void foo() {} |
1172 | |
1173 | template <E> struct B { |
1174 | static void foo() {} |
1175 | }; |
1176 | }; |
1177 | |
1178 | void test() { |
1179 | A::foo<E0>(); |
1180 | A::B<E0>::foo(); |
1181 | } |
1182 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A3fooILNS_1EE0EEEvv() |
1183 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A1BILNS_1EE0EE3fooEv() |
1184 | } |
1185 | |
1186 | // Don't ignore the visibility of template arguments just because we |
1187 | // explicitly instantiated something. |
1188 | namespace test64 { |
1189 | struct HIDDEN A {}; |
1190 | template <class P> struct B { |
1191 | static DEFAULT void foo() {} |
1192 | }; |
1193 | |
1194 | template class B<A>; |
1195 | // CHECK-LABEL: define weak_odr hidden void @_ZN6test641BINS_1AEE3fooEv() |
1196 | } |
1197 | |
1198 | namespace test65 { |
1199 | class HIDDEN A {}; |
1200 | template <class T> struct B { |
1201 | static void func(); |
1202 | template <class U> static void funcT1(); |
1203 | template <class U> static void funcT2(); |
1204 | class Inner {}; |
1205 | template <class U> class InnerT {}; |
1206 | }; |
1207 | template <template <class T> class Temp> struct C { |
1208 | static void foo() {} |
1209 | }; |
1210 | |
1211 | // CHECK-LABEL: define void @_ZN6test651BINS_1AEE4funcEv() |
1212 | template <> DEFAULT void B<A>::func() {} |
1213 | |
1214 | // CHECK-LABEL: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv() |
1215 | template <> template <> DEFAULT void B<A>::funcT2<A>() {} |
1216 | |
1217 | // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6funcT1IiEEvv() |
1218 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6funcT1IS1_EEvv() |
1219 | template <> template <class T> DEFAULT void B<A>::funcT1() {} |
1220 | |
1221 | // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE5Inner3fooEv() |
1222 | template <> struct DEFAULT B<A>::Inner { |
1223 | static void foo() {} |
1224 | }; |
1225 | |
1226 | // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6InnerTIiE3fooEv() |
1227 | // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6InnerTIS1_E3fooEv() |
1228 | template <> template <class U> struct DEFAULT B<A>::InnerT { |
1229 | static void foo() {} |
1230 | }; |
1231 | |
1232 | void test() { |
1233 | B<A>::funcT1<int>(); |
1234 | B<A>::funcT1<A>(); |
1235 | B<A>::Inner::foo(); |
1236 | B<A>::InnerT<int>::foo(); |
1237 | B<A>::InnerT<A>::foo(); |
1238 | } |
1239 | |
1240 | template class C<B<A>::InnerT>; |
1241 | } |
1242 | |
1243 | namespace test66 { |
1244 | template <typename T> |
1245 | struct DEFAULT barT { |
1246 | static void zed() {} |
1247 | }; |
1248 | class foo; |
1249 | class DEFAULT foo; |
1250 | template struct barT<foo>; |
1251 | // CHECK-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv |
1252 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv |
1253 | |
1254 | template <int* I> |
1255 | struct DEFAULT barI { |
1256 | static void zed() {} |
1257 | }; |
1258 | extern int I; |
1259 | extern int I DEFAULT; |
1260 | template struct barI<&I>; |
1261 | // CHECK-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv |
1262 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv |
1263 | |
1264 | typedef void (*fType)(void); |
1265 | template<fType F> |
1266 | struct DEFAULT barF { |
1267 | static void zed() {} |
1268 | }; |
1269 | void F(); |
1270 | void F() DEFAULT; |
1271 | template struct barF<F>; |
1272 | // CHECK-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv |
1273 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv |
1274 | } |
1275 | |
1276 | namespace test67 { |
1277 | template <typename T> |
1278 | struct DEFAULT bar { |
1279 | static void zed() {} |
1280 | }; |
1281 | |
1282 | class foo; |
1283 | class compute { |
1284 | void f(foo *rootfoo); |
1285 | }; |
1286 | class DEFAULT foo; |
1287 | |
1288 | template struct bar<foo>; |
1289 | // CHECK-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv |
1290 | // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv |
1291 | } |
1292 | |
1293 | namespace test68 { |
1294 | class A { public: ~A(); }; |
1295 | class f { |
1296 | public: |
1297 | f() { |
1298 | static A test; |
1299 | } |
1300 | }; |
1301 | void g() { |
1302 | f a; |
1303 | } |
1304 | // Check lines at top of file. |
1305 | } |
1306 | |
1307 | namespace test69 { |
1308 | // PR18174 |
1309 | namespace foo { |
1310 | void f(); |
1311 | } |
1312 | namespace foo { |
1313 | void f() {}; |
1314 | } |
1315 | namespace foo __attribute__((visibility("hidden"))) { |
1316 | } |
1317 | // CHECK-LABEL: define void @_ZN6test693foo1fEv |
1318 | // CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv |
1319 | } |
1320 | |