diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-25 00:27:52 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-25 00:27:52 +0000 |
commit | 99e9b4d172f6877e6ba5ebe75bb8238721f5e01c (patch) | |
tree | 16c143b06b39022258614b713ed5999a7d7679c0 /lib/Sema/SemaStmt.cpp | |
parent | d1a7846699a82f85ff3ce6b2e383409537c3f5c5 (diff) |
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
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 109 |
1 files changed, 62 insertions, 47 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 61d48cb63e..be9a09bc1d 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -236,25 +236,24 @@ Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II, } Action::OwningStmtResult -Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, +Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DeclPtrTy CondVar, StmtArg ThenVal, SourceLocation ElseLoc, StmtArg ElseVal) { OwningExprResult CondResult(CondVal.release()); - Expr *condExpr = CondResult.takeAs<Expr>(); - assert(condExpr && "ActOnIfStmt(): missing expression"); - VarDecl *ConditionVar = 0; - if (CXXConditionDeclExpr *Cond = dyn_cast<CXXConditionDeclExpr>(condExpr)) { - ConditionVar = Cond->getVarDecl(); - condExpr = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, - ConditionVar->getLocation(), - ConditionVar->getType().getNonReferenceType()); - // FIXME: Leaks the old condExpr + if (CondVar.get()) { + ConditionVar = CondVar.getAs<VarDecl>(); + CondResult = CheckConditionVariable(ConditionVar); + if (CondResult.isInvalid()) + return StmtError(); } + Expr *ConditionExpr = CondResult.takeAs<Expr>(); + if (!ConditionExpr) + return StmtError(); - if (CheckBooleanCondition(condExpr, IfLoc)) { - CondResult = condExpr; + if (CheckBooleanCondition(ConditionExpr, IfLoc)) { + CondResult = ConditionExpr; return StmtError(); } @@ -274,23 +273,27 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, DiagnoseUnusedExprResult(elseStmt); CondResult.release(); - return Owned(new (Context) IfStmt(IfLoc, ConditionVar, condExpr, thenStmt, - ElseLoc, elseStmt)); + return Owned(new (Context) IfStmt(IfLoc, ConditionVar, ConditionExpr, + thenStmt, ElseLoc, elseStmt)); } Action::OwningStmtResult -Sema::ActOnStartOfSwitchStmt(ExprArg cond) { - Expr *condExpr = cond.takeAs<Expr>(); +Sema::ActOnStartOfSwitchStmt(FullExprArg cond, DeclPtrTy CondVar) { + OwningExprResult CondResult(cond.release()); + VarDecl *ConditionVar = 0; - if (CXXConditionDeclExpr *Cond = dyn_cast<CXXConditionDeclExpr>(condExpr)) { - ConditionVar = Cond->getVarDecl(); - condExpr = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, - ConditionVar->getLocation(), - ConditionVar->getType().getNonReferenceType()); - // FIXME: Leaks the old condExpr + if (CondVar.get()) { + ConditionVar = CondVar.getAs<VarDecl>(); + CondResult = CheckConditionVariable(ConditionVar); + if (CondResult.isInvalid()) + return StmtError(); } + Expr *ConditionExpr = CondResult.takeAs<Expr>(); + if (!ConditionExpr) + return StmtError(); - SwitchStmt *SS = new (Context) SwitchStmt(ConditionVar, condExpr); + CondResult.release(); + SwitchStmt *SS = new (Context) SwitchStmt(ConditionVar, ConditionExpr); getSwitchStack().push_back(SS); return Owned(SS); } @@ -715,30 +718,31 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, StmtArg Switch, } Action::OwningStmtResult -Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, StmtArg Body) { - ExprArg CondArg(Cond.release()); - Expr *condExpr = CondArg.takeAs<Expr>(); - assert(condExpr && "ActOnWhileStmt(): missing expression"); - +Sema::ActOnWhileStmt(SourceLocation WhileLoc, FullExprArg Cond, + DeclPtrTy CondVar, StmtArg Body) { + OwningExprResult CondResult(Cond.release()); + VarDecl *ConditionVar = 0; - if (CXXConditionDeclExpr *Cond = dyn_cast<CXXConditionDeclExpr>(condExpr)) { - ConditionVar = Cond->getVarDecl(); - condExpr = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, - ConditionVar->getLocation(), - ConditionVar->getType().getNonReferenceType()); - // FIXME: Leaks the old condExpr + if (CondVar.get()) { + ConditionVar = CondVar.getAs<VarDecl>(); + CondResult = CheckConditionVariable(ConditionVar); + if (CondResult.isInvalid()) + return StmtError(); } - - if (CheckBooleanCondition(condExpr, WhileLoc)) { - CondArg = condExpr; + Expr *ConditionExpr = CondResult.takeAs<Expr>(); + if (!ConditionExpr) + return StmtError(); + + if (CheckBooleanCondition(ConditionExpr, WhileLoc)) { + CondResult = ConditionExpr; return StmtError(); } Stmt *bodyStmt = Body.takeAs<Stmt>(); DiagnoseUnusedExprResult(bodyStmt); - CondArg.release(); - return Owned(new (Context) WhileStmt(ConditionVar, condExpr, bodyStmt, + CondResult.release(); + return Owned(new (Context) WhileStmt(ConditionVar, ConditionExpr, bodyStmt, WhileLoc)); } @@ -764,12 +768,10 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, StmtArg Body, Action::OwningStmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, - StmtArg first, ExprArg second, ExprArg third, + StmtArg first, FullExprArg second, DeclPtrTy secondVar, + FullExprArg third, SourceLocation RParenLoc, StmtArg body) { Stmt *First = static_cast<Stmt*>(first.get()); - Expr *Second = second.takeAs<Expr>(); - Expr *Third = static_cast<Expr*>(third.get()); - Stmt *Body = static_cast<Stmt*>(body.get()); if (!getLangOptions().CPlusPlus) { if (DeclStmt *DS = dyn_cast_or_null<DeclStmt>(First)) { @@ -787,20 +789,33 @@ Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, } } } + + OwningExprResult SecondResult(second.release()); + VarDecl *ConditionVar = 0; + if (secondVar.get()) { + ConditionVar = secondVar.getAs<VarDecl>(); + SecondResult = CheckConditionVariable(ConditionVar); + if (SecondResult.isInvalid()) + return StmtError(); + } + + Expr *Second = SecondResult.takeAs<Expr>(); if (Second && CheckBooleanCondition(Second, ForLoc)) { - second = Second; + SecondResult = Second; return StmtError(); } + Expr *Third = third.release().takeAs<Expr>(); + Stmt *Body = static_cast<Stmt*>(body.get()); + DiagnoseUnusedExprResult(First); DiagnoseUnusedExprResult(Third); DiagnoseUnusedExprResult(Body); first.release(); - third.release(); body.release(); - return Owned(new (Context) ForStmt(First, Second, Third, Body, ForLoc, - LParenLoc, RParenLoc)); + return Owned(new (Context) ForStmt(First, Second, ConditionVar, Third, Body, + ForLoc, LParenLoc, RParenLoc)); } Action::OwningStmtResult |