deduction.cpp revision 57e97786433e70197a089360228d8f0d82e3ad4c
15291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor// RUN: %clang_cc1 -fsyntax-only -verify %s 2db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 3db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor// Template argument deduction with template template parameters. 4db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename T, template<T> class A> 5db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct X0 { 6db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor static const unsigned value = 0; 7db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 8db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 9db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<template<int> class A> 10db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct X0<int, A> { 11db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor static const unsigned value = 1; 12db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 13db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 14db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<int> struct X0i; 15db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<long> struct X0l; 16db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorint array_x0a[X0<long, X0l>::value == 0? 1 : -1]; 17db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorint array_x0b[X0<int, X0i>::value == 1? 1 : -1]; 18db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 19db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename T, typename U> 20db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct is_same { 21db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor static const bool value = false; 22db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 23db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 24db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename T> 25db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct is_same<T, T> { 26db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor static const bool value = true; 27db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 28db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 29db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename T> struct allocator { }; 30db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename T, typename Alloc = allocator<T> > struct vector {}; 31db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 32db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor// Fun with meta-lambdas! 33db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct _1 {}; 34db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct _2 {}; 35db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 36db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T. 37db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename T, typename Arg1, typename Arg2> 38db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct Replace { 39db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typedef T type; 40db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 41db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 42db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor// Replacement of the whole type. 43db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename Arg1, typename Arg2> 44db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct Replace<_1, Arg1, Arg2> { 45db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typedef Arg1 type; 46db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 47db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 48db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename Arg1, typename Arg2> 49db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct Replace<_2, Arg1, Arg2> { 50db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typedef Arg2 type; 51db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 52db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 53db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor// Replacement through cv-qualifiers 54db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<typename T, typename Arg1, typename Arg2> 55db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct Replace<const T, Arg1, Arg2> { 56db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typedef typename Replace<T, Arg1, Arg2>::type const type; 57db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 58db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 59db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor// Replacement of templates 60db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<template<typename> class TT, typename T1, typename Arg1, typename Arg2> 61db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct Replace<TT<T1>, Arg1, Arg2> { 62db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typedef TT<typename Replace<T1, Arg1, Arg2>::type> type; 63db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 64db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 65db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<template<typename, typename> class TT, typename T1, typename T2, 66db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typename Arg1, typename Arg2> 67db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct Replace<TT<T1, T2>, Arg1, Arg2> { 68db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typedef TT<typename Replace<T1, Arg1, Arg2>::type, 69db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typename Replace<T2, Arg1, Arg2>::type> type; 70db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 71db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 72db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor// Just for kicks... 73db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregortemplate<template<typename, typename> class TT, typename T1, 74db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typename Arg1, typename Arg2> 75db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorstruct Replace<TT<T1, _2>, Arg1, Arg2> { 76db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type; 77db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor}; 78db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregor 79db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorint array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1]; 80db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorint array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1]; 81db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorint array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1]; 82db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorint array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1]; 83db0d4b751e83b8841b8f48f913f17e50467f13d4Douglas Gregorint array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1]; 84e724246b9f655801bd96b727daf9dddc44beef4dChandler Carruth 85e724246b9f655801bd96b727daf9dddc44beef4dChandler Carruth// PR5911 86e724246b9f655801bd96b727daf9dddc44beef4dChandler Carruthtemplate <typename T, int N> void f(const T (&a)[N]); 87e724246b9f655801bd96b727daf9dddc44beef4dChandler Carruthint iarr[] = { 1 }; 88e724246b9f655801bd96b727daf9dddc44beef4dChandler Carruthvoid test_PR5911() { f(iarr); } 89a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth 90a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth// Must not examine base classes of incomplete type during template argument 91a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth// deduction. 92a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruthnamespace PR6257 { 93a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth template <typename T> struct X { 94a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth template <typename U> X(const X<U>& u); 95a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth }; 96a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth struct A; 97a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth void f(A& a); 98a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth void f(const X<A>& a); 99a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth void test(A& a) { (void)f(a); } 100a7ef13024e4cc3dfb75e3bc1695371b39d9a5240Chandler Carruth} 1015291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor 1025291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor// PR7463 1035291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregornamespace PR7463 { 1045495f37302f7c82192dab1ce8d9c9fe76ed0ee37Chandler Carruth const int f (); 1055291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor template <typename T_> void g (T_&); // expected-note{{T_ = int}} 1065291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor void h (void) { g(f()); } // expected-error{{no matching function for call}} 1075291c3cec0dbe8ad1d8e7e67e93af2b1586d5400Douglas Gregor} 10857e97786433e70197a089360228d8f0d82e3ad4cJohn McCall 10957e97786433e70197a089360228d8f0d82e3ad4cJohn McCallnamespace test0 { 11057e97786433e70197a089360228d8f0d82e3ad4cJohn McCall template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'T const' equal 'char'}} 11157e97786433e70197a089360228d8f0d82e3ad4cJohn McCall char *char_maker(); 11257e97786433e70197a089360228d8f0d82e3ad4cJohn McCall void test() { 11357e97786433e70197a089360228d8f0d82e3ad4cJohn McCall make(char_maker); // expected-error {{no matching function for call to 'make'}} 11457e97786433e70197a089360228d8f0d82e3ad4cJohn McCall } 11557e97786433e70197a089360228d8f0d82e3ad4cJohn McCall} 116