diff options
Diffstat (limited to 'test/Parser/cxx1z-class-template-argument-deduction.cpp')
-rw-r--r-- | test/Parser/cxx1z-class-template-argument-deduction.cpp | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/test/Parser/cxx1z-class-template-argument-deduction.cpp b/test/Parser/cxx1z-class-template-argument-deduction.cpp index b8f5a82d461b..532c893f2132 100644 --- a/test/Parser/cxx1z-class-template-argument-deduction.cpp +++ b/test/Parser/cxx1z-class-template-argument-deduction.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s -template <typename T> struct A { // expected-note 35{{declared here}} +template <typename T> struct A { // expected-note 38{{declared here}} constexpr A() {} constexpr A(int) {} constexpr operator int() { return 0; } @@ -17,6 +17,12 @@ namespace template_template_arg { Y<A> ya; // expected-error {{requires template arguments}} X<::A> xcca; Y<::A> ycca; // expected-error {{requires template arguments}} + X<A*> xap; // expected-error {{requires template arguments}} + X<const A> xca; // expected-error {{requires template arguments}} + X<A const> xac; // expected-error {{requires template arguments}} + // FIXME: This should not parse as a template template argument due to the + // trailing attributes. + X<A [[]]> xa_attr; template<template<typename> typename = A> struct XD {}; template<typename = A> struct YD {}; // expected-error {{requires template arguments}} @@ -28,6 +34,23 @@ namespace template_template_arg { template<typename T = A> struct G { }; // expected-error {{requires template arguments}} } +namespace template_template_arg_pack { + template<template<typename> typename...> struct XP {}; + template<typename...> struct YP {}; + + struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}} + + template<typename T> using ZId = Z; + + template<typename ...Ts> struct A { + XP<ZId<Ts>::Q...> xe; + YP<ZId<Ts>::Q...> ye; // expected-error {{requires template arguments}} + + XP<ZId<Ts>::Q> xp; // expected-error {{unexpanded parameter pack}} + YP<ZId<Ts>::Q> yp; // expected-error {{requires template arguments}} + }; +} + namespace injected_class_name { template<typename T> struct A { A(T); @@ -114,7 +137,6 @@ namespace expr { (void)A{n}; (void)new A(n); (void)new A{n}; - // FIXME: We should diagnose the lack of an initializer here. (void)new A; } } @@ -127,7 +149,7 @@ namespace decl { auto k() -> A; // expected-error{{requires template arguments}} - A a; // expected-error {{declaration of variable 'a' with deduced type 'A' requires an initializer}} + A a; A b = 0; const A c = 0; A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}} @@ -193,3 +215,18 @@ namespace typename_specifier { template<typename T> void g(typename T::A = 0); // expected-note {{refers to class template member}} void h() { g<X>(); } // expected-error {{no matching function}} } + +namespace parenthesized { + template<typename T> struct X { X(T); }; + auto n = (X([]{})); +} + +namespace within_template_arg_list { + template<typename T> struct X { constexpr X(T v) : v(v) {} T v; }; + template<int N = X(1).v> struct Y {}; + using T = Y<>; + using T = Y<X(1).v>; + using T = Y<within_template_arg_list::X(1).v>; + + template<int ...N> struct Z { Y<X(N)...> y; }; +} |