1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -fsyntax-only -verify %s
2f4a2713aSLionel Sambuc template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \
3f4a2713aSLionel Sambuc // expected-note{{explicitly specialized}}
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambuc template<> struct A<double, double>; // expected-note{{forward declaration}}
6f4a2713aSLionel Sambuc
7f4a2713aSLionel Sambuc template<> struct A<float, float> { // expected-note{{previous definition}}
8f4a2713aSLionel Sambuc int x;
9f4a2713aSLionel Sambuc };
10f4a2713aSLionel Sambuc
11f4a2713aSLionel Sambuc template<> struct A<float> { // expected-note{{previous definition}}
12f4a2713aSLionel Sambuc int y;
13f4a2713aSLionel Sambuc };
14f4a2713aSLionel Sambuc
test_specs(A<float,float> * a1,A<float,int> * a2)15f4a2713aSLionel Sambuc int test_specs(A<float, float> *a1, A<float, int> *a2) {
16f4a2713aSLionel Sambuc return a1->x + a2->y;
17f4a2713aSLionel Sambuc }
18f4a2713aSLionel Sambuc
test_incomplete_specs(A<double,double> * a1,A<double> * a2)19f4a2713aSLionel Sambuc int test_incomplete_specs(A<double, double> *a1,
20f4a2713aSLionel Sambuc A<double> *a2)
21f4a2713aSLionel Sambuc {
22f4a2713aSLionel Sambuc (void)a1->x; // expected-error{{member access into incomplete type}}
23f4a2713aSLionel Sambuc (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A<double, int>'}}
24f4a2713aSLionel Sambuc }
25f4a2713aSLionel Sambuc
26f4a2713aSLionel Sambuc typedef float FLOAT;
27f4a2713aSLionel Sambuc
28f4a2713aSLionel Sambuc template<> struct A<float, FLOAT>;
29f4a2713aSLionel Sambuc
30f4a2713aSLionel Sambuc template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
31f4a2713aSLionel Sambuc
32f4a2713aSLionel Sambuc template<> struct A<float, int> { }; // expected-error{{redefinition}}
33f4a2713aSLionel Sambuc
34f4a2713aSLionel Sambuc template<typename T, typename U = int> struct X;
35f4a2713aSLionel Sambuc
36f4a2713aSLionel Sambuc template <> struct X<int, int> { int foo(); }; // #1
37f4a2713aSLionel Sambuc template <> struct X<float> { int bar(); }; // #2
38f4a2713aSLionel Sambuc
39f4a2713aSLionel Sambuc typedef int int_type;
testme(X<int_type> * x1,X<float,int> * x2)40f4a2713aSLionel Sambuc void testme(X<int_type> *x1, X<float, int> *x2) {
41f4a2713aSLionel Sambuc (void)x1->foo(); // okay: refers to #1
42f4a2713aSLionel Sambuc (void)x2->bar(); // okay: refers to #2
43f4a2713aSLionel Sambuc }
44f4a2713aSLionel Sambuc
45f4a2713aSLionel Sambuc // Make sure specializations are proper classes.
46f4a2713aSLionel Sambuc template<>
47f4a2713aSLionel Sambuc struct A<char> {
48f4a2713aSLionel Sambuc A();
49f4a2713aSLionel Sambuc };
50f4a2713aSLionel Sambuc
A()51f4a2713aSLionel Sambuc A<char>::A() { }
52f4a2713aSLionel Sambuc
53f4a2713aSLionel Sambuc // Make sure we can see specializations defined before the primary template.
54f4a2713aSLionel Sambuc namespace N{
55f4a2713aSLionel Sambuc template<typename T> struct A0;
56f4a2713aSLionel Sambuc }
57f4a2713aSLionel Sambuc
58f4a2713aSLionel Sambuc namespace N {
59f4a2713aSLionel Sambuc template<>
60f4a2713aSLionel Sambuc struct A0<void> {
61f4a2713aSLionel Sambuc typedef void* pointer;
62f4a2713aSLionel Sambuc };
63f4a2713aSLionel Sambuc }
64f4a2713aSLionel Sambuc
65f4a2713aSLionel Sambuc namespace N {
66f4a2713aSLionel Sambuc template<typename T>
67f4a2713aSLionel Sambuc struct A0 {
68f4a2713aSLionel Sambuc void foo(A0<void>::pointer p = 0);
69f4a2713aSLionel Sambuc };
70f4a2713aSLionel Sambuc }
71f4a2713aSLionel Sambuc
72f4a2713aSLionel Sambuc // Diagnose specialization errors
73f4a2713aSLionel Sambuc struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
74f4a2713aSLionel Sambuc
75f4a2713aSLionel Sambuc template<> struct ::A<double>;
76f4a2713aSLionel Sambuc
77f4a2713aSLionel Sambuc namespace N {
78f4a2713aSLionel Sambuc template<typename T> struct B; // expected-note 2{{explicitly specialized}}
79f4a2713aSLionel Sambuc
80f4a2713aSLionel Sambuc template<> struct ::N::B<char>; // okay
81f4a2713aSLionel Sambuc template<> struct ::N::B<short>; // okay
82f4a2713aSLionel Sambuc template<> struct ::N::B<int>; // okay
83f4a2713aSLionel Sambuc
84f4a2713aSLionel Sambuc int f(int);
85f4a2713aSLionel Sambuc }
86f4a2713aSLionel Sambuc
87f4a2713aSLionel Sambuc template<> struct N::B<int> { }; // okay
88f4a2713aSLionel Sambuc
89f4a2713aSLionel Sambuc template<> struct N::B<float> { }; // expected-warning{{C++11 extension}}
90f4a2713aSLionel Sambuc
91f4a2713aSLionel Sambuc namespace M {
92f4a2713aSLionel Sambuc template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
93f4a2713aSLionel Sambuc
94*0a6a1f1dSLionel Sambuc template<> struct ::A<long double>; // expected-error{{must occur at global scope}}
95f4a2713aSLionel Sambuc }
96f4a2713aSLionel Sambuc
97f4a2713aSLionel Sambuc template<> struct N::B<char> {
testfN::B98f4a2713aSLionel Sambuc int testf(int x) { return f(x); }
99f4a2713aSLionel Sambuc };
100f4a2713aSLionel Sambuc
101f4a2713aSLionel Sambuc // PR5264
102f4a2713aSLionel Sambuc template <typename T> class Foo;
103f4a2713aSLionel Sambuc Foo<int>* v;
F()104f4a2713aSLionel Sambuc Foo<int>& F() { return *v; }
105f4a2713aSLionel Sambuc template <typename T> class Foo {};
106f4a2713aSLionel Sambuc Foo<int> x;
107f4a2713aSLionel Sambuc
108f4a2713aSLionel Sambuc
109f4a2713aSLionel Sambuc // Template template parameters
110f4a2713aSLionel Sambuc template<template<class T> class Wibble>
111f4a2713aSLionel Sambuc class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
112f4a2713aSLionel Sambuc
113f4a2713aSLionel Sambuc namespace rdar9676205 {
114f4a2713aSLionel Sambuc template<typename T>
115f4a2713aSLionel Sambuc struct X {
116f4a2713aSLionel Sambuc template<typename U>
117f4a2713aSLionel Sambuc struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
118f4a2713aSLionel Sambuc };
119f4a2713aSLionel Sambuc };
120f4a2713aSLionel Sambuc
121f4a2713aSLionel Sambuc }
122*0a6a1f1dSLionel Sambuc
123*0a6a1f1dSLionel Sambuc namespace PR18009 {
124*0a6a1f1dSLionel Sambuc template <typename T> struct A {
125*0a6a1f1dSLionel Sambuc template <int N, int M> struct S;
126*0a6a1f1dSLionel Sambuc template <int N> struct S<N, sizeof(T)> {};
127*0a6a1f1dSLionel Sambuc };
128*0a6a1f1dSLionel Sambuc A<int>::S<8, sizeof(int)> a; // ok
129*0a6a1f1dSLionel Sambuc
130*0a6a1f1dSLionel Sambuc template <typename T> struct B {
131*0a6a1f1dSLionel Sambuc template <int N, int M> struct S; // expected-note {{declared here}}
132*0a6a1f1dSLionel Sambuc template <int N> struct S<N, sizeof(T) +
133*0a6a1f1dSLionel Sambuc N // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
134*0a6a1f1dSLionel Sambuc > {};
135*0a6a1f1dSLionel Sambuc };
136*0a6a1f1dSLionel Sambuc B<int>::S<8, sizeof(int) + 8> s; // expected-error {{undefined}}
137*0a6a1f1dSLionel Sambuc
138*0a6a1f1dSLionel Sambuc template<int A> struct outer {
139*0a6a1f1dSLionel Sambuc template<int B, int C> struct inner {};
140*0a6a1f1dSLionel Sambuc template<int C> struct inner<A * 2, C> {};
141*0a6a1f1dSLionel Sambuc };
142*0a6a1f1dSLionel Sambuc }
143*0a6a1f1dSLionel Sambuc
144*0a6a1f1dSLionel Sambuc namespace PR16519 {
145*0a6a1f1dSLionel Sambuc template<typename T, T...N> struct integer_sequence { typedef T value_type; }; // expected-warning {{extension}}
146*0a6a1f1dSLionel Sambuc
147*0a6a1f1dSLionel Sambuc template<typename T> struct __make_integer_sequence;
148*0a6a1f1dSLionel Sambuc template<typename T, T N> using make_integer_sequence = typename __make_integer_sequence<T>::template make<N, N % 2>::type; // expected-warning {{extension}}
149*0a6a1f1dSLionel Sambuc
150*0a6a1f1dSLionel Sambuc template<typename T, typename T::value_type ...Extra> struct __make_integer_sequence_impl; // expected-warning {{extension}}
151*0a6a1f1dSLionel Sambuc template<typename T, T ...N, T ...Extra> struct __make_integer_sequence_impl<integer_sequence<T, N...>, Extra...> { // expected-warning 2{{extension}}
152*0a6a1f1dSLionel Sambuc typedef integer_sequence<T, N..., sizeof...(N) + N..., Extra...> type;
153*0a6a1f1dSLionel Sambuc };
154*0a6a1f1dSLionel Sambuc
155*0a6a1f1dSLionel Sambuc template<typename T> struct __make_integer_sequence {
156*0a6a1f1dSLionel Sambuc template<T N, T Parity, typename = void> struct make;
157*0a6a1f1dSLionel Sambuc template<typename Dummy> struct make<0, 0, Dummy> { typedef integer_sequence<T> type; };
158*0a6a1f1dSLionel Sambuc template<typename Dummy> struct make<1, 1, Dummy> { typedef integer_sequence<T, 0> type; };
159*0a6a1f1dSLionel Sambuc template<T N, typename Dummy> struct make<N, 0, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2> > {};
160*0a6a1f1dSLionel Sambuc template<T N, typename Dummy> struct make<N, 1, Dummy> : __make_integer_sequence_impl<make_integer_sequence<T, N/2>, N - 1> {};
161*0a6a1f1dSLionel Sambuc };
162*0a6a1f1dSLionel Sambuc
163*0a6a1f1dSLionel Sambuc using X = make_integer_sequence<int, 5>; // expected-warning {{extension}}
164*0a6a1f1dSLionel Sambuc using X = integer_sequence<int, 0, 1, 2, 3, 4>; // expected-warning {{extension}}
165*0a6a1f1dSLionel Sambuc }
166*0a6a1f1dSLionel Sambuc
167*0a6a1f1dSLionel Sambuc namespace DefaultArgVsPartialSpec {
168*0a6a1f1dSLionel Sambuc // Check that the diagnostic points at the partial specialization, not just at
169*0a6a1f1dSLionel Sambuc // the default argument.
170*0a6a1f1dSLionel Sambuc template<typename T, int N =
171*0a6a1f1dSLionel Sambuc sizeof(T) // expected-note {{template parameter is used in default argument declared here}}
172*0a6a1f1dSLionel Sambuc > struct X {};
173*0a6a1f1dSLionel Sambuc template<typename T> struct X<T> {}; // expected-error {{non-type template argument depends on a template parameter of the partial specialization}}
174*0a6a1f1dSLionel Sambuc
175*0a6a1f1dSLionel Sambuc template<typename T,
176*0a6a1f1dSLionel Sambuc T N = 0 // expected-note {{template parameter is declared here}}
177*0a6a1f1dSLionel Sambuc > struct S;
178*0a6a1f1dSLionel Sambuc template<typename T> struct S<T> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'T'}}
179*0a6a1f1dSLionel Sambuc }
180