1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 // Test that explicit instantiations do not instantiate entities
4 // marked with the exclude_from_explicit_instantiation attribute.
5 
6 #define EXCLUDE_FROM_EXPLICIT_INSTANTIATION __attribute__((exclude_from_explicit_instantiation))
7 
8 template <class T>
9 struct Foo {
10   EXCLUDE_FROM_EXPLICIT_INSTANTIATION inline void non_static_member_function1();
11 
12   EXCLUDE_FROM_EXPLICIT_INSTANTIATION void non_static_member_function2();
13 
14   EXCLUDE_FROM_EXPLICIT_INSTANTIATION static inline void static_member_function1();
15 
16   EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void static_member_function2();
17 
18   EXCLUDE_FROM_EXPLICIT_INSTANTIATION static int static_data_member;
19 
20   struct EXCLUDE_FROM_EXPLICIT_INSTANTIATION member_class1 {
non_static_member_functionFoo::member_class121     static void non_static_member_function() { using Fail = typename T::fail; }
22   };
23 
24   struct member_class2 {
non_static_member_functionFoo::member_class225     EXCLUDE_FROM_EXPLICIT_INSTANTIATION static void non_static_member_function() { using Fail = typename T::fail; }
26   };
27 };
28 
29 template <class T>
non_static_member_function1()30 inline void Foo<T>::non_static_member_function1() { using Fail = typename T::fail; }
31 
32 template <class T>
non_static_member_function2()33 void Foo<T>::non_static_member_function2() { using Fail = typename T::fail; }
34 
35 template <class T>
static_member_function1()36 inline void Foo<T>::static_member_function1() { using Fail = typename T::fail; }
37 
38 template <class T>
static_member_function2()39 void Foo<T>::static_member_function2() { using Fail = typename T::fail; }
40 
41 template <class T>
42 int Foo<T>::static_data_member = T::fail;
43 
44 // expected-no-diagnostics
45 template struct Foo<int>;
46