// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN // For clang, "internal" is just an alias for "hidden". We could use it for some // optimization purposes on 32-bit x86, but it's not worth it. // RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fvisibility internal -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-HIDDEN #define HIDDEN __attribute__((visibility("hidden"))) #define PROTECTED __attribute__((visibility("protected"))) #define DEFAULT __attribute__((visibility("default"))) namespace test30 { // When H is hidden, it should make X hidden, even if the template argument // is not. struct H { }; template<H *T> struct X { }; H DEFAULT a; X<&a> b; // CHECK: _ZN6test301bE = global // CHECK-HIDDEN: _ZN6test301bE = hidden global } namespace test25 { template<typename T> struct X { template<typename U> struct definition { }; }; class DEFAULT A { }; X<int>::definition<A> a; // CHECK: @_ZN6test251aE = global // CHECK-HIDDEN: @_ZN6test251aE = hidden global } namespace test28 { class DEFAULT foo { }; foo myvec; // CHECK: @_ZN6test285myvecE = global // CHECK-HIDDEN: @_ZN6test285myvecE = hidden global } namespace test29 { #pragma GCC visibility push(hidden) struct RECT { int top; }; DEFAULT extern RECT data_rect; RECT data_rect = { -1}; #pragma GCC visibility pop // CHECK: @_ZN6test299data_rectE = global // CHECK-HIDDEN: @_ZN6test299data_rectE = global } namespace test40 { template<typename T> struct foo { DEFAULT static int bar; }; template<typename T> int foo<T>::bar; template struct foo<int>; // CHECK: _ZN6test403fooIiE3barE = weak_odr global // CHECK-HIDDEN: _ZN6test403fooIiE3barE = weak_odr global } namespace test41 { // Unlike gcc we propagate the information that foo not only is hidden, but // has been explicitly marked as so. This lets us produce a hidden undefined // reference to bar. struct HIDDEN foo {}; extern foo bar; foo *zed() { return &bar; } // CHECK: @_ZN6test413barE = external hidden global // CHECK-HIDDEN: @_ZN6test413barE = external hidden global } namespace test48 { // Test that we use the visibility of struct foo when instantiating the // template. Note that is a case where we disagree with gcc, it produces // a default symbol. struct HIDDEN foo { }; DEFAULT foo x; struct bar { template<foo *z> struct zed { }; }; bar::zed<&x> y; // CHECK: _ZN6test481yE = hidden global // CHECK-HIDDEN: _ZN6test481yE = hidden global } // CHECK: @_ZN5Test425VariableInHiddenNamespaceE = hidden global i32 10 // CHECK: @_ZN5Test71aE = hidden global // CHECK: @_ZN5Test71bE = global // CHECK: @test9_var = global // CHECK-HIDDEN: @test9_var = global // CHECK: @_ZN6Test121A6hiddenE = external hidden global // CHECK: @_ZN6Test121A7visibleE = external global // CHECK-HIDDEN: @_ZN6Test121A6hiddenE = external hidden global // CHECK-HIDDEN: @_ZN6Test121A7visibleE = external global // CHECK: @_ZN6Test131B1aE = hidden global // CHECK: @_ZN6Test131C1aE = global // CHECK-HIDDEN: @_ZN6Test131B1aE = hidden global // CHECK-HIDDEN: @_ZN6Test131C1aE = global // CHECK: @_ZN6Test143varE = external global // CHECK-HIDDEN: @_ZN6Test143varE = external global // CHECK: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] // CHECK-HIDDEN: @_ZN6Test154TempINS_1AEE5Inner6bufferE = external global [0 x i8] namespace test27 { template<typename T> class C { class DEFAULT D { void f(); }; }; template<> class C<int>::D { virtual void g(); }; void C<int>::D::g() { } // CHECK: _ZTVN6test271CIiE1DE = unnamed_addr constant // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant } // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant // CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant // CHECK: @_ZZN6test681fC1EvE4test = linkonce_odr global // CHECK-HIDDEN: @_ZZN6test681fC1EvE4test = linkonce_odr hidden global // CHECK: @_ZGVZN6test681fC1EvE4test = linkonce_odr global // CHECK-HIDDEN: @_ZGVZN6test681fC1EvE4test = linkonce_odr hidden global // CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global // CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global // CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 // CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 namespace Test1 { // CHECK-LABEL: define hidden void @_ZN5Test11fEv void HIDDEN f() { } } namespace Test2 { struct HIDDEN A { void f(); }; // A::f is a member function of a hidden class. // CHECK-LABEL: define hidden void @_ZN5Test21A1fEv void A::f() { } } namespace Test3 { struct HIDDEN A { struct B { void f(); }; }; // B is a nested class where its parent class is hidden. // CHECK-LABEL: define hidden void @_ZN5Test31A1B1fEv void A::B::f() { } } namespace Test4 HIDDEN { int VariableInHiddenNamespace = 10; // Test4::g is in a hidden namespace. // CHECK-LABEL: define hidden void @_ZN5Test41gEv void g() { } struct DEFAULT A { void f(); }; // A has default visibility. // CHECK-LABEL: define void @_ZN5Test41A1fEv void A::f() { } } namespace Test5 { namespace NS HIDDEN { // f is in NS which is hidden. // CHECK-LABEL: define hidden void @_ZN5Test52NS1fEv() void f() { } } namespace NS { // g is in NS, but this NS decl is not hidden. // CHECK-LABEL: define void @_ZN5Test52NS1gEv void g() { } } } // <rdar://problem/8091955> namespace Test6 { struct HIDDEN foo { foo() { } void bonk(); virtual void bar() = 0; virtual void zonk() {} }; struct barc : public foo { barc(); virtual void bar(); }; barc::barc() {} } namespace Test7 { class HIDDEN A {}; A a; // top of file template <A&> struct Aref { static void foo() {} }; class B : public A {}; B b; // top of file // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefIL_ZNS_1aEEE3fooEv() void test() { Aref<a>::foo(); } } namespace Test8 { void foo(); void bar() {} // CHECK-HIDDEN-LABEL: define hidden void @_ZN5Test83barEv() // CHECK-HIDDEN: declare void @_ZN5Test83fooEv() void test() { foo(); bar(); } } // PR8457 namespace Test9 { extern "C" { struct A { int field; }; void DEFAULT test9_fun(struct A *a) { } struct A DEFAULT test9_var; // above } // CHECK-LABEL: define void @test9_fun( // CHECK-HIDDEN-LABEL: define void @test9_fun( void test() { A a = test9_var; test9_fun(&a); } } // PR8478 namespace Test10 { struct A; class DEFAULT B { void foo(A*); }; // CHECK-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( // CHECK-HIDDEN-LABEL: define void @_ZN6Test101B3fooEPNS_1AE( void B::foo(A*) {} } // PR8492 namespace Test11 { struct A { void foo() {} void DEFAULT bar() {} }; void test() { A a; a.foo(); a.bar(); } // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3fooEv( // CHECK-LABEL: define linkonce_odr void @_ZN6Test111A3barEv( // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6Test111A3fooEv( // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6Test111A3barEv( } // Tested at top of file. namespace Test12 { struct A { // This is hidden in all cases: the explicit attribute takes // priority over -fvisibility on the parent. static int hidden HIDDEN; // This is default in all cases because it's only a declaration. static int visible; }; void test() { A::hidden = 0; A::visible = 0; } } // Tested at top of file. namespace Test13 { struct HIDDEN A {}; // Should be hidden in all cases. struct B { static A a; }; A B::a; // Should be default in all cases. struct DEFAULT C { static A a; }; A C::a; }; // Tested at top of file. namespace Test14 { // Neither the visibility of the type nor -fvisibility=hidden should // apply to declarations. extern struct A *var; struct A *test() { return var; } } // rdar://problem/8613093 namespace Test15 { struct A {}; template <class T> struct Temp { struct Inner { static char buffer[0]; }; }; char *test() { return Temp<A>::Inner::buffer; } } namespace Test16 { struct Base1 { virtual void foo(); }; struct Base2 : virtual Base1 { virtual void foo(); }; template <class T> struct A : virtual Base1, Base2 { virtual void foo(); }; extern template struct A<char>; void test() { A<char> a; a.foo(); } } namespace Test17 { struct HIDDEN A { static void foo(); static void DEFAULT bar(); static void HIDDEN baz(); struct DEFAULT B { static void foo(); static void DEFAULT bar(); static void HIDDEN baz(); }; }; void test() { A::foo(); A::bar(); A::baz(); A::B::foo(); A::B::bar(); A::B::baz(); } // CHECK: declare hidden void @_ZN6Test171A3fooEv() // CHECK: declare void @_ZN6Test171A3barEv() // CHECK: declare hidden void @_ZN6Test171A3bazEv() // CHECK: declare void @_ZN6Test171A1B3fooEv() // CHECK: declare void @_ZN6Test171A1B3barEv() // CHECK: declare hidden void @_ZN6Test171A1B3bazEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3fooEv() // CHECK-HIDDEN: declare void @_ZN6Test171A3barEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test171A3bazEv() // CHECK-HIDDEN: declare void @_ZN6Test171A1B3fooEv() // CHECK-HIDDEN: declare void @_ZN6Test171A1B3barEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test171A1B3bazEv() } namespace Test18 { template <class T> struct HIDDEN A { static void foo(); static void DEFAULT bar(); static void HIDDEN baz(); struct DEFAULT B { static void foo(); static void DEFAULT bar(); static void HIDDEN baz(); }; }; struct HIDDEN H; void test() { A<int>::foo(); A<int>::bar(); A<int>::baz(); A<int>::B::foo(); A<int>::B::bar(); A<int>::B::baz(); A<H>::foo(); A<H>::bar(); A<H>::baz(); A<H>::B::foo(); A<H>::B::bar(); A<H>::B::baz(); } // CHECK: declare hidden void @_ZN6Test181AIiE3fooEv() // CHECK: declare void @_ZN6Test181AIiE3barEv() // CHECK: declare hidden void @_ZN6Test181AIiE3bazEv() // CHECK: declare void @_ZN6Test181AIiE1B3fooEv() // CHECK: declare void @_ZN6Test181AIiE1B3barEv() // CHECK: declare hidden void @_ZN6Test181AIiE1B3bazEv() // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3barEv() // CHECK: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() // CHECK: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3fooEv() // CHECK-HIDDEN: declare void @_ZN6Test181AIiE3barEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE3bazEv() // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3fooEv() // CHECK-HIDDEN: declare void @_ZN6Test181AIiE1B3barEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AIiE1B3bazEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3fooEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3barEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE3bazEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3fooEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3barEv() // CHECK-HIDDEN: declare hidden void @_ZN6Test181AINS_1HEE1B3bazEv() } namespace Test19 { struct A { A(); ~A(); }; // Tested at top of file. template <class T> void foo() { static A a; } void test() { foo<int>(); } } // Various things with class template specializations. namespace Test20 { template <unsigned> struct HIDDEN A {}; // An explicit specialization inherits the explicit visibility of // the template. template <> struct A<0> { static void test0(); static void test1(); }; // CHECK-LABEL: define hidden void @_ZN6Test201AILj0EE5test0Ev() void A<0>::test0() {} // CHECK: declare hidden void @_ZN6Test201AILj0EE5test1Ev() void test1() { A<0>::test1(); } // ...unless that's explicitly overridden. template <> struct DEFAULT A<1> { static void test2(); static void test3(); }; // CHECK-LABEL: define void @_ZN6Test201AILj1EE5test2Ev() void A<1>::test2() {} // CHECK: declare void @_ZN6Test201AILj1EE5test3Ev() void test3() { A<1>::test3(); } // <rdar://problem/8778497> // But we should assume that an unknown specialization has the // explicit visibility settings of the template. template <class T> struct B { static void test4() {} static void test5(); }; // CHECK-LABEL: define linkonce_odr hidden void @_ZN6Test201BINS_1AILj2EEEE5test4Ev() void test4() { B<A<2> >::test4(); } // CHECK: declare hidden void @_ZN6Test201BINS_1AILj2EEEE5test5Ev() void test5() { B<A<2> >::test5(); } } // PR9371 namespace test21 { enum En { en }; template<En> struct A { DEFAULT void foo() {} }; // CHECK-LABEL: define weak_odr void @_ZN6test211AILNS_2EnE0EE3fooEv( template void A<en>::foo(); } // rdar://problem/9616154 // Visibility on explicit specializations should take precedence. namespace test22 { class A1 {}; class A2 {}; template <class T> struct B {}; template <> struct DEFAULT B<A1> { static void foo(); static void bar() {} }; template <> struct B<A2> { static void foo(); static void bar() {} }; void test() { B<A1>::foo(); B<A1>::bar(); B<A2>::foo(); B<A2>::bar(); } // CHECK: declare void @_ZN6test221BINS_2A1EE3fooEv() // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() // CHECK: declare void @_ZN6test221BINS_2A2EE3fooEv() // CHECK-LABEL: define linkonce_odr void @_ZN6test221BINS_2A2EE3barEv() // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A1EE3fooEv() // CHECK-HIDDEN-LABEL: define linkonce_odr void @_ZN6test221BINS_2A1EE3barEv() // CHECK-HIDDEN: declare void @_ZN6test221BINS_2A2EE3fooEv() // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test221BINS_2A2EE3barEv() } namespace PR10113 { namespace foo DEFAULT { template<typename T> class bar { void zed() {} }; } template class foo::bar<char>; // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR101133foo3barIcE3zedEv struct zed { }; template class foo::bar<zed>; // CHECK-LABEL: define weak_odr void @_ZN7PR101133foo3barINS_3zedEE3zedEv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN7PR101133foo3barINS_3zedEE3zedEv } namespace PR11690 { template<class T> struct Class { void size() const { } }; template class DEFAULT Class<char>; // CHECK-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZNK7PR116905ClassIcE4sizeEv template<class T> void Method() {} template DEFAULT void Method<char>(); // CHECK-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN7PR116906MethodIcEEvv } namespace PR11690_2 { namespace foo DEFAULT { class bar; template<typename T1, typename T2 = bar> class zed { void bar() { } }; } struct baz { }; template class foo::zed<baz>; // CHECK-LABEL: define weak_odr void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN9PR11690_23foo3zedINS_3bazENS0_3barEE3barEv } namespace test23 { // Having a template argument that is explicitly visible should not make // the template instantiation visible. template <typename T> struct X { static void f() { } }; class DEFAULT A; void g() { X<A> y; y.f(); } // CHECK-LABEL: define linkonce_odr void @_ZN6test231XINS_1AEE1fEv // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test231XINS_1AEE1fEv } namespace PR12001 { template <typename P1> void Bind(const P1& p1) { } class DEFAULT Version { }; void f() { Bind(Version()); } // CHECK-LABEL: define linkonce_odr void @_ZN7PR120014BindINS_7VersionEEEvRKT_ // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN7PR120014BindINS_7VersionEEEvRKT_ } namespace test24 { class DEFAULT A { }; struct S { template <typename T> void mem() {} }; void test() { S s; s.mem<A>(); } // CHECK-LABEL: define linkonce_odr void @_ZN6test241S3memINS_1AEEEvv // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test241S3memINS_1AEEEvv } namespace test26 { template<typename T> class C { DEFAULT void f(); }; template<> void C<int>::f() { } // CHECK-LABEL: define void @_ZN6test261CIiE1fEv // CHECK-HIDDEN-LABEL: define void @_ZN6test261CIiE1fEv } namespace test31 { struct A { struct HIDDEN B { static void DEFAULT baz(); }; }; void f() { A::B::baz(); } // CHECK: declare void @_ZN6test311A1B3bazEv() // CHECK-HIDDEN: declare void @_ZN6test311A1B3bazEv() } namespace test32 { struct HIDDEN A { struct DEFAULT B { void DEFAULT baz(); }; }; void A::B::baz() { } // CHECK-LABEL: define void @_ZN6test321A1B3bazEv // CHECK-HIDDEN-LABEL: define void @_ZN6test321A1B3bazEv } namespace test33 { template<typename T> class foo { void bar() {} }; struct HIDDEN zed { }; template class DEFAULT foo<zed>; // CHECK-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test333fooINS_3zedEE3barEv } namespace test34 { struct foo { }; template<class T> void bar() {} template DEFAULT void bar<foo>(); // CHECK-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test343barINS_3fooEEEvv } namespace test35 { // This is a really ugly testcase. GCC propagates the DEFAULT in zed's // definition. It's not really clear what we can do here, because we // produce the symbols before even seeing the DEFAULT definition of zed. // FIXME: Maybe the best thing to do here is error? It's certainly hard // to argue that this ought to be valid. template<typename T> struct DEFAULT foo { void bar() {} }; class zed; template class foo<zed>; class DEFAULT zed { }; // CHECK-LABEL: define weak_odr void @_ZN6test353fooINS_3zedEE3barEv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test353fooINS_3zedEE3barEv } namespace test36 { template<typename T1, typename T2> class foo { void bar() {} }; class DEFAULT S1 {}; struct HIDDEN S2 {}; template class foo<S1, S2>; // CHECK-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test363fooINS_2S1ENS_2S2EE3barEv } namespace test37 { struct HIDDEN foo { }; template<class T> DEFAULT void bar() {} template DEFAULT void bar<foo>(); // CHECK-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test373barINS_3fooEEEvv } namespace test38 { template<typename T> class DEFAULT foo { void bar() {} }; struct HIDDEN zed { }; template class foo<zed>; // CHECK-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test383fooINS_3zedEE3barEv } namespace test39 { class DEFAULT default_t; class HIDDEN hidden_t; template <class T> class A { template <class U> class B { HIDDEN void hidden() {} void noattr() {} template <class V> void temp() {} }; }; template class DEFAULT A<hidden_t>; template class DEFAULT A<hidden_t>::B<hidden_t>; template void A<hidden_t>::B<hidden_t>::temp<default_t>(); template void A<hidden_t>::B<hidden_t>::temp<hidden_t>(); // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv // CHECK-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv // GCC produces a default for this one. Why? // CHECK-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E6hiddenEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E6noattrEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempINS_9default_tEEEvv // GCC produces a default for this one. Why? // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test391AINS_8hidden_tEE1BIS1_E4tempIS1_EEvv } namespace test42 { struct HIDDEN foo { }; template <class P> struct bar { }; template <> struct HIDDEN bar<foo> { DEFAULT static void zed(); }; void bar<foo>::zed() { } // CHECK-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv // CHECK-HIDDEN-LABEL: define void @_ZN6test423barINS_3fooEE3zedEv } namespace test43 { struct HIDDEN foo { }; template <class P> void bar() { } template <> DEFAULT void bar<foo>() { } // CHECK-LABEL: define void @_ZN6test433barINS_3fooEEEvv // CHECK-HIDDEN-LABEL: define void @_ZN6test433barINS_3fooEEEvv } namespace test44 { template <typename T> struct foo { foo() {} }; namespace { struct bar; } template struct DEFAULT foo<bar>; foo<bar> x; // CHECK-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev // CHECK-HIDDEN-LABEL: define internal void @_ZN6test443fooINS_12_GLOBAL__N_13barEEC1Ev } namespace test45 { template <typename T> struct foo { template <typename T2> struct bar { bar() {}; }; }; namespace { struct zed; } template struct DEFAULT foo<int>::bar<zed>; foo<int>::bar<zed> x; // CHECK-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev // CHECK-HIDDEN-LABEL: define internal void @_ZN6test453fooIiE3barINS_12_GLOBAL__N_13zedEEC1Ev } namespace test46 { template <typename T> void foo() { } namespace { struct bar; } template DEFAULT void foo<bar>(); void zed() { foo<bar>(); } // CHECK-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv // CHECK-HIDDEN-LABEL: define internal void @_ZN6test463fooINS_12_GLOBAL__N_13barEEEvv } namespace test47 { struct foo { template <typename T> static void bar() { } }; namespace { struct zed; } template DEFAULT void foo::bar<zed>(); void baz() { foo::bar<zed>(); } // CHECK-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv // CHECK-HIDDEN-LABEL: define internal void @_ZN6test473foo3barINS_12_GLOBAL__N_13zedEEEvv } namespace test49 { // Test that we use the visibility of struct foo when instantiating the // template. Note that is a case where we disagree with gcc, it produces // a default symbol. struct HIDDEN foo { }; DEFAULT foo x; struct bar { template<foo *z> void zed() { } }; template void bar::zed<&x>(); // CHECK-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test493bar3zedIXadL_ZNS_1xEEEEEvv } namespace test50 { // Test that we use the visibility of struct foo when instantiating the // template. Note that is a case where we disagree with gcc, it produces // a default symbol. struct HIDDEN foo { }; DEFAULT foo x; template<foo *z> struct DEFAULT bar { void zed() { } }; template void bar<&x>::zed(); // CHECK-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test503barIXadL_ZNS_1xEEEE3zedEv } namespace test51 { // Test that we use the visibility of struct foo when instantiating the // template. Note that is a case where we disagree with gcc, it produces // a default symbol. struct HIDDEN foo { }; DEFAULT foo x; template<foo *z> void DEFAULT zed() { } template void zed<&x>(); // CHECK-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv // CHECK-HIDDEN-LABEL: define weak_odr hidden void @_ZN6test513zedIXadL_ZNS_1xEEEEEvv } namespace test52 { // Test that we use the linkage of struct foo when instantiating the // template. Note that is a case where we disagree with gcc, it produces // an external symbol. namespace { struct foo { }; } template<foo *x> void zed() { } void f() { zed<nullptr>(); } // CHECK-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv // CHECK-HIDDEN-LABEL: define internal void @_ZN6test523zedILPNS_12_GLOBAL__N_13fooE0EEEvv } namespace test53 { template<typename _Tp > struct vector { static void _M_fill_insert(); }; #pragma GCC visibility push(hidden) // GCC doesn't seem to use the visibility of enums at all, we do. enum zed {v1}; // GCC fails to mark this specialization hidden, we mark it. template<> struct vector<int> { static void _M_fill_insert(); }; void foo() { vector<unsigned>::_M_fill_insert(); vector<int>::_M_fill_insert(); vector<zed>::_M_fill_insert(); } #pragma GCC visibility pop // CHECK: declare void @_ZN6test536vectorIjE14_M_fill_insertEv // CHECK-HIDDEN: declare void @_ZN6test536vectorIjE14_M_fill_insertEv // CHECK: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorIiE14_M_fill_insertEv // CHECK: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv // CHECK-HIDDEN: declare hidden void @_ZN6test536vectorINS_3zedEE14_M_fill_insertEv } namespace test54 { template <class T> struct foo { static void bar(); }; #pragma GCC visibility push(hidden) class zed { zed(const zed &); }; void bah() { foo<zed>::bar(); } #pragma GCC visibility pop // CHECK: declare hidden void @_ZN6test543fooINS_3zedEE3barEv // CHECK-HIDDEN: declare hidden void @_ZN6test543fooINS_3zedEE3barEv } namespace test55 { template <class T> struct HIDDEN foo { static void bar(); }; template <class T> struct foo; void foobar() { foo<int>::bar(); } // CHECK: declare hidden void @_ZN6test553fooIiE3barEv // CHECK-HIDDEN: declare hidden void @_ZN6test553fooIiE3barEv } namespace test56 { template <class T> struct foo; template <class T> struct HIDDEN foo { static void bar(); }; void foobar() { foo<int>::bar(); } // CHECK: declare hidden void @_ZN6test563fooIiE3barEv // CHECK-HIDDEN: declare hidden void @_ZN6test563fooIiE3barEv } namespace test57 { #pragma GCC visibility push(hidden) template <class T> struct foo; void bar(foo<int>*); template <class T> struct foo { static void zed(); }; void bah() { foo<int>::zed(); } #pragma GCC visibility pop // CHECK: declare hidden void @_ZN6test573fooIiE3zedEv // CHECK-HIDDEN: declare hidden void @_ZN6test573fooIiE3zedEv } namespace test58 { #pragma GCC visibility push(hidden) struct foo; template<typename T> struct DEFAULT bar { static void zed() { } }; void bah() { bar<foo>::zed(); } #pragma GCC visibility pop // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test583barINS_3fooEE3zedEv } namespace test59 { DEFAULT int f(); HIDDEN int g(); typedef int (*foo)(); template<foo x, foo y> void test() {} void use() { test<&g, &f>(); // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1gEvEEXadL_ZNS_1fEvEEEEvv test<&f, &g>(); // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test594testIXadL_ZNS_1fEvEEXadL_ZNS_1gEvEEEEvv } } namespace test60 { template<int i> class HIDDEN a {}; template<int i> class DEFAULT b {}; template<template<int> class x, template<int> class y> void test() {} void use() { test<a, b>(); // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1aENS_1bEEEvv test<b, a>(); // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv // CHECK-HIDDEN-LABEL: define linkonce_odr hidden void @_ZN6test604testINS_1bENS_1aEEEvv } } namespace test61 { template <typename T1> struct Class1 { void f1() { f2(); } inline void f2(); }; template<> inline void Class1<int>::f2() { } void g(Class1<int> *x) { x->f1(); } } namespace test61 { // Just test that we don't crash. Currently we apply this attribute. Current // gcc issues a warning about it being unused since "the type is already // defined". We should probably do the same. template class HIDDEN Class1<int>; } namespace test62 { template <typename T1> struct Class1 { void f1() { f2(); } inline void f2() {} }; template<> inline void Class1<int>::f2() { } void g(Class1<int> *x) { x->f2(); } } namespace test62 { template class HIDDEN Class1<int>; // Just test that we don't crash. Currently we apply this attribute. Current // gcc issues a warning about it being unused since "the type is already // defined". We should probably do the same. } namespace test63 { enum HIDDEN E { E0 }; struct A { template <E> static void foo() {} template <E> struct B { static void foo() {} }; }; void test() { A::foo<E0>(); A::B<E0>::foo(); } // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A3fooILNS_1EE0EEEvv() // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test631A1BILNS_1EE0EE3fooEv() } // Don't ignore the visibility of template arguments just because we // explicitly instantiated something. namespace test64 { struct HIDDEN A {}; template <class P> struct B { static DEFAULT void foo() {} }; template class B<A>; // CHECK-LABEL: define weak_odr hidden void @_ZN6test641BINS_1AEE3fooEv() } namespace test65 { class HIDDEN A {}; template <class T> struct B { static void func(); template <class U> static void funcT1(); template <class U> static void funcT2(); class Inner {}; template <class U> class InnerT {}; }; template <template <class T> class Temp> struct C { static void foo() {} }; // CHECK-LABEL: define void @_ZN6test651BINS_1AEE4funcEv() template <> DEFAULT void B<A>::func() {} // CHECK-LABEL: define void @_ZN6test651BINS_1AEE6funcT2IS1_EEvv() template <> template <> DEFAULT void B<A>::funcT2<A>() {} // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6funcT1IiEEvv() // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6funcT1IS1_EEvv() template <> template <class T> DEFAULT void B<A>::funcT1() {} // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE5Inner3fooEv() template <> struct DEFAULT B<A>::Inner { static void foo() {} }; // CHECK-LABEL: define linkonce_odr void @_ZN6test651BINS_1AEE6InnerTIiE3fooEv() // CHECK-LABEL: define linkonce_odr hidden void @_ZN6test651BINS_1AEE6InnerTIS1_E3fooEv() template <> template <class U> struct DEFAULT B<A>::InnerT { static void foo() {} }; void test() { B<A>::funcT1<int>(); B<A>::funcT1<A>(); B<A>::Inner::foo(); B<A>::InnerT<int>::foo(); B<A>::InnerT<A>::foo(); } template class C<B<A>::InnerT>; } namespace test66 { template <typename T> struct DEFAULT barT { static void zed() {} }; class foo; class DEFAULT foo; template struct barT<foo>; // CHECK-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barTINS_3fooEE3zedEv template <int* I> struct DEFAULT barI { static void zed() {} }; extern int I; extern int I DEFAULT; template struct barI<&I>; // CHECK-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barIIXadL_ZNS_1IEEEE3zedEv typedef void (*fType)(void); template<fType F> struct DEFAULT barF { static void zed() {} }; void F(); void F() DEFAULT; template struct barF<F>; // CHECK-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test664barFIXadL_ZNS_1FEvEEE3zedEv } namespace test67 { template <typename T> struct DEFAULT bar { static void zed() {} }; class foo; class compute { void f(foo *rootfoo); }; class DEFAULT foo; template struct bar<foo>; // CHECK-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv // CHECK-HIDDEN-LABEL: define weak_odr void @_ZN6test673barINS_3fooEE3zedEv } namespace test68 { class A { public: ~A(); }; class f { public: f() { static A test; } }; void g() { f a; } // Check lines at top of file. } namespace test69 { // PR18174 namespace foo { void f(); } namespace foo { void f() {}; } namespace foo __attribute__((visibility("hidden"))) { } // CHECK-LABEL: define void @_ZN6test693foo1fEv // CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv }