[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/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 5589297..2c9045d 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2487,8 +2487,9 @@
}
// Issue diagnostic and remove constexpr specifier if present.
- if (DS.isConstexprSpecified() && DSC != DeclSpecContext::DSC_condition) {
- Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr);
+ if (DS.hasConstexprSpecifier() && DSC != DeclSpecContext::DSC_condition) {
+ Diag(DS.getConstexprSpecLoc(), diag::err_typename_invalid_constexpr)
+ << (DS.getConstexprSpecifier() == CSK_consteval);
DS.ClearConstexprSpec();
}
}
@@ -3626,7 +3627,12 @@
// constexpr
case tok::kw_constexpr:
- isInvalid = DS.SetConstexprSpec(Loc, PrevSpec, DiagID);
+ isInvalid = DS.SetConstexprSpec(CSK_constexpr, Loc, PrevSpec, DiagID);
+ break;
+
+ // consteval
+ case tok::kw_consteval:
+ isInvalid = DS.SetConstexprSpec(CSK_consteval, Loc, PrevSpec, DiagID);
break;
// type-specifier
@@ -5031,6 +5037,9 @@
case tok::annot_decltype:
case tok::kw_constexpr:
+ // C++20 consteval.
+ case tok::kw_consteval:
+
// C11 _Atomic
case tok::kw__Atomic:
return true;
@@ -6267,7 +6276,7 @@
Actions.CurContext->isRecord());
Qualifiers Q = Qualifiers::fromCVRUMask(DS.getTypeQualifiers());
- if (D.getDeclSpec().isConstexprSpecified() && !getLangOpts().CPlusPlus14)
+ if (D.getDeclSpec().hasConstexprSpecifier() && !getLangOpts().CPlusPlus14)
Q.addConst();
// FIXME: Collect C++ address spaces.
// If there are multiple different address spaces, the source is invalid.