Index: include/clang/Parse/Parser.h =================================================================== --- include/clang/Parse/Parser.h (revision 71954) +++ include/clang/Parse/Parser.h (working copy) @@ -141,6 +141,7 @@ typedef Action::ExprArg ExprArg; typedef Action::MultiStmtArg MultiStmtArg; + typedef Action::FullExprArg FullExprArg; /// Adorns a ExprResult with Actions to make it an OwningExprResult OwningExprResult Owned(ExprResult res) { Index: include/clang/Parse/Action.h =================================================================== --- include/clang/Parse/Action.h (revision 71954) +++ include/clang/Parse/Action.h (working copy) @@ -102,6 +102,34 @@ typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg; typedef ASTMultiPtr<&ActionBase::DeleteTemplateParams> MultiTemplateParamsArg; + class FullExprArg { + public: + FullExprArg(const FullExprArg& Other) + : Expr(move(const_cast(Other).Expr)) {} + + template + T *takeAs() { + return static_cast(Expr.take()); + } + + OwningExprResult release() { + return move(Expr); + } + private: + // FIXME: No need to make the entire Action class a friend when it's just + // Action::FullExpr that needs access to the constructor below. + friend class Action; + + explicit FullExprArg(ExprArg expr) + : Expr(move(expr)) {} + + ExprArg Expr; + }; + + FullExprArg FullExpr(ExprArg &Arg) { + return FullExprArg(ActOnFinishFullExpr(move(Arg))); + } + // Utilities for Action implementations to return smart results. OwningExprResult ExprError() { return OwningExprResult(*this, true); } @@ -461,8 +489,9 @@ return StmtEmpty(); } - virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, - StmtArg ThenVal, SourceLocation ElseLoc, + virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, + FullExprArg CondVal, StmtArg ThenVal, + SourceLocation ElseLoc, StmtArg ElseVal) { return StmtEmpty(); } @@ -1042,6 +1071,13 @@ return ExprEmpty(); } + + /// ActOnFinishFullExpr - Called whenever a full expression has been parsed. + /// (C++ [intro.execution]p12. + virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) { + return move(Expr); + } + //===---------------------------- C++ Classes ---------------------------===// /// ActOnBaseSpecifier - Parsed a base specifier virtual BaseResult ActOnBaseSpecifier(DeclPtrTy classdecl, Index: tools/clang-cc/PrintParserCallbacks.cpp =================================================================== --- tools/clang-cc/PrintParserCallbacks.cpp (revision 71954) +++ tools/clang-cc/PrintParserCallbacks.cpp (working copy) @@ -296,8 +296,9 @@ return StmtEmpty(); } - virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, - StmtArg ThenVal,SourceLocation ElseLoc, + virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, + FullExprArg CondVal, StmtArg ThenVal, + SourceLocation ElseLoc, StmtArg ElseVal) { llvm::cout << __FUNCTION__ << "\n"; return StmtEmpty(); Index: lib/Sema/Sema.h =================================================================== --- lib/Sema/Sema.h (revision 71954) +++ lib/Sema/Sema.h (working copy) @@ -1172,9 +1172,9 @@ IdentifierInfo *II, SourceLocation ColonLoc, StmtArg SubStmt); - virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, - StmtArg ThenVal, SourceLocation ElseLoc, - StmtArg ElseVal); + virtual OwningStmtResult ActOnIfStmt(SourceLocation IfLoc, + FullExprArg CondVal, StmtArg ThenVal, + SourceLocation ElseLoc, StmtArg ElseVal); virtual OwningStmtResult ActOnStartOfSwitchStmt(ExprArg Cond); virtual OwningStmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch, StmtArg Body); Index: lib/Sema/SemaStmt.cpp =================================================================== --- lib/Sema/SemaStmt.cpp (revision 71954) +++ lib/Sema/SemaStmt.cpp (working copy) @@ -180,17 +180,19 @@ } Action::OwningStmtResult -Sema::ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, +Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, StmtArg ThenVal, SourceLocation ElseLoc, StmtArg ElseVal) { - Expr *condExpr = CondVal.takeAs(); + OwningExprResult CondResult(CondVal.release()); + + Expr *condExpr = CondResult.takeAs(); assert(condExpr && "ActOnIfStmt(): missing expression"); if (!condExpr->isTypeDependent()) { DefaultFunctionArrayConversion(condExpr); // Take ownership again until we're past the error checking. - CondVal = condExpr; + CondResult = condExpr; QualType condType = condExpr->getType(); if (getLangOptions().CPlusPlus) { @@ -213,7 +215,7 @@ Diag(stmt->getSemiLoc(), diag::warn_empty_if_body); } - CondVal.release(); + CondResult.release(); return Owned(new (Context) IfStmt(IfLoc, condExpr, thenStmt, ElseLoc, ElseVal.takeAs())); } Index: lib/Sema/SemaTemplateInstantiateStmt.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateStmt.cpp (revision 71954) +++ lib/Sema/SemaTemplateInstantiateStmt.cpp (working copy) @@ -25,6 +25,10 @@ Sema &SemaRef; const TemplateArgumentList &TemplateArgs; + Sema::FullExprArg FullExpr(Sema::ExprArg &expr) { + return SemaRef.FullExpr(expr); + } + public: typedef Sema::OwningExprResult OwningExprResult; typedef Sema::OwningStmtResult OwningStmtResult; @@ -225,7 +229,7 @@ if (Else.isInvalid()) return SemaRef.StmtError(); - return SemaRef.ActOnIfStmt(S->getIfLoc(), move(Cond), move(Then), + return SemaRef.ActOnIfStmt(S->getIfLoc(), FullExpr(Cond), move(Then), S->getElseLoc(), move(Else)); } Index: lib/Parse/ParseStmt.cpp =================================================================== --- lib/Parse/ParseStmt.cpp (revision 71954) +++ lib/Parse/ParseStmt.cpp (working copy) @@ -632,7 +632,7 @@ if (ElseStmt.isInvalid()) ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc); - return Actions.ActOnIfStmt(IfLoc, move(CondExp), move(ThenStmt), + return Actions.ActOnIfStmt(IfLoc, Actions.FullExpr(CondExp), move(ThenStmt), ElseLoc, move(ElseStmt)); }