From a99fad8ff134273fe85f2970c7d89133d1218900 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 17 May 2009 18:26:53 +0000 Subject: [PATCH] Add the FullExprArg wrapper and use it for if statement conditions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71982 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Action.h | 40 ++++++++++++++++++++++-- include/clang/Parse/Parser.h | 1 + lib/Parse/ParseStmt.cpp | 2 +- lib/Sema/Sema.h | 6 ++-- lib/Sema/SemaStmt.cpp | 10 +++--- lib/Sema/SemaTemplateInstantiateStmt.cpp | 6 +++- tools/clang-cc/PrintParserCallbacks.cpp | 5 +-- 7 files changed, 57 insertions(+), 13 deletions(-) diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 6b137ce518..11f006b071 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -102,6 +102,34 @@ public: typedef ASTMultiPtr<&ActionBase::DeleteStmt> MultiStmtArg; typedef ASTMultiPtr<&ActionBase::DeleteTemplateParams> MultiTemplateParamsArg; + class FullExprArg { + public: + FullExprArg(const FullExprArg& Other) + : Expr(move(const_cast(Other).Expr)) {} + + OwningExprResult release() { + return move(Expr); + } + + ExprArg* operator->() { + return &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 @@ public: 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 @@ public: 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, diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index b70f2bba78..8ade37479b 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -141,6 +141,7 @@ public: 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) { diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 50db966aed..16b7a9f07f 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -632,7 +632,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement() { 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)); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 9a12dfd971..c4890499a6 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1172,9 +1172,9 @@ public: 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); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index d59443b2cb..5c04c2491f 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -180,17 +180,19 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, } 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 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, ExprArg CondVal, Diag(stmt->getSemiLoc(), diag::warn_empty_if_body); } - CondVal.release(); + CondResult.release(); return Owned(new (Context) IfStmt(IfLoc, condExpr, thenStmt, ElseLoc, ElseVal.takeAs())); } diff --git a/lib/Sema/SemaTemplateInstantiateStmt.cpp b/lib/Sema/SemaTemplateInstantiateStmt.cpp index 716bea7f7e..ce5ebb58dc 100644 --- a/lib/Sema/SemaTemplateInstantiateStmt.cpp +++ b/lib/Sema/SemaTemplateInstantiateStmt.cpp @@ -25,6 +25,10 @@ namespace { 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 @@ Sema::OwningStmtResult TemplateStmtInstantiator::VisitIfStmt(IfStmt *S) { 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)); } diff --git a/tools/clang-cc/PrintParserCallbacks.cpp b/tools/clang-cc/PrintParserCallbacks.cpp index ceb0500c3f..4ee48f072a 100644 --- a/tools/clang-cc/PrintParserCallbacks.cpp +++ b/tools/clang-cc/PrintParserCallbacks.cpp @@ -296,8 +296,9 @@ namespace { 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(); -- 2.40.0