xref: /aosp_15_r20/external/clang/test/Parser/cxx-template-decl.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s -fdelayed-template-parsing -DDELAYED_TEMPLATE_PARSING
3*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=gnu++1z %s
4*67e74705SXin Li 
5*67e74705SXin Li 
6*67e74705SXin Li 
7*67e74705SXin Li // Errors
8*67e74705SXin Li export class foo { };   // expected-error {{expected template}}
9*67e74705SXin Li template  x;            // expected-error {{C++ requires a type specifier for all declarations}} \
10*67e74705SXin Li                         // expected-error {{does not refer}}
11*67e74705SXin Li export template x;      // expected-error {{expected '<' after 'template'}}
12*67e74705SXin Li export template<class T> class x0; // expected-warning {{exported templates are unsupported}}
13*67e74705SXin Li template < ;            // expected-error {{expected template parameter}} \
14*67e74705SXin Li // expected-error{{expected ',' or '>' in template-parameter-list}} \
15*67e74705SXin Li // expected-warning {{declaration does not declare anything}}
16*67e74705SXin Li template <int +> struct x1; // expected-error {{expected ',' or '>' in template-parameter-list}}
17*67e74705SXin Li 
18*67e74705SXin Li // verifies that we only walk to the ',' & still produce errors on the rest of the template parameters
19*67e74705SXin Li template <int +, T> struct x2; // expected-error {{expected ',' or '>' in template-parameter-list}} \
20*67e74705SXin Li                                 expected-error {{expected unqualified-id}}
21*67e74705SXin Li template<template<int+>> struct x3; // expected-error {{expected ',' or '>' in template-parameter-list}} \
22*67e74705SXin Li                                          expected-error {{template template parameter requires 'class' after the parameter list}}
23*67e74705SXin Li template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \
24*67e74705SXin Li // expected-error{{extraneous}}
25*67e74705SXin Li template <template <typename> > struct Err2;       // expected-error {{template template parameter requires 'class' after the parameter list}}
26*67e74705SXin Li template <template <typename> Foo> struct Err3;    // expected-error {{template template parameter requires 'class' after the parameter list}}
27*67e74705SXin Li 
28*67e74705SXin Li template <template <typename> typename Foo> struct Cxx1z;
29*67e74705SXin Li #if __cplusplus <= 201402L
30*67e74705SXin Li // expected-warning@-2 {{extension}}
31*67e74705SXin Li #endif
32*67e74705SXin Li 
33*67e74705SXin Li // Template function declarations
34*67e74705SXin Li template <typename T> void foo();
35*67e74705SXin Li template <typename T, typename U> void foo();
36*67e74705SXin Li 
37*67e74705SXin Li // Template function definitions.
38*67e74705SXin Li template <typename T> void foo() { }
39*67e74705SXin Li 
40*67e74705SXin Li // Template class (forward) declarations
41*67e74705SXin Li template <typename T> struct A;
42*67e74705SXin Li template <typename T, typename U> struct b;
43*67e74705SXin Li template <typename> struct C;
44*67e74705SXin Li template <typename, typename> struct D;
45*67e74705SXin Li 
46*67e74705SXin Li // Forward declarations with default parameters?
47*67e74705SXin Li template <typename T = int> class X1;
48*67e74705SXin Li template <typename = int> class X2;
49*67e74705SXin Li 
50*67e74705SXin Li // Forward declarations w/template template parameters
51*67e74705SXin Li template <template <typename> class T> class TTP1;
52*67e74705SXin Li template <template <typename> class> class TTP2;
53*67e74705SXin Li template <template <typename> class T = foo> class TTP3; // expected-error{{must be a class template}}
54*67e74705SXin Li template <template <typename> class = foo> class TTP3; // expected-error{{must be a class template}}
55*67e74705SXin Li template <template <typename X, typename Y> class T> class TTP5;
56*67e74705SXin Li 
57*67e74705SXin Li // Forward declarations with non-type params
58*67e74705SXin Li template <int> class NTP0;
59*67e74705SXin Li template <int N> class NTP1;
60*67e74705SXin Li template <int N = 5> class NTP2;
61*67e74705SXin Li template <int = 10> class NTP3;
62*67e74705SXin Li template <unsigned int N = 12u> class NTP4;
63*67e74705SXin Li template <unsigned int = 12u> class NTP5;
64*67e74705SXin Li template <unsigned = 15u> class NTP6;
65*67e74705SXin Li template <typename T, T Obj> class NTP7;
66*67e74705SXin Li 
67*67e74705SXin Li // Template class declarations
68*67e74705SXin Li template <typename T> struct A { };
69*67e74705SXin Li template <typename T, typename U> struct B { };
70*67e74705SXin Li 
71*67e74705SXin Li // Template parameter shadowing
72*67e74705SXin Li template<typename T, // expected-note{{template parameter is declared here}}
73*67e74705SXin Li          typename T> // expected-error{{declaration of 'T' shadows template parameter}}
74*67e74705SXin Li   void shadow1();
75*67e74705SXin Li 
76*67e74705SXin Li template<typename T> // expected-note{{template parameter is declared here}}
77*67e74705SXin Li void shadow2(int T); // expected-error{{declaration of 'T' shadows template parameter}}
78*67e74705SXin Li 
79*67e74705SXin Li template<typename T> // expected-note{{template parameter is declared here}}
80*67e74705SXin Li class T { // expected-error{{declaration of 'T' shadows template parameter}}
81*67e74705SXin Li };
82*67e74705SXin Li 
83*67e74705SXin Li template<int Size> // expected-note{{template parameter is declared here}}
84*67e74705SXin Li void shadow3(int Size); // expected-error{{declaration of 'Size' shadows template parameter}}
85*67e74705SXin Li 
86*67e74705SXin Li // <rdar://problem/6952203>
87*67e74705SXin Li template<typename T> // expected-note{{here}}
88*67e74705SXin Li struct shadow4 {
89*67e74705SXin Li   int T; // expected-error{{shadows}}
90*67e74705SXin Li };
91*67e74705SXin Li 
92*67e74705SXin Li template<typename T> // expected-note{{here}}
93*67e74705SXin Li struct shadow5 {
94*67e74705SXin Li   int T(int, float); // expected-error{{shadows}}
95*67e74705SXin Li };
96*67e74705SXin Li 
97*67e74705SXin Li template<typename T, // expected-note{{template parameter is declared here}}
98*67e74705SXin Li          T T> // expected-error{{declaration of 'T' shadows template parameter}}
99*67e74705SXin Li void shadow6();
100*67e74705SXin Li 
101*67e74705SXin Li template<typename T, // expected-note{{template parameter is declared here}}
102*67e74705SXin Li          template<typename> class T> // expected-error{{declaration of 'T' shadows template parameter}}
103*67e74705SXin Li void shadow7();
104*67e74705SXin Li 
105*67e74705SXin Li // PR8302
106*67e74705SXin Li template<template<typename> class T> struct shadow8 { // expected-note{{template parameter is declared here}}
107*67e74705SXin Li   template<template<typename> class T> struct inner; // expected-error{{declaration of 'T' shadows template parameter}}
108*67e74705SXin Li };
109*67e74705SXin Li 
110*67e74705SXin Li // Non-type template parameters in scope
111*67e74705SXin Li template<int Size>
112*67e74705SXin Li void f(int& i) {
113*67e74705SXin Li   i = Size;
114*67e74705SXin Li  #ifdef DELAYED_TEMPLATE_PARSING
115*67e74705SXin Li   Size = i;
116*67e74705SXin Li  #else
117*67e74705SXin Li   Size = i; // expected-error{{expression is not assignable}}
118*67e74705SXin Li  #endif
119*67e74705SXin Li }
120*67e74705SXin Li 
121*67e74705SXin Li template<typename T>
122*67e74705SXin Li const T& min(const T&, const T&);
123*67e74705SXin Li 
124*67e74705SXin Li void f2() {
125*67e74705SXin Li   int x;
126*67e74705SXin Li   A< typeof(x>1) > a;
127*67e74705SXin Li }
128*67e74705SXin Li 
129*67e74705SXin Li 
130*67e74705SXin Li // PR3844
131*67e74705SXin Li template <> struct S<int> { }; // expected-error{{explicit specialization of non-template struct 'S'}}
132*67e74705SXin Li template <> union U<int> { }; // expected-error{{explicit specialization of non-template union 'U'}}
133*67e74705SXin Li 
134*67e74705SXin Li namespace PR6184 {
135*67e74705SXin Li   namespace N {
136*67e74705SXin Li     template <typename T>
137*67e74705SXin Li     void bar(typename T::x);
138*67e74705SXin Li   }
139*67e74705SXin Li 
140*67e74705SXin Li   template <typename T>
141*67e74705SXin Li   void N::bar(typename T::x) { }
142*67e74705SXin Li }
143*67e74705SXin Li 
144*67e74705SXin Li // This PR occurred only in template parsing mode.
145*67e74705SXin Li namespace PR17637 {
146*67e74705SXin Li template <int>
147*67e74705SXin Li struct L {
148*67e74705SXin Li   template <typename T>
149*67e74705SXin Li   struct O {
150*67e74705SXin Li     template <typename U>
151*67e74705SXin Li     static void Fun(U);
152*67e74705SXin Li   };
153*67e74705SXin Li };
154*67e74705SXin Li 
155*67e74705SXin Li template <int k>
156*67e74705SXin Li template <typename T>
157*67e74705SXin Li template <typename U>
158*67e74705SXin Li void L<k>::O<T>::Fun(U) {}
159*67e74705SXin Li 
160*67e74705SXin Li void Instantiate() { L<0>::O<int>::Fun(0); }
161*67e74705SXin Li 
162*67e74705SXin Li }
163*67e74705SXin Li 
164*67e74705SXin Li namespace explicit_partial_specializations {
165*67e74705SXin Li typedef char (&oneT)[1];
166*67e74705SXin Li typedef char (&twoT)[2];
167*67e74705SXin Li typedef char (&threeT)[3];
168*67e74705SXin Li typedef char (&fourT)[4];
169*67e74705SXin Li typedef char (&fiveT)[5];
170*67e74705SXin Li typedef char (&sixT)[6];
171*67e74705SXin Li 
172*67e74705SXin Li char one[1];
173*67e74705SXin Li char two[2];
174*67e74705SXin Li char three[3];
175*67e74705SXin Li char four[4];
176*67e74705SXin Li char five[5];
177*67e74705SXin Li char six[6];
178*67e74705SXin Li 
179*67e74705SXin Li template<bool b> struct bool_ { typedef int type; };
180*67e74705SXin Li template<> struct bool_<false> {  };
181*67e74705SXin Li 
182*67e74705SXin Li #define XCAT(x,y) x ## y
183*67e74705SXin Li #define CAT(x,y) XCAT(x,y)
184*67e74705SXin Li #define sassert(_b_) bool_<(_b_)>::type CAT(var, __LINE__);
185*67e74705SXin Li 
186*67e74705SXin Li 
187*67e74705SXin Li template <int>
188*67e74705SXin Li struct L {
189*67e74705SXin Li   template <typename T>
190*67e74705SXin Li   struct O {
191*67e74705SXin Li     template <typename U>
192*67e74705SXin Li     static oneT Fun(U);
193*67e74705SXin Li 
194*67e74705SXin Li   };
195*67e74705SXin Li };
196*67e74705SXin Li template <int k>
197*67e74705SXin Li template <typename T>
198*67e74705SXin Li template <typename U>
199*67e74705SXin Li oneT L<k>::O<T>::Fun(U) { return one; }
200*67e74705SXin Li 
201*67e74705SXin Li template<>
202*67e74705SXin Li template<>
203*67e74705SXin Li template<typename U>
204*67e74705SXin Li oneT L<0>::O<char>::Fun(U) { return one; }
205*67e74705SXin Li 
206*67e74705SXin Li 
207*67e74705SXin Li void Instantiate() {
208*67e74705SXin Li   sassert(sizeof(L<0>::O<int>::Fun(0)) == sizeof(one));
209*67e74705SXin Li   sassert(sizeof(L<0>::O<char>::Fun(0)) == sizeof(one));
210*67e74705SXin Li }
211*67e74705SXin Li 
212*67e74705SXin Li }
213*67e74705SXin Li 
214*67e74705SXin Li namespace func_tmpl_spec_def_in_func {
215*67e74705SXin Li // We failed to diagnose function template specialization definitions inside
216*67e74705SXin Li // functions during recovery previously.
217*67e74705SXin Li template <class> void FuncTemplate() {}
218*67e74705SXin Li void TopLevelFunc() {
219*67e74705SXin Li   // expected-error@+2 {{expected a qualified name after 'typename'}}
220*67e74705SXin Li   // expected-error@+1 {{function definition is not allowed here}}
221*67e74705SXin Li   typename template <> void FuncTemplate<void>() { }
222*67e74705SXin Li   // expected-error@+1 {{function definition is not allowed here}}
223*67e74705SXin Li   void NonTemplateInner() { }
224*67e74705SXin Li }
225*67e74705SXin Li }
226*67e74705SXin Li 
227*67e74705SXin Li namespace broken_baseclause {
228*67e74705SXin Li template<typename T>
229*67e74705SXin Li struct base { };
230*67e74705SXin Li 
231*67e74705SXin Li struct t1 : base<int,
232*67e74705SXin Li   public:  // expected-error {{expected expression}}
233*67e74705SXin Li };  // expected-error {{expected class name}}
234*67e74705SXin Li // expected-error@-1 {{expected '{' after base class list}}
235*67e74705SXin Li struct t2 : base<int,
236*67e74705SXin Li   public  // expected-error {{expected expression}}
237*67e74705SXin Li };  // expected-error {{expected class name}}
238*67e74705SXin Li // expected-error@-1 {{expected '{' after base class list}}
239*67e74705SXin Li 
240*67e74705SXin Li }
241