1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
2d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
3d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor// This test creates cases where implicit instantiations of various entities
4d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor// would cause a diagnostic, but provides expliict specializations for those
5d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor// entities that avoid the diagnostic. The specializations are alternately
6d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor// declarations and definitions, and the intent of this test is to verify
7d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor// that we allow specializations only in the appropriate namespaces (and
8d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor// nowhere else).
9d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregorstruct NonDefaultConstructible {
10d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  NonDefaultConstructible(int);
11d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor};
12d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
13d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
14d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor// C++ [temp.expl.spec]p1:
15d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//   An explicit specialization of any of the following:
16d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
17d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//     -- function template
18d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregornamespace N0 {
19d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  template<typename T> void f0(T) { // expected-note{{here}}
20d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor    T t;
21d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  }
22d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
23d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  template<> void f0(NonDefaultConstructible) { }
24d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
25d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  void test_f0(NonDefaultConstructible NDC) {
26d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor    f0(NDC);
27d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  }
28d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
29d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  template<> void f0(int);
30d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  template<> void f0(long);
31d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor}
32d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
33d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregortemplate<> void N0::f0(int) { } // okay
34d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
35d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregornamespace N1 {
36a1c4f7c833093f87d5187c4449a3d4534cfa40a4Richard Smith  template<> void N0::f0(long) { } // expected-error{{does not enclose namespace}}
37d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor}
38d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
39d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smithtemplate<> void N0::f0(double); // expected-warning{{C++11 extension}}
40d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smithtemplate<> void N0::f0(double) { }
41d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
420a4074768a6ecd81513f0db02bfb0e96ab3e56a0Douglas Gregorstruct X1 {
430a4074768a6ecd81513f0db02bfb0e96ab3e56a0Douglas Gregor  template<typename T> void f(T);
440a4074768a6ecd81513f0db02bfb0e96ab3e56a0Douglas Gregor
450a4074768a6ecd81513f0db02bfb0e96ab3e56a0Douglas Gregor  template<> void f(int); // expected-error{{in class scope}}
460a4074768a6ecd81513f0db02bfb0e96ab3e56a0Douglas Gregor};
470a4074768a6ecd81513f0db02bfb0e96ab3e56a0Douglas Gregor
48d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//     -- class template
493d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregornamespace N0 {
503d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor
51d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregortemplate<typename T>
523d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregorstruct X0 { // expected-note 2{{here}}
53251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  static T member; // expected-note{{here}}
54d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
551fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor  void f1(T t) { // expected-note{{explicitly specialized declaration is here}}
56d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor    t = 17;
57d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  }
58d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
59f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct Inner : public T { }; // expected-note 3{{here}}
60d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
61d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  template<typename U>
6242887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  struct InnerTemplate : public T { }; // expected-note 2{{explicitly specialized}} \
6342887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor   // expected-error{{base specifier}}
64d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
65d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  template<typename U>
66741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  void ft1(T t, U u); // expected-note{{explicitly specialized}}
67d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor};
68d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
693d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor}
703d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor
71d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregortemplate<typename T>
72d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregortemplate<typename U>
733d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregorvoid N0::X0<T>::ft1(T t, U u) {
74d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  t = u;
75d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor}
76d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
773d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregortemplate<typename T> T N0::X0<T>::member;
78d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
79d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smithtemplate<> struct N0::X0<void> { }; // expected-warning{{C++11 extension}}
803d92d8c94e9447a6d903241e180590b4025c5927Douglas GregorN0::X0<void> test_X0;
81d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
823d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregornamespace N1 {
833d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor  template<> struct N0::X0<const void> { }; // expected-error{{originally}}
843d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor}
853d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor
863d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregornamespace N0 {
873d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor  template<> struct X0<volatile void>;
883d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor}
893d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregor
901fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregortemplate<> struct N0::X0<volatile void> {
911fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor  void f1(void *);
921fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor};
93d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
94d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//     -- member function of a class template
95a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregortemplate<> void N0::X0<void*>::f1(void *) { } // expected-warning{{member function specialization}}
96d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
973d92d8c94e9447a6d903241e180590b4025c5927Douglas Gregorvoid test_spec(N0::X0<void*> xvp, void *vp) {
98d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  xvp.f1(vp);
99d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor}
100d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
1011fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregornamespace N0 {
1021fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor  template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
10363e5e64a49ef936383ad93ea283b2b07f115e78cDouglas Gregor
10463e5e64a49ef936383ad93ea283b2b07f115e78cDouglas Gregor  template<> void X0<const volatile void*>::f1(const volatile void*);
10563e5e64a49ef936383ad93ea283b2b07f115e78cDouglas Gregor}
10663e5e64a49ef936383ad93ea283b2b07f115e78cDouglas Gregor
10763e5e64a49ef936383ad93ea283b2b07f115e78cDouglas Gregorvoid test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
10863e5e64a49ef936383ad93ea283b2b07f115e78cDouglas Gregor  x0.f1(cvp); // okay: we've explicitly specialized
1091fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor}
1101fef4e60e7e884803977a8376c172ea584f8a5d1Douglas Gregor
111d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//     -- static data member of a class template
112251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregornamespace N0 {
113251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  // This actually tests p15; the following is a declaration, not a definition.
114251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  template<>
115251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  NonDefaultConstructible X0<NonDefaultConstructible>::member;
116251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor
117251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  template<> long X0<long>::member = 17;
118251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor
119251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  template<> float X0<float>::member;
120f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
121f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<> double X0<double>::member;
122251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor}
123d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
124d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas GregorNonDefaultConstructible &get_static_member() {
125251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  return N0::X0<NonDefaultConstructible>::member;
126d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor}
127d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
128d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smithtemplate<> int N0::X0<int>::member;  // expected-warning{{C++11 extension}}
129251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor
130251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregortemplate<> float N0::X0<float>::member = 3.14f;
131251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor
132f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregornamespace N1 {
133a1c4f7c833093f87d5187c4449a3d4534cfa40a4Richard Smith  template<> double N0::X0<double>::member = 3.14; // expected-error{{does not enclose namespace}}
134f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor}
135f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
136d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//    -- member class of a class template
137f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregornamespace N0 {
138f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
139f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<>
140f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct X0<void*>::Inner { };
141f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
142f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<>
143f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct X0<int>::Inner { };
144f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
145f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<>
146f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct X0<unsigned>::Inner;
147f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
148f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<>
149f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct X0<float>::Inner;
150f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
151f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<>
152f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct X0<double>::Inner; // expected-note{{forward declaration}}
153f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor}
154f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
155d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregortemplate<>
156d7c56e1114bfe7d461786903bb720d2c6efc05a1Richard Smithstruct N0::X0<long>::Inner { }; // expected-warning{{C++11 extension}}
157d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
158f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregortemplate<>
159f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregorstruct N0::X0<float>::Inner { };
160f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
161f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregornamespace N1 {
162f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<>
163f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}
164d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
165f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  template<>
166f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor  struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}
167f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor};
168f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
169f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas GregorN0::X0<void*>::Inner inner0;
170f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas GregorN0::X0<int>::Inner inner1;
171f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas GregorN0::X0<long>::Inner inner2;
172f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas GregorN0::X0<float>::Inner inner3;
173f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas GregorN0::X0<double>::Inner inner4; // expected-error{{incomplete}}
174f6b1185f0a8a209c06dfc1efdb6a59cc851e970cDouglas Gregor
175d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//    -- member class template of a class template
17642887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregornamespace N0 {
17742887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  template<>
17842887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  template<>
17942887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  struct X0<void*>::InnerTemplate<int> { };
18042887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor
18142887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  template<> template<>
18242887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}
18342887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor
18442887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  template<> template<>
18542887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  struct X0<int>::InnerTemplate<long>;
186d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
18742887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  template<> template<>
18842887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  struct X0<int>::InnerTemplate<double>;
18942887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor}
19042887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor
19142887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregortemplate<> template<>
19242887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregorstruct N0::X0<int>::InnerTemplate<long> { }; // okay
19342887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor
19442887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregortemplate<> template<>
195a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorstruct N0::X0<int>::InnerTemplate<float> { }; // expected-warning{{class template specialization}}
196d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
19742887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregornamespace N1 {
19842887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  template<> template<>
19942887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor  struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}
20042887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor}
20142887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor
20242887b9224e1d47372fb8a00cba27c925924fa52Douglas GregorN0::X0<void*>::InnerTemplate<int> inner_template0;
20342887b9224e1d47372fb8a00cba27c925924fa52Douglas GregorN0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}
20442887b9224e1d47372fb8a00cba27c925924fa52Douglas GregorN0::X0<int>::InnerTemplate<long> inner_template2;
20542887b9224e1d47372fb8a00cba27c925924fa52Douglas GregorN0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
20642887b9224e1d47372fb8a00cba27c925924fa52Douglas Gregor
207d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor//    -- member function template of a class template
208741fab61570f145a52b808a6824841c41e892c28Douglas Gregornamespace N0 {
209741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  template<>
210741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  template<>
211741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  void X0<void*>::ft1(void*, const void*) { }
212741fab61570f145a52b808a6824841c41e892c28Douglas Gregor
213741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  template<> template<>
214741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  void X0<void*>::ft1(void *, int);
215741fab61570f145a52b808a6824841c41e892c28Douglas Gregor
216741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  template<> template<>
217741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  void X0<void*>::ft1(void *, unsigned);
218741fab61570f145a52b808a6824841c41e892c28Douglas Gregor
219741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  template<> template<>
220741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  void X0<void*>::ft1(void *, long);
221741fab61570f145a52b808a6824841c41e892c28Douglas Gregor}
222741fab61570f145a52b808a6824841c41e892c28Douglas Gregor
223741fab61570f145a52b808a6824841c41e892c28Douglas Gregortemplate<> template<>
224741fab61570f145a52b808a6824841c41e892c28Douglas Gregorvoid N0::X0<void*>::ft1(void *, unsigned) { } // okay
225741fab61570f145a52b808a6824841c41e892c28Douglas Gregor
226741fab61570f145a52b808a6824841c41e892c28Douglas Gregortemplate<> template<>
227a4d5de539bc2f0cd25d6292e84eaa067591ff792Douglas Gregorvoid N0::X0<void*>::ft1(void *, float) { } // expected-warning{{function template specialization}}
228741fab61570f145a52b808a6824841c41e892c28Douglas Gregor
229741fab61570f145a52b808a6824841c41e892c28Douglas Gregornamespace N1 {
230741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  template<> template<>
231a1c4f7c833093f87d5187c4449a3d4534cfa40a4Richard Smith  void N0::X0<void*>::ft1(void *, long) { } // expected-error{{does not enclose namespace}}
232741fab61570f145a52b808a6824841c41e892c28Douglas Gregor}
233741fab61570f145a52b808a6824841c41e892c28Douglas Gregor
234d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor
235741fab61570f145a52b808a6824841c41e892c28Douglas Gregorvoid test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
236741fab61570f145a52b808a6824841c41e892c28Douglas Gregor                        int i, unsigned u) {
237d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor  xvp.ft1(vp, cvp);
238741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  xvp.ft1(vp, i);
239741fab61570f145a52b808a6824841c41e892c28Douglas Gregor  xvp.ft1(vp, u);
240d5cb8765ad3841ead8eaacb0360ac385f2f0e080Douglas Gregor}
241eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor
242eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregornamespace PR8979 {
243eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor  template<typename Z>
244eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor  struct X0 {
245eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor    template <class T, class U> class Inner;
246eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor    struct OtherInner;
247eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor    template<typename T, typename U> void f(Inner<T, U>&);
248eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor
249eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor    typedef Inner<OtherInner, OtherInner> MyInner;
250eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor    template<> void f(MyInner&); // expected-error{{cannot specialize a function 'f' within class scope}}
251eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor  };
252eef7ac5837ef3e0682ac0973121fff8edaa46ca4Douglas Gregor}
253