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