diff options
author | Gauthier Harnisch <tyker1@outlook.com> | 2019-06-14 08:56:20 +0000 |
---|---|---|
committer | Gauthier Harnisch <tyker1@outlook.com> | 2019-06-14 08:56:20 +0000 |
commit | 796ed03b841289a5ca75a3046b09d6b8222f01ef (patch) | |
tree | 3592b4b7315dcf883f35915dec065aca170d4f53 /clang/lib/Sema/DeclSpec.cpp | |
parent | b63e577444d3617843e0835feb7aa457fee79f97 (diff) | |
download | llvm-796ed03b841289a5ca75a3046b09d6b8222f01ef.tar.gz |
[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
Diffstat (limited to 'clang/lib/Sema/DeclSpec.cpp')
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 08c3b0ff3273..21d7f6bd426c 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -564,6 +564,15 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, llvm_unreachable("Unknown typespec!"); } +const char *DeclSpec::getSpecifierName(ConstexprSpecKind C) { + switch (C) { + case CSK_unspecified: return "unspecified"; + case CSK_constexpr: return "constexpr"; + case CSK_consteval: return "consteval"; + } + llvm_unreachable("Unknown ConstexprSpecKind"); +} + const char *DeclSpec::getSpecifierName(TQ T) { switch (T) { case DeclSpec::TQ_unspecified: return "unspecified"; @@ -1025,16 +1034,17 @@ bool DeclSpec::setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, return false; } -bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, +bool DeclSpec::SetConstexprSpec(ConstexprSpecKind ConstexprKind, + SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID) { - // 'constexpr constexpr' is ok, but warn as this is likely not what the user - // intended. - if (Constexpr_specified) { + if (ConstexprSpecifier != CSK_unspecified) { + if (ConstexprSpecifier == CSK_consteval || ConstexprKind == CSK_consteval) + return BadSpecifier(ConstexprKind, ConstexprSpecifier, PrevSpec, DiagID); DiagID = diag::warn_duplicate_declspec; PrevSpec = "constexpr"; return true; } - Constexpr_specified = true; + ConstexprSpecifier = ConstexprKind; ConstexprLoc = Loc; return false; } @@ -1280,9 +1290,10 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { else if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type) << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); - if (Constexpr_specified) + if (getConstexprSpecifier() == CSK_constexpr) S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr); - + if (getConstexprSpecifier() == CSK_consteval) + S.Diag(ConstexprLoc, diag::warn_cxx20_compat_consteval); // C++ [class.friend]p6: // No storage-class-specifier shall appear in the decl-specifier-seq // of a friend declaration. |