xref: /llvm-project/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp (revision 017b504b462ce7d4938f704a1f10118ead347d3d)
1 // RUN: %clang_cc1 -fms-extensions -fsyntax-only -Wno-unused-value -verify %s
2 // RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -Wno-unused-value -verify %s
3 
4 class A {
5 public:
6   template<class U> A(U p) {}
7   template<> A(int p) {}
8 
9   template<class U> void f(U p) {}
10 
11   template<> void f(int p) {}
12 
13   void f(int p) {}
14 };
15 
16 void test1() {
17   A a(3);
18   char *b;
19   a.f(b);
20   a.f<int>(99);
21   a.f(100);
22 }
23 
24 template<class T> class B {
25 public:
26   template<class U> B(U p) {}
27   template<> B(int p) {}
28 
29   template<class U> void f(U p) { T y = 9; }
30 
31   template<> void f(int p) {
32     T a = 3;
33   }
34 
35   void f(int p) { T a = 3; }
36 };
37 
38 void test2() {
39   B<char> b(3);
40   char *ptr;
41   b.f(ptr);
42   b.f<int>(99);
43   b.f(100);
44 }
45 
46 namespace PR12709 {
47   template<class T> class TemplateClass {
48     void member_function() { specialized_member_template<false>(); }
49 
50     template<bool b> void specialized_member_template() {}
51 
52     template<> void specialized_member_template<false>() {}
53   };
54 
55   void f() { TemplateClass<int> t; }
56 }
57 
58 namespace Duplicates {
59   template<typename T> struct A {
60     template<typename U> void f();
61     template<> void f<int>() {}
62     template<> void f<T>() {}
63   };
64 
65   // FIXME: We should diagnose the duplicate explicit specialization definitions
66   // here.
67   template struct A<int>;
68 }
69 
70 namespace PR28082 {
71 struct S {
72   template <int>
73   int f(int = 0);
74   template <>
75   int f<0>(int);
76 };
77 }
78 
79 namespace UsesThis {
80   template<typename T>
81   struct A {
82     int x;
83 
84     static inline int y;
85 
86     template<typename U = void>
87     static void f();
88 
89     template<typename U = void>
90     void g();
91 
92     template<typename U>
93     static auto h() -> A*;
94 
95     void i();
96 
97     static void j();
98 
99     template<>
100     void f<int>() {
101       this->x; // expected-error {{invalid use of 'this' outside of a non-static member function}}
102       x; // expected-error {{invalid use of member 'x' in static member function}}
103       A::x; // expected-error {{invalid use of member 'x' in static member function}}
104       +x; // expected-error {{invalid use of member 'x' in static member function}}
105       +A::x; // expected-error {{invalid use of member 'x' in static member function}}
106       &x; // expected-error {{invalid use of member 'x' in static member function}}
107       &A::x;
108       this->y; // expected-error {{invalid use of 'this' outside of a non-static member function}}
109       y;
110       A::y;
111       +y;
112       +A::y;
113       &y;
114       &A::y;
115       f();
116       f<void>();
117       g(); // expected-error {{call to non-static member function without an object argument}}
118       g<void>(); // expected-error {{call to non-static member function without an object argument}}
119       i(); // expected-error {{call to non-static member function without an object argument}}
120       j();
121       &i; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
122       &j;
123       &A::i;
124       &A::j;
125     }
126 
127     template<>
128     void g<int>() {
129       this->x;
130       x;
131       A::x;
132       +x;
133       +A::x;
134       &x;
135       &A::x;
136       this->y;
137       y;
138       A::y;
139       +y;
140       +A::y;
141       &y;
142       &A::y;
143       f();
144       f<void>();
145       g();
146       g<void>();
147       i();
148       j();
149       &i; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
150       &j;
151       &A::i;
152       &A::j;
153     }
154 
155     template<>
156     auto h<int>() -> decltype(this); // expected-error {{'this' cannot be used in a static member function declaration}}
157   };
158 
159   template struct A<int>; // expected-note {{in instantiation of}}
160   template<> template<> void A<int>::f<int>();
161   template<> template<> void A<int>::g<int>();
162   void test1() {
163     A<int>().f<int>(); // expected-note {{in instantiation of}}
164     A<int>().g<int>(); // expected-note {{in instantiation of}}
165   }
166 
167   template <typename T>
168   struct Foo {
169     template <typename X>
170     int bar(X x) {
171       return 0;
172     }
173 
174     template <>
175     int bar(int x) {
176       return bar(5.0); // ok
177     }
178   };
179 
180   void call() {
181     Foo<double> f;
182     f.bar(1);
183   }
184 
185   struct B {
186     int x0;
187     static inline int y0;
188 
189     int f0(int);
190     static int g0(int);
191 
192     int x2;
193     static inline int y2;
194 
195     int f2(int);
196     static int g2(int);
197   };
198 
199   template<typename T>
200   struct D : B {
201     int x1;
202     static inline int y1;
203 
204     int f1(int);
205     static int g1(int);
206 
207     using B::x2;
208     using B::y2;
209     using B::f2;
210     using B::g2;
211 
212     template<typename U>
213     void non_static_spec(U);
214 
215     template<typename U>
216     static void static_spec(U);
217 
218     template<>
219     void non_static_spec(int z) {
220       ++z;
221       ++x0;
222       ++x1;
223       ++x2;
224       ++y0;
225       ++y1;
226       ++y2;
227 
228       &z;
229       &x0;
230       &x1;
231       &x2;
232       &y0;
233       &y1;
234       &y2;
235 
236       &f0; // expected-error {{must explicitly qualify name of member function when taking its address}}
237       &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
238       &f2; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
239       &g0;
240       &g1;
241       &g2;
242 
243       &B::x0;
244       &D::x1;
245       &B::x2;
246       &B::y0;
247       &D::y1;
248       &B::y2;
249       &B::f0;
250       &D::f1;
251       &B::f2;
252       &B::g0;
253       &D::g1;
254       &B::g2;
255 
256       f0(0);
257       f0(z);
258       f0(x0);
259       f0(x1);
260       f0(x2);
261       f0(y0);
262       f0(y1);
263       f0(y2);
264       g0(0);
265       g0(z);
266       g0(x0);
267       g0(x1);
268       g0(x2);
269       g0(y0);
270       g0(y1);
271       g0(y2);
272 
273       f1(0);
274       f1(z);
275       f1(x0);
276       f1(x1);
277       f1(x2);
278       f1(y0);
279       f1(y1);
280       f1(y2);
281       g1(0);
282       g1(z);
283       g1(x0);
284       g1(x1);
285       g1(x2);
286       g1(y0);
287       g1(y1);
288       g1(y2);
289 
290       f2(0);
291       f2(z);
292       f2(x0);
293       f2(x1);
294       f2(x2);
295       f2(y0);
296       f2(y1);
297       f2(y2);
298       g2(0);
299       g2(z);
300       g2(x0);
301       g2(x1);
302       g2(x2);
303       g2(y0);
304       g2(y1);
305       g2(y2);
306     }
307 
308     template<>
309     void static_spec(int z) {
310       ++z;
311       ++x0; // expected-error {{invalid use of member 'x0' in static member function}}
312       ++x1; // expected-error {{invalid use of member 'x1' in static member function}}
313       ++x2; // expected-error {{invalid use of member 'x2' in static member function}}
314       ++y0;
315       ++y1;
316       ++y2;
317 
318       &z;
319       &x0; // expected-error {{invalid use of member 'x0' in static member function}}
320       &x1; // expected-error {{invalid use of member 'x1' in static member function}}
321       &x2; // expected-error {{invalid use of member 'x2' in static member function}}
322       &y0;
323       &y1;
324       &y2;
325 
326       &f0; // expected-error {{must explicitly qualify name of member function when taking its address}}
327       &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
328       &f2; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
329       &g0;
330       &g1;
331       &g2;
332 
333       &B::x0;
334       &D::x1;
335       &B::x2;
336       &B::y0;
337       &D::y1;
338       &B::y2;
339       &B::f0;
340       &D::f1;
341       &B::f2;
342       &B::g0;
343       &D::g1;
344       &B::g2;
345 
346       f0(0); // expected-error {{call to non-static member function without an object argument}}
347       f0(z); // expected-error {{call to non-static member function without an object argument}}
348       f0(x0); // expected-error {{call to non-static member function without an object argument}}
349       f0(x1); // expected-error {{call to non-static member function without an object argument}}
350       f0(x2); // expected-error {{call to non-static member function without an object argument}}
351       f0(y0); // expected-error {{call to non-static member function without an object argument}}
352       f0(y1); // expected-error {{call to non-static member function without an object argument}}
353       f0(y2); // expected-error {{call to non-static member function without an object argument}}
354       g0(0);
355       g0(z);
356       g0(x0); // expected-error {{invalid use of member 'x0' in static member function}}
357       g0(x1); // expected-error {{invalid use of member 'x1' in static member function}}
358       g0(x2); // expected-error {{invalid use of member 'x2' in static member function}}
359       g0(y0);
360       g0(y1);
361       g0(y2);
362 
363       f1(0); // expected-error {{call to non-static member function without an object argument}}
364       f1(z); // expected-error {{call to non-static member function without an object argument}}
365       f1(x0); // expected-error {{call to non-static member function without an object argument}}
366       f1(x1); // expected-error {{call to non-static member function without an object argument}}
367       f1(x2); // expected-error {{call to non-static member function without an object argument}}
368       f1(y0); // expected-error {{call to non-static member function without an object argument}}
369       f1(y1); // expected-error {{call to non-static member function without an object argument}}
370       f1(y2); // expected-error {{call to non-static member function without an object argument}}
371       g1(0);
372       g1(z);
373       g1(x0); // expected-error {{invalid use of member 'x0' in static member function}}
374       g1(x1); // expected-error {{invalid use of member 'x1' in static member function}}
375       g1(x2); // expected-error {{invalid use of member 'x2' in static member function}}
376       g1(y0);
377       g1(y1);
378       g1(y2);
379 
380       f2(0); // expected-error {{call to non-static member function without an object argument}}
381       f2(z); // expected-error {{call to non-static member function without an object argument}}
382       f2(x0); // expected-error {{call to non-static member function without an object argument}}
383       f2(x1); // expected-error {{call to non-static member function without an object argument}}
384       f2(x2); // expected-error {{call to non-static member function without an object argument}}
385       f2(y0); // expected-error {{call to non-static member function without an object argument}}
386       f2(y1); // expected-error {{call to non-static member function without an object argument}}
387       f2(y2); // expected-error {{call to non-static member function without an object argument}}
388       g2(0);
389       g2(z);
390       g2(x0); // expected-error {{invalid use of member 'x0' in static member function}}
391       g2(x1); // expected-error {{invalid use of member 'x1' in static member function}}
392       g2(x2); // expected-error {{invalid use of member 'x2' in static member function}}
393       g2(y0);
394       g2(y1);
395       g2(y2);
396     }
397   };
398 
399   template struct D<int>;
400 
401   void test2() {
402     D<int>().non_static_spec(0); // expected-note {{in instantiation of}}
403     D<int>().static_spec(0); // expected-note {{in instantiation of}}
404   }
405 
406   template<typename T>
407   struct E : T {
408     int x1;
409     static inline int y1;
410 
411     int f1(int);
412     static int g1(int);
413 
414     using T::x0;
415     using T::y0;
416     using T::f0;
417     using T::g0;
418 
419     template<typename U>
420     void non_static_spec(U);
421 
422     template<typename U>
423     static void static_spec(U);
424 
425     template<>
426     void non_static_spec(int z) {
427       ++z;
428       ++x0;
429       ++x1;
430       ++y0;
431       ++y1;
432 
433       &z;
434       &x0;
435       &x1;
436       &y0;
437       &y1;
438 
439       &f0; // expected-error {{must explicitly qualify name of member function when taking its address}}
440       &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
441       &g0;
442       &g1;
443 
444       &T::x0;
445       &E::x1;
446       &T::y0;
447       &E::y1;
448       &T::f0;
449       &E::f1;
450       &T::g0;
451       &E::g1;
452 
453       f0(0);
454       f0(z);
455       f0(x0);
456       f0(x1);
457       f0(y0);
458       f0(y1);
459       g0(0);
460       g0(z);
461       g0(x0);
462       g0(x1);
463       g0(y0);
464       g0(y1);
465 
466       f1(0);
467       f1(z);
468       f1(x0);
469       f1(x1);
470       f1(y0);
471       f1(y1);
472       g1(0);
473       g1(z);
474       g1(x0);
475       g1(x1);
476       g1(y0);
477       g1(y1);
478 
479       T::f0(0);
480       T::f0(z);
481       T::f0(x0);
482       T::f0(x1);
483       T::f0(y0);
484       T::f0(y1);
485       T::g0(0);
486       T::g0(z);
487       T::g0(x0);
488       T::g0(x1);
489       T::g0(y0);
490       T::g0(y1);
491 
492       E::f1(0);
493       E::f1(z);
494       E::f1(x0);
495       E::f1(x1);
496       E::f1(y0);
497       E::f1(y1);
498       E::g1(0);
499       E::g1(z);
500       E::g1(x0);
501       E::g1(x1);
502       E::g1(y0);
503       E::g1(y1);
504     }
505 
506     template<>
507     void static_spec(int z) {
508       ++z;
509       ++x0; // expected-error {{invalid use of member 'x0' in static member function}}
510       ++x1; // expected-error {{invalid use of member 'x1' in static member function}}
511       ++y0;
512       ++y1;
513 
514       &z;
515       &x0; // expected-error {{invalid use of member 'x0' in static member function}}
516       &x1; // expected-error {{invalid use of member 'x1' in static member function}}
517       &y0;
518       &y1;
519 
520       &f0; // expected-error {{must explicitly qualify name of member function when taking its address}}
521       &f1; // expected-error 2{{must explicitly qualify name of member function when taking its address}}
522       &g0;
523       &g1;
524 
525       &T::x0;
526       &E::x1;
527       &T::y0;
528       &E::y1;
529       &T::f0;
530       &E::f1;
531       &T::g0;
532       &E::g1;
533 
534       f0(0); // expected-error {{call to non-static member function without an object argument}}
535       f0(z); // expected-error {{call to non-static member function without an object argument}}
536       f0(x0); // expected-error {{call to non-static member function without an object argument}}
537       f0(x1); // expected-error {{call to non-static member function without an object argument}}
538       f0(y0); // expected-error {{call to non-static member function without an object argument}}
539       f0(y1); // expected-error {{call to non-static member function without an object argument}}
540       g0(0);
541       g0(z);
542       g0(x0); // expected-error {{invalid use of member 'x0' in static member function}}
543       g0(x1); // expected-error {{invalid use of member 'x1' in static member function}}
544       g0(y0);
545       g0(y1);
546 
547       f1(0); // expected-error {{call to non-static member function without an object argument}}
548       f1(z); // expected-error {{call to non-static member function without an object argument}}
549       f1(x0); // expected-error {{call to non-static member function without an object argument}}
550       f1(x1); // expected-error {{call to non-static member function without an object argument}}
551       f1(y0); // expected-error {{call to non-static member function without an object argument}}
552       f1(y1); // expected-error {{call to non-static member function without an object argument}}
553       g1(0);
554       g1(z);
555       g1(x0); // expected-error {{invalid use of member 'x0' in static member function}}
556       g1(x1); // expected-error {{invalid use of member 'x1' in static member function}}
557       g1(y0);
558       g1(y1);
559 
560       T::f0(0); // expected-error {{call to non-static member function without an object argument}}
561       T::f0(z); // expected-error {{call to non-static member function without an object argument}}
562       T::f0(x0); // expected-error {{call to non-static member function without an object argument}}
563       T::f0(x1); // expected-error {{call to non-static member function without an object argument}}
564       T::f0(y0); // expected-error {{call to non-static member function without an object argument}}
565       T::f0(y1); // expected-error {{call to non-static member function without an object argument}}
566       T::g0(0);
567       T::g0(z);
568       T::g0(x0); // expected-error {{invalid use of member 'x0' in static member function}}
569       T::g0(x1); // expected-error {{invalid use of member 'x1' in static member function}}
570       T::g0(y0);
571       T::g0(y1);
572 
573       E::f1(0); // expected-error {{call to non-static member function without an object argument}}
574       E::f1(z); // expected-error {{call to non-static member function without an object argument}}
575       E::f1(x0); // expected-error {{call to non-static member function without an object argument}}
576       E::f1(x1); // expected-error {{call to non-static member function without an object argument}}
577       E::f1(y0); // expected-error {{call to non-static member function without an object argument}}
578       E::f1(y1); // expected-error {{call to non-static member function without an object argument}}
579       E::g1(0);
580       E::g1(z);
581       E::g1(x0); // expected-error {{invalid use of member 'x0' in static member function}}
582       E::g1(x1); // expected-error {{invalid use of member 'x1' in static member function}}
583       E::g1(y0);
584       E::g1(y1);
585     }
586   };
587 
588   template struct E<B>;
589 
590   void test3() {
591     E<B>().non_static_spec(0); // expected-note {{in instantiation of}}
592     E<B>().static_spec(0); // expected-note {{in instantiation of}}
593   }
594 }
595 
596 namespace GH111266 {
597   template<class T> struct S {
598     template<int> auto foo();
599     template<> auto foo<1>() {
600       return [](auto x) { return x; };
601     }
602   };
603   template struct S<void>;
604   void test() {
605     S<void>().foo<1>();
606   }
607 } // namespace GH111266
608