xref: /llvm-project/clang/test/Parser/cxx-template-argument.cpp (revision 1fe406fffe11dad0457a4d214ce67bf492196145)
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
4 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 %s -fdelayed-template-parsing
5 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -fdelayed-template-parsing
6 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -fdelayed-template-parsing
7 
8 template<typename T> struct A {};
9 
10 // Check for template argument lists followed by junk
11 // FIXME: The diagnostics here aren't great...
12 A<int+> int x; // expected-error {{expected '>'}} expected-note {{to match this '<'}} expected-error {{expected unqualified-id}}
13 A<int x; // expected-error {{expected '>'}} expected-note {{to match this '<'}}
14 
15 // PR8912
16 template <bool> struct S {};
17 S<bool(2 > 1)> s;
18 
19 // Test behavior when a template-id is ended by a token which starts with '>'.
20 namespace greatergreater {
21   template<typename T> struct S { S(); S(T); };
22   void f(S<int>=0); // expected-error {{a space is required between a right angle bracket and an equals sign (use '> =')}}
23   void f(S<S<int>>=S<int>()); // expected-error {{use '> >'}} expected-error {{use '> ='}}
24   template<typename T> void t();
25   struct R {
26     friend void operator==(void (*)(), R) {}
27     friend void operator>=(void (*)(), R) {}
28   };
29   void g() {
30     (void)(&t<int>==R()); // expected-error {{use '> ='}}
31     (void)(&t<int>>=R()); // expected-error {{use '> >'}}
32     (void)(&t<S<int>>>=R());
33 #if __cplusplus <= 199711L
34     // expected-error@-2 {{use '> >'}}
35 #endif
36     (void)(&t<S<int>>==R()); // expected-error {{use '> >'}} expected-error {{use '> ='}}
37   }
38 }
39 
40 namespace PR5925 {
41   template <typename x>
42   class foo { // expected-note {{here}}
43   };
44   void bar(foo *X) { // expected-error {{requires template arguments}}
45   }
46 }
47 
48 namespace PR13210 {
49   template <class T>
50   class C {}; // expected-note {{here}}
51 
52   void f() {
53     new C(); // expected-error {{requires template arguments}}
54   }
55 }
56 
57 // Don't emit spurious messages
58 namespace pr16225add {
59 
60   template<class T1, typename T2> struct Known { }; // expected-note 3 {{template is declared here}}
61   template<class T1, typename T2> struct X;
62   template<class T1, typename T2> struct ABC; // expected-note {{template is declared here}}
63   template<int N1, int N2> struct ABC2 {};
64 
65   template<class T1, typename T2> struct foo :
66     UnknownBase<T1,T2> // expected-error {{no template named 'UnknownBase'}}
67   { };
68 
69   template<class T1, typename T2> struct foo2 :
70     UnknownBase<T1,T2>, // expected-error {{no template named 'UnknownBase'}}
71     Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
72   { };
73 
74   template<class T1, typename T2> struct foo3 :
75     UnknownBase<T1,T2,ABC<T2,T1> > // expected-error {{no template named 'UnknownBase'}}
76   { };
77 
78   template<class T1, typename T2> struct foo4 :
79     UnknownBase<T1,ABC<T2> >, // expected-error {{too few template arguments for class template 'ABC'}}
80     Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
81   { };
82 
83   template<class T1, typename T2> struct foo5 :
84     UnknownBase<T1,T2,ABC<T2,T1>> // expected-error {{no template named 'UnknownBase'}}
85 #if __cplusplus <= 199711L
86     // expected-error@-2 {{use '> >'}}
87 #endif
88   { };
89 
90   template<class T1, typename T2> struct foo6 :
91     UnknownBase<T1,ABC<T2,T1>>, // expected-error {{no template named 'UnknownBase'}}
92 #if __cplusplus <= 199711L
93     // expected-error@-2 {{use '> >'}}
94 #endif
95     Known<T1>  // expected-error {{too few template arguments for class template 'Known'}}
96   { };
97 
98   template<class T1, typename T2, int N> struct foo7 :
99     UnknownBase<T1,T2,(N>1)> // expected-error {{no template named 'UnknownBase'}}
100   { };
101 
102   template<class T1, typename T2> struct foo8 :
103     UnknownBase<X<int,int>,X<int,int>> // expected-error {{no template named 'UnknownBase'}}
104 #if __cplusplus <= 199711L
105     // expected-error@-2 {{use '> >'}}
106 #endif
107   { };
108 
109   template<class T1, typename T2> struct foo9 :
110     UnknownBase<Known<int,int>,X<int,int>> // expected-error {{no template named 'UnknownBase'}}
111 #if __cplusplus <= 199711L
112     // expected-error@-2 {{use '> >'}}
113 #endif
114   { };
115 
116   template<class T1, typename T2> struct foo10 :
117     UnknownBase<Known<int,int>,X<int,X<int,int>>> // expected-error {{no template named 'UnknownBase'}}
118 #if __cplusplus <= 199711L
119     // expected-error@-2 {{use '> >'}}
120 #endif
121   { };
122 
123   template<int N1, int N2> struct foo11 :
124     UnknownBase<2<N1,N2<4> // expected-error {{no template named 'UnknownBase'}}
125   { };
126 
127 }
128 
129 namespace PR18793 {
130   template<typename T, T> struct S {};
131   template<typename T> int g(S<T, (T())> *);
132 }
133 
134 namespace r360308_regression {
135   template<typename> struct S1 { static int const n = 0; };
136   template<int, typename> struct S2 { typedef int t; };
137   template<typename T> struct S3 { typename S2<S1<T>::n < 0, int>::t n; };
138 
139   template<typename FT> bool f(FT p) {
140     const bool a = p.first<FT(0), b = p.second>FT(0);
141     return a == b;
142   }
143 }
144 
145 namespace GH95598 {
146 template<typename _Tp, bool _IsPtr = __is_pointer(_Tp)>
147 struct __is_pointer {};
148 // expected-warning@-1 {{keyword '__is_pointer' will be made available as an identifier for the remainder of the translation unit}}
149 
150 template<bool>
151 struct ts{};
152 
153 template<typename _Tp>
154   struct is_pointer : ts<__is_pointer(_Tp)> {};
155 }
156