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