| 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 | |
| 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 | |
| 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 2{{template is declared here}} |
| 112 | |
| 113 | template<typename ...Ts> |
| 114 | struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}} |
| 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}} |
| 135 | void g() { f(foo<int, char, double>()); } // expected-error {{no matching function}} |
| 136 | } |
| 137 | |