Clang Project

clang_source_code/test/SemaCXX/attr-exclude_from_explicit_instantiation.extern_declaration.cpp
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
9template <class T>
10struct 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 {
22    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 {
28    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
34template <class T>
35inline void Foo<T>::non_static_member_function1() {
36  using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}}
37}
38
39template <class T>
40void Foo<T>::non_static_member_function2() {
41  using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}}
42}
43
44template <class T>
45inline void Foo<T>::static_member_function1() {
46  using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}}
47}
48
49template <class T>
50void Foo<T>::static_member_function2() {
51  using Fail = typename T::invalid; // expected-error{{no type named 'invalid' in 'Empty'}}
52}
53
54template <class T>
55int Foo<T>::static_data_member = T::invalid; // expected-error{{no member named 'invalid' in 'Empty'}}
56
57struct Empty { };
58extern template struct Foo<Empty>;
59
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