default-arguments.cpp revision eaf75f4e0f65444bb122ade7725a4a32badcbf77
1d7d5f0223bd30dfd618762349c6209dd1d5ea3e6Daniel Dunbar// RUN: clang-cc -fsyntax-only -verify %s
262cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregortemplate<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
362cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
462cb18dd11472965e03374d40bc27d650bc331b6Douglas GregorX<int, 1> *x1;
562cb18dd11472965e03374d40bc27d650bc331b6Douglas GregorX<int> *x2;
662cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
739a8de10c18365bde7062d8959b7ed525449c561Douglas GregorX<> *x3; // expected-error{{too few template arguments for class template 'X'}}
862cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
962cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregortemplate<typename U = float, int M> struct X;
1062cb18dd11472965e03374d40bc27d650bc331b6Douglas Gregor
1162cb18dd11472965e03374d40bc27d650bc331b6Douglas GregorX<> *x4;
129bff9a91fbd6213e2d042aadd8ede92bed6be666Anders Carlsson
13f4e2a2ce1101d875c4b69294416438007947daebAnders Carlssontemplate<typename T = int> struct Z { };
149bff9a91fbd6213e2d042aadd8ede92bed6be666Anders Carlssontemplate struct Z<>;
153b56c002591b59c6c257951f6613b44de83fa860Anders Carlsson
163b56c002591b59c6c257951f6613b44de83fa860Anders Carlsson// PR4362
173b56c002591b59c6c257951f6613b44de83fa860Anders Carlssontemplate<class T> struct a { };
183b56c002591b59c6c257951f6613b44de83fa860Anders Carlssontemplate<> struct a<int> { static const bool v = true; };
193b56c002591b59c6c257951f6613b44de83fa860Anders Carlsson
203b56c002591b59c6c257951f6613b44de83fa860Anders Carlssontemplate<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}
213b56c002591b59c6c257951f6613b44de83fa860Anders Carlsson
223b56c002591b59c6c257951f6613b44de83fa860Anders Carlssontemplate struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
233b56c002591b59c6c257951f6613b44de83fa860Anders Carlssontemplate struct p<int>;
24542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor
25542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor// PR5187
26542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregortemplate<typename T, typename U>
27542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregorstruct A;
28542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor
29542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregortemplate<typename T, typename U = T>
30542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregorstruct A;
31542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor
32542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregortemplate<typename T, typename U>
33542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregorstruct A {
34542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor  void f(A<T>);
35542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor};
36542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor
37542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregortemplate<typename T>
38542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregorstruct B { };
39542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor
40542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregortemplate<>
41542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregorstruct B<void> {
42542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor  typedef B<void*> type;
43542b548e041a6fab0fe06601ccc6b91a81bc217aDouglas Gregor};
440f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
450f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor// Nested default arguments for template parameters.
460f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregortemplate<typename T> struct X1 { };
470f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
480f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregortemplate<typename T>
490f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregorstruct X2 {
500f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  template<typename U = typename X1<T>::type> // expected-error{{no type named}}
510f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  struct Inner1 { };
520f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
530f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  template<T Value = X1<T>::value> // expected-error{{no member named 'value'}}
540f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  struct NonType1 { };
550f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
560f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  template<T Value>
570f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  struct Inner2 { };
580f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
590f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  template<typename U>
600f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  struct Inner3 {
610f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor    template<typename X = T, typename V = U>
620f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor    struct VeryInner { };
630f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
640f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor    template<T Value1 = sizeof(T), T Value2 = sizeof(U),
650f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor             T Value3 = Value1 + Value2>
660f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor    struct NonType2 { };
670f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor  };
680f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor};
690f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
700f8716b7bb25d61a82f699b3975167451f7b5a68Douglas GregorX2<int> x2i;
710f8716b7bb25d61a82f699b3975167451f7b5a68Douglas GregorX2<int>::Inner1<float> x2iif;
720f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
730f8716b7bb25d61a82f699b3975167451f7b5a68Douglas GregorX2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}}
740f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
750f8716b7bb25d61a82f699b3975167451f7b5a68Douglas GregorX2<int>::NonType1<'a'> x2_nontype1;
760f8716b7bb25d61a82f699b3975167451f7b5a68Douglas GregorX2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}}
770f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
780f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor// Check multi-level substitution into template type arguments
790f8716b7bb25d61a82f699b3975167451f7b5a68Douglas GregorX2<int>::Inner3<float>::VeryInner<> vi;
800f8716b7bb25d61a82f699b3975167451f7b5a68Douglas GregorX2<char>::Inner3<int>::NonType2<> x2_deep_nontype;
810f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
820f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregortemplate<typename T, typename U>
830f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregorstruct is_same { static const bool value = false; };
840f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
850f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregortemplate<typename T>
860f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregorstruct is_same<T, T> { static const bool value = true; };
870f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
887bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregorint array1[is_same<__typeof__(vi),
890f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor               X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];
900f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor
917bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregorint array2[is_same<__typeof(x2_deep_nontype),
927bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor                   X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int),
930f8716b7bb25d61a82f699b3975167451f7b5a68Douglas Gregor                                    sizeof(char)+sizeof(int)> >::value? 1 : -1];
947bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor
957bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor// Template template parameter defaults
967bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregortemplate<template<typename T> class X = X2> struct X3 { };
977bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregorint array3[is_same<X3<>, X3<X2> >::value? 1 : -1];
987bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor
997bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregorstruct add_pointer {
1007bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor  template<typename T>
1017bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor  struct apply {
1027bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor    typedef T* type;
1037bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor  };
1047bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor};
1057bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor
1067bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregortemplate<typename T, template<typename> class X = T::template apply>
1077bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor  struct X4;
1087bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregorint array4[is_same<X4<add_pointer>,
1097bb87fca7d22a8a194d04188746b90f46512975fDouglas Gregor                   X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
1109148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregor
1119148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregortemplate<int> struct X5 {}; // expected-note{{has a different type 'int'}}
1129148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregortemplate<long> struct X5b {};
1139148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregortemplate<typename T,
1149148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregor         template<T> class B = X5> // expected-error{{template template argument has different}} \
1159148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregor                                   // expected-note{{previous non-type template parameter}}
1169148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregor  struct X6 {};
1179148c3f5829f4d031249faeb1043e7be914539e8Douglas Gregor
1189148c3f5829f4d031249faeb1043e7be914539e8Douglas GregorX6<int> x6a;
119f35f828f9883123772a9731af190a608f3236ef4Douglas GregorX6<long> x6b; // expected-note{{while checking a default template argument}}
1209148c3f5829f4d031249faeb1043e7be914539e8Douglas GregorX6<long, X5b> x6c;
121eaf75f4e0f65444bb122ade7725a4a32badcbf77Douglas Gregor
122eaf75f4e0f65444bb122ade7725a4a32badcbf77Douglas Gregor
123eaf75f4e0f65444bb122ade7725a4a32badcbf77Douglas Gregortemplate<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}
124