// 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 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 inline void Foo::non_static_member_function1() { using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} } template void Foo::non_static_member_function2() { using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} } template inline void Foo::static_member_function1() { using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} } template void Foo::static_member_function2() { using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} } template int Foo::static_data_member = T::invalid; // expected-error{{no member named 'invalid' in 'Empty'}} struct Empty { }; extern template struct Foo; int main() { Foo foo; foo.non_static_member_function1(); // expected-note{{in instantiation of}} foo.non_static_member_function2(); // expected-note{{in instantiation of}} Foo::static_member_function1(); // expected-note{{in instantiation of}} Foo::static_member_function2(); // expected-note{{in instantiation of}} (void)foo.static_data_member; // expected-note{{in instantiation of}} Foo::member_class1::static_member_function(); // expected-note{{in instantiation of}} Foo::member_class2::static_member_function(); // expected-note{{in instantiation of}} }