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