<div dir="ltr">Thanks!</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 23, 2016 at 12:02 PM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Thu Jun 23 14:02:52 2016<br>
New Revision: 273600<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=273600&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=273600&view=rev</a><br>
Log:<br>
Re-commit r273548, reverted in r273589, with a fix to not produce<br>
-Wfor-loop-analysis warnings for a for-loop with a condition variable. In such<br>
a case, the loop condition variable is modified on each iteration of the loop<br>
by definition.<br>
<br>
Original commit message:<br>
<br>
Rearrange condition handling so that semantic checks on a condition variable<br>
are performed before the other substatements of the construct are parsed,<br>
rather than deferring them until the end. This allows better error recovery<br>
from semantic errors in the condition, improves diagnostic order, and is a<br>
prerequisite for C++17 constexpr if.<br>
<br>
Modified:<br>
  cfe/trunk/include/clang/Parse/Parser.h<br>
  cfe/trunk/include/clang/Sema/Sema.h<br>
  cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
  cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
  cfe/trunk/lib/Parse/ParseStmt.cpp<br>
  cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
  cfe/trunk/lib/Sema/SemaExpr.cpp<br>
  cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
  cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
  cfe/trunk/lib/Sema/SemaStmt.cpp<br>
  cfe/trunk/lib/Sema/TreeTransform.h<br>
  cfe/trunk/test/FixIt/fixit-vexing-parse.cpp<br>
  cfe/trunk/test/Parser/cxx0x-condition.cpp<br>
  cfe/trunk/test/SemaCXX/crashes.cpp<br>
  cfe/trunk/test/SemaCXX/for-range-examples.cpp<br>
  cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a><br>
<br>
Modified: cfe/trunk/include/clang/Parse/Parser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Parse/Parser.h (original)<br>
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Jun 23 14:02:52 2016<br>
@@ -1588,8 +1588,8 @@ private:<br>
<br>
  //===--------------------------------------------------------------------===//<br>
  // C++ if/switch/while condition expression.<br>
-Â bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation Loc, bool ConvertToBoolean);<br>
+Â Sema::ConditionResult ParseCXXCondition(SourceLocation Loc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionKind CK);<br>
<br>
  //===--------------------------------------------------------------------===//<br>
  // C++ Coroutines<br>
@@ -1680,10 +1680,9 @@ private:<br>
                   unsigned ScopeFlags);<br>
  void ParseCompoundStatementLeadingPragmas();<br>
  StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);<br>
-Â bool ParseParenExprOrCondition(ExprResult &ExprResult,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Decl *&DeclResult,<br>
+Â bool ParseParenExprOrCondition(Sema::ConditionResult &CondResult,<br>
                 SourceLocation Loc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â bool ConvertToBoolean);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionKind CK);<br>
  StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc);<br>
  StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc);<br>
  StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc);<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jun 23 14:02:52 2016<br>
@@ -3298,6 +3298,7 @@ public:<br>
 public:<br>
  class FullExprArg {<br>
  public:<br>
+Â Â FullExprArg() : E(nullptr) { }<br>
   FullExprArg(Sema &actions) : E(nullptr) { }<br>
<br>
   ExprResult release() {<br>
@@ -3391,27 +3392,23 @@ public:<br>
                 ArrayRef<const Attr*> Attrs,<br>
                 Stmt *SubStmt);<br>
<br>
-Â StmtResult ActOnIfStmt(SourceLocation IfLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â FullExprArg CondVal, Decl *CondVar,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *ThenVal,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation ElseLoc, Stmt *ElseVal);<br>
+Â class ConditionResult;<br>
+Â StmtResult ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal);<br>
  StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Decl *CondVar);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionResult Cond);<br>
  StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc,<br>
                      Stmt *Switch, Stmt *Body);<br>
-Â StmtResult ActOnWhileStmt(SourceLocation WhileLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â FullExprArg Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Decl *CondVar, Stmt *Body);<br>
+Â StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *Body);<br>
  StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation WhileLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation CondLParen, Expr *Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation CondRParen);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation WhileLoc, SourceLocation CondLParen,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *Cond, SourceLocation CondRParen);<br>
<br>
  StmtResult ActOnForStmt(SourceLocation ForLoc,<br>
              SourceLocation LParenLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *First, FullExprArg Second,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Decl *SecondVar,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *First,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionResult Second,<br>
              FullExprArg Third,<br>
              SourceLocation RParenLoc,<br>
              Stmt *Body);<br>
@@ -4801,11 +4798,6 @@ public:<br>
               bool WarnOnNonAbstractTypes,<br>
               SourceLocation DtorLoc);<br>
<br>
-Â DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);<br>
-Â ExprResult CheckConditionVariable(VarDecl *ConditionVar,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation StmtLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â bool ConvertToBoolean);<br>
-<br>
  ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen,<br>
                Expr *Operand, SourceLocation RParen);<br>
  ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand,<br>
@@ -8923,6 +8915,46 @@ public:<br>
  /// type, and if so, emit a note describing what happened.<br>
  void EmitRelatedResultTypeNoteForReturn(QualType destType);<br>
<br>
+Â class ConditionResult {<br>
+Â Â Decl *ConditionVar;<br>
+Â Â FullExprArg Condition;<br>
+Â Â bool Invalid;<br>
+<br>
+Â Â friend class Sema;<br>
+Â Â ConditionResult(Decl *ConditionVar, FullExprArg Condition)<br>
+Â Â Â Â : ConditionVar(ConditionVar), Condition(Condition), Invalid(false) {}<br>
+Â Â explicit ConditionResult(bool Invalid)<br>
+Â Â Â Â : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid) {}<br>
+<br>
+Â public:<br>
+Â Â ConditionResult() : ConditionResult(false) {}<br>
+Â Â bool isInvalid() const { return Invalid; }<br>
+Â Â std::pair<VarDecl *, Expr *> get() const {<br>
+Â Â Â return std::make_pair(cast_or_null<VarDecl>(ConditionVar),<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Condition.get());<br>
+Â Â }<br>
+Â };<br>
+Â static ConditionResult ConditionError() { return ConditionResult(true); }<br>
+<br>
+Â enum class ConditionKind {<br>
+Â Â Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'.<br>
+  Switch  ///< An integral condition for a 'switch' statement.<br>
+Â };<br>
+<br>
+Â ConditionResult ActOnCondition(Scope *S, SourceLocation Loc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *SubExpr, ConditionKind CK);<br>
+<br>
+Â ConditionResult ActOnConditionVariable(Decl *ConditionVar,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation StmtLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionKind CK);<br>
+<br>
+Â DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D);<br>
+<br>
+Â ExprResult CheckConditionVariable(VarDecl *ConditionVar,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation StmtLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionKind CK);<br>
+Â ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond);<br>
+<br>
  /// CheckBooleanCondition - Diagnose problems involving the use of<br>
  /// the given expression as a boolean condition (e.g. in an if<br>
  /// statement). Also performs the standard function and array<br>
@@ -8931,10 +8963,7 @@ public:<br>
  /// \param Loc - A location associated with the condition, e.g. the<br>
  /// 'if' keyword.<br>
  /// \return true iff there were any errors<br>
-Â ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc);<br>
-<br>
-Â ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *SubExpr);<br>
+Â ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E);<br>
<br>
  /// DiagnoseAssignmentAsCondition - Given that an expression is<br>
  /// being used as a boolean condition, warn if it's an assignment.<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Jun 23 14:02:52 2016<br>
@@ -3420,10 +3420,11 @@ Parser::tryParseExceptionSpecification(b<br>
   NoexceptExpr = ParseConstantExpression();<br>
   T.consumeClose();<br>
   // The argument must be contextually convertible to bool. We use<br>
-Â Â // ActOnBooleanCondition for this purpose.<br>
+Â Â // CheckBooleanCondition for this purpose.<br>
+Â Â // FIXME: Add a proper Sema entry point for this.<br>
   if (!NoexceptExpr.isInvalid()) {<br>
-Â Â Â NoexceptExpr = Actions.ActOnBooleanCondition(getCurScope(), KeywordLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â NoexceptExpr.get());<br>
+Â Â Â NoexceptExpr =<br>
+Â Â Â Â Â Actions.CheckBooleanCondition(KeywordLoc, NoexceptExpr.get());<br>
    NoexceptRange = SourceRange(KeywordLoc, T.getCloseLocation());<br>
   } else {<br>
    NoexceptType = EST_None;<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jun 23 14:02:52 2016<br>
@@ -1726,27 +1726,19 @@ Parser::ParseCXXTypeConstructExpression(<br>
 /// [GNU]  type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]<br>
 ///       '=' assignment-expression<br>
 ///<br>
-/// \param ExprOut if the condition was parsed as an expression, the parsed<br>
-/// expression.<br>
-///<br>
-/// \param DeclOut if the condition was parsed as a declaration, the parsed<br>
-/// declaration.<br>
-///<br>
 /// \param Loc The location of the start of the statement that requires this<br>
 /// condition, e.g., the "for" in a for loop.<br>
 ///<br>
 /// \param ConvertToBoolean Whether the condition expression should be<br>
 /// converted to a boolean value.<br>
 ///<br>
-/// \returns true if there was a parsing, false otherwise.<br>
-bool Parser::ParseCXXCondition(ExprResult &ExprOut,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Decl *&DeclOut,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation Loc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â bool ConvertToBoolean) {<br>
+/// \returns The parsed condition.<br>
+Sema::ConditionResult Parser::ParseCXXCondition(SourceLocation Loc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionKind CK) {<br>
  if (Tok.is(tok::code_completion)) {<br>
   Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition);<br>
   cutOffParsing();<br>
-Â Â return true;<br>
+Â Â return Sema::ConditionError();<br>
  }<br>
<br>
  ParsedAttributesWithRange attrs(AttrFactory);<br>
@@ -1756,16 +1748,11 @@ bool Parser::ParseCXXCondition(ExprResul<br>
   ProhibitAttributes(attrs);<br>
<br>
   // Parse the expression.<br>
-Â Â ExprOut = ParseExpression(); // expression<br>
-Â Â DeclOut = nullptr;<br>
-Â Â if (ExprOut.isInvalid())<br>
-Â Â Â return true;<br>
-<br>
-Â Â // If required, convert to a boolean value.<br>
-Â Â if (ConvertToBoolean)<br>
-Â Â Â ExprOut<br>
-Â Â Â Â = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get());<br>
-Â Â return ExprOut.isInvalid();<br>
+Â Â ExprResult Expr = ParseExpression(); // expression<br>
+Â Â if (Expr.isInvalid())<br>
+Â Â Â return Sema::ConditionError();<br>
+<br>
+Â Â return Actions.ActOnCondition(getCurScope(), Loc, Expr.get(), CK);<br>
  }<br>
<br>
  // type-specifier-seq<br>
@@ -1783,7 +1770,7 @@ bool Parser::ParseCXXCondition(ExprResul<br>
   ExprResult AsmLabel(ParseSimpleAsm(&Loc));<br>
   if (AsmLabel.isInvalid()) {<br>
    SkipUntil(tok::semi, StopAtSemi);<br>
-Â Â Â return true;<br>
+Â Â Â return Sema::ConditionError();<br>
   }<br>
   DeclaratorInfo.setAsmLabel(AsmLabel.get());<br>
   DeclaratorInfo.SetRangeEnd(Loc);<br>
@@ -1795,8 +1782,9 @@ bool Parser::ParseCXXCondition(ExprResul<br>
  // Type-check the declaration itself.<br>
  DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),<br>
                             DeclaratorInfo);<br>
-Â DeclOut = Dcl.get();<br>
-Â ExprOut = ExprError();<br>
+Â if (Dcl.isInvalid())<br>
+Â Â return Sema::ConditionError();<br>
+Â Decl *DeclOut = Dcl.get();<br>
<br>
  // '=' assignment-expression<br>
  // If a '==' or '+=' is found, suggest a fixit to '='.<br>
@@ -1816,12 +1804,11 @@ bool Parser::ParseCXXCondition(ExprResul<br>
   SourceLocation LParen = ConsumeParen(), RParen = LParen;<br>
   if (SkipUntil(tok::r_paren, StopAtSemi | StopBeforeMatch))<br>
    RParen = ConsumeParen();<br>
-Â Â Diag(DeclOut ? DeclOut->getLocation() : LParen,<br>
+Â Â Diag(DeclOut->getLocation(),<br>
     diag::err_expected_init_in_condition_lparen)<br>
    << SourceRange(LParen, RParen);<br>
  } else {<br>
-Â Â Diag(DeclOut ? DeclOut->getLocation() : Tok.getLocation(),<br>
-Â Â Â Â Â diag::err_expected_init_in_condition);<br>
+Â Â Diag(DeclOut->getLocation(), diag::err_expected_init_in_condition);<br>
  }<br>
<br>
  if (!InitExpr.isInvalid())<br>
@@ -1834,8 +1821,7 @@ bool Parser::ParseCXXCondition(ExprResul<br>
  // (This is currently handled by Sema).<br>
<br>
  Actions.FinalizeDeclaration(DeclOut);<br>
-<br>
-Â return false;<br>
+Â return Actions.ActOnConditionVariable(DeclOut, Loc, CK);<br>
 }<br>
<br>
 /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Jun 23 14:02:52 2016<br>
@@ -1052,29 +1052,28 @@ StmtResult Parser::ParseCompoundStatemen<br>
 /// should try to recover harder. It returns false if the condition is<br>
 /// successfully parsed. Note that a successful parse can still have semantic<br>
 /// errors in the condition.<br>
-bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Decl *&DeclResult,<br>
+bool Parser::ParseParenExprOrCondition(Sema::ConditionResult &Cond,<br>
                    SourceLocation Loc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â bool ConvertToBoolean) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionKind CK) {<br>
  BalancedDelimiterTracker T(*this, tok::l_paren);<br>
  T.consumeOpen();<br>
<br>
  if (getLangOpts().CPlusPlus)<br>
-Â Â ParseCXXCondition(ExprResult, DeclResult, Loc, ConvertToBoolean);<br>
+Â Â Cond = ParseCXXCondition(Loc, CK);<br>
  else {<br>
-Â Â ExprResult = ParseExpression();<br>
-Â Â DeclResult = nullptr;<br>
+Â Â ExprResult CondExpr = ParseExpression();<br>
<br>
   // If required, convert to a boolean value.<br>
-Â Â if (!ExprResult.isInvalid() && ConvertToBoolean)<br>
-Â Â Â ExprResult<br>
-Â Â Â Â = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get());<br>
+Â Â if (CondExpr.isInvalid())<br>
+Â Â Â Cond = Sema::ConditionError();<br>
+Â Â else<br>
+Â Â Â Cond = Actions.ActOnCondition(getCurScope(), Loc, CondExpr.get(), CK);<br>
  }<br>
<br>
  // If the parser was confused by the condition and we don't have a ')', try to<br>
  // recover by skipping ahead to a semi and bailing out. If condexp is<br>
  // semantically invalid but we have well formed code, keep going.<br>
-Â if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) {<br>
+Â if (Cond.isInvalid() && Tok.isNot(tok::r_paren)) {<br>
   SkipUntil(tok::semi);<br>
   // Skipping may have stopped if it found the containing ')'. If so, we can<br>
   // continue parsing the if statement.<br>
@@ -1132,13 +1131,10 @@ StmtResult Parser::ParseIfStatement(Sour<br>
  ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX);<br>
<br>
  // Parse the condition.<br>
-Â ExprResult CondExp;<br>
-Â Decl *CondVar = nullptr;<br>
-Â if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true))<br>
+Â Sema::ConditionResult Cond;<br>
+Â if (ParseParenExprOrCondition(Cond, IfLoc, Sema::ConditionKind::Boolean))<br>
   return StmtError();<br>
<br>
-Â FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get(), IfLoc));<br>
-<br>
  // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if<br>
  // there is no compound stmt. C90 does not have this clause. We only do this<br>
  // if the body isn't a compound statement to avoid push/pop in common cases.<br>
@@ -1221,8 +1217,8 @@ StmtResult Parser::ParseIfStatement(Sour<br>
  if (ElseStmt.isInvalid())<br>
   ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc);<br>
<br>
-Â return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ElseLoc, ElseStmt.get());<br>
+Â return Actions.ActOnIfStmt(IfLoc, Cond, ThenStmt.get(), ElseLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ElseStmt.get());<br>
 }<br>
<br>
 /// ParseSwitchStatement<br>
@@ -1259,13 +1255,11 @@ StmtResult Parser::ParseSwitchStatement(<br>
  ParseScope SwitchScope(this, ScopeFlags);<br>
<br>
  // Parse the condition.<br>
-Â ExprResult Cond;<br>
-Â Decl *CondVar = nullptr;<br>
-Â if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false))<br>
+Â Sema::ConditionResult Cond;<br>
+Â if (ParseParenExprOrCondition(Cond, SwitchLoc, Sema::ConditionKind::Switch))<br>
   return StmtError();<br>
<br>
-Â StmtResult Switch<br>
-Â Â = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar);<br>
+Â StmtResult Switch = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond);<br>
<br>
  if (Switch.isInvalid()) {<br>
   // Skip the switch body.<br>
@@ -1347,13 +1341,10 @@ StmtResult Parser::ParseWhileStatement(S<br>
  ParseScope WhileScope(this, ScopeFlags);<br>
<br>
  // Parse the condition.<br>
-Â ExprResult Cond;<br>
-Â Decl *CondVar = nullptr;<br>
-Â if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true))<br>
+Â Sema::ConditionResult Cond;<br>
+Â if (ParseParenExprOrCondition(Cond, WhileLoc, Sema::ConditionKind::Boolean))<br>
   return StmtError();<br>
<br>
-Â FullExprArg FullCond(Actions.MakeFullExpr(Cond.get(), WhileLoc));<br>
-<br>
  // C99 6.8.5p5 - In C99, the body of the while statement is a scope, even if<br>
  // there is no compound stmt. C90 does not have this clause. We only do this<br>
  // if the body isn't a compound statement to avoid push/pop in common cases.<br>
@@ -1374,10 +1365,10 @@ StmtResult Parser::ParseWhileStatement(S<br>
  InnerScope.Exit();<br>
  WhileScope.Exit();<br>
<br>
-Â if ((Cond.isInvalid() && !CondVar) || Body.isInvalid())<br>
+Â if (Cond.isInvalid() || Body.isInvalid())<br>
   return StmtError();<br>
<br>
-Â return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get());<br>
+Â return Actions.ActOnWhileStmt(WhileLoc, Cond, Body.get());<br>
 }<br>
<br>
 /// ParseDoStatement<br>
@@ -1535,12 +1526,10 @@ StmtResult Parser::ParseForStatement(Sou<br>
<br>
  bool ForEach = false, ForRange = false;<br>
  StmtResult FirstPart;<br>
-Â bool SecondPartIsInvalid = false;<br>
-Â FullExprArg SecondPart(Actions);<br>
+Â Sema::ConditionResult SecondPart;<br>
  ExprResult Collection;<br>
  ForRangeInit ForRangeInit;<br>
  FullExprArg ThirdPart(Actions);<br>
-Â Decl *SecondVar = nullptr;<br>
<br>
  if (Tok.is(tok::code_completion)) {<br>
   Actions.CodeCompleteOrdinaryName(getCurScope(),<br>
@@ -1645,7 +1634,7 @@ StmtResult Parser::ParseForStatement(Sou<br>
    Diag(Tok, diag::err_for_range_expected_decl)<br>
     << FirstPart.get()->getSourceRange();<br>
    SkipUntil(tok::r_paren, StopBeforeMatch);<br>
-Â Â Â SecondPartIsInvalid = true;<br>
+Â Â Â SecondPart = Sema::ConditionError();<br>
   } else {<br>
    if (!Value.isInvalid()) {<br>
     Diag(Tok, diag::err_expected_semi_for);<br>
@@ -1660,29 +1649,28 @@ StmtResult Parser::ParseForStatement(Sou<br>
<br>
  // Parse the second part of the for specifier.<br>
  getCurScope()->AddFlags(Scope::BreakScope | Scope::ContinueScope);<br>
-Â if (!ForEach && !ForRange) {<br>
-Â Â assert(!SecondPart.get() && "Shouldn't have a second expression yet.");<br>
+Â if (!ForEach && !ForRange && !SecondPart.isInvalid()) {<br>
   // Parse the second part of the for specifier.<br>
   if (Tok.is(tok::semi)) { // for (...;;<br>
    // no second part.<br>
   } else if (Tok.is(tok::r_paren)) {<br>
    // missing both semicolons.<br>
   } else {<br>
-Â Â Â ExprResult Second;<br>
    if (getLangOpts().CPlusPlus)<br>
-Â Â Â Â ParseCXXCondition(Second, SecondVar, ForLoc, true);<br>
+Â Â Â Â SecondPart = ParseCXXCondition(ForLoc, Sema::ConditionKind::Boolean);<br>
    else {<br>
-Â Â Â Â Second = ParseExpression();<br>
-Â Â Â Â if (!Second.isInvalid())<br>
-Â Â Â Â Â Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Second.get());<br>
+Â Â Â Â ExprResult SecondExpr = ParseExpression();<br>
+Â Â Â Â if (SecondExpr.isInvalid())<br>
+Â Â Â Â Â SecondPart = Sema::ConditionError();<br>
+Â Â Â Â else<br>
+Â Â Â Â Â SecondPart =<br>
+Â Â Â Â Â Â Â Actions.ActOnCondition(getCurScope(), ForLoc, SecondExpr.get(),<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionKind::Boolean);<br>
    }<br>
-Â Â Â SecondPartIsInvalid = Second.isInvalid();<br>
-Â Â Â SecondPart = Actions.MakeFullExpr(Second.get(), ForLoc);<br>
   }<br>
<br>
   if (Tok.isNot(tok::semi)) {<br>
-Â Â Â if (!SecondPartIsInvalid || SecondVar)<br>
+Â Â Â if (!SecondPart.isInvalid())<br>
     Diag(Tok, diag::err_expected_semi_for);<br>
    else<br>
     // Skip until semicolon or rparen, don't consume it.<br>
@@ -1781,8 +1769,8 @@ StmtResult Parser::ParseForStatement(Sou<br>
   return Actions.FinishCXXForRangeStmt(ForRangeStmt.get(), Body.get());<br>
<br>
  return Actions.ActOnForStmt(ForLoc, T.getOpenLocation(), FirstPart.get(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SecondPart, SecondVar, ThirdPart,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â T.getCloseLocation(), Body.get());<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SecondPart, ThirdPart, T.getCloseLocation(),<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Body.get());<br>
 }<br>
<br>
 /// ParseGotoStatement<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jun 23 14:02:52 2016<br>
@@ -10092,10 +10092,10 @@ buildSingleCopyAssignRecursively(Sema &S<br>
                   SizeType, VK_LValue, OK_Ordinary, Loc);<br>
<br>
  // Construct the loop that copies all elements of this array.<br>
-Â return S.ActOnForStmt(Loc, Loc, InitStmt,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â S.MakeFullExpr(Comparison),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â nullptr, S.MakeFullDiscardedValueExpr(Increment),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Loc, Copy.get());<br>
+Â return S.ActOnForStmt(<br>
+Â Â Â Loc, Loc, InitStmt,<br>
+Â Â Â S.ActOnCondition(nullptr, Loc, Comparison, Sema::ConditionKind::Boolean),<br>
+Â Â Â S.MakeFullDiscardedValueExpr(Increment), Loc, Copy.get());<br>
 }<br>
<br>
 static StmtResult<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Jun 23 14:02:52 2016<br>
@@ -14341,7 +14341,7 @@ void Sema::DiagnoseEqualityWithExtraPare<br>
   }<br>
 }<br>
<br>
-ExprResult Sema::CheckBooleanCondition(Expr *E, SourceLocation Loc) {<br>
+ExprResult Sema::CheckBooleanCondition(SourceLocation Loc, Expr *E) {<br>
  DiagnoseAssignmentAsCondition(E);<br>
  if (ParenExpr *parenE = dyn_cast<ParenExpr>(E))<br>
   DiagnoseEqualityWithExtraParens(parenE);<br>
@@ -14371,12 +14371,26 @@ ExprResult Sema::CheckBooleanCondition(E<br>
  return E;<br>
 }<br>
<br>
-ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *SubExpr) {<br>
+Sema::ConditionResult Sema::ActOnCondition(Scope *S, SourceLocation Loc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *SubExpr, ConditionKind CK) {<br>
+Â // Empty conditions are valid in for-statements.<br>
  if (!SubExpr)<br>
-Â Â return ExprError();<br>
+Â Â return ConditionResult();<br>
<br>
-Â return CheckBooleanCondition(SubExpr, Loc);<br>
+Â ExprResult Cond;<br>
+Â switch (CK) {<br>
+Â case ConditionKind::Boolean:<br>
+Â Â Cond = CheckBooleanCondition(Loc, SubExpr);<br>
+Â Â break;<br>
+<br>
+Â case ConditionKind::Switch:<br>
+Â Â Cond = CheckSwitchCondition(Loc, SubExpr);<br>
+Â Â break;<br>
+Â }<br>
+Â if (Cond.isInvalid())<br>
+Â Â return ConditionError();<br>
+<br>
+Â return ConditionResult(nullptr, MakeFullExpr(Cond.get(), Loc));<br>
 }<br>
<br>
 namespace {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 23 14:02:52 2016<br>
@@ -3054,11 +3054,21 @@ void Sema::CheckVirtualDtorCall(CXXDestr<br>
  }<br>
 }<br>
<br>
+Sema::ConditionResult Sema::ActOnConditionVariable(Decl *ConditionVar,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation StmtLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionKind CK) {<br>
+Â ExprResult E =<br>
+Â Â Â CheckConditionVariable(cast<VarDecl>(ConditionVar), StmtLoc, CK);<br>
+Â if (E.isInvalid())<br>
+Â Â return ConditionError();<br>
+Â return ConditionResult(ConditionVar, MakeFullExpr(E.get(), StmtLoc));<br>
+}<br>
+<br>
 /// \brief Check the use of the given variable as a C++ condition in an if,<br>
 /// while, do-while, or switch statement.<br>
 ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar,<br>
                     SourceLocation StmtLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â bool ConvertToBoolean) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionKind CK) {<br>
  if (ConditionVar->isInvalidDecl())<br>
   return ExprError();<br>
<br>
@@ -3082,13 +3092,15 @@ ExprResult Sema::CheckConditionVariable(<br>
<br>
  MarkDeclRefReferenced(cast<DeclRefExpr>(Condition.get()));<br>
<br>
-Â if (ConvertToBoolean) {<br>
-Â Â Condition = CheckBooleanCondition(Condition.get(), StmtLoc);<br>
-Â Â if (Condition.isInvalid())<br>
-Â Â Â return ExprError();<br>
+Â switch (CK) {<br>
+Â case ConditionKind::Boolean:<br>
+Â Â return CheckBooleanCondition(StmtLoc, Condition.get());<br>
+<br>
+Â case ConditionKind::Switch:<br>
+Â Â return CheckSwitchCondition(StmtLoc, Condition.get());<br>
  }<br>
<br>
-Â return Condition;<br>
+Â llvm_unreachable("unexpected condition kind");<br>
 }<br>
<br>
 /// CheckCXXBooleanCondition - Returns true if a conversion to bool is invalid.<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Thu Jun 23 14:02:52 2016<br>
@@ -6826,12 +6826,11 @@ OMPClause *Sema::ActOnOpenMPIfClause(Ope<br>
  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&<br>
    !Condition->isInstantiationDependent() &&<br>
    !Condition->containsUnexpandedParameterPack()) {<br>
-Â Â ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Condition->getExprLoc(), Condition);<br>
+Â Â ExprResult Val = CheckBooleanCondition(StartLoc, Condition);<br>
   if (Val.isInvalid())<br>
    return nullptr;<br>
<br>
-Â Â ValExpr = Val.get();<br>
+Â Â ValExpr = MakeFullExpr(Val.get()).get();<br>
  }<br>
<br>
  return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc,<br>
@@ -6846,12 +6845,11 @@ OMPClause *Sema::ActOnOpenMPFinalClause(<br>
  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&<br>
    !Condition->isInstantiationDependent() &&<br>
    !Condition->containsUnexpandedParameterPack()) {<br>
-Â Â ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Condition->getExprLoc(), Condition);<br>
+Â Â ExprResult Val = CheckBooleanCondition(StartLoc, Condition);<br>
   if (Val.isInvalid())<br>
    return nullptr;<br>
<br>
-Â Â ValExpr = Val.get();<br>
+Â Â ValExpr = MakeFullExpr(Val.get()).get();<br>
  }<br>
<br>
  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Jun 23 14:02:52 2016<br>
@@ -504,39 +504,30 @@ public:<br>
 }<br>
<br>
 StmtResult<br>
-Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,<br>
+Sema::ActOnIfStmt(SourceLocation IfLoc, ConditionResult Cond,<br>
          Stmt *thenStmt, SourceLocation ElseLoc,<br>
          Stmt *elseStmt) {<br>
-Â ExprResult CondResult(CondVal.release());<br>
-<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (CondVar) {<br>
-Â Â ConditionVar = cast<VarDecl>(CondVar);<br>
-Â Â CondResult = CheckConditionVariable(ConditionVar, IfLoc, true);<br>
-Â Â CondResult = ActOnFinishFullExpr(CondResult.get(), IfLoc);<br>
+Â auto CondVal = Cond.get();<br>
+Â if (Cond.isInvalid()) {<br>
+Â Â CondVal.first = nullptr;<br>
+Â Â CondVal.second = new (Context)<br>
+Â Â Â Â OpaqueValueExpr(SourceLocation(), Context.BoolTy, VK_RValue);<br>
  }<br>
-Â Expr *ConditionExpr = CondResult.getAs<Expr>();<br>
-Â if (ConditionExpr) {<br>
-<br>
-Â Â if (!Diags.isIgnored(diag::warn_comma_operator,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionExpr->getExprLoc()))<br>
-Â Â Â CommaVisitor(*this).Visit(ConditionExpr);<br>
<br>
-Â Â DiagnoseUnusedExprResult(thenStmt);<br>
+Â if (!Diags.isIgnored(diag::warn_comma_operator,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â CondVal.second->getExprLoc()))<br>
+Â Â CommaVisitor(*this).Visit(CondVal.second);<br>
<br>
-Â Â if (!elseStmt) {<br>
-Â Â Â DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â diag::warn_empty_if_body);<br>
-Â Â }<br>
+Â DiagnoseUnusedExprResult(thenStmt);<br>
<br>
-Â Â DiagnoseUnusedExprResult(elseStmt);<br>
-Â } else {<br>
-Â Â // Create a dummy Expr for the condition for error recovery<br>
-Â Â ConditionExpr = new (Context) OpaqueValueExpr(SourceLocation(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Context.BoolTy, VK_RValue);<br>
+Â if (!elseStmt) {<br>
+Â Â DiagnoseEmptyStmtBody(CondVal.second->getLocEnd(), thenStmt,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â diag::warn_empty_if_body);<br>
  }<br>
<br>
-Â return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr,<br>
+Â DiagnoseUnusedExprResult(elseStmt);<br>
+<br>
+Â return new (Context) IfStmt(Context, IfLoc, CondVal.first, CondVal.second,<br>
                thenStmt, ElseLoc, elseStmt);<br>
 }<br>
<br>
@@ -599,24 +590,7 @@ static QualType GetTypeBeforeIntegralPro<br>
  return expr->getType();<br>
 }<br>
<br>
-StmtResult<br>
-Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, Expr *Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Decl *CondVar) {<br>
-Â ExprResult CondResult;<br>
-<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (CondVar) {<br>
-Â Â ConditionVar = cast<VarDecl>(CondVar);<br>
-Â Â CondResult = CheckConditionVariable(ConditionVar, SourceLocation(), false);<br>
-Â Â if (CondResult.isInvalid())<br>
-Â Â Â return StmtError();<br>
-<br>
-Â Â Cond = CondResult.get();<br>
-Â }<br>
-<br>
-Â if (!Cond)<br>
-Â Â return StmtError();<br>
-<br>
+ExprResult Sema::CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond) {<br>
  class SwitchConvertDiagnoser : public ICEConvertDiagnoser {<br>
   Expr *Cond;<br>
<br>
@@ -664,24 +638,24 @@ Sema::ActOnStartOfSwitchStmt(SourceLocat<br>
   }<br>
  } SwitchDiagnoser(Cond);<br>
<br>
-Â CondResult =<br>
+Â ExprResult CondResult =<br>
    PerformContextualImplicitConversion(SwitchLoc, Cond, SwitchDiagnoser);<br>
-Â if (CondResult.isInvalid()) return StmtError();<br>
-Â Cond = CondResult.get();<br>
+Â if (CondResult.isInvalid())<br>
+Â Â return ExprError();<br>
<br>
  // C99 6.8.4.2p5 - Integer promotions are performed on the controlling expr.<br>
-Â CondResult = UsualUnaryConversions(Cond);<br>
-Â if (CondResult.isInvalid()) return StmtError();<br>
-Â Cond = CondResult.get();<br>
+Â return UsualUnaryConversions(CondResult.get());<br>
+}<br>
<br>
-Â CondResult = ActOnFinishFullExpr(Cond, SwitchLoc);<br>
-Â if (CondResult.isInvalid())<br>
+StmtResult<br>
+Sema::ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, ConditionResult Cond) {<br>
+Â if (Cond.isInvalid())<br>
   return StmtError();<br>
-Â Cond = CondResult.get();<br>
<br>
  getCurFunction()->setHasBranchIntoScope();<br>
<br>
-Â SwitchStmt *SS = new (Context) SwitchStmt(Context, ConditionVar, Cond);<br>
+Â SwitchStmt *SS =<br>
+Â Â Â new (Context) SwitchStmt(Context, Cond.get().first, Cond.get().second);<br>
  getCurFunction()->SwitchStack.push_back(SS);<br>
  return SS;<br>
 }<br>
@@ -1242,27 +1216,17 @@ Sema::DiagnoseAssignmentEnum(QualType Ds<br>
   }<br>
 }<br>
<br>
-StmtResult<br>
-Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Decl *CondVar, Stmt *Body) {<br>
-Â ExprResult CondResult(Cond.release());<br>
-<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (CondVar) {<br>
-Â Â ConditionVar = cast<VarDecl>(CondVar);<br>
-Â Â CondResult = CheckConditionVariable(ConditionVar, WhileLoc, true);<br>
-Â Â CondResult = ActOnFinishFullExpr(CondResult.get(), WhileLoc);<br>
-Â Â if (CondResult.isInvalid())<br>
-Â Â Â return StmtError();<br>
-Â }<br>
-Â Expr *ConditionExpr = CondResult.get();<br>
-Â if (!ConditionExpr)<br>
+StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *Body) {<br>
+Â if (Cond.isInvalid())<br>
   return StmtError();<br>
-Â CheckBreakContinueBinding(ConditionExpr);<br>
<br>
-Â if (ConditionExpr &&<br>
-Â Â Â !Diags.isIgnored(diag::warn_comma_operator, ConditionExpr->getExprLoc()))<br>
-Â Â CommaVisitor(*this).Visit(ConditionExpr);<br>
+Â auto CondVal = Cond.get();<br>
+Â CheckBreakContinueBinding(CondVal.second);<br>
+<br>
+Â if (CondVal.second &&<br>
+Â Â Â !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))<br>
+Â Â CommaVisitor(*this).Visit(CondVal.second);<br>
<br>
  DiagnoseUnusedExprResult(Body);<br>
<br>
@@ -1270,7 +1234,7 @@ Sema::ActOnWhileStmt(SourceLocation Whil<br>
   getCurCompoundScope().setHasEmptyLoopBodies();<br>
<br>
  return new (Context)<br>
-Â Â Â WhileStmt(Context, ConditionVar, ConditionExpr, Body, WhileLoc);<br>
+Â Â Â WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc);<br>
 }<br>
<br>
 StmtResult<br>
@@ -1280,7 +1244,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc,<br>
  assert(Cond && "ActOnDoStmt(): missing expression");<br>
<br>
  CheckBreakContinueBinding(Cond);<br>
-Â ExprResult CondResult = CheckBooleanCondition(Cond, DoLoc);<br>
+Â ExprResult CondResult = CheckBooleanCondition(DoLoc, Cond);<br>
  if (CondResult.isInvalid())<br>
   return StmtError();<br>
  Cond = CondResult.get();<br>
@@ -1644,11 +1608,13 @@ void Sema::CheckBreakContinueBinding(Exp<br>
  }<br>
 }<br>
<br>
-StmtResult<br>
-Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Stmt *First, FullExprArg second, Decl *secondVar,<br>
-Â Â Â Â Â Â Â Â Â Â FullExprArg third,<br>
-Â Â Â Â Â Â Â Â Â Â SourceLocation RParenLoc, Stmt *Body) {<br>
+StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *First, ConditionResult Second,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â FullExprArg third, SourceLocation RParenLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *Body) {<br>
+Â if (Second.isInvalid())<br>
+Â Â return StmtError();<br>
+<br>
  if (!getLangOpts().CPlusPlus) {<br>
   if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) {<br>
    // C99 6.8.5p3: The declaration part of a 'for' statement shall only<br>
@@ -1666,26 +1632,18 @@ Sema::ActOnForStmt(SourceLocation ForLoc<br>
   }<br>
  }<br>
<br>
-Â CheckBreakContinueBinding(second.get());<br>
+Â CheckBreakContinueBinding(Second.get().second);<br>
  CheckBreakContinueBinding(third.get());<br>
<br>
-Â CheckForLoopConditionalStatement(*this, second.get(), third.get(), Body);<br>
+Â if (!Second.get().first)<br>
+Â Â CheckForLoopConditionalStatement(*this, Second.get().second, third.get(),<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Body);<br>
  CheckForRedundantIteration(*this, third.get(), Body);<br>
<br>
-Â ExprResult SecondResult(second.release());<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (secondVar) {<br>
-Â Â ConditionVar = cast<VarDecl>(secondVar);<br>
-Â Â SecondResult = CheckConditionVariable(ConditionVar, ForLoc, true);<br>
-Â Â SecondResult = ActOnFinishFullExpr(SecondResult.get(), ForLoc);<br>
-Â Â if (SecondResult.isInvalid())<br>
-Â Â Â return StmtError();<br>
-Â }<br>
-<br>
-Â if (SecondResult.get() &&<br>
+Â if (Second.get().second &&<br>
    !Diags.isIgnored(diag::warn_comma_operator,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â SecondResult.get()->getExprLoc()))<br>
-Â Â CommaVisitor(*this).Visit(SecondResult.get());<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Second.get().second->getExprLoc()))<br>
+Â Â CommaVisitor(*this).Visit(Second.get().second);<br>
<br>
  Expr *Third = third.release().getAs<Expr>();<br>
<br>
@@ -1696,8 +1654,9 @@ Sema::ActOnForStmt(SourceLocation ForLoc<br>
  if (isa<NullStmt>(Body))<br>
   getCurCompoundScope().setHasEmptyLoopBodies();<br>
<br>
-Â return new (Context) ForStmt(Context, First, SecondResult.get(), ConditionVar,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Third, Body, ForLoc, LParenLoc, RParenLoc);<br>
+Â return new (Context)<br>
+Â Â Â ForStmt(Context, First, Second.get().second, Second.get().first, Third,<br>
+Â Â Â Â Â Â Â Body, ForLoc, LParenLoc, RParenLoc);<br>
 }<br>
<br>
 /// In an Objective C collection iteration statement:<br>
@@ -2384,8 +2343,10 @@ Sema::BuildCXXForRangeStmt(SourceLocatio<br>
   // Build and check __begin != __end expression.<br>
   NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,<br>
              BeginRef.get(), EndRef.get());<br>
-Â Â NotEqExpr = ActOnBooleanCondition(S, ColonLoc, NotEqExpr.get());<br>
-Â Â NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());<br>
+Â Â if (!NotEqExpr.isInvalid())<br>
+Â Â Â NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());<br>
+Â Â if (!NotEqExpr.isInvalid())<br>
+Â Â Â NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());<br>
   if (NotEqExpr.isInvalid()) {<br>
    Diag(RangeLoc, diag::note_for_range_invalid_iterator)<br>
     << RangeLoc << 0 << BeginRangeRef.get()->getType();<br>
<br>
Modified: cfe/trunk/lib/Sema/TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/TreeTransform.h Thu Jun 23 14:02:52 2016<br>
@@ -410,6 +410,14 @@ public:<br>
   return D;<br>
  }<br>
<br>
+Â /// \brief Transform the specified condition.<br>
+Â ///<br>
+Â /// By default, this transforms the variable and expression and rebuilds<br>
+Â /// the condition.<br>
+Â Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *Expr,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionKind Kind);<br>
+<br>
  /// \brief Transform the attributes associated with the given declaration and<br>
  /// place them on the new declaration.<br>
  ///<br>
@@ -1166,10 +1174,9 @@ public:<br>
  ///<br>
  /// By default, performs semantic analysis to build the new statement.<br>
  /// Subclasses may override this routine to provide different behavior.<br>
-Â StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â VarDecl *CondVar, Stmt *Then,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation ElseLoc, Stmt *Else) {<br>
-Â Â return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);<br>
+Â StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::ConditionResult Cond,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *Then, SourceLocation ElseLoc, Stmt *Else) {<br>
+Â Â return getSema().ActOnIfStmt(IfLoc, Cond, Then, ElseLoc, Else);<br>
  }<br>
<br>
  /// \brief Start building a new switch statement.<br>
@@ -1177,9 +1184,8 @@ public:<br>
  /// By default, performs semantic analysis to build the new statement.<br>
  /// Subclasses may override this routine to provide different behavior.<br>
  StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Expr *Cond, VarDecl *CondVar) {<br>
-Â Â return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â CondVar);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionResult Cond) {<br>
+Â Â return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond);<br>
  }<br>
<br>
  /// \brief Attach the body to the switch statement.<br>
@@ -1195,9 +1201,9 @@ public:<br>
  ///<br>
  /// By default, performs semantic analysis to build the new statement.<br>
  /// Subclasses may override this routine to provide different behavior.<br>
-Â StmtResult RebuildWhileStmt(SourceLocation WhileLoc, Sema::FullExprArg Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â VarDecl *CondVar, Stmt *Body) {<br>
-Â Â return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body);<br>
+Â StmtResult RebuildWhileStmt(SourceLocation WhileLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::ConditionResult Cond, Stmt *Body) {<br>
+Â Â return getSema().ActOnWhileStmt(WhileLoc, Cond, Body);<br>
  }<br>
<br>
  /// \brief Build a new do-while statement.<br>
@@ -1216,11 +1222,11 @@ public:<br>
  /// By default, performs semantic analysis to build the new statement.<br>
  /// Subclasses may override this routine to provide different behavior.<br>
  StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *Init, Sema::FullExprArg Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â VarDecl *CondVar, Sema::FullExprArg Inc,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â SourceLocation RParenLoc, Stmt *Body) {<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *Init, Sema::ConditionResult Cond,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Sema::FullExprArg Inc, SourceLocation RParenLoc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Stmt *Body) {<br>
   return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â CondVar, Inc, RParenLoc, Body);<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Inc, RParenLoc, Body);<br>
  }<br>
<br>
  /// \brief Build a new goto statement.<br>
@@ -3357,6 +3363,31 @@ bool TreeTransform<Derived>::TransformEx<br>
  return false;<br>
 }<br>
<br>
+template <typename Derived><br>
+Sema::ConditionResult TreeTransform<Derived>::TransformCondition(<br>
+Â Â SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {<br>
+Â if (Var) {<br>
+Â Â VarDecl *ConditionVar = cast_or_null<VarDecl>(<br>
+Â Â Â Â getDerived().TransformDefinition(Var->getLocation(), Var));<br>
+<br>
+Â Â if (!ConditionVar)<br>
+Â Â Â return Sema::ConditionError();<br>
+<br>
+Â Â return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);<br>
+Â }<br>
+<br>
+Â if (Expr) {<br>
+Â Â ExprResult CondExpr = getDerived().TransformExpr(Expr);<br>
+<br>
+Â Â if (CondExpr.isInvalid())<br>
+Â Â Â return Sema::ConditionError();<br>
+<br>
+Â Â return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind);<br>
+Â }<br>
+<br>
+Â return Sema::ConditionResult();<br>
+}<br>
+<br>
 template<typename Derived><br>
 NestedNameSpecifierLoc<br>
 TreeTransform<Derived>::TransformNestedNameSpecifierLoc(<br>
@@ -4962,8 +4993,8 @@ bool TreeTransform<Derived>::TransformEx<br>
   if (NoexceptExpr.isInvalid())<br>
    return true;<br>
<br>
-Â Â NoexceptExpr = getSema().CheckBooleanCondition(<br>
-Â Â Â Â NoexceptExpr.get(), NoexceptExpr.get()->getLocStart());<br>
+Â Â // FIXME: This is bogus, a noexcept expression is not a condition.<br>
+Â Â NoexceptExpr = getSema().CheckBooleanCondition(Loc, NoexceptExpr.get());<br>
   if (NoexceptExpr.isInvalid())<br>
    return true;<br>
<br>
@@ -6195,35 +6226,10 @@ template<typename Derived><br>
 StmtResult<br>
 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {<br>
  // Transform the condition<br>
-Â ExprResult Cond;<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (S->getConditionVariable()) {<br>
-Â Â ConditionVar<br>
-Â Â Â = cast_or_null<VarDecl>(<br>
-Â Â Â Â Â Â Â Â Â Â getDerived().TransformDefinition(<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()->getLocation(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()));<br>
-Â Â if (!ConditionVar)<br>
-Â Â Â return StmtError();<br>
-Â } else {<br>
-Â Â Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-Â Â if (Cond.isInvalid())<br>
-Â Â Â return StmtError();<br>
-<br>
-Â Â // Convert the condition to a boolean value.<br>
-Â Â if (S->getCond()) {<br>
-Â Â Â ExprResult CondE = getSema().ActOnBooleanCondition(nullptr, S->getIfLoc(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Cond.get());<br>
-Â Â Â if (CondE.isInvalid())<br>
-Â Â Â Â return StmtError();<br>
-<br>
-Â Â Â Cond = CondE.get();<br>
-Â Â }<br>
-Â }<br>
-<br>
-Â Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.get(), S->getIfLoc()));<br>
-Â if (!S->getConditionVariable() && S->getCond() && !FullCond.get())<br>
+Â Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+Â Â Â S->getIfLoc(), S->getConditionVariable(), S->getCond(),<br>
+Â Â Â Sema::ConditionKind::Boolean);<br>
+Â if (Cond.isInvalid())<br>
   return StmtError();<br>
<br>
  // Transform the "then" branch.<br>
@@ -6237,14 +6243,12 @@ TreeTransform<Derived>::TransformIfStmt(<br>
   return StmtError();<br>
<br>
  if (!getDerived().AlwaysRebuild() &&<br>
-Â Â Â FullCond.get() == S->getCond() &&<br>
-Â Â Â ConditionVar == S->getConditionVariable() &&<br>
+Â Â Â Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&<br>
    Then.get() == S->getThen() &&<br>
    Else.get() == S->getElse())<br>
   return S;<br>
<br>
-Â return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Then.get(),<br>
+Â return getDerived().RebuildIfStmt(S->getIfLoc(), Cond, Then.get(),<br>
                   S->getElseLoc(), Else.get());<br>
 }<br>
<br>
@@ -6252,27 +6256,15 @@ template<typename Derived><br>
 StmtResult<br>
 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {<br>
  // Transform the condition.<br>
-Â ExprResult Cond;<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (S->getConditionVariable()) {<br>
-Â Â ConditionVar<br>
-Â Â Â = cast_or_null<VarDecl>(<br>
-Â Â Â Â Â Â Â Â Â Â getDerived().TransformDefinition(<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()->getLocation(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()));<br>
-Â Â if (!ConditionVar)<br>
-Â Â Â return StmtError();<br>
-Â } else {<br>
-Â Â Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-Â Â if (Cond.isInvalid())<br>
-Â Â Â return StmtError();<br>
-Â }<br>
+Â Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+Â Â Â S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),<br>
+Â Â Â Sema::ConditionKind::Switch);<br>
+Â if (Cond.isInvalid())<br>
+Â Â return StmtError();<br>
<br>
  // Rebuild the switch statement.<br>
  StmtResult Switch<br>
-Â Â = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionVar);<br>
+Â Â = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond);<br>
  if (Switch.isInvalid())<br>
   return StmtError();<br>
<br>
@@ -6290,36 +6282,10 @@ template<typename Derived><br>
 StmtResult<br>
 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {<br>
  // Transform the condition<br>
-Â ExprResult Cond;<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (S->getConditionVariable()) {<br>
-Â Â ConditionVar<br>
-Â Â Â = cast_or_null<VarDecl>(<br>
-Â Â Â Â Â Â Â Â Â Â getDerived().TransformDefinition(<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()->getLocation(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()));<br>
-Â Â if (!ConditionVar)<br>
-Â Â Â return StmtError();<br>
-Â } else {<br>
-Â Â Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-Â Â if (Cond.isInvalid())<br>
-Â Â Â return StmtError();<br>
-<br>
-Â Â if (S->getCond()) {<br>
-Â Â Â // Convert the condition to a boolean value.<br>
-Â Â Â ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getWhileLoc(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Cond.get());<br>
-Â Â Â if (CondE.isInvalid())<br>
-Â Â Â Â return StmtError();<br>
-Â Â Â Cond = CondE;<br>
-Â Â }<br>
-Â }<br>
-<br>
-Â Sema::FullExprArg FullCond(<br>
-Â Â Â getSema().MakeFullExpr(Cond.get(), S->getWhileLoc()));<br>
-Â if (!S->getConditionVariable() && S->getCond() && !FullCond.get())<br>
+Â Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+Â Â Â S->getWhileLoc(), S->getConditionVariable(), S->getCond(),<br>
+Â Â Â Sema::ConditionKind::Boolean);<br>
+Â if (Cond.isInvalid())<br>
   return StmtError();<br>
<br>
  // Transform the body<br>
@@ -6328,13 +6294,11 @@ TreeTransform<Derived>::TransformWhileSt<br>
   return StmtError();<br>
<br>
  if (!getDerived().AlwaysRebuild() &&<br>
-Â Â Â FullCond.get() == S->getCond() &&<br>
-Â Â Â ConditionVar == S->getConditionVariable() &&<br>
+Â Â Â Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&<br>
    Body.get() == S->getBody())<br>
   return Owned(S);<br>
<br>
-Â return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ConditionVar, Body.get());<br>
+Â return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get());<br>
 }<br>
<br>
 template<typename Derived><br>
@@ -6374,37 +6338,10 @@ TreeTransform<Derived>::TransformForStmt<br>
   getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());<br>
<br>
  // Transform the condition<br>
-Â ExprResult Cond;<br>
-Â VarDecl *ConditionVar = nullptr;<br>
-Â if (S->getConditionVariable()) {<br>
-Â Â ConditionVar<br>
-Â Â Â = cast_or_null<VarDecl>(<br>
-Â Â Â Â Â Â Â Â Â Â getDerived().TransformDefinition(<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()->getLocation(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getConditionVariable()));<br>
-Â Â if (!ConditionVar)<br>
-Â Â Â return StmtError();<br>
-Â } else {<br>
-Â Â Cond = getDerived().TransformExpr(S->getCond());<br>
-<br>
-Â Â if (Cond.isInvalid())<br>
-Â Â Â return StmtError();<br>
-<br>
-Â Â if (S->getCond()) {<br>
-Â Â Â // Convert the condition to a boolean value.<br>
-Â Â Â ExprResult CondE = getSema().ActOnBooleanCondition(nullptr,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getForLoc(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Cond.get());<br>
-Â Â Â if (CondE.isInvalid())<br>
-Â Â Â Â return StmtError();<br>
-<br>
-Â Â Â Cond = CondE.get();<br>
-Â Â }<br>
-Â }<br>
-<br>
-Â Sema::FullExprArg FullCond(<br>
-Â Â Â getSema().MakeFullExpr(Cond.get(), S->getForLoc()));<br>
-Â if (!S->getConditionVariable() && S->getCond() && !FullCond.get())<br>
+Â Sema::ConditionResult Cond = getDerived().TransformCondition(<br>
+Â Â Â S->getForLoc(), S->getConditionVariable(), S->getCond(),<br>
+Â Â Â Sema::ConditionKind::Boolean);<br>
+Â if (Cond.isInvalid())<br>
   return StmtError();<br>
<br>
  // Transform the increment<br>
@@ -6423,14 +6360,14 @@ TreeTransform<Derived>::TransformForStmt<br>
<br>
  if (!getDerived().AlwaysRebuild() &&<br>
    Init.get() == S->getInit() &&<br>
-Â Â Â FullCond.get() == S->getCond() &&<br>
+Â Â Â Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&<br>
    Inc.get() == S->getInc() &&<br>
    Body.get() == S->getBody())<br>
   return S;<br>
<br>
  return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Init.get(), FullCond, ConditionVar,<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â FullInc, S->getRParenLoc(), Body.get());<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Init.get(), Cond, FullInc,<br>
+Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â S->getRParenLoc(), Body.get());<br>
 }<br>
<br>
 template<typename Derived><br>
@@ -6924,7 +6861,7 @@ TreeTransform<Derived>::TransformCXXForR<br>
  if (Cond.isInvalid())<br>
   return StmtError();<br>
  if (Cond.get())<br>
-Â Â Cond = SemaRef.CheckBooleanCondition(Cond.get(), S->getColonLoc());<br>
+Â Â Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());<br>
  if (Cond.isInvalid())<br>
   return StmtError();<br>
  if (Cond.get())<br>
<br>
Modified: cfe/trunk/test/FixIt/fixit-vexing-parse.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-vexing-parse.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-vexing-parse.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/FixIt/fixit-vexing-parse.cpp (original)<br>
+++ cfe/trunk/test/FixIt/fixit-vexing-parse.cpp Thu Jun 23 14:02:52 2016<br>
@@ -60,7 +60,7 @@ namespace N {<br>
   VO m(int (*p)[4]);<br>
<br>
   // Don't emit warning and fixit because direct initializer is not permitted here.<br>
-Â Â if (int n(int())){} // expected-error {{function type is not allowed here}} expected-error {{condition must have an initializer}}<br>
+Â Â if (int n(int())){} // expected-error {{function type is not allowed here}}<br>
<br>
   // CHECK: fix-it:"{{.*}}":{66:8-66:10}:" = {}"<br>
   U u(); // expected-warning {{function declaration}} expected-note {{replace parentheses with an initializer}}<br>
<br>
Modified: cfe/trunk/test/Parser/cxx0x-condition.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-condition.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-condition.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Parser/cxx0x-condition.cpp (original)<br>
+++ cfe/trunk/test/Parser/cxx0x-condition.cpp Thu Jun 23 14:02:52 2016<br>
@@ -23,9 +23,9 @@ void f() {<br>
<br>
  if (S b(a)) {} // expected-error {{variable declaration in condition cannot have a parenthesized initializer}}<br>
<br>
-Â if (S b(n)) {} // expected-error {{a function type is not allowed here}} expected-error {{must have an initializer}}<br>
+Â if (S b(n)) {} // expected-error {{a function type is not allowed here}}<br>
  if (S b(n) = 0) {} // expected-error {{a function type is not allowed here}}<br>
-Â if (S b(n) == 0) {} // expected-error {{a function type is not allowed here}} expected-error {{did you mean '='?}}<br>
+Â if (S b(n) == 0) {} // expected-error {{a function type is not allowed here}}<br>
<br>
  S s(a);<br>
  if (S{s}) {} // ok<br>
<br>
Modified: cfe/trunk/test/SemaCXX/crashes.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/crashes.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/crashes.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/crashes.cpp Thu Jun 23 14:02:52 2016<br>
@@ -105,8 +105,7 @@ namespace PR9026 {<br>
 namespace PR10270 {<br>
  template<typename T> class C;<br>
  template<typename T> void f() {<br>
-Â Â if (C<T> == 1) // expected-error{{expected unqualified-id}} \<br>
-Â Â Â Â Â Â Â Â Â Â // expected-error{{invalid '==' at end of declaration}}<br>
+Â Â if (C<T> == 1) // expected-error{{expected unqualified-id}}<br>
    return;<br>
  }<br>
 }<br>
<br>
Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Thu Jun 23 14:02:52 2016<br>
@@ -176,9 +176,9 @@ namespace test4 {<br>
<br>
   // Make sure these don't crash. Better diagnostics would be nice.<br>
   for (: {1, 2, 3}) {} // expected-error {{expected expression}} expected-error {{expected ';'}}<br>
-Â Â for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}<br>
+Â Â for (1 : {1, 2, 3}) {} // expected-error {{must declare a variable}}<br>
   for (+x : {1, 2, 3}) {} // expected-error {{undeclared identifier}} expected-error {{expected ';'}}<br>
-Â Â for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}} expected-warning {{result unused}}<br>
+Â Â for (+y : {1, 2, 3}) {} // expected-error {{must declare a variable}}<br>
  }<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/foreach.mm?rev=273600&r1=273599&r2=273600&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/foreach.mm?rev=273600&r1=273599&r2=273600&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a> (original)<br>
+++ cfe/trunk/test/SemaObjCXX/<a href="http://foreach.mm" rel="noreferrer" target="_blank">foreach.mm</a> Thu Jun 23 14:02:52 2016<br>
@@ -6,10 +6,8 @@<br>
 void f(NSArray *a) {<br>
   id keys;<br>
   for (int i : a); // expected-error{{selector element type 'int' is not a valid object}}<br>
-Â Â for ((id)2 : a);Â // expected-error {{for range declaration must declare a variable}} \<br>
-Â Â Â Â Â Â Â Â Â Â Â // expected-warning {{expression result unused}}<br>
-Â Â for (2 : a); // expected-error {{for range declaration must declare a variable}} \<br>
-Â Â Â Â Â Â Â Â Â // expected-warning {{expression result unused}}<br>
+Â Â for ((id)2 : a);Â // expected-error {{for range declaration must declare a variable}}<br>
+Â Â for (2 : a); // expected-error {{for range declaration must declare a variable}}<br>
<br>
  for (id thisKey : keys);<br>
<br>
@@ -65,8 +63,7 @@ int main ()<br>
 @end<br>
 void test2(NSObject<NSFastEnumeration> *collection) {<br>
  Test2 *obj;<br>
-Â for (obj.prop : collection) { // expected-error {{for range declaration must declare a variable}} \<br>
-Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â // expected-warning {{property access result unused - getters should not be used for side effects}}<br>
+Â for (obj.prop : collection) { // expected-error {{for range declaration must declare a variable}}<br>
  }<br>
 }<br>
<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">--Â <div>Peter</div></div></div>
</div>