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