| // RUN: %clang_cc1 -Wno-unused-local-typedef -fsyntax-only -verify %s |
| |
| // Test that extern instantiation declarations cause members marked with |
| // the exclude_from_explicit_instantiation attribute to be instantiated in |
| // the current TU. |
| |
| #define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) |
| |
| template <class T> |
| struct Foo { |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void non_static_member_function1(); |
| |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2(); |
| |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1(); |
| |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2(); |
| |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member; |
| |
| struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 { |
| static void static_member_function() { |
| using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} |
| } |
| }; |
| |
| struct member_class2 { |
| EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function() { |
| using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} |
| } |
| }; |
| }; |
| |
| template <class T> |
| inline void Foo<T>::non_static_member_function1() { |
| using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} |
| } |
| |
| template <class T> |
| void Foo<T>::non_static_member_function2() { |
| using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} |
| } |
| |
| template <class T> |
| inline void Foo<T>::static_member_function1() { |
| using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} |
| } |
| |
| template <class T> |
| void Foo<T>::static_member_function2() { |
| using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} |
| } |
| |
| template <class T> |
| int Foo<T>::static_data_member = T::invalid; // expected-error{{no member named 'invalid' in 'Empty'}} |
| |
| struct Empty { }; |
| extern template struct Foo<Empty>; |
| |
| int main() { |
| Foo<Empty> foo; |
| foo.non_static_member_function1(); // expected-note{{in instantiation of}} |
| foo.non_static_member_function2(); // expected-note{{in instantiation of}} |
| Foo<Empty>::static_member_function1(); // expected-note{{in instantiation of}} |
| Foo<Empty>::static_member_function2(); // expected-note{{in instantiation of}} |
| (void)foo.static_data_member; // expected-note{{in instantiation of}} |
| Foo<Empty>::member_class1::static_member_function(); // expected-note{{in instantiation of}} |
| Foo<Empty>::member_class2::static_member_function(); // expected-note{{in instantiation of}} |
| } |