1// RUN: %clang_cc1 -fsyntax-only -verify %s
2// expected-no-diagnostics
3
4// This test creates cases where implicit instantiations of various entities
5// would cause a diagnostic, but provides expliict specializations for those
6// entities that avoid the diagnostic. The intent is to verify that
7// implicit instantiations do not occur (because the explicit specialization
8// is used instead).
9struct NonDefaultConstructible {
10  NonDefaultConstructible(int);
11};
12
13
14// C++ [temp.expl.spec]p1:
15//   An explicit specialization of any of the following:
16
17//     -- function template
18template<typename T> void f0(T) {
19  T t;
20}
21
22template<> void f0(NonDefaultConstructible) { }
23
24void test_f0(NonDefaultConstructible NDC) {
25  f0(NDC);
26}
27
28//     -- class template
29template<typename T>
30struct X0 {
31  static T member;
32
33  void f1(T t) {
34    t = 17;
35  }
36
37  struct Inner : public T { };
38
39  template<typename U>
40  struct InnerTemplate : public T { };
41
42  template<typename U>
43  void ft1(T t, U u);
44};
45
46template<typename T>
47template<typename U>
48void X0<T>::ft1(T t, U u) {
49  t = u;
50}
51
52template<typename T> T X0<T>::member;
53
54template<> struct X0<void> { };
55X0<void> test_X0;
56
57
58//     -- member function of a class template
59template<> void X0<void*>::f1(void *) { }
60
61void test_spec(X0<void*> xvp, void *vp) {
62  xvp.f1(vp);
63}
64
65//     -- static data member of a class template
66template<>
67NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
68
69NonDefaultConstructible &get_static_member() {
70  return X0<NonDefaultConstructible>::member;
71}
72
73//    -- member class of a class template
74template<>
75struct X0<void*>::Inner { };
76
77X0<void*>::Inner inner0;
78
79//    -- member class template of a class template
80template<>
81template<>
82struct X0<void*>::InnerTemplate<int> { };
83
84X0<void*>::InnerTemplate<int> inner_template0;
85
86//    -- member function template of a class template
87template<>
88template<>
89void X0<void*>::ft1(void*, const void*) { }
90
91void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
92  xvp.ft1(vp, cvp);
93}
94
95// example from the standard:
96template<class T> class stream;
97template<> class stream<char> { /* ... */ };
98template<class T> class Array { /* ... */ };
99template<class T> void sort(Array<T>& v) { /* ... */ }
100template<> void sort<char*>(Array<char*>&) ;
101