p2.cpp revision 1fef4e60e7e884803977a8376c172ea584f8a5d1
1// RUN: clang-cc -fsyntax-only -verify %s
2
3// This test creates cases where implicit instantiations of various entities
4// would cause a diagnostic, but provides expliict specializations for those
5// entities that avoid the diagnostic. The specializations are alternately
6// declarations and definitions, and the intent of this test is to verify
7// that we allow specializations only in the appropriate namespaces (and
8// nowhere else).
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
18namespace N0 {
19  template<typename T> void f0(T) { // expected-note{{here}}
20    T t;
21  }
22
23  template<> void f0(NonDefaultConstructible) { }
24
25  void test_f0(NonDefaultConstructible NDC) {
26    f0(NDC);
27  }
28
29  template<> void f0(int);
30  template<> void f0(long);
31}
32
33template<> void N0::f0(int) { } // okay
34
35namespace N1 {
36  template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}}
37}
38
39template<> void N0::f0(double) { } // expected-error{{originally be declared}}
40
41struct X1 {
42  template<typename T> void f(T);
43
44  template<> void f(int); // expected-error{{in class scope}}
45};
46
47//     -- class template
48namespace N0 {
49
50template<typename T>
51struct X0 { // expected-note 2{{here}}
52  static T member;
53
54  void f1(T t) { // expected-note{{explicitly specialized declaration is here}}
55    t = 17;
56  }
57
58  struct Inner : public T { };
59
60  template<typename U>
61  struct InnerTemplate : public T { };
62
63  template<typename U>
64  void ft1(T t, U u);
65};
66
67}
68
69template<typename T>
70template<typename U>
71void N0::X0<T>::ft1(T t, U u) {
72  t = u;
73}
74
75template<typename T> T N0::X0<T>::member;
76
77template<> struct N0::X0<void> { }; // expected-error{{originally}}
78N0::X0<void> test_X0;
79
80namespace N1 {
81  template<> struct N0::X0<const void> { }; // expected-error{{originally}}
82}
83
84namespace N0 {
85  template<> struct X0<volatile void>;
86}
87
88template<> struct N0::X0<volatile void> {
89  void f1(void *);
90};
91
92//     -- member function of a class template
93template<> void N0::X0<void*>::f1(void *) { } // expected-error{{member function specialization}}
94
95void test_spec(N0::X0<void*> xvp, void *vp) {
96  xvp.f1(vp);
97}
98
99namespace N0 {
100  template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
101}
102
103#if 0
104// FIXME: update the remainder of this test to check for scopes properly.
105//     -- static data member of a class template
106template<>
107NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
108
109NonDefaultConstructible &get_static_member() {
110  return X0<NonDefaultConstructible>::member;
111}
112
113//    -- member class of a class template
114template<>
115struct X0<void*>::Inner { };
116
117X0<void*>::Inner inner0;
118
119//    -- member class template of a class template
120template<>
121template<>
122struct X0<void*>::InnerTemplate<int> { };
123
124X0<void*>::InnerTemplate<int> inner_template0;
125
126//    -- member function template of a class template
127template<>
128template<>
129void X0<void*>::ft1(void*, const void*) { }
130
131void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
132  xvp.ft1(vp, cvp);
133}
134#endif
135