1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
3a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor// This test creates cases where implicit instantiations of various entities
4a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor// would cause a diagnostic, but provides expliict specializations for those
5a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor// entities that avoid the diagnostic. The specializations are alternately
6a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor// declarations and definitions, and the intent of this test is to verify
7a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor// that we allow specializations only in the appropriate namespaces (and
8a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor// nowhere else).
9a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct NonDefaultConstructible {
10a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  NonDefaultConstructible(int);
11a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor};
12a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
13a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
14a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor// C++ [temp.expl.spec]p1:
15a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//   An explicit specialization of any of the following:
16a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
17a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//     -- function template
18a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
19a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<typename T> void f0(T) {
20a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor    T t;
21a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  }
22a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
23a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> void f0(NonDefaultConstructible) { }
24a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
25a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void test_f0(NonDefaultConstructible NDC) {
26a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor    f0(NDC);
27a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  }
28a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
29a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> void f0(int);
30a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> void f0(long);
31a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
32a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
33a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> void N0::f0(int) { } // okay
34a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
35a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N1 {
36a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}}
37a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
38a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
39a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> void N0::f0(double) { }
40a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
41a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct X1 {
42a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<typename T> void f(T);
43a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
44a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> void f(int); // expected-error{{in class scope}}
45a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor};
46a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
47a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//     -- class template
48a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
49a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
50a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<typename T>
51a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct X0 { // expected-note {{here}}
52a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  static T member;
53a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
54a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void f1(T t) {
55a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor    t = 17;
56a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  }
57a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
58a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct Inner : public T { }; // expected-note 2{{here}}
59a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
60a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<typename U>
61a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct InnerTemplate : public T { }; // expected-note 1{{explicitly specialized}} \
62a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor   // expected-error{{base specifier}}
63a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
64a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<typename U>
65a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void ft1(T t, U u);
66a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor};
67a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
68a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
69a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
70a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<typename T>
71a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<typename U>
72a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorvoid N0::X0<T>::ft1(T t, U u) {
73a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  t = u;
74a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
75a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
76a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<typename T> T N0::X0<T>::member;
77a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
78a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> struct N0::X0<void> { };
79a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<void> test_X0;
80a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
81a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N1 {
82a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' must originally be declared in namespace 'N0'}}
83a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
84a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
85a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
86a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> struct X0<volatile void>;
87a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
88a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
89a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> struct N0::X0<volatile void> {
90a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void f1(void *);
91a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor};
92a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
93a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//     -- member function of a class template
94a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> void N0::X0<void*>::f1(void *) { }
95a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
96a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorvoid test_spec(N0::X0<void*> xvp, void *vp) {
97a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  xvp.f1(vp);
98a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
99a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
100a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
101a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
102a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
103a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> void X0<const volatile void*>::f1(const volatile void*);
104a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
105a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
106a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorvoid test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
107a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  x0.f1(cvp); // okay: we've explicitly specialized
108a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
109a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
110a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//     -- static data member of a class template
111a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
112a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  // This actually tests p15; the following is a declaration, not a definition.
113a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
114a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  NonDefaultConstructible X0<NonDefaultConstructible>::member;
115a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
116a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> long X0<long>::member = 17;
117a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
118a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> float X0<float>::member;
119a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
120a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> double X0<double>::member;
121a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
122a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
123a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorNonDefaultConstructible &get_static_member() {
124a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  return N0::X0<NonDefaultConstructible>::member;
125a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
126a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
127a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> int N0::X0<int>::member;
128a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
129a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> float N0::X0<float>::member = 3.14f;
130a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
131a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N1 {
132a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> double N0::X0<double>::member = 3.14; // expected-error{{not in a namespace enclosing}}
133a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
134a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
135a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//    -- member class of a class template
136a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
137a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
138a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
139a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<void*>::Inner { };
140a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
141a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
142a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<int>::Inner { };
143a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
144a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
145a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<unsigned>::Inner;
146a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
147a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
148a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<float>::Inner;
149a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
150a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
151a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<double>::Inner; // expected-note{{forward declaration}}
152a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
153a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
154a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<>
155a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct N0::X0<long>::Inner { };
156a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
157a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<>
158a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct N0::X0<float>::Inner { };
159a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
160a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N1 {
161a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
162a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}
163a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
164a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
165a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}
166a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor};
167a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
168a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<void*>::Inner inner0;
169a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<int>::Inner inner1;
170a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<long>::Inner inner2;
171a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<float>::Inner inner3;
172a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<double>::Inner inner4; // expected-error{{incomplete}}
173a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
174a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//    -- member class template of a class template
175a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
176a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
177a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
178a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<void*>::InnerTemplate<int> { };
179a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
180a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
181a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}
182a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
183a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
184a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<int>::InnerTemplate<long>;
185a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
186a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
187a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct X0<int>::InnerTemplate<double>;
188a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
189a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
190a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> template<>
191a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct N0::X0<int>::InnerTemplate<long> { }; // okay
192a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
193a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> template<>
194a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct N0::X0<int>::InnerTemplate<float> { };
195a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
196a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N1 {
197a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
198a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}
199a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
200a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
201a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<void*>::InnerTemplate<int> inner_template0;
202a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}
203a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<int>::InnerTemplate<long> inner_template2;
204a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas GregorN0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
205a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
206a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor//    -- member function template of a class template
207a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N0 {
208a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
209a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<>
210a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void X0<void*>::ft1(void*, const void*) { }
211a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
212a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
213a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void X0<void*>::ft1(void *, int);
214a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
215a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
216a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void X0<void*>::ft1(void *, unsigned);
217a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
218a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
219a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void X0<void*>::ft1(void *, long);
220a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
221a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
222a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> template<>
223a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorvoid N0::X0<void*>::ft1(void *, unsigned) { } // okay
224a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
225a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> template<>
226a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorvoid N0::X0<void*>::ft1(void *, float) { }
227a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
228a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregornamespace N1 {
229a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  template<> template<>
230a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  void N0::X0<void*>::ft1(void *, long) { } // expected-error{{enclosing}}
231a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
232a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
233a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor
234a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorvoid test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
235a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor                        int i, unsigned u) {
236a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  xvp.ft1(vp, cvp);
237a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  xvp.ft1(vp, i);
238a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor  xvp.ft1(vp, u);
239a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregor}
240cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
241cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregornamespace has_inline_namespaces {
242cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  inline namespace inner {
243cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor    template<class T> void f(T&);
244cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
245cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor    template<class T>
246cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor    struct X0 {
247cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor      struct MemberClass;
248cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
249cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor      void mem_func();
250cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
251cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor      template<typename U>
252cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor      struct MemberClassTemplate;
253cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
254cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor      template<typename U>
255cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor      void mem_func_template(U&);
256cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
257cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor      static int value;
258cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor    };
259cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  }
260cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
261cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  struct X1;
262cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  struct X2;
263cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
264cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  // An explicit specialization whose declarator-id is not qualified
265cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  // shall be declared in the nearest enclosing namespace of the
266cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  // template, or, if the namespace is inline (7.3.1), any namespace
267cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  // from its enclosing namespace set.
268cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> void f(X1&);
269cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> void f<X2>(X2&);
270cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
271cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> struct X0<X1> { };
272cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
273cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> struct X0<X2>::MemberClass { };
274cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
275cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> void X0<X2>::mem_func();
276cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
277cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> template<typename T> struct X0<X2>::MemberClassTemplate { };
278cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
279cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> template<typename T> void X0<X2>::mem_func_template(T&) { }
280cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
281cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor  template<> int X0<X2>::value = 12;
282cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor}
283cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
284cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregorstruct X3;
285cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregorstruct X4;
286cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
287cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> void has_inline_namespaces::f(X3&);
288cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> void has_inline_namespaces::f<X4>(X4&);
289cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
290cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> struct has_inline_namespaces::X0<X3> { };
291cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
292cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> struct has_inline_namespaces::X0<X4>::MemberClass { };
293cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
294cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> void has_inline_namespaces::X0<X4>::mem_func();
295cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
296cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> template<typename T>
297cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregorstruct has_inline_namespaces::X0<X4>::MemberClassTemplate { };
298cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
299cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> template<typename T>
300cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregorvoid has_inline_namespaces::X0<X4>::mem_func_template(T&) { }
301cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregor
302cc20945c787a56abe418947fc6a2c520bcec66c0Douglas Gregortemplate<> int has_inline_namespaces::X0<X4>::value = 13;
303