summaryrefslogtreecommitdiffstats
path: root/lib/Parse/ParseExprCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-06-23 19:02:52 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-06-23 19:02:52 +0000
commita64a49776e41ee8edeb24caf928e489f7b1df0e5 (patch)
tree6b775601632fc52f916af0ee057604c7d1e0fede /lib/Parse/ParseExprCXX.cpp
parentc4e95c76197d386452a9b4524a4a5429b32bce72 (diff)
Re-commit r273548, reverted in r273589, with a fix to not produce
-Wfor-loop-analysis warnings for a for-loop with a condition variable. In such a case, the loop condition variable is modified on each iteration of the loop by definition. Original commit message: Rearrange condition handling so that semantic checks on a condition variable are performed before the other substatements of the construct are parsed, rather than deferring them until the end. This allows better error recovery from semantic errors in the condition, improves diagnostic order, and is a prerequisite for C++17 constexpr if. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@273600 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseExprCXX.cpp')
-rw-r--r--lib/Parse/ParseExprCXX.cpp44
1 files changed, 15 insertions, 29 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index b0740970d8..00f20e5e7b 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1726,27 +1726,19 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
/// '=' assignment-expression
///
-/// \param ExprOut if the condition was parsed as an expression, the parsed
-/// expression.
-///
-/// \param DeclOut if the condition was parsed as a declaration, the parsed
-/// declaration.
-///
/// \param Loc The location of the start of the statement that requires this
/// condition, e.g., the "for" in a for loop.
///
/// \param ConvertToBoolean Whether the condition expression should be
/// converted to a boolean value.
///
-/// \returns true if there was a parsing, false otherwise.
-bool Parser::ParseCXXCondition(ExprResult &ExprOut,
- Decl *&DeclOut,
- SourceLocation Loc,
- bool ConvertToBoolean) {
+/// \returns The parsed condition.
+Sema::ConditionResult Parser::ParseCXXCondition(SourceLocation Loc,
+ Sema::ConditionKind CK) {
if (Tok.is(tok::code_completion)) {
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);
cutOffParsing();
- return true;
+ return Sema::ConditionError();
}
ParsedAttributesWithRange attrs(AttrFactory);
@@ -1756,16 +1748,11 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
ProhibitAttributes(attrs);
// Parse the expression.
- ExprOut = ParseExpression(); // expression
- DeclOut = nullptr;
- if (ExprOut.isInvalid())
- return true;
+ ExprResult Expr = ParseExpression(); // expression
+ if (Expr.isInvalid())
+ return Sema::ConditionError();
- // If required, convert to a boolean value.
- if (ConvertToBoolean)
- ExprOut
- = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get());
- return ExprOut.isInvalid();
+ return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK);
}
// type-specifier-seq
@@ -1783,7 +1770,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
ExprResult AsmLabel(ParseSimpleAsm(&Loc));
if (AsmLabel.isInvalid()) {
SkipUntil(tok::semi, StopAtSemi);
- return true;
+ return Sema::ConditionError();
}
DeclaratorInfo.setAsmLabel(AsmLabel.get());
DeclaratorInfo.SetRangeEnd(Loc);
@@ -1795,8 +1782,9 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
// Type-check the declaration itself.
DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),
DeclaratorInfo);
- DeclOut = Dcl.get();
- ExprOut = ExprError();
+ if (Dcl.isInvalid())
+ return Sema::ConditionError();
+ Decl *DeclOut = Dcl.get();
// '=' assignment-expression
// If a '==' or '+=' is found, suggest a fixit to '='.
@@ -1816,12 +1804,11 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
SourceLocation LParen = ConsumeParen(), RParen = LParen;
if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))
RParen = ConsumeParen();
- Diag(DeclOut ? DeclOut->getLocation() : LParen,
+ Diag(DeclOut->getLocation(),
diag::err_expected_init_in_condition_lparen)
<< SourceRange(LParen, RParen);
} else {
- Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(),
- diag::err_expected_init_in_condition);
+ Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);
}
if (!InitExpr.isInvalid())
@@ -1834,8 +1821,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
// (This is currently handled by Sema).
Actions.FinalizeDeclaration(DeclOut);
-
- return false;
+ return Actions.ActOnConditionVariable(DeclOut, Loc, CK);
}
/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.