1762bb9d0ad20320b9f97a841dce57ba5e8e48b07Richard Smith// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
2f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
3f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor// Metafunction to extract the Nth type from a set of types.
4f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<unsigned N, typename ...Types> struct get_nth_type;
5f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
6f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<unsigned N, typename Head, typename ...Tail>
7f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregorstruct get_nth_type<N, Head, Tail...> : get_nth_type<N-1, Tail...> { };
8f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
9f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename Head, typename ...Tail>
10f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregorstruct get_nth_type<0, Head, Tail...> {
11f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  typedef Head type;
12f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor};
13f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
14f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor// Placeholder type  when get_nth_type fails.
15f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregorstruct no_type {};
16f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
17f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<unsigned N>
18f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregorstruct get_nth_type<N> {
19f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  typedef no_type type;
20f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor};
21f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
22f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename T, typename U> struct pair { };
23f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename T, typename U> pair<T, U> make_pair(T, U);
24f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
25f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor// For a function parameter pack that occurs at the end of the
26f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor// parameter-declaration-list, the type A of each remaining argument
27f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor// of the call is compared with the type P of the declarator-id of the
28f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor// function parameter pack.
29f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename ...Args>
30f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortypename get_nth_type<0, Args...>::type first_arg(Args...);
31f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
32f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename ...Args>
33f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortypename get_nth_type<1, Args...>::type second_arg(Args...);
34f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
35f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregorvoid test_simple_deduction(int *ip, float *fp, double *dp) {
36f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip1 = first_arg(ip);
37f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip2 = first_arg(ip, fp);
38f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip3 = first_arg(ip, fp, dp);
39f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  no_type nt1 = first_arg();
40f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor}
41f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
42f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename ...Args>
43f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortypename get_nth_type<0, Args...>::type first_arg_ref(Args&...);
44f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
45f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename ...Args>
46f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortypename get_nth_type<1, Args...>::type second_arg_ref(Args&...);
47f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
48f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregorvoid test_simple_ref_deduction(int *ip, float *fp, double *dp) {
49f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip1 = first_arg_ref(ip);
50f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip2 = first_arg_ref(ip, fp);
51f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip3 = first_arg_ref(ip, fp, dp);
52f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  no_type nt1 = first_arg_ref();
53f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor}
54f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
55f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
5629805ca6d278b4d9563adfee67f2478f0fecdcfcRichard Smith// FIXME: Use the template parameter names in this diagnostic.
57f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename ...Args1, typename ...Args2>
5829805ca6d278b4d9563adfee67f2478f0fecdcfcRichard Smithtypename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: could not match 'pair<type-parameter-0-0, type-parameter-0-1>' against 'int'}}
59f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
60f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortemplate<typename ...Args1, typename ...Args2>
61f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregortypename get_nth_type<1, Args1...>::type second_arg_pair(pair<Args1, Args2>...);
62f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
63f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregorvoid test_pair_deduction(int *ip, float *fp, double *dp) {
64f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip1 = first_arg_pair(make_pair(ip, 17));
65f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip2 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
66f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  int *ip3 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
67f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor                            make_pair(dp, 17));
68f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  float *fp1 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
69f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  float *fp2 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
70f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor                               make_pair(dp, 17));
71f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  no_type nt1 = first_arg_pair();
72f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  no_type nt2 = second_arg_pair();
73f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  no_type nt3 = second_arg_pair(make_pair(ip, 17));
74f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
75f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor
76f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor  first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}}
77f5c65ffbd7374b6c8d9f1e361041578640cab320Douglas Gregor}
787d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor
797d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor// For a function parameter pack that does not occur at the end of the
807d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor// parameter-declaration-list, the type of the parameter pack is a
817d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor// non-deduced context.
827d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregortemplate<typename ...Types> struct tuple { };
837d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor
847d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregortemplate<typename ...Types>
857d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregorvoid pack_not_at_end(tuple<Types...>, Types... values, int);
867d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor
877d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregorvoid test_pack_not_at_end(tuple<int*, double*> t2) {
887d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor  pack_not_at_end(t2, 0, 0, 0);
897d5c0c1273bdc1cb3dff1cb5a62d07b1439e82c7Douglas Gregor}
90