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).
9 struct 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
f0(T)18 template<typename T> void f0(T) {
19 T t;
20 }
21
f0(NonDefaultConstructible)22 template<> void f0(NonDefaultConstructible) { }
23
test_f0(NonDefaultConstructible NDC)24 void test_f0(NonDefaultConstructible NDC) {
25 f0(NDC);
26 }
27
28 // -- class template
29 template<typename T>
30 struct X0 {
31 static T member;
32
f1X033 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
46 template<typename T>
47 template<typename U>
ft1(T t,U u)48 void X0<T>::ft1(T t, U u) {
49 t = u;
50 }
51
52 template<typename T> T X0<T>::member;
53
54 template<> struct X0<void> { };
55 X0<void> test_X0;
56
57
58 // -- member function of a class template
f1(void *)59 template<> void X0<void*>::f1(void *) { }
60
test_spec(X0<void * > xvp,void * vp)61 void test_spec(X0<void*> xvp, void *vp) {
62 xvp.f1(vp);
63 }
64
65 // -- static data member of a class template
66 template<>
67 NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
68
get_static_member()69 NonDefaultConstructible &get_static_member() {
70 return X0<NonDefaultConstructible>::member;
71 }
72
73 // -- member class of a class template
74 template<>
75 struct X0<void*>::Inner { };
76
77 X0<void*>::Inner inner0;
78
79 // -- member class template of a class template
80 template<>
81 template<>
82 struct X0<void*>::InnerTemplate<int> { };
83
84 X0<void*>::InnerTemplate<int> inner_template0;
85
86 // -- member function template of a class template
87 template<>
88 template<>
ft1(void *,const void *)89 void X0<void*>::ft1(void*, const void*) { }
90
test_func_template(X0<void * > xvp,void * vp,const void * cvp)91 void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
92 xvp.ft1(vp, cvp);
93 }
94
95 // example from the standard:
96 template<class T> class stream;
97 template<> class stream<char> { /* ... */ };
98 template<class T> class Array { /* ... */ };
sort(Array<T> & v)99 template<class T> void sort(Array<T>& v) { /* ... */ }
100 template<> void sort<char*>(Array<char*>&) ;
101