1 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
2 
3 template<typename T, typename U> struct pair { };
4 template<typename ...Types> struct tuple { };
5 
6 template<typename T, typename U>
7 struct is_same {
8   static const bool value = false;
9 };
10 
11 template<typename T>
12 struct is_same<T, T> {
13   static const bool value = true;
14 };
15 
16 namespace ExpandIntoFixed {
17   template<typename T,
18            typename U,
19            typename V = pair<T, U>,
20            typename W = V*>
21   class X0 { };
22 
23   template<typename ...Ts>
24   class X1 {
25   public:
26     typedef X0<Ts...> type;
27   };
28 
29   static_assert(is_same<X1<int, int>::type,
30                         X0<int, int, pair<int, int>, pair<int, int>*>>::value,
31                 "fails with two default arguments");
32 
33   static_assert(is_same<X1<int, int, float>::type,
34                         X0<int, int, float, float*>>::value,
35                 "fails with one default argument");
36 
37   static_assert(is_same<X1<int, int, float, double>::type,
38                         X0<int, int, float, double>>::value,
39                 "fails with no default arguments");
40 }
41 
42 namespace ExpandIntoFixedShifted {
43   template<typename T,
44            typename U,
45            typename V = pair<T, U>,
46            typename W = V*>
47   class X0 { };
48 
49   template<typename ...Ts>
50   class X1 {
51   public:
52     typedef X0<char, Ts...> type;
53   };
54 
55   static_assert(is_same<X1<int>::type,
56                         X0<char, int, pair<char, int>, pair<char, int>*>>::value,
57                 "fails with two default arguments");
58 
59   static_assert(is_same<X1<int, float>::type,
60                         X0<char, int, float, float*>>::value,
61                 "fails with one default argument");
62 
63   static_assert(is_same<X1<int, float, double>::type,
64                         X0<char, int, float, double>>::value,
65                 "fails with no default arguments");
66 }
67 
68 namespace Deduction {
69   template <typename X, typename Y = double> struct Foo {};
70   template <typename ...Args> tuple<Args...> &foo(Foo<Args...>);
71 
call_foo(Foo<int,float> foo_if,Foo<int> foo_i)72   void call_foo(Foo<int, float> foo_if, Foo<int> foo_i) {
73     tuple<int, float> &t1 = foo(foo_if);
74     tuple<int, double> &t2 = foo(foo_i);
75   }
76 }
77 
78 namespace PR9021a {
79   template<typename, typename>
80   struct A { };
81 
82   template<typename ...T>
83   struct B {
84     A<T...> a1;
85   };
86 
test()87   void test() {
88     B<int, int> c;
89   }
90 }
91 
92 namespace PR9021b {
93   template<class, class>
94   struct t2
95   {
96 
97   };
98 
99   template<template<class...> class M>
100   struct m
101   {
102     template<class... B>
103     using inner = M<B...>;
104   };
105 
106   m<t2> sta2;
107 }
108 
109 namespace PartialSpecialization {
110   template<typename T, typename U, typename V = U>
111   struct X0; // expected-note{{template is declared here}}
112 
113   template<typename ...Ts>
114   struct X0<Ts...> {
115   };
116 
117   X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
118   X0<int, float> x0if;
119   X0<int, float, double> x0ifd;
120 }
121 
122 namespace FixedAliasTemplate {
123   template<typename,typename,typename> struct S {};
124   template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}}
125   template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}}
126   S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}}
127 }
128 
129 namespace PR18401 {
130   template<typename... Args> struct foo { };
131   template<typename T, typename... Args> using bar = foo<T, Args...>; // expected-note 2{{template parameter is declared here}} expected-note {{'bar' declared here}}
132   template<typename T, typename... Args> using baz = bar<Args..., T>; // expected-error {{pack expansion used as argument for non-pack parameter of alias template}}
133   // FIXME: We should still record the alias template, but mark it as invalid.
134   template<typename...T> void f(baz<T...>); // expected-error {{no template named 'baz'; did you mean 'bar'}} expected-error {{pack expansion used as argument for non-pack}}
g()135   void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}}
136 }
137