diff options
author | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2015-06-25 00:23:39 +0000 |
---|---|---|
committer | Hubert Tong <hubert.reinterpretcast@gmail.com> | 2015-06-25 00:23:39 +0000 |
commit | ec3cb573f522cf6748eae8afa5b33f9b65c33d6e (patch) | |
tree | 2198fc7989005e81e19307e2c1214fff7284ae37 /clang/lib/Parse | |
parent | 6a75acb1c2fde67614d86084d09f9debc0425d67 (diff) | |
download | bcm5719-llvm-ec3cb573f522cf6748eae8afa5b33f9b65c33d6e.tar.gz bcm5719-llvm-ec3cb573f522cf6748eae8afa5b33f9b65c33d6e.zip |
[Concepts] Parsing of requires-clause in template-declaration
Summary:
This change implements parse-only acceptance of the optional
requires-clause in a template-declaration. Diagnostic testing is added
for cases where the grammar is ambiguous with the expectation that the
longest token sequence which matches the syntax of a
constraint-expression is consumed without backtracking.
Reviewers: faisalv, fraggamuffin, rsmith
Reviewed By: rsmith
Subscribers: cfe-commits
Differential Revision: http://reviews.llvm.org/D10462
llvm-svn: 240611
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 13 |
2 files changed, 30 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index da759c76522..36a302e52e6 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -205,6 +205,24 @@ ExprResult Parser::ParseConstantExpression(TypeCastState isTypeCast) { return Actions.ActOnConstantExpression(Res); } +/// \brief Parse a constraint-expression. +/// +/// \verbatim +/// constraint-expression: [Concepts TS temp.constr.decl p1] +/// logical-or-expression +/// \endverbatim +ExprResult Parser::ParseConstraintExpression() { + // FIXME: this may erroneously consume a function-body as the braced + // initializer list of a compound literal + // + // FIXME: this may erroneously consume a parenthesized rvalue reference + // declarator as a parenthesized address-of-label expression + ExprResult LHS(ParseCastExpression(/*isUnaryExpression=*/false)); + ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr)); + + return Res; +} + bool Parser::isNotExpressionStart() { tok::TokenKind K = Tok.getKind(); if (K == tok::l_brace || K == tok::r_brace || diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index a8116785fdf..2a9becbc857 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -116,7 +116,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, SmallVector<Decl*, 4> TemplateParams; if (ParseTemplateParameters(CurTemplateDepthTracker.getDepth(), TemplateParams, LAngleLoc, RAngleLoc)) { - // Skip until the semi-colon or a }. + // Skip until the semi-colon or a '}'. SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); TryConsumeToken(tok::semi); return nullptr; @@ -132,6 +132,17 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, if (!TemplateParams.empty()) { isSpecialization = false; ++CurTemplateDepthTracker; + + if (TryConsumeToken(tok::kw_requires)) { + ExprResult ER = + Actions.CorrectDelayedTyposInExpr(ParseConstraintExpression()); + if (!ER.isUsable()) { + // Skip until the semi-colon or a '}'. + SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch); + TryConsumeToken(tok::semi); + return nullptr; + } + } } else { LastParamListWasEmpty = true; } |