visibility.cpp revision a77e0726341a4afbe9c25b05cf944edf17f64543
1// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s 2// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN 3 4#define HIDDEN __attribute__((visibility("hidden"))) 5#define PROTECTED __attribute__((visibility("protected"))) 6#define DEFAULT __attribute__((visibility("default"))) 7 8namespace test30 { 9 // When H is hidden, it should make X hidden, even if the template argument 10 // is not. 11 struct H { 12 }; 13 template<H *T> 14 struct X { 15 }; 16 H DEFAULT a; 17 X<&a> b; 18 // CHECK: _ZN6test301bE = global 19 // CHECK-HIDDEN: _ZN6test301bE = hidden global 20} 21 22namespace test25 { 23 template<typename T> 24 struct X { 25 template<typename U> 26 struct definition { 27 }; 28 }; 29 30 class DEFAULT A { }; 31 32 X<int>::definition<A> a; 33 // CHECK: @_ZN6test251aE = global 34 // CHECK-HIDDEN: @_ZN6test251aE = hidden global 35} 36 37namespace test28 { 38 class DEFAULT foo { 39 }; 40 foo myvec; 41 // CHECK: @_ZN6test285myvecE = global 42 // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global 43} 44 45namespace test29 { 46#pragma GCC visibility push(hidden) 47 struct RECT { 48 int top; 49 }; 50 __attribute__ ((visibility ("default"))) extern RECT data_rect; 51 RECT data_rect = { -1}; 52#pragma GCC visibility pop 53 // CHECK: @_ZN6test299data_rectE = global 54 // CHECK-HIDDEN: @_ZN6test299data_rectE = global 55} 56 57// CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 58// CHECK: @_ZN5Test71aE = hidden global 59// CHECK: @_ZN5Test71bE = global 60// CHECK: @test9_var = global 61// CHECK-HIDDEN: @test9_var = global 62// CHECK: @_ZN6Test121A6hiddenE = external hidden global 63// CHECK: @_ZN6Test121A7visibleE = external global 64// CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global 65// CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global 66// CHECK: @_ZN6Test131B1aE = hidden global 67// CHECK: @_ZN6Test131C1aE = global 68// CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global 69// CHECK-HIDDEN: @_ZN6Test131C1aE = global 70// CHECK: @_ZN6Test143varE = external global 71// CHECK-HIDDEN: @_ZN6Test143varE = external global 72// CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] 73// CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] 74 75namespace test27 { 76 template<typename T> 77 class C { 78 class __attribute__((visibility("default"))) D { 79 void f(); 80 }; 81 }; 82 83 template<> 84 class C<int>::D { 85 virtual void g(); 86 }; 87 88 void C<int>::D::g() { 89 } 90 // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant 91 // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant 92} 93 94// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global 95// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 96// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global 97// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 98// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant 99// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant 100// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant 101 102namespace Test1 { 103 // CHECK: define hidden void @_ZN5Test11fEv 104 void HIDDEN f() { } 105 106} 107 108namespace Test2 { 109 struct HIDDEN A { 110 void f(); 111 }; 112 113 // A::f is a member function of a hidden class. 114 // CHECK: define hidden void @_ZN5Test21A1fEv 115 void A::f() { } 116} 117 118namespace Test3 { 119 struct HIDDEN A { 120 struct B { 121 void f(); 122 }; 123 }; 124 125 // B is a nested class where its parent class is hidden. 126 // CHECK: define hidden void @_ZN5Test31A1B1fEv 127 void A::B::f() { } 128} 129 130namespace Test4 HIDDEN { 131 int VariableInHiddenNamespace = 10; 132 133 // Test4::g is in a hidden namespace. 134 // CHECK: define hidden void @_ZN5Test41gEv 135 void g() { } 136 137 struct DEFAULT A { 138 void f(); 139 }; 140 141 // A has default visibility. 142 // CHECK: define void @_ZN5Test41A1fEv 143 void A::f() { } 144} 145 146namespace Test5 { 147 148 namespace NS HIDDEN { 149 // f is in NS which is hidden. 150 // CHECK: define hidden void @_ZN5Test52NS1fEv() 151 void f() { } 152 } 153 154 namespace NS { 155 // g is in NS, but this NS decl is not hidden. 156 // CHECK: define void @_ZN5Test52NS1gEv 157 void g() { } 158 } 159} 160 161// <rdar://problem/8091955> 162namespace Test6 { 163 struct HIDDEN foo { 164 foo() { } 165 void bonk(); 166 virtual void bar() = 0; 167 168 virtual void zonk() {} 169 }; 170 171 struct barc : public foo { 172 barc(); 173 virtual void bar(); 174 }; 175 176 barc::barc() {} 177} 178 179namespace Test7 { 180 class HIDDEN A {}; 181 A a; // top of file 182 183 template <A&> struct Aref { 184 static void foo() {} 185 }; 186 187 class B : public A {}; 188 B b; // top of file 189 190 // CHECK: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv() 191 void test() { 192 Aref<a>::foo(); 193 } 194} 195 196namespace Test8 { 197 void foo(); 198 void bar() {} 199 // CHECK-HIDDEN: define hidden void @_ZN5Test83barEv() 200 // CHECK-HIDDEN: declare void @_ZN5Test83fooEv() 201 202 void test() { 203 foo(); 204 bar(); 205 } 206} 207 208// PR8457 209namespace Test9 { 210 extern "C" { 211 struct A { int field; }; 212 void DEFAULT test9_fun(struct A *a) { } 213 struct A DEFAULT test9_var; // above 214 } 215 // CHECK: define void @test9_fun( 216 // CHECK-HIDDEN: define void @test9_fun( 217 218 void test() { 219 A a = test9_var; 220 test9_fun(&a); 221 } 222} 223 224// PR8478 225namespace Test10 { 226 struct A; 227 228 class DEFAULT B { 229 void foo(A*); 230 }; 231 232 // CHECK: define void @_ZN6Test101B3fooEPNS_1AE( 233 // CHECK-HIDDEN: define void @_ZN6Test101B3fooEPNS_1AE( 234 void B::foo(A*) {} 235} 236 237// PR8492 238namespace Test11 { 239 struct A { 240 void foo() {} 241 void DEFAULT bar() {} 242 }; 243 244 void test() { 245 A a; 246 a.foo(); 247 a.bar(); 248 } 249 250 // CHECK: define linkonce_odr void @_ZN6Test111A3fooEv( 251 // CHECK: define linkonce_odr void @_ZN6Test111A3barEv( 252 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6Test111A3fooEv( 253 // CHECK-HIDDEN: define linkonce_odr void @_ZN6Test111A3barEv( 254} 255 256// Tested at top of file. 257namespace Test12 { 258 struct A { 259 // This is hidden in all cases: the explicit attribute takes 260 // priority over -fvisibility on the parent. 261 static int hidden HIDDEN; 262 263 // This is default in all cases because it's only a declaration. 264 static int visible; 265 }; 266 267 void test() { 268 A::hidden = 0; 269 A::visible = 0; 270 } 271} 272 273// Tested at top of file. 274namespace Test13 { 275 struct HIDDEN A {}; 276 277 // Should be hidden in all cases. 278 struct B { 279 static A a; 280 }; 281 A B::a; 282 283 // Should be default in all cases. 284 struct DEFAULT C { 285 static A a; 286 }; 287 A C::a; 288}; 289 290// Tested at top of file. 291namespace Test14 { 292 // Neither the visibility of the type nor -fvisibility=hidden should 293 // apply to declarations. 294 extern struct A *var; 295 296 struct A *test() { return var; } 297} 298 299// rdar://problem/8613093 300namespace Test15 { 301 struct A {}; 302 template <class T> struct Temp { 303 struct Inner { 304 static char buffer[0]; 305 }; 306 }; 307 308 char *test() { 309 return Temp<A>::Inner::buffer; 310 } 311} 312 313namespace Test16 { 314 struct Base1 { virtual void foo(); }; 315 struct Base2 : virtual Base1 { virtual void foo(); }; 316 template <class T> struct A : virtual Base1, Base2 { 317 virtual void foo(); 318 }; 319 extern template struct A<char>; 320 321 void test() { 322 A<char> a; 323 a.foo(); 324 } 325} 326 327namespace Test17 { 328 struct HIDDEN A { 329 static void foo(); 330 static void DEFAULT bar(); 331 static void HIDDEN baz(); 332 333 struct DEFAULT B { 334 static void foo(); 335 static void DEFAULT bar(); 336 static void HIDDEN baz(); 337 }; 338 }; 339 340 void test() { 341 A::foo(); 342 A::bar(); 343 A::baz(); 344 A::B::foo(); 345 A::B::bar(); 346 A::B::baz(); 347 } 348 // CHECK: declare hidden void @_ZN6Test171A3fooEv() 349 // CHECK: declare void @_ZN6Test171A3barEv() 350 // CHECK: declare hidden void @_ZN6Test171A3bazEv() 351 // CHECK: declare void @_ZN6Test171A1B3fooEv() 352 // CHECK: declare void @_ZN6Test171A1B3barEv() 353 // CHECK: declare hidden void @_ZN6Test171A1B3bazEv() 354 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv() 355 // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv() 356 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv() 357 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv() 358 // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv() 359 // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv() 360} 361 362namespace Test18 { 363 template <class T> struct HIDDEN A { 364 static void foo(); 365 static void DEFAULT bar(); 366 static void HIDDEN baz(); 367 368 struct DEFAULT B { 369 static void foo(); 370 static void DEFAULT bar(); 371 static void HIDDEN baz(); 372 }; 373 }; 374 struct HIDDEN H; 375 376 void test() { 377 A<int>::foo(); 378 A<int>::bar(); 379 A<int>::baz(); 380 A<int>::B::foo(); 381 A<int>::B::bar(); 382 A<int>::B::baz(); 383 A<H>::foo(); 384 A<H>::bar(); 385 A<H>::baz(); 386 A<H>::B::foo(); 387 A<H>::B::bar(); 388 A<H>::B::baz(); 389 } 390 // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv() 391 // CHECK: declare void @_ZN6Test181AIiE3barEv() 392 // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv() 393 // CHECK: declare void @_ZN6Test181AIiE1B3fooEv() 394 // CHECK: declare void @_ZN6Test181AIiE1B3barEv() 395 // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv() 396 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 397 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 398 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 399 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 400 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 401 // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 402 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv() 403 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv() 404 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv() 405 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv() 406 // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv() 407 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv() 408 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() 409 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv() 410 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() 411 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() 412 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() 413 // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() 414} 415 416namespace Test19 { 417 struct A { A(); ~A(); }; 418 419 // Tested at top of file. 420 template <class T> void foo() { 421 static A a; 422 } 423 424 void test() { 425 foo<int>(); 426 } 427} 428 429// Various things with class template specializations. 430namespace Test20 { 431 template <unsigned> struct HIDDEN A {}; 432 433 // An explicit specialization inherits the explicit visibility of 434 // the template. 435 template <> struct A<0> { 436 static void test0(); 437 static void test1(); 438 }; 439 440 // CHECK: define hidden void @_ZN6Test201AILj0EE5test0Ev() 441 void A<0>::test0() {} 442 443 // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev() 444 void test1() { 445 A<0>::test1(); 446 } 447 448 // ...unless that's explicitly overridden. 449 template <> struct DEFAULT A<1> { 450 static void test2(); 451 static void test3(); 452 }; 453 454 // CHECK: define void @_ZN6Test201AILj1EE5test2Ev() 455 void A<1>::test2() {} 456 457 // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev() 458 void test3() { 459 A<1>::test3(); 460 } 461 462 // <rdar://problem/8778497> 463 // But we should assume that an unknown specialization has the 464 // explicit visibility settings of the template. 465 template <class T> struct B { 466 static void test4() {} 467 static void test5(); 468 }; 469 470 // CHECK: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev() 471 void test4() { 472 B<A<2> >::test4(); 473 } 474 475 // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev() 476 void test5() { 477 B<A<2> >::test5(); 478 } 479} 480 481// PR9371 482namespace test21 { 483 enum En { en }; 484 template<En> struct A { 485 __attribute__((visibility("default"))) void foo() {} 486 }; 487 488 // CHECK: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv( 489 template void A<en>::foo(); 490} 491 492// rdar://problem/9616154 493// Visibility on explicit specializations should take precedence. 494namespace test22 { 495 class A1 {}; 496 class A2 {}; 497 498 template <class T> struct B {}; 499 template <> struct DEFAULT B<A1> { 500 static void foo(); 501 static void bar() {} 502 }; 503 template <> struct B<A2> { 504 static void foo(); 505 static void bar() {} 506 }; 507 508 void test() { 509 B<A1>::foo(); 510 B<A1>::bar(); 511 B<A2>::foo(); 512 B<A2>::bar(); 513 } 514 // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv() 515 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() 516 // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv() 517 // CHECK: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv() 518 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv() 519 // CHECK-HIDDEN: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() 520 // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv() 521 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv() 522} 523 524namespace PR10113 { 525 namespace foo DEFAULT { 526 template<typename T> 527 class bar { 528 void zed() {} 529 }; 530 } 531 template class foo::bar<char>; 532 // CHECK: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv 533 // CHECK-HIDDEN: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv 534 535 struct zed { 536 }; 537 template class foo::bar<zed>; 538 // CHECK: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv 539 // CHECK-HIDDEN: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv 540} 541 542namespace PR11690 { 543 template<class T> struct Class { 544 void size() const { 545 } 546 }; 547 template class DEFAULT Class<char>; 548 // CHECK: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv 549 // CHECK-HIDDEN: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv 550 551 template<class T> void Method() {} 552 template DEFAULT void Method<char>(); 553 // CHECK: define weak_odr void @_ZN7PR116906MethodIcEEvv 554 // CHECK-HIDDEN: define weak_odr void @_ZN7PR116906MethodIcEEvv 555} 556 557namespace PR11690_2 { 558 namespace foo DEFAULT { 559 class bar; 560 template<typename T1, typename T2 = bar> 561 class zed { 562 void bar() { 563 } 564 }; 565 } 566 struct baz { 567 }; 568 template class foo::zed<baz>; 569 // CHECK: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv 570 // CHECK-HIDDEN: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv 571} 572 573namespace test23 { 574 // Having a template argument that is explicitly visible should not make 575 // the template instantiation visible. 576 template <typename T> 577 struct X { 578 static void f() { 579 } 580 }; 581 582 class DEFAULT A; 583 584 void g() { 585 X<A> y; 586 y.f(); 587 } 588 // CHECK: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv 589 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv 590} 591 592namespace PR12001 { 593 template <typename P1> 594 void Bind(const P1& p1) { 595 } 596 597 class DEFAULT Version { }; 598 599 void f() { 600 Bind(Version()); 601 } 602 // CHECK: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_ 603 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_ 604} 605 606namespace test24 { 607 class DEFAULT A { }; 608 609 struct S { 610 template <typename T> 611 void mem() {} 612 }; 613 614 void test() { 615 S s; 616 s.mem<A>(); 617 } 618 // CHECK: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv 619 // CHECK-HIDDEN: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv 620} 621 622namespace test26 { 623 template<typename T> 624 class C { 625 __attribute__((visibility("default"))) void f(); 626 }; 627 628 template<> 629 void C<int>::f() { } 630 631 // CHECK: define void @_ZN6test261CIiE1fEv 632 // CHECK-HIDDEN: define void @_ZN6test261CIiE1fEv 633} 634 635namespace test31 { 636 struct A { 637 struct HIDDEN B { 638 static void DEFAULT baz(); 639 }; 640 }; 641 void f() { 642 A::B::baz(); 643 } 644 // CHECK: declare void @_ZN6test311A1B3bazEv() 645 // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv() 646} 647 648namespace test32 { 649 struct HIDDEN A { 650 struct DEFAULT B { 651 void DEFAULT baz(); 652 }; 653 }; 654 void A::B::baz() { 655 } 656 // CHECK: define void @_ZN6test321A1B3bazEv 657 // CHECK-HIDDEN: define void @_ZN6test321A1B3bazEv 658} 659