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