1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
4 template<typename T
, typename U
= int> struct A
; // expected-note {{template is declared here}} \
5 // expected-note{{explicitly specialized}}
7 template<> struct A
<double, double>; // expected-note{{forward declaration}}
9 template<> struct A
<float, float> { // expected-note{{previous definition}}
13 template<> struct A
<float> { // expected-note{{previous definition}}
17 int test_specs(A
<float, float> *a1
, A
<float, int> *a2
) {
21 int test_incomplete_specs(A
<double, double> *a1
,
24 (void)a1
->x
; // expected-error{{member access into incomplete type}}
25 (void)a2
->x
; // expected-error{{implicit instantiation of undefined template 'A<double>'}}
30 template<> struct A
<float, FLOAT
>;
32 template<> struct A
<FLOAT
, float> { }; // expected-error{{redefinition}}
34 template<> struct A
<float, int> { }; // expected-error{{redefinition}}
36 template<typename T
, typename U
= int> struct X
;
38 template <> struct X
<int, int> { int foo(); }; // #1
39 template <> struct X
<float> { int bar(); }; // #2
42 void testme(X
<int_type
> *x1
, X
<float, int> *x2
) {
43 (void)x1
->foo(); // okay: refers to #1
44 (void)x2
->bar(); // okay: refers to #2
47 // Make sure specializations are proper classes.
55 // Make sure we can see specializations defined before the primary template.
57 template<typename T
> struct A0
;
63 typedef void* pointer
;
70 void foo(A0
<void>::pointer p
= 0);
74 // Diagnose specialization errors
75 struct A
<double> { }; // expected-error{{template specialization requires 'template<>'}}
77 template<> struct ::A
<double>; // expected-warning {{extra qualification on member}}
80 template<typename T
> struct B
; // expected-note {{explicitly specialized}}
82 template<> struct ::N::B
<char>; // expected-warning {{extra qualification on member}}
83 template<> struct ::N::B
<short>; // expected-warning {{extra qualification on member}}
84 template<> struct ::N::B
<int>; // expected-warning {{extra qualification on member}}
89 template<> struct N::B
<int> { }; // okay
91 template<> struct N::B
<float> { };
95 template<> struct ::N::B
<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
97 template<> struct ::A
<long double>; // expected-error{{must occur at global scope}}
100 template<> struct N::B
<char> {
101 int testf(int x
) { return f(x
); }
105 template <typename T
> class Foo
;
107 Foo
<int>& F() { return *v
; }
108 template <typename T
> class Foo
{};
112 // Template template parameters
113 template<template<class T
> class Wibble
>
114 class Wibble
<int> { }; // expected-error{{cannot specialize a template template parameter}}
116 namespace rdar9676205
{
118 struct X
{ // expected-note {{here}}
120 struct X
<U
*> { // expected-error{{partial specialization of 'X' not in a namespace enclosing}}
127 template <typename T
> struct A
{
128 template <int N
, int M
> struct S
;
129 template <int N
> struct S
<N
, sizeof(T
)> {};
131 A
<int>::S
<8, sizeof(int)> a
; // ok
133 template <typename T
> struct B
{
134 template <int N
, int M
> struct S
;
135 template <int N
> struct S
<N
, sizeof(T
) + N
> {}; // ok (dr1315)
137 B
<int>::S
<8, sizeof(int) + 8> b
;
139 template <typename T
> struct C
{
140 template <int N
, int M
> struct S
;
141 template <int N
> struct S
<N
, N
? **(T(*)[N
])0 : 0> {}; // ok
145 template<int A
> struct outer
{
146 template<int B
, int C
> struct inner
{};
147 template<int C
> struct inner
<A
* 2, C
> {};
152 template<typename T
, T
...N
> struct integer_sequence
{ typedef T value_type
; };
153 #if __cplusplus <= 199711L
154 // expected-warning@-2 {{variadic templates are a C++11 extension}}
157 template<typename T
> struct __make_integer_sequence
;
158 template<typename T
, T N
> using make_integer_sequence
= typename __make_integer_sequence
<T
>::template make
<N
, N
% 2>::type
;
159 #if __cplusplus <= 199711L
160 // expected-warning@-2 {{alias declarations are a C++11 extension}}
163 template<typename T
, typename
T::value_type
...Extra
> struct __make_integer_sequence_impl
;
164 #if __cplusplus <= 199711L
165 // expected-warning@-2 {{variadic templates are a C++11 extension}}
168 // Note that the following seemingly-equivalent template parameter list is
169 // not OK; it would result in a partial specialization that is not more
170 // specialized than the primary template. (See NTTPTypeVsPartialOrder below.)
172 // template<typename T, T ...N, T ...Extra>
173 template<typename T
, T
...N
, typename integer_sequence
<T
, N
...>::value_type
...Extra
>
174 #if __cplusplus <= 199711L
175 // expected-warning@-2 2{{variadic templates are a C++11 extension}}
177 struct __make_integer_sequence_impl
<integer_sequence
<T
, N
...>, Extra
...> {
178 typedef integer_sequence
<T
, N
..., sizeof...(N
) + N
..., Extra
...> type
;
181 template<typename T
> struct __make_integer_sequence
{
182 template<T N
, T Parity
, typename
= void> struct make
;
183 template<typename Dummy
> struct make
<0, 0, Dummy
> { typedef integer_sequence
<T
> type
; };
184 template<typename Dummy
> struct make
<1, 1, Dummy
> { typedef integer_sequence
<T
, 0> type
; };
185 template<T N
, typename Dummy
> struct make
<N
, 0, Dummy
> : __make_integer_sequence_impl
<make_integer_sequence
<T
, N
/2> > {};
186 template<T N
, typename Dummy
> struct make
<N
, 1, Dummy
> : __make_integer_sequence_impl
<make_integer_sequence
<T
, N
/2>, N
- 1> {};
189 using X
= make_integer_sequence
<int, 5>;
190 #if __cplusplus <= 199711L
191 // expected-warning@-2 {{alias declarations are a C++11 extension}}
194 using X
= integer_sequence
<int, 0, 1, 2, 3, 4>;
195 #if __cplusplus <= 199711L
196 // expected-warning@-2 {{alias declarations are a C++11 extension}}
200 namespace NTTPTypeVsPartialOrder
{
201 struct X
{ typedef int value_type
; };
202 template<typename T
> struct Y
{ typedef T value_type
; };
204 template<typename T
, typename
T::value_type N
> struct A
;
205 template<int N
> struct A
<X
, N
> {};
206 template<typename T
, T N
> struct A
<Y
<T
>, N
> {};
211 template<int, typename T
, typename
T::value_type
> struct B
;
212 template<typename T
, typename
T::value_type N
> struct B
<0, T
, N
>;
213 template<int N
> struct B
<0, X
, N
> {};
214 template<typename T
, T N
> struct B
<0, Y
<T
>, N
> {};
219 namespace DefaultArgVsPartialSpec
{
220 // Check that the diagnostic points at the partial specialization, not just at
221 // the default argument.
222 template<typename T
, int N
=
223 sizeof(T
) // ok (dr1315)
225 template<typename T
> struct X
<T
> {};
228 T N
= 0 // expected-note {{template parameter is declared here}}
230 template<typename T
> struct S
<T
> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}