1// RUN: %clang_cc1 -fsyntax-only -verify %s
2template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
3
4X<int, 1> *x1;
5X<int> *x2;
6
7X<> *x3; // expected-error{{too few template arguments for class template 'X'}}
8
9template<typename U = float, int M> struct X;
10
11X<> *x4;
12
13template<typename T = int> struct Z { };
14template struct Z<>;
15
16// PR4362
17template<class T> struct a { };
18template<> struct a<int> { static const bool v = true; };
19
20template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}
21
22template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
23template struct p<int>;
24
25// PR5187
26template<typename T, typename U>
27struct A;
28
29template<typename T, typename U = T>
30struct A;
31
32template<typename T, typename U>
33struct A {
34  void f(A<T>);
35};
36
37template<typename T>
38struct B { };
39
40template<>
41struct B<void> {
42  typedef B<void*> type;
43};
44
45// Nested default arguments for template parameters.
46template<typename T> struct X1 { };
47
48template<typename T>
49struct X2 {
50  template<typename U = typename X1<T>::type> // expected-error{{no type named 'type' in 'X1<int>'}} \
51                                              // expected-error{{no type named 'type' in 'X1<char>'}}
52  struct Inner1 { }; // expected-note{{template is declared here}}
53
54  template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \
55                                   // expected-error{{no member named 'value' in 'X1<char>'}}
56  struct NonType1 { }; // expected-note{{template is declared here}}
57
58  template<T Value>
59  struct Inner2 { };
60
61  template<typename U>
62  struct Inner3 {
63    template<typename X = T, typename V = U>
64    struct VeryInner { };
65
66    template<T Value1 = sizeof(T), T Value2 = sizeof(U),
67             T Value3 = Value1 + Value2>
68    struct NonType2 { };
69  };
70};
71
72X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}}
73X2<int>::Inner1<float> x2iif;
74
75X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}}
76
77X2<int>::NonType1<'a'> x2_nontype1;
78X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}}
79
80// Check multi-level substitution into template type arguments
81X2<int>::Inner3<float>::VeryInner<> vi;
82X2<char>::Inner3<int>::NonType2<> x2_deep_nontype; // expected-note{{in instantiation of template class 'X2<char>' requested here}}
83
84template<typename T, typename U>
85struct is_same { static const bool value = false; };
86
87template<typename T>
88struct is_same<T, T> { static const bool value = true; };
89
90int array1[is_same<__typeof__(vi),
91               X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];
92
93int array2[is_same<__typeof(x2_deep_nontype),
94                   X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int),
95                                    sizeof(char)+sizeof(int)> >::value? 1 : -1];
96
97// Template template parameter defaults
98template<template<typename T> class X = X2> struct X3 { };
99int array3[is_same<X3<>, X3<X2> >::value? 1 : -1];
100
101struct add_pointer {
102  template<typename T>
103  struct apply {
104    typedef T* type;
105  };
106};
107
108template<typename T, template<typename> class X = T::template apply>
109  struct X4;
110int array4[is_same<X4<add_pointer>,
111                   X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
112
113template<int> struct X5 {}; // expected-note{{has a different type 'int'}}
114template<long> struct X5b {};
115template<typename T,
116         template<T> class B = X5> // expected-error{{template template argument has different}} \
117                                   // expected-note{{previous non-type template parameter}}
118  struct X6 {};
119
120X6<int> x6a;
121X6<long> x6b; // expected-note{{while checking a default template argument}}
122X6<long, X5b> x6c;
123
124
125template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}
126
127namespace PR9643 {
128  template<typename T> class allocator {};
129  template<typename T, typename U = allocator<T> > class vector {};
130
131  template<template<typename U, typename = allocator<U> > class container,
132           typename DT>
133  container<DT> initializer(const DT& d) {
134    return container<DT>();
135  }
136
137  void f() {
138    vector<int, allocator<int> > v = initializer<vector>(5);
139  }
140}
141
142namespace PR16288 {
143  template<typename X>
144  struct S {
145    template<typename T = int, typename U> // expected-warning {{C++11}}
146    void f();
147  };
148  template<typename X>
149  template<typename T, typename U>
150  void S<X>::f() {}
151}
152
153namespace DR1635 {
154  template <class T> struct X {
155    template <class U = typename T::type> static void f(int) {} // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} \
156                                                                // expected-warning {{C++11}}
157    static void f(...) {}
158  };
159
160  int g() { X<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}}
161}
162