default-arguments.cpp revision a5728872c7702ddd09537c95bc3cbd20e1f2fb09
12700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor// RUN: %clang_cc1 -fsyntax-only -verify %s
22700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
32700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
42700dcde044893642b9b77638e052aa90be7cd51Douglas GregorX<int, 1> *x1;
52700dcde044893642b9b77638e052aa90be7cd51Douglas GregorX<int> *x2;
62700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
72700dcde044893642b9b77638e052aa90be7cd51Douglas GregorX<> *x3; // expected-error{{too few template arguments for class template 'X'}}
82700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
92700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename U = float, int M> struct X;
102700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
112700dcde044893642b9b77638e052aa90be7cd51Douglas GregorX<> *x4;
122700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
132700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T = int> struct Z { };
142700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate struct Z<>;
152700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
162700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor// PR4362
172700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<class T> struct a { };
182700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<> struct a<int> { static const bool v = true; };
192700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
202700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}
212700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
222700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
232700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate struct p<int>;
242700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
252700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor// PR5187
262700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T, typename U>
272700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct A;
282700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
292700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T, typename U = T>
302700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct A;
312700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
32c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregortemplate<typename T, typename U>
33c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregorstruct A {
342700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  void f(A<T>);
352700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor};
362700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
372700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T>
382700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct B { };
392700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
402700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<>
412700dcde044893642b9b77638e052aa90be7cd51Douglas Gregorstruct B<void> {
422700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor  typedef B<void*> type;
432700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor};
44c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregor
45c68afe2cbe7f875a9243c411077602fb5f5dc74bDouglas Gregor// Nested default arguments for template parameters.
462700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T> struct X1 { };
472700dcde044893642b9b77638e052aa90be7cd51Douglas Gregor
482700dcde044893642b9b77638e052aa90be7cd51Douglas Gregortemplate<typename T>
49struct X2 {
50  template<typename U = typename X1<T>::type> // expected-error{{no type named}}
51  struct Inner1 { };
52
53  template<T Value = X1<T>::value> // expected-error{{no member named 'value'}}
54  struct NonType1 { };
55
56  template<T Value>
57  struct Inner2 { };
58
59  template<typename U>
60  struct Inner3 {
61    template<typename X = T, typename V = U>
62    struct VeryInner { };
63
64    template<T Value1 = sizeof(T), T Value2 = sizeof(U),
65             T Value3 = Value1 + Value2>
66    struct NonType2 { };
67  };
68};
69
70X2<int> x2i;
71X2<int>::Inner1<float> x2iif;
72
73X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}}
74
75X2<int>::NonType1<'a'> x2_nontype1;
76X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}}
77
78// Check multi-level substitution into template type arguments
79X2<int>::Inner3<float>::VeryInner<> vi;
80X2<char>::Inner3<int>::NonType2<> x2_deep_nontype;
81
82template<typename T, typename U>
83struct is_same { static const bool value = false; };
84
85template<typename T>
86struct is_same<T, T> { static const bool value = true; };
87
88int array1[is_same<__typeof__(vi),
89               X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];
90
91int array2[is_same<__typeof(x2_deep_nontype),
92                   X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int),
93                                    sizeof(char)+sizeof(int)> >::value? 1 : -1];
94
95// Template template parameter defaults
96template<template<typename T> class X = X2> struct X3 { };
97int array3[is_same<X3<>, X3<X2> >::value? 1 : -1];
98
99struct add_pointer {
100  template<typename T>
101  struct apply {
102    typedef T* type;
103  };
104};
105
106template<typename T, template<typename> class X = T::template apply>
107  struct X4;
108int array4[is_same<X4<add_pointer>,
109                   X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
110
111template<int> struct X5 {}; // expected-note{{has a different type 'int'}}
112template<long> struct X5b {};
113template<typename T,
114         template<T> class B = X5> // expected-error{{template template argument has different}} \
115                                   // expected-note{{previous non-type template parameter}}
116  struct X6 {};
117
118X6<int> x6a;
119X6<long> x6b; // expected-note{{while checking a default template argument}}
120X6<long, X5b> x6c;
121
122
123template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}
124