1 // RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx17 %std_cxx98-14 %s
2 // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s
4 template<template<typename T
> class X
> struct A
; // #A
5 // expected-note@-1 2{{previous template template parameter is here}}
7 template<template<typename T
, int I
> class X
> struct B
; // expected-note{{previous template template parameter is here}}
9 template<template<int I
> class X
> struct C
;
10 // expected-error@-1 {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}}
11 // expected-note@-2 {{previous template template parameter is here}}
13 template<class> struct X
; // expected-note {{template is declared here}}
14 template<int N
> struct Y
; // expected-note {{template parameter is declared here}}
15 template<long N
> struct Ylong
;
16 template<const int &N
> struct Yref
; // expected-note {{template parameter is declared here}}
19 template<class> struct Z
;
21 template<class, class> struct TooMany
; // expected-note{{template is declared here}}
28 A
<Y
> *a4
; // expected-error@#A {{template argument for non-type template parameter must be an expression}}
29 // expected-note@-1 {{different template parameters}}
30 A
<TooMany
> *a5
; // expected-error {{too few template arguments for class template 'TooMany'}}
31 // expected-note@-1 {{different template parameters}}
32 B
<X
> *a6
; // expected-error {{too many template arguments for class template 'X'}}
33 // expected-note@-1 {{different template parameters}}
36 C
<Yref
> *a9
; // expected-note {{different template parameters}}
38 template<typename T
> void f(int);
40 A
<f
> *a9
; // expected-error{{must be a class template}}
42 // Evil digraph '<:' is parsed as '[', expect error.
44 #if __cplusplus <= 199711L
45 // expected-error@-2 {{found '<::' after a template name which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
48 // Do not do a digraph correction here.
49 A
<: :N::Z
> *a11
; // expected-error{{expected expression}} \
50 precxx17
-error
{{a type specifier is required
for all declarations
}} \
51 cxx17
-error
{{expected unqualified
-id
}}
55 template <typename
, typename
= int>
59 template <typename
,int>
61 { X
<int> const_ref(); };
63 template <template<typename
,int> class TT
, typename T
, int N
>
64 int operator<<(int, TT
<T
, N
> a
) { // expected-note{{candidate template ignored}}
65 0 << a
.const_ref(); // expected-error{{invalid operands to binary expression ('int' and 'X<int>')}}
68 void f0( Y
<int,1> y
){ 1 << y
; } // expected-note{{in instantiation of function template specialization 'N::operator<<<N::Y, int, 1>' requested here}}
72 template <typename Primitive
, template <Primitive
...> class F
>
73 #if __cplusplus <= 199711L
74 // expected-warning@-2 {{variadic templates are a C++11 extension}}
78 typedef typename
Primitive::template call
<F
> x
;
81 template <template <typename
> class... Templates
>
82 #if __cplusplus <= 199711L
83 // expected-warning@-2 {{variadic templates are a C++11 extension}}
86 struct template_tuple
{
87 #if __cplusplus >= 201103L
88 static constexpr int N
= sizeof...(Templates
);
93 template <template <typename
> class... Templates
>
94 #if __cplusplus <= 199711L
95 // expected-warning@-2 {{variadic templates are a C++11 extension}}
98 template_tuple
<Templates
...> f7() {}
100 #if __cplusplus >= 201103L
101 struct S
: public template_tuple
<identity
, identity
> {
102 static_assert(N
== 2, "Number of template arguments incorrect");
110 namespace CheckDependentNonTypeParamTypes
{
111 template<template<typename T
, typename U
, T v
> class X
> struct A
{
112 // expected-note@-1 {{previous template template parameter is here}}
120 // FIXME: If we accept A<B> at all, it's not obvious what should happen
121 // here. While parsing the template, we form
122 // X<unsigned char, int, (unsigned char)1234>
123 // but in the final instantiation do we get
124 // B<unsigned char, int, (int)1234>
126 // B<unsigned char, int, (int)(unsigned char)1234>
128 X
<unsigned char, int, 1234> x
;
129 int check
[x
.value
== 1234 ? 1 : -1];
133 template<typename T
, typename U
, U v
> struct B
{
134 // expected-error@-1 {{conflicting deduction 'U' against 'T' for parameter}}
135 static const U value
= v
;
138 // FIXME: This should probably be rejected, but the rules are at best unclear.
139 A
<B
> ab
; // expected-note {{different template parameters}}
149 template<template<typename T
, T
> class U
> struct A
{};
150 template<template<typename T
, T
> class U
> struct B
: A
<U
> {};
154 template<typename T
> struct A
{};
155 template<typename T
= int> struct A
;
156 template<template<typename
...> class A
> void f(A
<int>*) { A
<> a
; } // expected-warning 0-1{{extension}}
157 void g() { f((A
<>*)0); }