Clang Project

clang_source_code/test/SemaCXX/attr-exclude_from_explicit_instantiation.merge_redeclarations.cpp
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
8template <class T>
9struct 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
20template <class T>
21EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func1() {
22  using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}}
23}
24
25template <class T>
26void Foo<T>::func2() {
27  using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}}
28}
29
30template <class T>
31EXCLUDE_FROM_EXPLICIT_INSTANTIATION void Foo<T>::func3() {
32  using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}}
33}
34
35struct Empty { };
36extern template struct Foo<Empty>;
37
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