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 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 57namespace test40 { 58 template<typename T> 59 struct foo { 60 DEFAULT static int bar; 61 }; 62 template<typename T> 63 int foo<T>::bar; 64 template struct foo<int>; 65 // CHECK: _ZN6test403fooIiE3barE = weak_odr global 66 // CHECK-HIDDEN: _ZN6test403fooIiE3barE = weak_odr global 67} 68 69namespace test41 { 70 // Unlike gcc we propagate the information that foo not only is hidden, but 71 // has been explicitly marked as so. This lets us produce a hidden undefined 72 // reference to bar. 73 struct __attribute__((visibility("hidden"))) foo {}; 74 extern foo bar; 75 foo *zed() { 76 return &bar; 77 } 78 // CHECK: @_ZN6test413barE = external hidden global 79 // CHECK-HIDDEN: @_ZN6test413barE = external hidden global 80} 81 82namespace test48 { 83 // Test that we use the visibility of struct foo when instantiating the 84 // template. Note that is a case where we disagree with gcc, it produces 85 // a default symbol. 86 struct HIDDEN foo { 87 }; 88 DEFAULT foo x; 89 90 struct bar { 91 template<foo *z> 92 struct zed { 93 }; 94 }; 95 96 bar::zed<&x> y; 97 // CHECK: _ZN6test481yE = hidden global 98 // CHECK-HIDDEN: _ZN6test481yE = hidden global 99} 100 101// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 102// CHECK: @_ZN5Test71aE = hidden global 103// CHECK: @_ZN5Test71bE = global 104// CHECK: @test9_var = global 105// CHECK-HIDDEN: @test9_var = global 106// CHECK: @_ZN6Test121A6hiddenE = external hidden global 107// CHECK: @_ZN6Test121A7visibleE = external global 108// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global 109// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global 110// CHECK: @_ZN6Test131B1aE = hidden global 111// CHECK: @_ZN6Test131C1aE = global 112// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global 113// CHECK-HIDDEN: @_ZN6Test131C1aE = global 114// CHECK: @_ZN6Test143varE = external global 115// CHECK-HIDDEN: @_ZN6Test143varE = external global 116// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] 117// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] 118 119namespace test27 { 120 template<typename T> 121 class C { 122 class __attribute__((visibility("default"))) D { 123 void f(); 124 }; 125 }; 126 127 template<> 128 class C<int>::D { 129 virtual void g(); 130 }; 131 132 void C<int>::D::g() { 133 } 134 // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant 135 // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant 136} 137 138// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global 139// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 140// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global 141// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 142// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant 143// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant 144// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant 145 146namespace Test1 { 147 // CHECK: define hidden void @_ZN5Test11fEv 148 void HIDDEN f() { } 149 150} 151 152namespace Test2 { 153 struct HIDDEN A { 154 void f(); 155 }; 156 157 // A::f is a member function of a hidden class. 158 // CHECK: define hidden void @_ZN5Test21A1fEv 159 void A::f() { } 160} 161 162namespace Test3 { 163 struct HIDDEN A { 164 struct B { 165 void f(); 166 }; 167 }; 168 169 // B is a nested class where its parent class is hidden. 170 // CHECK: define hidden void @_ZN5Test31A1B1fEv 171 void A::B::f() { } 172} 173 174namespace Test4 HIDDEN { 175 int VariableInHiddenNamespace = 10; 176 177 // Test4::g is in a hidden namespace. 178 // CHECK: define hidden void @_ZN5Test41gEv 179 void g() { } 180 181 struct DEFAULT A { 182 void f(); 183 }; 184 185 // A has default visibility. 186 // CHECK: define void @_ZN5Test41A1fEv 187 void A::f() { } 188} 189 190namespace Test5 { 191 192 namespace NS HIDDEN { 193 // f is in NS which is hidden. 194 // CHECK: define hidden void @_ZN5Test52NS1fEv() 195 void f() { } 196 } 197 198 namespace NS { 199 // g is in NS, but this NS decl is not hidden. 200 // CHECK: define void @_ZN5Test52NS1gEv 201 void g() { } 202 } 203} 204 205// <rdar://problem/8091955> 206namespace Test6 { 207 struct HIDDEN foo { 208 foo() { } 209 void bonk(); 210 virtual void bar() = 0; 211 212 virtual void zonk() {} 213 }; 214 215 struct barc : public foo { 216 barc(); 217 virtual void bar(); 218 }; 219 220 barc::barc() {} 221} 222 223namespace Test7 { 224 class HIDDEN A {}; 225 A a; // top of file 226 227 template <A&> struct Aref { 228 static void foo() {} 229 }; 230 231 class B : public A {}; 232 B b; // top of file 233 234 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv() 235 void test() { 236 Aref<a>::foo(); 237 } 238} 239 240namespace Test8 { 241 void foo(); 242 void bar() {} 243 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv() 244 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv() 245 246 void test() { 247 foo(); 248 bar(); 249 } 250} 251 252// PR8457 253namespace Test9 { 254 extern "C" { 255 struct A { int field; }; 256 void DEFAULT test9_fun(struct A *a) { } 257 struct A DEFAULT test9_var; // above 258 } 259 // CHECK: define void @test9_fun( 260 // CHECK-HIDDEN: define void @test9_fun( 261 262 void test() { 263 A a = test9_var; 264 test9_fun(&a); 265 } 266} 267 268// PR8478 269namespace Test10 { 270 struct A; 271 272 class DEFAULT B { 273 void foo(A*); 274 }; 275 276 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE( 277 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE( 278 void B::foo(A*) {} 279} 280 281// PR8492 282namespace Test11 { 283 struct A { 284 void foo() {} 285 void DEFAULT bar() {} 286 }; 287 288 void test() { 289 A a; 290 a.foo(); 291 a.bar(); 292 } 293 294 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv( 295 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv( 296 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv( 297 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv( 298} 299 300// Tested at top of file. 301namespace Test12 { 302 struct A { 303 // This is hidden in all cases: the explicit attribute takes 304 // priority over -fvisibility on the parent. 305 static int hidden HIDDEN; 306 307 // This is default in all cases because it's only a declaration. 308 static int visible; 309 }; 310 311 void test() { 312 A::hidden = 0; 313 A::visible = 0; 314 } 315} 316 317// Tested at top of file. 318namespace Test13 { 319 struct HIDDEN A {}; 320 321 // Should be hidden in all cases. 322 struct B { 323 static A a; 324 }; 325 A B::a; 326 327 // Should be default in all cases. 328 struct DEFAULT C { 329 static A a; 330 }; 331 A C::a; 332}; 333 334// Tested at top of file. 335namespace Test14 { 336 // Neither the visibility of the type nor -fvisibility=hidden should 337 // apply to declarations. 338 extern struct A *var; 339 340 struct A *test() { return var; } 341} 342 343// rdar://problem/8613093 344namespace Test15 { 345 struct A {}; 346 template <class T> struct Temp { 347 struct Inner { 348 static char buffer[0]; 349 }; 350 }; 351 352 char *test() { 353 return Temp<A>::Inner::buffer; 354 } 355} 356 357namespace Test16 { 358 struct Base1 { virtual void foo(); }; 359 struct Base2 : virtual Base1 { virtual void foo(); }; 360 template <class T> struct A : virtual Base1, Base2 { 361 virtual void foo(); 362 }; 363 extern template struct A<char>; 364 365 void test() { 366 A<char> a; 367 a.foo(); 368 } 369} 370 371namespace Test17 { 372 struct HIDDEN A { 373 static void foo(); 374 static void DEFAULT bar(); 375 static void HIDDEN baz(); 376 377 struct DEFAULT B { 378 static void foo(); 379 static void DEFAULT bar(); 380 static void HIDDEN baz(); 381 }; 382 }; 383 384 void test() { 385 A::foo(); 386 A::bar(); 387 A::baz(); 388 A::B::foo(); 389 A::B::bar(); 390 A::B::baz(); 391 } 392 // CHECK: declare hidden void @_ZN6Test171A3fooEv() 393 // CHECK: declare void @_ZN6Test171A3barEv() 394 // CHECK: declare hidden void @_ZN6Test171A3bazEv() 395 // CHECK: declare void @_ZN6Test171A1B3fooEv() 396 // CHECK: declare void @_ZN6Test171A1B3barEv() 397 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv() 398 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv() 399 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv() 400 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv() 401 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv() 402 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv() 403 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv() 404} 405 406namespace Test18 { 407 template <class T> struct HIDDEN A { 408 static void foo(); 409 static void DEFAULT bar(); 410 static void HIDDEN baz(); 411 412 struct DEFAULT B { 413 static void foo(); 414 static void DEFAULT bar(); 415 static void HIDDEN baz(); 416 }; 417 }; 418 struct HIDDEN H; 419 420 void test() { 421 A<int>::foo(); 422 A<int>::bar(); 423 A<int>::baz(); 424 A<int>::B::foo(); 425 A<int>::B::bar(); 426 A<int>::B::baz(); 427 A<H>::foo(); 428 A<H>::bar(); 429 A<H>::baz(); 430 A<H>::B::foo(); 431 A<H>::B::bar(); 432 A<H>::B::baz(); 433 } 434 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv() 435 // CHECK: declare void @_ZN6Test181AIiE3barEv() 436 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv() 437 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv() 438 // CHECK: declare void @_ZN6Test181AIiE1B3barEv() 439 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv() 440 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 441 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 442 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 443 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 444 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 445 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 446 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv() 447 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv() 448 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv() 449 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv() 450 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv() 451 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv() 452 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 453 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 454 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 455 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 456 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 457 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 458} 459 460namespace Test19 { 461 struct A { A(); ~A(); }; 462 463 // Tested at top of file. 464 template <class T> void foo() { 465 static A a; 466 } 467 468 void test() { 469 foo<int>(); 470 } 471} 472 473// Various things with class template specializations. 474namespace Test20 { 475 template <unsigned> struct HIDDEN A {}; 476 477 // An explicit specialization inherits the explicit visibility of 478 // the template. 479 template <> struct A<0> { 480 static void test0(); 481 static void test1(); 482 }; 483 484 // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev() 485 void A<0>::test0() {} 486 487 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev() 488 void test1() { 489 A<0>::test1(); 490 } 491 492 // ...unless that's explicitly overridden. 493 template <> struct DEFAULT A<1> { 494 static void test2(); 495 static void test3(); 496 }; 497 498 // CHECK: define void @_ZN6Test201AILj1EE5test2Ev() 499 void A<1>::test2() {} 500 501 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev() 502 void test3() { 503 A<1>::test3(); 504 } 505 506 // <rdar://problem/8778497> 507 // But we should assume that an unknown specialization has the 508 // explicit visibility settings of the template. 509 template <class T> struct B { 510 static void test4() {} 511 static void test5(); 512 }; 513 514 // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev() 515 void test4() { 516 B<A<2> >::test4(); 517 } 518 519 // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev() 520 void test5() { 521 B<A<2> >::test5(); 522 } 523} 524 525// PR9371 526namespace test21 { 527 enum En { en }; 528 template<En> struct A { 529 __attribute__((visibility("default"))) void foo() {} 530 }; 531 532 // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv( 533 template void A<en>::foo(); 534} 535 536// rdar://problem/9616154 537// Visibility on explicit specializations should take precedence. 538namespace test22 { 539 class A1 {}; 540 class A2 {}; 541 542 template <class T> struct B {}; 543 template <> struct DEFAULT B<A1> { 544 static void foo(); 545 static void bar() {} 546 }; 547 template <> struct B<A2> { 548 static void foo(); 549 static void bar() {} 550 }; 551 552 void test() { 553 B<A1>::foo(); 554 B<A1>::bar(); 555 B<A2>::foo(); 556 B<A2>::bar(); 557 } 558 // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv() 559 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() 560 // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv() 561 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv() 562 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv() 563 // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() 564 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv() 565 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv() 566} 567 568namespace PR10113 { 569 namespace foo DEFAULT { 570 template<typename T> 571 class bar { 572 void zed() {} 573 }; 574 } 575 template class foo::bar<char>; 576 // CHECK: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv 577 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv 578 579 struct zed { 580 }; 581 template class foo::bar<zed>; 582 // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv 583 584 // FIXME: This should be hidden as zed is hidden. 585 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv 586} 587 588namespace PR11690 { 589 template<class T> struct Class { 590 void size() const { 591 } 592 }; 593 template class DEFAULT Class<char>; 594 // CHECK: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv 595 // CHECK-HIDDEN: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv 596 597 template<class T> void Method() {} 598 template DEFAULT void Method<char>(); 599 // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv 600 // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv 601} 602 603namespace PR11690_2 { 604 namespace foo DEFAULT { 605 class bar; 606 template<typename T1, typename T2 = bar> 607 class zed { 608 void bar() { 609 } 610 }; 611 } 612 struct baz { 613 }; 614 template class foo::zed<baz>; 615 // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv 616 617 // FIXME: This should be hidden as baz is hidden. 618 // CHECK-HIDDEN: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv 619} 620 621namespace test23 { 622 // Having a template argument that is explicitly visible should not make 623 // the template instantiation visible. 624 template <typename T> 625 struct X { 626 static void f() { 627 } 628 }; 629 630 class DEFAULT A; 631 632 void g() { 633 X<A> y; 634 y.f(); 635 } 636 // CHECK: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv 637 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv 638} 639 640namespace PR12001 { 641 template <typename P1> 642 void Bind(const P1& p1) { 643 } 644 645 class DEFAULT Version { }; 646 647 void f() { 648 Bind(Version()); 649 } 650 // CHECK: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_ 651 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_ 652} 653 654namespace test24 { 655 class DEFAULT A { }; 656 657 struct S { 658 template <typename T> 659 void mem() {} 660 }; 661 662 void test() { 663 S s; 664 s.mem<A>(); 665 } 666 // CHECK: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv 667 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv 668} 669 670namespace test26 { 671 template<typename T> 672 class C { 673 __attribute__((visibility("default"))) void f(); 674 }; 675 676 template<> 677 void C<int>::f() { } 678 679 // CHECK: define void @_ZN6test261CIiE1fEv 680 // CHECK-HIDDEN: define void @_ZN6test261CIiE1fEv 681} 682 683namespace test31 { 684 struct A { 685 struct HIDDEN B { 686 static void DEFAULT baz(); 687 }; 688 }; 689 void f() { 690 A::B::baz(); 691 } 692 // CHECK: declare void @_ZN6test311A1B3bazEv() 693 // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv() 694} 695 696namespace test32 { 697 struct HIDDEN A { 698 struct DEFAULT B { 699 void DEFAULT baz(); 700 }; 701 }; 702 void A::B::baz() { 703 } 704 // CHECK: define void @_ZN6test321A1B3bazEv 705 // CHECK-HIDDEN: define void @_ZN6test321A1B3bazEv 706} 707 708namespace test33 { 709 template<typename T> 710 class foo { 711 void bar() {} 712 }; 713 struct HIDDEN zed { 714 }; 715 template class DEFAULT foo<zed>; 716 // CHECK: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv 717 // CHECK-HIDDEN: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv 718} 719 720namespace test34 { 721 struct foo { 722 }; 723 template<class T> 724 void bar() {} 725 template DEFAULT void bar<foo>(); 726 // CHECK: define weak_odr void @_ZN6test343barINS_3fooEEEvv 727 // CHECK-HIDDEN: define weak_odr void @_ZN6test343barINS_3fooEEEvv 728} 729 730namespace test35 { 731 // This is a really ugly testcase. GCC propagates the DEFAULT in zed's 732 // definition. What we do instead is be conservative about merging 733 // implicit visibilities. 734 // FIXME: Maybe the best thing to do here is error? The test at least 735 // makes sure we don't produce a hidden symbol for foo<zed>::bar. 736 template<typename T> 737 struct DEFAULT foo { 738 void bar() {} 739 }; 740 class zed; 741 template class foo<zed>; 742 class DEFAULT zed { 743 }; 744 // CHECK: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv 745 // CHECK-HIDDEN: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv 746} 747 748namespace test36 { 749 template<typename T1, typename T2> 750 class foo { 751 void bar() {} 752 }; 753 class DEFAULT S1 {}; 754 struct HIDDEN S2 {}; 755 template class foo<S1, S2>; 756 // CHECK: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv 757 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv 758} 759 760namespace test37 { 761 struct HIDDEN foo { 762 }; 763 template<class T> 764 DEFAULT void bar() {} 765 template DEFAULT void bar<foo>(); 766 // CHECK: define weak_odr void @_ZN6test373barINS_3fooEEEvv 767 // CHECK-HIDDEN: define weak_odr void @_ZN6test373barINS_3fooEEEvv 768} 769 770namespace test38 { 771 template<typename T> 772 class DEFAULT foo { 773 void bar() {} 774 }; 775 struct HIDDEN zed { 776 }; 777 template class foo<zed>; 778 // CHECK: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv 779 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv 780} 781 782namespace test39 { 783 class DEFAULT default_t; 784 class HIDDEN hidden_t; 785 template <class T> class A { 786 template <class U> class B { 787 HIDDEN void hidden() {} 788 void noattr() {} 789 template <class V> void temp() {} 790 }; 791 }; 792 template class DEFAULT A<hidden_t>; 793 template class DEFAULT A<hidden_t>::B<hidden_t>; 794 template void A<hidden_t>::B<hidden_t>::temp<default_t>(); 795 template void A<hidden_t>::B<hidden_t>::temp<hidden_t>(); 796 797 // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv 798 // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv 799 // CHECK: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv 800 801 // GCC produces a default for this one. Why? 802 // CHECK: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv 803 804 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv 805 // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv 806 // CHECK-HIDDEN: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv 807 808 // GCC produces a default for this one. Why? 809 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv 810} 811 812namespace test42 { 813 struct HIDDEN foo { 814 }; 815 template <class P> 816 struct bar { 817 }; 818 template <> 819 struct HIDDEN bar<foo> { 820 DEFAULT static void zed(); 821 }; 822 void bar<foo>::zed() { 823 } 824 // CHECK: define hidden void @_ZN6test423barINS_3fooEE3zedEv 825 // CHECK-HIDDEN: define hidden void @_ZN6test423barINS_3fooEE3zedEv 826} 827 828namespace test43 { 829 struct HIDDEN foo { 830 }; 831 template <class P> 832 void bar() { 833 } 834 template <> 835 DEFAULT void bar<foo>() { 836 } 837 // CHECK: define hidden void @_ZN6test433barINS_3fooEEEvv 838 // CHECK-HIDDEN: define hidden void @_ZN6test433barINS_3fooEEEvv 839} 840 841namespace test44 { 842 template <typename T> 843 struct foo { 844 foo() {} 845 }; 846 namespace { 847 struct bar; 848 } 849 template struct DEFAULT foo<bar>; 850 foo<bar> x; 851 // CHECK: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev 852 // CHECK-HIDDEN: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev 853} 854 855namespace test45 { 856 template <typename T> 857 struct foo { 858 template <typename T2> 859 struct bar { 860 bar() {}; 861 }; 862 }; 863 namespace { 864 struct zed; 865 } 866 template struct DEFAULT foo<int>::bar<zed>; 867 foo<int>::bar<zed> x; 868 // CHECK: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev 869 // CHECK-HIDDEN: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev 870} 871 872namespace test46 { 873 template <typename T> 874 void foo() { 875 } 876 namespace { 877 struct bar; 878 } 879 template DEFAULT void foo<bar>(); 880 void zed() { 881 foo<bar>(); 882 } 883 // CHECK: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv 884 // CHECK-HIDDEN: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv 885} 886 887namespace test47 { 888 struct foo { 889 template <typename T> 890 static void bar() { 891 } 892 }; 893 namespace { 894 struct zed; 895 } 896 template __attribute__((visibility("default"))) void foo::bar<zed>(); 897 void baz() { 898 foo::bar<zed>(); 899 } 900 // CHECK: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv 901 // CHECK-HIDDEN: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv 902} 903 904namespace test49 { 905 // Test that we use the visibility of struct foo when instantiating the 906 // template. Note that is a case where we disagree with gcc, it produces 907 // a default symbol. 908 909 struct HIDDEN foo { 910 }; 911 912 DEFAULT foo x; 913 914 struct bar { 915 template<foo *z> 916 void zed() { 917 } 918 }; 919 920 template void bar::zed<&x>(); 921 // CHECK: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv 922 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv 923} 924 925namespace test50 { 926 // Test that we use the visibility of struct foo when instantiating the 927 // template. Note that is a case where we disagree with gcc, it produces 928 // a default symbol. 929 930 struct HIDDEN foo { 931 }; 932 DEFAULT foo x; 933 template<foo *z> 934 struct DEFAULT bar { 935 void zed() { 936 } 937 }; 938 template void bar<&x>::zed(); 939 // CHECK: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv 940 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv 941} 942 943namespace test51 { 944 // Test that we use the visibility of struct foo when instantiating the 945 // template. Note that is a case where we disagree with gcc, it produces 946 // a default symbol. 947 948 struct HIDDEN foo { 949 }; 950 DEFAULT foo x; 951 template<foo *z> 952 void DEFAULT zed() { 953 } 954 template void zed<&x>(); 955 // CHECK: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv 956 // CHECK-HIDDEN: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv 957} 958 959namespace test52 { 960 // Test that we use the linkage of struct foo when instantiating the 961 // template. Note that is a case where we disagree with gcc, it produces 962 // an external symbol. 963 964 namespace { 965 struct foo { 966 }; 967 } 968 template<foo *x> 969 void zed() { 970 } 971 void f() { 972 zed<nullptr>(); 973 } 974 // CHECK: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv 975 // CHECK-HIDDEN: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv 976} 977 978namespace test53 { 979 template<typename _Tp > struct vector { 980 static void _M_fill_insert(); 981 }; 982#pragma GCC visibility push(hidden) 983 // GCC doesn't seem to use the visibility of enums at all, we do. 984 enum zed {v1}; 985 986 // GCC fails to mark this specialization hidden, we mark it. 987 template<> 988 struct vector<int> { 989 static void _M_fill_insert(); 990 }; 991 void foo() { 992 vector<unsigned>::_M_fill_insert(); 993 vector<int>::_M_fill_insert(); 994 vector<zed>::_M_fill_insert(); 995 } 996#pragma GCC visibility pop 997 // CHECK: declare void @_ZN6test536vectorIjE14_M_fill_insertEv 998 // CHECK-HIDDEN: declare void @_ZN6test536vectorIjE14_M_fill_insertEv 999 // CHECK: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv 1000 // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv 1001 // CHECK: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv 1002 // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv 1003} 1004 1005namespace test54 { 1006 template <class T> 1007 struct foo { 1008 static void bar(); 1009 }; 1010#pragma GCC visibility push(hidden) 1011 class zed { 1012 zed(const zed &); 1013 }; 1014 void bah() { 1015 foo<zed>::bar(); 1016 } 1017#pragma GCC visibility pop 1018 // CHECK: declare hidden void @_ZN6test543fooINS_3zedEE3barEv 1019 // CHECK-HIDDEN: declare hidden void @_ZN6test543fooINS_3zedEE3barEv 1020} 1021 1022namespace test55 { 1023 template <class T> 1024 struct __attribute__((visibility("hidden"))) foo { 1025 static void bar(); 1026 }; 1027 template <class T> struct foo; 1028 void foobar() { 1029 foo<int>::bar(); 1030 } 1031 // CHECK: declare hidden void @_ZN6test553fooIiE3barEv 1032 // CHECK-HIDDEN: declare hidden void @_ZN6test553fooIiE3barEv 1033} 1034 1035namespace test56 { 1036 template <class T> struct foo; 1037 template <class T> 1038 struct __attribute__((visibility("hidden"))) foo { 1039 static void bar(); 1040 }; 1041 void foobar() { 1042 foo<int>::bar(); 1043 } 1044 // CHECK: declare hidden void @_ZN6test563fooIiE3barEv 1045 // CHECK-HIDDEN: declare hidden void @_ZN6test563fooIiE3barEv 1046} 1047 1048namespace test57 { 1049#pragma GCC visibility push(hidden) 1050 template <class T> 1051 struct foo; 1052 void bar(foo<int>*); 1053 template <class T> 1054 struct foo { 1055 static void zed(); 1056 }; 1057 void bah() { 1058 foo<int>::zed(); 1059 } 1060#pragma GCC visibility pop 1061 // CHECK: declare hidden void @_ZN6test573fooIiE3zedEv 1062 // CHECK-HIDDEN: declare hidden void @_ZN6test573fooIiE3zedEv 1063} 1064 1065namespace test58 { 1066#pragma GCC visibility push(hidden) 1067 struct foo; 1068 template<typename T> 1069 struct __attribute__((visibility("default"))) bar { 1070 static void zed() { 1071 } 1072 }; 1073 void bah() { 1074 bar<foo>::zed(); 1075 } 1076#pragma GCC visibility pop 1077 // CHECK: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv 1078 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv 1079} 1080 1081namespace test59 { 1082 DEFAULT int f(); 1083 HIDDEN int g(); 1084 typedef int (*foo)(); 1085 template<foo x, foo y> 1086 void test() {} 1087 void use() { 1088 test<&g, &f>(); 1089 // CHECK: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv 1090 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv 1091 1092 test<&f, &g>(); 1093 // CHECK: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv 1094 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv 1095 } 1096} 1097 1098namespace test60 { 1099 template<int i> 1100 class __attribute__((visibility("hidden"))) a {}; 1101 template<int i> 1102 class __attribute__((visibility("default"))) b {}; 1103 template<template<int> class x, template<int> class y> 1104 void test() {} 1105 void use() { 1106 test<a, b>(); 1107 // CHECK: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv 1108 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv 1109 1110 test<b, a>(); 1111 // CHECK: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv 1112 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv 1113 } 1114} 1115