Eliminate CXXConditionDeclExpr with extreme prejudice.

All statements that involve conditions can now hold on to a separate
condition declaration (a VarDecl), and will use a DeclRefExpr
referring to that VarDecl for the condition expression. ForStmts now
have such a VarDecl (I'd missed those in previous commits).

Also, since this change reworks the Action interface for
if/while/switch/for, use FullExprArg for the full expressions in those
expressions, to ensure that we're emitting

Note that we are (still) not generating the right cleanups for
condition variables in for statements. That will be a follow-on
commit.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89817 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 5648472..157d883 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -549,7 +549,7 @@
                                            CommaLocs.data(), RParenLoc);
 }
 
-/// ParseCXXCondition - if/switch/while/for condition expression.
+/// ParseCXXCondition - if/switch/while condition expression.
 ///
 ///       condition:
 ///         expression
@@ -557,11 +557,20 @@
 /// [GNU]   type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
 ///             '=' assignment-expression
 ///
-Parser::OwningExprResult Parser::ParseCXXCondition() {
-  if (!isCXXConditionDeclaration())
-    return ParseExpression(); // expression
-
-  SourceLocation StartLoc = Tok.getLocation();
+/// \param ExprResult if the condition was parsed as an expression, the
+/// parsed expression.
+///
+/// \param DeclResult if the condition was parsed as a declaration, the
+/// parsed declaration.
+///
+/// \returns true if there was a parsing, false otherwise.
+bool Parser::ParseCXXCondition(OwningExprResult &ExprResult,
+                               DeclPtrTy &DeclResult) {
+  if (!isCXXConditionDeclaration()) {
+    ExprResult = ParseExpression(); // expression
+    DeclResult = DeclPtrTy();
+    return ExprResult.isInvalid();
+  }
 
   // type-specifier-seq
   DeclSpec DS;
@@ -577,7 +586,7 @@
     OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
     if (AsmLabel.isInvalid()) {
       SkipUntil(tok::semi);
-      return ExprError();
+      return true;
     }
     DeclaratorInfo.setAsmLabel(AsmLabel.release());
     DeclaratorInfo.SetRangeEnd(Loc);
@@ -590,17 +599,24 @@
     DeclaratorInfo.AddAttributes(AttrList, Loc);
   }
 
+  // Type-check the declaration itself.
+  Action::DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(CurScope, 
+                                                                DeclaratorInfo);
+  DeclResult = Dcl.get();
+  ExprResult = ExprError();
+  
   // '=' assignment-expression
-  if (Tok.isNot(tok::equal))
-    return ExprError(Diag(Tok, diag::err_expected_equal_after_declarator));
-  SourceLocation EqualLoc = ConsumeToken();
-  OwningExprResult AssignExpr(ParseAssignmentExpression());
-  if (AssignExpr.isInvalid())
-    return ExprError();
-
-  return Actions.ActOnCXXConditionDeclarationExpr(CurScope, StartLoc,
-                                                  DeclaratorInfo,EqualLoc,
-                                                  move(AssignExpr));
+  if (Tok.is(tok::equal)) {
+    SourceLocation EqualLoc = ConsumeToken();
+    OwningExprResult AssignExpr(ParseAssignmentExpression());
+    if (!AssignExpr.isInvalid()) 
+      Actions.AddInitializerToDecl(DeclResult, move(AssignExpr));
+  } else {
+    // FIXME: C++0x allows a braced-init-list
+    Diag(Tok, diag::err_expected_equal_after_declarator);
+  }
+  
+  return false;
 }
 
 /// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.