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