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.
llvm-svn: 273600
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 00d5651..8eeaef7 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -10092,10 +10092,10 @@
SizeType, VK_LValue, OK_Ordinary, Loc);
// Construct the loop that copies all elements of this array.
- return S.ActOnForStmt(Loc, Loc, InitStmt,
- S.MakeFullExpr(Comparison),
- nullptr, S.MakeFullDiscardedValueExpr(Increment),
- Loc, Copy.get());
+ return S.ActOnForStmt(
+ Loc, Loc, InitStmt,
+ S.ActOnCondition(nullptr, Loc, Comparison, Sema::ConditionKind::Boolean),
+ S.MakeFullDiscardedValueExpr(Increment), Loc, Copy.get());
}
static StmtResult
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 755d99d..f975b81 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14341,7 +14341,7 @@
}
}
-ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) {
+ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E) {
DiagnoseAssignmentAsCondition(E);
if (ParenExpr *parenE = dyn_cast<ParenExpr>(E))
DiagnoseEqualityWithExtraParens(parenE);
@@ -14371,12 +14371,26 @@
return E;
}
-ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
- Expr *SubExpr) {
+Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc,
+ Expr *SubExpr, ConditionKind CK) {
+ // Empty conditions are valid in for-statements.
if (!SubExpr)
- return ExprError();
+ return ConditionResult();
- return CheckBooleanCondition(SubExpr, Loc);
+ ExprResult Cond;
+ switch (CK) {
+ case ConditionKind::Boolean:
+ Cond = CheckBooleanCondition(Loc, SubExpr);
+ break;
+
+ case ConditionKind::Switch:
+ Cond = CheckSwitchCondition(Loc, SubExpr);
+ break;
+ }
+ if (Cond.isInvalid())
+ return ConditionError();
+
+ return ConditionResult(nullptr, MakeFullExpr(Cond.get(), Loc));
}
namespace {
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index d5e944f..f97b9c9 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3054,11 +3054,21 @@
}
}
+Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar,
+ SourceLocation StmtLoc,
+ ConditionKind CK) {
+ ExprResult E =
+ CheckConditionVariable(cast<VarDecl>(ConditionVar), StmtLoc, CK);
+ if (E.isInvalid())
+ return ConditionError();
+ return ConditionResult(ConditionVar, MakeFullExpr(E.get(), StmtLoc));
+}
+
/// \brief Check the use of the given variable as a C++ condition in an if,
/// while, do-while, or switch statement.
ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,
SourceLocation StmtLoc,
- bool ConvertToBoolean) {
+ ConditionKind CK) {
if (ConditionVar->isInvalidDecl())
return ExprError();
@@ -3082,13 +3092,15 @@
MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));
- if (ConvertToBoolean) {
- Condition = CheckBooleanCondition(Condition.get(), StmtLoc);
- if (Condition.isInvalid())
- return ExprError();
+ switch (CK) {
+ case ConditionKind::Boolean:
+ return CheckBooleanCondition(StmtLoc, Condition.get());
+
+ case ConditionKind::Switch:
+ return CheckSwitchCondition(StmtLoc, Condition.get());
}
- return Condition;
+ llvm_unreachable("unexpected condition kind");
}
/// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 5f28aa3..ca84b8c 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -6826,12 +6826,11 @@
if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
!Condition->isInstantiationDependent() &&
!Condition->containsUnexpandedParameterPack()) {
- ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
- Condition->getExprLoc(), Condition);
+ ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
if (Val.isInvalid())
return nullptr;
- ValExpr = Val.get();
+ ValExpr = MakeFullExpr(Val.get()).get();
}
return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,
@@ -6846,12 +6845,11 @@
if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
!Condition->isInstantiationDependent() &&
!Condition->containsUnexpandedParameterPack()) {
- ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),
- Condition->getExprLoc(), Condition);
+ ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
if (Val.isInvalid())
return nullptr;
- ValExpr = Val.get();
+ ValExpr = MakeFullExpr(Val.get()).get();
}
return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7156cd2..8d5bec8 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -504,39 +504,30 @@
}
StmtResult
-Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
+Sema::ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,
Stmt *thenStmt, SourceLocation ElseLoc,
Stmt *elseStmt) {
- ExprResult CondResult(CondVal.release());
-
- VarDecl *ConditionVar = nullptr;
- if (CondVar) {
- ConditionVar = cast<VarDecl>(CondVar);
- CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);
- CondResult = ActOnFinishFullExpr(CondResult.get(), IfLoc);
- }
- Expr *ConditionExpr = CondResult.getAs<Expr>();
- if (ConditionExpr) {
-
- if (!Diags.isIgnored(diag::warn_comma_operator,
- ConditionExpr->getExprLoc()))
- CommaVisitor(*this).Visit(ConditionExpr);
-
- DiagnoseUnusedExprResult(thenStmt);
-
- if (!elseStmt) {
- DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,
- diag::warn_empty_if_body);
- }
-
- DiagnoseUnusedExprResult(elseStmt);
- } else {
- // Create a dummy Expr for the condition for error recovery
- ConditionExpr = new (Context) OpaqueValueExpr(SourceLocation(),
- Context.BoolTy, VK_RValue);
+ auto CondVal = Cond.get();
+ if (Cond.isInvalid()) {
+ CondVal.first = nullptr;
+ CondVal.second = new (Context)
+ OpaqueValueExpr(SourceLocation(), Context.BoolTy, VK_RValue);
}
- return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,
+ if (!Diags.isIgnored(diag::warn_comma_operator,
+ CondVal.second->getExprLoc()))
+ CommaVisitor(*this).Visit(CondVal.second);
+
+ DiagnoseUnusedExprResult(thenStmt);
+
+ if (!elseStmt) {
+ DiagnoseEmptyStmtBody(CondVal.second->getLocEnd(), thenStmt,
+ diag::warn_empty_if_body);
+ }
+
+ DiagnoseUnusedExprResult(elseStmt);
+
+ return new (Context) IfStmt(Context, IfLoc, CondVal.first, CondVal.second,
thenStmt, ElseLoc, elseStmt);
}
@@ -599,24 +590,7 @@
return expr->getType();
}
-StmtResult
-Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,
- Decl *CondVar) {
- ExprResult CondResult;
-
- VarDecl *ConditionVar = nullptr;
- if (CondVar) {
- ConditionVar = cast<VarDecl>(CondVar);
- CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);
- if (CondResult.isInvalid())
- return StmtError();
-
- Cond = CondResult.get();
- }
-
- if (!Cond)
- return StmtError();
-
+ExprResult Sema::CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond) {
class SwitchConvertDiagnoser : public ICEConvertDiagnoser {
Expr *Cond;
@@ -664,24 +638,24 @@
}
} SwitchDiagnoser(Cond);
- CondResult =
+ ExprResult CondResult =
PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);
- if (CondResult.isInvalid()) return StmtError();
- Cond = CondResult.get();
+ if (CondResult.isInvalid())
+ return ExprError();
// C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.
- CondResult = UsualUnaryConversions(Cond);
- if (CondResult.isInvalid()) return StmtError();
- Cond = CondResult.get();
+ return UsualUnaryConversions(CondResult.get());
+}
- CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);
- if (CondResult.isInvalid())
+StmtResult
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, ConditionResult Cond) {
+ if (Cond.isInvalid())
return StmtError();
- Cond = CondResult.get();
getCurFunction()->setHasBranchIntoScope();
- SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);
+ SwitchStmt *SS =
+ new (Context) SwitchStmt(Context, Cond.get().first, Cond.get().second);
getCurFunction()->SwitchStack.push_back(SS);
return SS;
}
@@ -1242,27 +1216,17 @@
}
}
-StmtResult
-Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,
- Decl *CondVar, Stmt *Body) {
- ExprResult CondResult(Cond.release());
-
- VarDecl *ConditionVar = nullptr;
- if (CondVar) {
- ConditionVar = cast<VarDecl>(CondVar);
- CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);
- CondResult = ActOnFinishFullExpr(CondResult.get(), WhileLoc);
- if (CondResult.isInvalid())
- return StmtError();
- }
- Expr *ConditionExpr = CondResult.get();
- if (!ConditionExpr)
+StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
+ Stmt *Body) {
+ if (Cond.isInvalid())
return StmtError();
- CheckBreakContinueBinding(ConditionExpr);
- if (ConditionExpr &&
- !Diags.isIgnored(diag::warn_comma_operator, ConditionExpr->getExprLoc()))
- CommaVisitor(*this).Visit(ConditionExpr);
+ auto CondVal = Cond.get();
+ CheckBreakContinueBinding(CondVal.second);
+
+ if (CondVal.second &&
+ !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
+ CommaVisitor(*this).Visit(CondVal.second);
DiagnoseUnusedExprResult(Body);
@@ -1270,7 +1234,7 @@
getCurCompoundScope().setHasEmptyLoopBodies();
return new (Context)
- WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);
+ WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc);
}
StmtResult
@@ -1280,7 +1244,7 @@
assert(Cond && "ActOnDoStmt(): missing expression");
CheckBreakContinueBinding(Cond);
- ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);
+ ExprResult CondResult = CheckBooleanCondition(DoLoc, Cond);
if (CondResult.isInvalid())
return StmtError();
Cond = CondResult.get();
@@ -1644,11 +1608,13 @@
}
}
-StmtResult
-Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
- Stmt *First, FullExprArg second, Decl *secondVar,
- FullExprArg third,
- SourceLocation RParenLoc, Stmt *Body) {
+StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
+ Stmt *First, ConditionResult Second,
+ FullExprArg third, SourceLocation RParenLoc,
+ Stmt *Body) {
+ if (Second.isInvalid())
+ return StmtError();
+
if (!getLangOpts().CPlusPlus) {
if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {
// C99 6.8.5p3: The declaration part of a 'for' statement shall only
@@ -1666,26 +1632,18 @@
}
}
- CheckBreakContinueBinding(second.get());
+ CheckBreakContinueBinding(Second.get().second);
CheckBreakContinueBinding(third.get());
- CheckForLoopConditionalStatement(*this, second.get(), third.get(), Body);
+ if (!Second.get().first)
+ CheckForLoopConditionalStatement(*this, Second.get().second, third.get(),
+ Body);
CheckForRedundantIteration(*this, third.get(), Body);
- ExprResult SecondResult(second.release());
- VarDecl *ConditionVar = nullptr;
- if (secondVar) {
- ConditionVar = cast<VarDecl>(secondVar);
- SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);
- SecondResult = ActOnFinishFullExpr(SecondResult.get(), ForLoc);
- if (SecondResult.isInvalid())
- return StmtError();
- }
-
- if (SecondResult.get() &&
+ if (Second.get().second &&
!Diags.isIgnored(diag::warn_comma_operator,
- SecondResult.get()->getExprLoc()))
- CommaVisitor(*this).Visit(SecondResult.get());
+ Second.get().second->getExprLoc()))
+ CommaVisitor(*this).Visit(Second.get().second);
Expr *Third = third.release().getAs<Expr>();
@@ -1696,8 +1654,9 @@
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
- return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,
- Third, Body, ForLoc, LParenLoc, RParenLoc);
+ return new (Context)
+ ForStmt(Context, First, Second.get().second, Second.get().first, Third,
+ Body, ForLoc, LParenLoc, RParenLoc);
}
/// In an Objective C collection iteration statement:
@@ -2384,8 +2343,10 @@
// Build and check __begin != __end expression.
NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,
BeginRef.get(), EndRef.get());
- NotEqExpr = ActOnBooleanCondition(S, ColonLoc, NotEqExpr.get());
- NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
+ if (!NotEqExpr.isInvalid())
+ NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());
+ if (!NotEqExpr.isInvalid())
+ NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
if (NotEqExpr.isInvalid()) {
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
<< RangeLoc << 0 << BeginRangeRef.get()->getType();
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 4bdd9e5..5814197 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -410,6 +410,14 @@
return D;
}
+ /// \brief Transform the specified condition.
+ ///
+ /// By default, this transforms the variable and expression and rebuilds
+ /// the condition.
+ Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
+ Expr *Expr,
+ Sema::ConditionKind Kind);
+
/// \brief Transform the attributes associated with the given declaration and
/// place them on the new declaration.
///
@@ -1166,10 +1174,9 @@
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
- VarDecl *CondVar, Stmt *Then,
- SourceLocation ElseLoc, Stmt *Else) {
- return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);
+ StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::ConditionResult Cond,
+ Stmt *Then, SourceLocation ElseLoc, Stmt *Else) {
+ return getSema().ActOnIfStmt(IfLoc, Cond, Then, ElseLoc, Else);
}
/// \brief Start building a new switch statement.
@@ -1177,9 +1184,8 @@
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
- Expr *Cond, VarDecl *CondVar) {
- return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond,
- CondVar);
+ Sema::ConditionResult Cond) {
+ return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond);
}
/// \brief Attach the body to the switch statement.
@@ -1195,9 +1201,9 @@
///
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
- StmtResult RebuildWhileStmt(SourceLocation WhileLoc, Sema::FullExprArg Cond,
- VarDecl *CondVar, Stmt *Body) {
- return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body);
+ StmtResult RebuildWhileStmt(SourceLocation WhileLoc,
+ Sema::ConditionResult Cond, Stmt *Body) {
+ return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);
}
/// \brief Build a new do-while statement.
@@ -1216,11 +1222,11 @@
/// By default, performs semantic analysis to build the new statement.
/// Subclasses may override this routine to provide different behavior.
StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
- Stmt *Init, Sema::FullExprArg Cond,
- VarDecl *CondVar, Sema::FullExprArg Inc,
- SourceLocation RParenLoc, Stmt *Body) {
+ Stmt *Init, Sema::ConditionResult Cond,
+ Sema::FullExprArg Inc, SourceLocation RParenLoc,
+ Stmt *Body) {
return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
- CondVar, Inc, RParenLoc, Body);
+ Inc, RParenLoc, Body);
}
/// \brief Build a new goto statement.
@@ -3357,6 +3363,31 @@
return false;
}
+template <typename Derived>
+Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
+ SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
+ if (Var) {
+ VarDecl *ConditionVar = cast_or_null<VarDecl>(
+ getDerived().TransformDefinition(Var->getLocation(), Var));
+
+ if (!ConditionVar)
+ return Sema::ConditionError();
+
+ return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
+ }
+
+ if (Expr) {
+ ExprResult CondExpr = getDerived().TransformExpr(Expr);
+
+ if (CondExpr.isInvalid())
+ return Sema::ConditionError();
+
+ return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind);
+ }
+
+ return Sema::ConditionResult();
+}
+
template<typename Derived>
NestedNameSpecifierLoc
TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
@@ -4962,8 +4993,8 @@
if (NoexceptExpr.isInvalid())
return true;
- NoexceptExpr = getSema().CheckBooleanCondition(
- NoexceptExpr.get(), NoexceptExpr.get()->getLocStart());
+ // FIXME: This is bogus, a noexcept expression is not a condition.
+ NoexceptExpr = getSema().CheckBooleanCondition(Loc, NoexceptExpr.get());
if (NoexceptExpr.isInvalid())
return true;
@@ -6195,35 +6226,10 @@
StmtResult
TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
// Transform the condition
- ExprResult Cond;
- VarDecl *ConditionVar = nullptr;
- if (S->getConditionVariable()) {
- ConditionVar
- = cast_or_null<VarDecl>(
- getDerived().TransformDefinition(
- S->getConditionVariable()->getLocation(),
- S->getConditionVariable()));
- if (!ConditionVar)
- return StmtError();
- } else {
- Cond = getDerived().TransformExpr(S->getCond());
-
- if (Cond.isInvalid())
- return StmtError();
-
- // Convert the condition to a boolean value.
- if (S->getCond()) {
- ExprResult CondE = getSema().ActOnBooleanCondition(nullptr, S->getIfLoc(),
- Cond.get());
- if (CondE.isInvalid())
- return StmtError();
-
- Cond = CondE.get();
- }
- }
-
- Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get(), S->getIfLoc()));
- if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+ Sema::ConditionResult Cond = getDerived().TransformCondition(
+ S->getIfLoc(), S->getConditionVariable(), S->getCond(),
+ Sema::ConditionKind::Boolean);
+ if (Cond.isInvalid())
return StmtError();
// Transform the "then" branch.
@@ -6237,14 +6243,12 @@
return StmtError();
if (!getDerived().AlwaysRebuild() &&
- FullCond.get() == S->getCond() &&
- ConditionVar == S->getConditionVariable() &&
+ Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
Then.get() == S->getThen() &&
Else.get() == S->getElse())
return S;
- return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
- Then.get(),
+ return getDerived().RebuildIfStmt(S->getIfLoc(), Cond, Then.get(),
S->getElseLoc(), Else.get());
}
@@ -6252,27 +6256,15 @@
StmtResult
TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
// Transform the condition.
- ExprResult Cond;
- VarDecl *ConditionVar = nullptr;
- if (S->getConditionVariable()) {
- ConditionVar
- = cast_or_null<VarDecl>(
- getDerived().TransformDefinition(
- S->getConditionVariable()->getLocation(),
- S->getConditionVariable()));
- if (!ConditionVar)
- return StmtError();
- } else {
- Cond = getDerived().TransformExpr(S->getCond());
-
- if (Cond.isInvalid())
- return StmtError();
- }
+ Sema::ConditionResult Cond = getDerived().TransformCondition(
+ S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
+ Sema::ConditionKind::Switch);
+ if (Cond.isInvalid())
+ return StmtError();
// Rebuild the switch statement.
StmtResult Switch
- = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),
- ConditionVar);
+ = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond);
if (Switch.isInvalid())
return StmtError();
@@ -6290,36 +6282,10 @@
StmtResult
TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
// Transform the condition
- ExprResult Cond;
- VarDecl *ConditionVar = nullptr;
- if (S->getConditionVariable()) {
- ConditionVar
- = cast_or_null<VarDecl>(
- getDerived().TransformDefinition(
- S->getConditionVariable()->getLocation(),
- S->getConditionVariable()));
- if (!ConditionVar)
- return StmtError();
- } else {
- Cond = getDerived().TransformExpr(S->getCond());
-
- if (Cond.isInvalid())
- return StmtError();
-
- if (S->getCond()) {
- // Convert the condition to a boolean value.
- ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,
- S->getWhileLoc(),
- Cond.get());
- if (CondE.isInvalid())
- return StmtError();
- Cond = CondE;
- }
- }
-
- Sema::FullExprArg FullCond(
- getSema().MakeFullExpr(Cond.get(), S->getWhileLoc()));
- if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+ Sema::ConditionResult Cond = getDerived().TransformCondition(
+ S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
+ Sema::ConditionKind::Boolean);
+ if (Cond.isInvalid())
return StmtError();
// Transform the body
@@ -6328,13 +6294,11 @@
return StmtError();
if (!getDerived().AlwaysRebuild() &&
- FullCond.get() == S->getCond() &&
- ConditionVar == S->getConditionVariable() &&
+ Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
Body.get() == S->getBody())
return Owned(S);
- return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,
- ConditionVar, Body.get());
+ return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get());
}
template<typename Derived>
@@ -6374,37 +6338,10 @@
getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
// Transform the condition
- ExprResult Cond;
- VarDecl *ConditionVar = nullptr;
- if (S->getConditionVariable()) {
- ConditionVar
- = cast_or_null<VarDecl>(
- getDerived().TransformDefinition(
- S->getConditionVariable()->getLocation(),
- S->getConditionVariable()));
- if (!ConditionVar)
- return StmtError();
- } else {
- Cond = getDerived().TransformExpr(S->getCond());
-
- if (Cond.isInvalid())
- return StmtError();
-
- if (S->getCond()) {
- // Convert the condition to a boolean value.
- ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,
- S->getForLoc(),
- Cond.get());
- if (CondE.isInvalid())
- return StmtError();
-
- Cond = CondE.get();
- }
- }
-
- Sema::FullExprArg FullCond(
- getSema().MakeFullExpr(Cond.get(), S->getForLoc()));
- if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
+ Sema::ConditionResult Cond = getDerived().TransformCondition(
+ S->getForLoc(), S->getConditionVariable(), S->getCond(),
+ Sema::ConditionKind::Boolean);
+ if (Cond.isInvalid())
return StmtError();
// Transform the increment
@@ -6423,14 +6360,14 @@
if (!getDerived().AlwaysRebuild() &&
Init.get() == S->getInit() &&
- FullCond.get() == S->getCond() &&
+ Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
Inc.get() == S->getInc() &&
Body.get() == S->getBody())
return S;
return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
- Init.get(), FullCond, ConditionVar,
- FullInc, S->getRParenLoc(), Body.get());
+ Init.get(), Cond, FullInc,
+ S->getRParenLoc(), Body.get());
}
template<typename Derived>
@@ -6924,7 +6861,7 @@
if (Cond.isInvalid())
return StmtError();
if (Cond.get())
- Cond = SemaRef.CheckBooleanCondition(Cond.get(), S->getColonLoc());
+ Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
if (Cond.isInvalid())
return StmtError();
if (Cond.get())