summaryrefslogtreecommitdiffstats
path: root/test/Parser/cxx1z-class-template-argument-deduction.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2017-02-09 19:17:44 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2017-02-09 19:17:44 +0000
commit85d7bd3c86c4f7b800fe1c2c58f881ddd0290059 (patch)
tree6339c13061b4cd712d2e0882d361fa7000a38dee /test/Parser/cxx1z-class-template-argument-deduction.cpp
parent542041838281a49128517d5600a9aebac15740a1 (diff)
[c++1z] P0091R3: Basic support for deducing class template arguments via deduction-guides.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@294613 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Parser/cxx1z-class-template-argument-deduction.cpp')
-rw-r--r--test/Parser/cxx1z-class-template-argument-deduction.cpp98
1 files changed, 53 insertions, 45 deletions
diff --git a/test/Parser/cxx1z-class-template-argument-deduction.cpp b/test/Parser/cxx1z-class-template-argument-deduction.cpp
index 65b1105d34..10be123eb0 100644
--- a/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -1,6 +1,12 @@
// 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 35{{declared here}}
+ constexpr A() {}
+ constexpr A(int) {}
+ constexpr operator int() { return 0; }
+};
+A() -> A<int>;
+A(int) -> A<int>;
// Make sure we still correctly parse cases where a template can appear without arguments.
namespace template_template_arg {
@@ -18,7 +24,7 @@ namespace template_template_arg {
template<typename = ::A> struct YCCD {}; // expected-error {{requires template arguments}}
// FIXME: replacing the invalid type with 'int' here is horrible
- template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}} expected-error {{not implicitly convertible to 'int'}}
+ template <A a = A<int>()> class C { }; // expected-error {{requires template arguments}}
template<typename T = A> struct G { }; // expected-error {{requires template arguments}}
}
@@ -27,7 +33,7 @@ namespace injected_class_name {
A(T);
void f(int) {
A a = 1;
- injected_class_name::A b = 1; // expected-error {{not yet supported}}
+ injected_class_name::A b = 1; // expected-error {{no viable constructor or deduction guide}}
}
void f(T);
};
@@ -46,8 +52,8 @@ struct member {
operator A(); // expected-error {{requires template arguments; argument deduction not allowed in conversion function type}}
- static A x; // expected-error {{requires an initializer}}
- static A y = 0; // expected-error {{not yet supported}}
+ static A x; // FIXME: We deduce A<int> from the initializer despite this not being a definition!
+ static constexpr A y = 0;
};
namespace in_typedef {
@@ -67,18 +73,18 @@ namespace stmt {
// simple-declaration or cast. We also permit it in conditions,
// for-range-declarations, member-declarations for static data members, and
// new-expressions, because not doing so would be bizarre.
- A local = 0; // expected-error {{not yet supported}}
- static A local_static = 0; // expected-error {{not yet supported}}
- static thread_local A thread_local_static = 0; // expected-error {{not yet supported}}
- if (A a = 0) {} // expected-error {{not yet supported}}
- if (A a = 0; a) {} // expected-error {{not yet supported}}
- switch (A a = 0) {} // expected-error {{not yet supported}}
- switch (A a = 0; a) {} // expected-error {{not yet supported}}
- for (A a = 0; a; /**/) {} // expected-error {{not yet supported}}
- for (/**/; A a = 0; /**/) {} // expected-error {{not yet supported}}
- while (A a = 0) {} // expected-error {{not yet supported}}
+ A local = 0;
+ static A local_static = 0;
+ static thread_local A thread_local_static = 0;
+ if (A a = 0) {}
+ if (A a = 0; a) {}
+ switch (A a = 0) {} // expected-warning {{no case matching constant switch condition '0'}}
+ switch (A a = 0; a) {} // expected-warning {{no case matching constant switch condition '0'}}
+ for (A a = 0; a; /**/) {}
+ for (/**/; A a = 0; /**/) {}
+ while (A a = 0) {}
int arr[3];
- for (A a : arr) {} // expected-error {{not yet supported}}
+ for (A a : arr) {}
}
namespace std {
@@ -104,12 +110,12 @@ namespace expr {
(void)(A)(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
(void)(A){n}; // expected-error{{requires template arguments; argument deduction not allowed here}}
- (void)A(n); // expected-error {{not yet supported}}
- (void)A{n}; // expected-error {{not yet supported}}
- (void)new A(n); // expected-error {{not yet supported}}
- (void)new A{n}; // expected-error {{not yet supported}}
+ (void)A(n);
+ (void)A{n};
+ (void)new A(n);
+ (void)new A{n};
// FIXME: We should diagnose the lack of an initializer here.
- (void)new A; // expected-error {{not yet supported}}
+ (void)new A;
}
}
@@ -121,55 +127,57 @@ namespace decl {
auto k() -> A; // expected-error{{requires template arguments}}
- A a; // expected-error {{requires an initializer}}
- A b = 0; // expected-error {{not yet supported}}
- const A c = 0; // expected-error {{not yet supported}}
+ A a; // FIXME: This is (technically) syntactically invalid.
+ A b = 0;
+ const A c = 0;
A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
- A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{not yet supported}}
+ A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{type 'A<int>' decomposes into 0 elements, but 2 names were provided}}
}
namespace typename_specifier {
struct F {};
void e() {
- (void) typename ::A(0); // expected-error {{not yet supported}}
- (void) typename ::A{0}; // expected-error {{not yet supported}}
- new typename ::A(0); // expected-error {{not yet supported}}
- new typename ::A{0}; // expected-error {{not yet supported}}
- typename ::A a = 0; // expected-error {{not yet supported}}
- const typename ::A b = 0; // expected-error {{not yet supported}}
- if (typename ::A a = 0) {} // expected-error {{not yet supported}}
- for (typename ::A a = 0; typename ::A b = 0; /**/) {} // expected-error 2{{not yet supported}}
+ (void) typename ::A(0);
+ (void) typename ::A{0};
+ new typename ::A(0);
+ new typename ::A{0};
+ typename ::A a = 0;
+ const typename ::A b = 0;
+ if (typename ::A a = 0) {}
+ for (typename ::A a = 0; typename ::A b = 0; /**/) {}
(void)(typename ::A)(0); // expected-error{{requires template arguments; argument deduction not allowed here}}
(void)(typename ::A){0}; // expected-error{{requires template arguments; argument deduction not allowed here}}
}
- typename ::A a = 0; // expected-error {{not yet supported}}
- const typename ::A b = 0; // expected-error {{not yet supported}}
+ typename ::A a = 0;
+ const typename ::A b = 0;
typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
- typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{not yet supported}}
+ typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{type 'typename ::A<int>' (aka 'A<int>') decomposes into 0}}
struct X { template<typename T> struct A {}; }; // expected-note 8{{template}}
+ // FIXME: We do not yet properly support class template argument deduction
+ // during template instantiation.
template<typename T> void f() {
- (void) typename T::A(0); // expected-error {{not yet supported}}
- (void) typename T::A{0}; // expected-error {{not yet supported}}
- new typename T::A(0); // expected-error {{not yet supported}}
- new typename T::A{0}; // expected-error {{not yet supported}}
- typename T::A a = 0; // expected-error {{not yet supported}}
- const typename T::A b = 0; // expected-error {{not yet supported}}
- if (typename T::A a = 0) {} // expected-error {{not yet supported}}
- for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error 2{{not yet supported}}
+ (void) typename T::A(0); // expected-error {{no viable}}
+ (void) typename T::A{0}; // expected-error {{no viable}}
+ new typename T::A(0); // expected-error {{no viable}}
+ new typename T::A{0}; // expected-error {{no viable}}
+ typename T::A a = 0; // expected-error {{no viable}}
+ const typename T::A b = 0; // expected-error {{no viable}}
+ if (typename T::A a = 0) {} // expected-error {{no viable}}
+ for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error 2{{no viable}}
{(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
{(void)(typename T::A){0};} // expected-error{{refers to class template member}}
@@ -179,7 +187,7 @@ namespace typename_specifier {
{typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
{typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
{typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
- {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{not yet supported}}
+ {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{no viable}}
}
template void f<X>(); // expected-note {{instantiation of}}