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