1*d269579aSLouis Dionne // RUN: %clang_cc1 -Wno-unused-local-typedef -fsyntax-only -verify %s 2*d269579aSLouis Dionne 3*d269579aSLouis Dionne // Test that extern instantiation declarations cause members marked with 4*d269579aSLouis Dionne // the exclude_from_explicit_instantiation attribute to be instantiated in 5*d269579aSLouis Dionne // the current TU. 6*d269579aSLouis Dionne 7*d269579aSLouis Dionne #define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) 8*d269579aSLouis Dionne 9*d269579aSLouis Dionne template <class T> 10*d269579aSLouis Dionne struct Foo { 11*d269579aSLouis Dionne EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void non_static_member_function1(); 12*d269579aSLouis Dionne 13*d269579aSLouis Dionne EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2(); 14*d269579aSLouis Dionne 15*d269579aSLouis Dionne EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1(); 16*d269579aSLouis Dionne 17*d269579aSLouis Dionne EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2(); 18*d269579aSLouis Dionne 19*d269579aSLouis Dionne EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; 20*d269579aSLouis Dionne 21*d269579aSLouis Dionne struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 { static_member_functionFoo::member_class122*d269579aSLouis Dionne static void static_member_function() { 23*d269579aSLouis Dionne using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 24*d269579aSLouis Dionne } 25*d269579aSLouis Dionne }; 26*d269579aSLouis Dionne 27*d269579aSLouis Dionne struct member_class2 { static_member_functionFoo::member_class228*d269579aSLouis Dionne EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() { 29*d269579aSLouis Dionne using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 30*d269579aSLouis Dionne } 31*d269579aSLouis Dionne }; 32*d269579aSLouis Dionne }; 33*d269579aSLouis Dionne 34*d269579aSLouis Dionne template <class T> non_static_member_function1()35*d269579aSLouis Dionneinline void Foo<T>::non_static_member_function1() { 36*d269579aSLouis Dionne using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 37*d269579aSLouis Dionne } 38*d269579aSLouis Dionne 39*d269579aSLouis Dionne template <class T> non_static_member_function2()40*d269579aSLouis Dionnevoid Foo<T>::non_static_member_function2() { 41*d269579aSLouis Dionne using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 42*d269579aSLouis Dionne } 43*d269579aSLouis Dionne 44*d269579aSLouis Dionne template <class T> static_member_function1()45*d269579aSLouis Dionneinline void Foo<T>::static_member_function1() { 46*d269579aSLouis Dionne using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 47*d269579aSLouis Dionne } 48*d269579aSLouis Dionne 49*d269579aSLouis Dionne template <class T> static_member_function2()50*d269579aSLouis Dionnevoid Foo<T>::static_member_function2() { 51*d269579aSLouis Dionne using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 52*d269579aSLouis Dionne } 53*d269579aSLouis Dionne 54*d269579aSLouis Dionne template <class T> 55*d269579aSLouis Dionne int Foo<T>::static_data_member = T::invalid; // expected-error{{no member named 'invalid' in 'Empty'}} 56*d269579aSLouis Dionne 57*d269579aSLouis Dionne struct Empty { }; 58*d269579aSLouis Dionne extern template struct Foo<Empty>; 59*d269579aSLouis Dionne main()60*d269579aSLouis Dionneint main() { 61*d269579aSLouis Dionne Foo<Empty> foo; 62*d269579aSLouis Dionne foo.non_static_member_function1(); // expected-note{{in instantiation of}} 63*d269579aSLouis Dionne foo.non_static_member_function2(); // expected-note{{in instantiation of}} 64*d269579aSLouis Dionne Foo<Empty>::static_member_function1(); // expected-note{{in instantiation of}} 65*d269579aSLouis Dionne Foo<Empty>::static_member_function2(); // expected-note{{in instantiation of}} 66*d269579aSLouis Dionne (void)foo.static_data_member; // expected-note{{in instantiation of}} 67*d269579aSLouis Dionne Foo<Empty>::member_class1::static_member_function(); // expected-note{{in instantiation of}} 68*d269579aSLouis Dionne Foo<Empty>::member_class2::static_member_function(); // expected-note{{in instantiation of}} 69*d269579aSLouis Dionne } 70