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; zed()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 g()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 f()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 f()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 f()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 g()191 void g() { } 192 193 struct DEFAULT A { 194 void f(); 195 }; 196 197 // A has default visibility. 198 // CHECK-LABEL: define void @_ZN5Test41A1fEv f()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() f()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 g()213 void g() { } 214 } 215 } 216 217 // <rdar://problem/8091955> 218 namespace Test6 { 219 struct HIDDEN foo { fooTest6::foo220 foo() { } 221 void bonk(); 222 virtual void bar() = 0; 223 zonkTest6::foo224 virtual void zonk() {} 225 }; 226 227 struct barc : public foo { 228 barc(); 229 virtual void bar(); 230 }; 231 barc()232 barc::barc() {} 233 } 234 235 namespace Test7 { 236 class HIDDEN A {}; 237 A a; // top of file 238 239 template <A&> struct Aref { fooTest7::Aref240 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() test()247 void test() { 248 Aref<a>::foo(); 249 } 250 } 251 252 namespace Test8 { 253 void foo(); bar()254 void bar() {} 255 // CHECK-HIDDEN-LABEL: define hidden void @_ZN5Test83barEv() 256 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv() 257 test()258 void test() { 259 foo(); 260 bar(); 261 } 262 } 263 264 // PR8457 265 namespace Test9 { 266 extern "C" { 267 struct A { int field; }; test9_fun(struct A * a)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 test()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( foo(A *)290 void B::foo(A*) {} 291 } 292 293 // PR8492 294 namespace Test11 { 295 struct A { fooTest11::A296 void foo() {} barTest11::A297 void DEFAULT bar() {} 298 }; 299 test()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 test()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 test()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 test()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 test()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 test()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 test()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. foo()476 template <class T> void foo() { 477 static A a; 478 } 479 test()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() test0()497 void A<0>::test0() {} 498 499 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev() test1()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() test2()511 void A<1>::test2() {} 512 513 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev() test3()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 { test4Test20::B522 static void test4() {} 523 static void test5(); 524 }; 525 526 // CHECK-LABEL: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev() test4()527 void test4() { 528 B<A<2> >::test4(); 529 } 530 531 // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev() test5()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 { footest21::A541 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(); bartest22::B557 static void bar() {} 558 }; 559 template <> struct B<A2> { 560 static void foo(); bartest22::B561 static void bar() {} 562 }; 563 test()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 { zed()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 { sizePR11690::Class600 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 Method()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 { bar()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 { ftest23::X634 static void f() { 635 } 636 }; 637 638 class DEFAULT A; 639 g()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> Bind(const P1 & p1)650 void Bind(const P1& p1) { 651 } 652 653 class DEFAULT Version { }; 654 f()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> memtest24::S667 void mem() {} 668 }; 669 test()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<> f()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 }; f()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 }; baz()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 { bar()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> bar()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 { bartest35::foo746 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 { bar()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> bar()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 { bar()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 { hidden()795 HIDDEN void hidden() {} noattr()796 void noattr() {} temp()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 }; zed()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> bar()840 void bar() { 841 } 842 template <> bar()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 { footest44::foo852 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 { bartest45::foo::bar868 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> foo()882 void foo() { 883 } 884 namespace { 885 struct bar; 886 } 887 template DEFAULT void foo<bar>(); zed()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> bartest47::foo898 static void bar() { 899 } 900 }; 901 namespace { 902 struct zed; 903 } 904 template DEFAULT void foo::bar<zed>(); baz()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> zedtest49::bar924 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 { zedtest50::bar943 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> zed()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> zed()977 void zed() { 978 } f()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 }; foo()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 }; bah()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; foobar()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 }; foobar()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 }; bah()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 { zedtest58::bar1078 static void zed() { 1079 } 1080 }; bah()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> test()1094 void test() {} use()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> test()1112 void test() {} use()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 { f1test61::Class11128 void f1() { f2(); } 1129 inline void f2(); 1130 }; 1131 template<> f2()1132 inline void Class1<int>::f2() 1133 { 1134 } g(Class1<int> * x)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 { f1test62::Class11150 void f1() { f2(); } f2test62::Class11151 inline void f2() {} 1152 }; 1153 template<> f2()1154 inline void Class1<int>::f2() 1155 { 1156 } g(Class1<int> * x)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 { footest63::A1171 template <E> static void foo() {} 1172 1173 template <E> struct B { footest63::A::B1174 static void foo() {} 1175 }; 1176 }; 1177 test()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 { footest64::B1191 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 { footest65::C1208 static void foo() {} 1209 }; 1210 1211 // CHECK-LABEL: define void @_ZN6test651BINS_1AEE4funcEv() func()1212 template <> DEFAULT void B<A>::func() {} 1213 1214 // CHECK-LABEL: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv() funcT2()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() funcT1()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 { footest65::B::Inner1223 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 { footest65::B::InnerT1229 static void foo() {} 1230 }; 1231 test()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 { zedtest66::barT1246 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 { zedtest66::barI1256 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 { zedtest66::barF1267 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 { zedtest67::bar1279 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: f()1297 f() { 1298 static A test; 1299 } 1300 }; g()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 { f()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