[C++20] add Basic consteval specifier
Summary:
this revision adds Lexing, Parsing and Basic Semantic for the consteval specifier as specified by http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1073r3.html
with this patch, the consteval specifier is treated as constexpr but can only be applied to function declaration.
Changes:
- add the consteval keyword.
- add parsing of consteval specifier for normal declarations and lambdas expressions.
- add the whether a declaration is constexpr is now represented by and enum everywhere except for variable because they can't be consteval.
- adapt diagnostic about constexpr to print constexpr or consteval depending on the case.
- add tests for basic semantic.
Reviewers: rsmith, martong, shafik
Reviewed By: rsmith
Subscribers: eraman, efriedma, rnkovacs, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D61790
llvm-svn: 363362
diff --git a/clang/test/SemaCXX/cxx2a-compat.cpp b/clang/test/SemaCXX/cxx2a-compat.cpp
index 49db0bc..c8d22b7 100644
--- a/clang/test/SemaCXX/cxx2a-compat.cpp
+++ b/clang/test/SemaCXX/cxx2a-compat.cpp
@@ -56,4 +56,13 @@
#if !defined(__cpp_conditional_explicit) || __cpp_conditional_explicit != 201806L
#error "the feature test macro __cpp_conditional_explicit isn't correct"
#endif
+#endif
+
+auto l = []() consteval {};
+int consteval();
+#if __cplusplus <= 201703L
+// expected-warning@-3 {{'consteval' is a keyword in C++2a}}
+// expected-error@-4 {{expected body of lambda expression}}
+#else
+// expected-error@-5 {{expected unqualified-id}}
#endif
\ No newline at end of file
diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp
new file mode 100644
index 0000000..c531b92
--- /dev/null
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -std=c++2a -fsyntax-only %s -verify
+
+namespace basic_sema {
+
+consteval int f1(int i) {
+ return i;
+}
+
+consteval constexpr int f2(int i) {
+ //expected-error@-1 {{cannot combine}}
+ return i;
+}
+
+constexpr auto l_eval = [](int i) consteval {
+
+ return i;
+};
+
+constexpr consteval int f3(int i) {
+ //expected-error@-1 {{cannot combine}}
+ return i;
+}
+
+struct A {
+ consteval int f1(int i) const {
+ return i;
+ }
+ consteval A(int i);
+ consteval A() = default;
+ consteval ~A() = default; // expected-error {{destructor cannot be marked consteval}}
+};
+
+consteval struct B {}; // expected-error {{struct cannot be marked consteval}}
+
+consteval typedef B b; // expected-error {{typedef cannot be consteval}}
+
+consteval int redecl() {return 0;} // expected-note {{previous declaration is here}}
+constexpr int redecl() {return 0;} // expected-error {{constexpr declaration of 'redecl' follows consteval declaration}}
+
+consteval int i = 0; // expected-error {{consteval can only be used in function declarations}}
+
+consteval int; // expected-error {{consteval can only be used in function declarations}}
+
+consteval int f1() {} // expected-error {{no return statement in consteval function}}
+
+struct C {
+ C() {}
+};
+
+struct D {
+ C c;
+ consteval D() = default; // expected-error {{cannot be consteval}}
+};
+}
+
+consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
+ return 0;
+}