1 // RUN: %clang_cc1 -fsyntax-only -verify %s 2 3 // Test that we properly merge the exclude_from_explicit_instantiation 4 // attribute on redeclarations. 5 6 #define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation)) 7 8 template <class T> 9 struct Foo { 10 // Declaration without the attribute, definition with the attribute. 11 void func1(); 12 13 // Declaration with the attribute, definition without the attribute. 14 EXCLUDE_FROM_EXPLICIT_INSTANTIATION void func2(); 15 16 // Declaration with the attribute, definition with the attribute. 17 EXCLUDE_FROM_EXPLICIT_INSTANTIATION void func3(); 18 }; 19 20 template <class T> func1()21EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func1() { 22 using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 23 } 24 25 template <class T> func2()26void Foo<T>::func2() { 27 using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 28 } 29 30 template <class T> func3()31EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func3() { 32 using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}} 33 } 34 35 struct Empty { }; 36 extern template struct Foo<Empty>; 37 main()38int main() { 39 Foo<Empty> foo; 40 foo.func1(); // expected-note{{in instantiation of}} 41 foo.func2(); // expected-note{{in instantiation of}} 42 foo.func3(); // expected-note{{in instantiation of}} 43 } 44