18fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
28fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
38fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregortemplate<typename T, typename U> struct pair { };
48fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregortemplate<typename ...Types> struct tuple { };
58fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
68fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregortemplate<typename T, typename U>
78fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregorstruct is_same {
88fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static const bool value = false;
98fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor};
108fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
118fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregortemplate<typename T>
128fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregorstruct is_same<T, T> {
138fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static const bool value = true;
148fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor};
158fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
168fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregornamespace ExpandIntoFixed {
178fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename T,
188fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor           typename U,
198fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor           typename V = pair<T, U>,
208fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor           typename W = V*>
218fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  class X0 { };
228fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
238fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename ...Ts>
248fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  class X1 {
258fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  public:
268fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    typedef X0<Ts...> type;
278fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  };
288fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
298fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static_assert(is_same<X1<int, int>::type,
308fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                        X0<int, int, pair<int, int>, pair<int, int>*>>::value,
318fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                "fails with two default arguments");
328fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
338fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static_assert(is_same<X1<int, int, float>::type,
348fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                        X0<int, int, float, float*>>::value,
358fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                "fails with one default argument");
368fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
378fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static_assert(is_same<X1<int, int, float, double>::type,
388fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                        X0<int, int, float, double>>::value,
398fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                "fails with no default arguments");
408fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor}
418fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
428fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregornamespace ExpandIntoFixedShifted {
438fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename T,
448fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor           typename U,
458fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor           typename V = pair<T, U>,
468fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor           typename W = V*>
478fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  class X0 { };
488fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
498fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename ...Ts>
508fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  class X1 {
518fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  public:
528fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    typedef X0<char, Ts...> type;
538fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  };
548fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
558fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static_assert(is_same<X1<int>::type,
568fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                        X0<char, int, pair<char, int>, pair<char, int>*>>::value,
578fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                "fails with two default arguments");
588fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
598fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static_assert(is_same<X1<int, float>::type,
608fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                        X0<char, int, float, float*>>::value,
618fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                "fails with one default argument");
628fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
638fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  static_assert(is_same<X1<int, float, double>::type,
648fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                        X0<char, int, float, double>>::value,
658fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor                "fails with no default arguments");
668fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor}
678fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
688fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregornamespace Deduction {
698fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template <typename X, typename Y = double> struct Foo {};
708fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template <typename ...Args> tuple<Args...> &foo(Foo<Args...>);
718fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
728fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  void call_foo(Foo<int, float> foo_if, Foo<int> foo_i) {
738fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    tuple<int, float> &t1 = foo(foo_if);
748fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    tuple<int, double> &t2 = foo(foo_i);
758fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  }
768fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor}
778fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
788fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregornamespace PR9021a {
798fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename, typename>
808fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  struct A { };
818fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
828fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename ...T>
838fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  struct B {
848fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    A<T...> a1;
858fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  };
868fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
878fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  void test() {
888fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    B<int, int> c;
898fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  }
908fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor}
918fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
928fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregornamespace PR9021b {
938fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<class, class>
948fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  struct t2
958fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  {
968fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
978fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  };
988fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
998fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<template<class...> class M>
1008fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  struct m
1018fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  {
1028fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    template<class... B>
1038fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor    using inner = M<B...>;
1048fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  };
1058fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
1068fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  m<t2> sta2;
1078fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor}
1088fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
1098fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregornamespace PartialSpecialization {
1108fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename T, typename U, typename V = U>
1118fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  struct X0; // expected-note{{template is declared here}}
1128fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
1138fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  template<typename ...Ts>
1148fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  struct X0<Ts...> {
1158fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  };
1168fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor
1178fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
1188fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  X0<int, float> x0if;
1198fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor  X0<int, float, double> x0ifd;
1208fbbae532e3cb5f45e9e862c60d48c78b0997325Douglas Gregor}
121b70126a328f89937f46db42f9e3cba1592887c91Douglas Gregor
122b70126a328f89937f46db42f9e3cba1592887c91Douglas Gregornamespace FixedAliasTemplate {
123b70126a328f89937f46db42f9e3cba1592887c91Douglas Gregor  template<typename,typename,typename> struct S {};
124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, typename U> using U = S<T, int, U>; // expected-note 2{{template parameter is declared here}}
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...); // expected-error 2{{pack expansion used as argument for non-pack parameter of alias template}}
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  S<int, int, double> &s1 = f({}, 0, 0.0); // expected-error {{no matching function}}
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace PR18401 {
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename... Args> struct foo { };
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, typename... Args> using bar = foo<T, Args...>; // expected-note 2{{template parameter is declared here}} expected-note {{'bar' declared here}}
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  template<typename T, typename... Args> using baz = bar<Args..., T>; // expected-error {{pack expansion used as argument for non-pack parameter of alias template}}
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // FIXME: We should still record the alias template, but mark it as invalid.
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  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}}
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}}
136b70126a328f89937f46db42f9e3cba1592887c91Douglas Gregor}
137