diff --git a/hphp/compiler/analysis/alias_manager.cpp b/hphp/compiler/analysis/alias_manager.cpp index 4cd83721e..d6b4c6e89 100644 --- a/hphp/compiler/analysis/alias_manager.cpp +++ b/hphp/compiler/analysis/alias_manager.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,8 @@ #include #include #include +#include +#include #include #include #include @@ -601,7 +604,7 @@ void AliasManager::cleanRefs(ExpressionPtr e, if (e->is(Expression::KindOfAssignmentExpression) || e->is(Expression::KindOfBinaryOpExpression) || e->is(Expression::KindOfUnaryOpExpression)) { - ExpressionPtr var = e->getNthExpr(0); + ExpressionPtr var = e->getStoreVariable(); if (var->is(Expression::KindOfSimpleVariable) && !(var->getContext() & Expression::RefAssignmentLHS)) { SimpleVariablePtr sv(spc(SimpleVariable, var)); @@ -845,18 +848,11 @@ int AliasManager::checkInterf(ExpressionPtr rv, ExpressionPtr e, return testAccesses(e, rv, forLval); } + case Expression::KindOfAssignmentExpression: + case Expression::KindOfBinaryOpExpression: case Expression::KindOfUnaryOpExpression: isLoad = false; - return testAccesses( - spc(UnaryOpExpression,e)->getExpression(), rv, forLval); - case Expression::KindOfBinaryOpExpression: - isLoad = false; - return testAccesses( - spc(BinaryOpExpression,e)->getExp1(), rv, forLval); - case Expression::KindOfAssignmentExpression: - isLoad = false; - return testAccesses( - spc(AssignmentExpression,e)->getVariable(), rv, forLval); + return testAccesses(e->getStoreVariable(), rv, forLval); default: not_reached(); @@ -883,11 +879,9 @@ int AliasManager::checkAnyInterf(ExpressionPtr e1, ExpressionPtr e2, return DisjointAccess; } case Expression::KindOfAssignmentExpression: - e1 = spc(AssignmentExpression, e1)->getVariable(); - break; - case Expression::KindOfUnaryOpExpression: case Expression::KindOfBinaryOpExpression: - e1 = e1->getNthExpr(0); + case Expression::KindOfUnaryOpExpression: + e1 = e1->getStoreVariable(); if (!e1 || !e1->hasContext(Expression::OprLValue)) return DisjointAccess; break; default: @@ -1065,14 +1059,10 @@ void AliasManager::setCanonPtrForArrayCSE( // need to switch on rep ExpressionPtr rep0; switch (rep->getKindOf()) { - case Expression::KindOfUnaryOpExpression: - rep0 = spc(UnaryOpExpression, rep)->getExpression(); - break; - case Expression::KindOfBinaryOpExpression: - rep0 = spc(BinaryOpExpression, rep)->getExp1(); - break; case Expression::KindOfAssignmentExpression: - rep0 = spc(AssignmentExpression, rep)->getVariable(); + case Expression::KindOfBinaryOpExpression: + case Expression::KindOfUnaryOpExpression: + rep0 = rep->getStoreVariable(); break; case Expression::KindOfListAssignment: // TODO: IMPLEMENT @@ -1152,11 +1142,12 @@ ExpressionPtr AliasManager::canonicalizeNode( return ExpressionPtr(); } + ExpressionPtr var; switch (e->getKindOf()) { - case Expression::KindOfAssignmentExpression: + case Expression::KindOfAssignmentExpression: { case Expression::KindOfBinaryOpExpression: - case Expression::KindOfUnaryOpExpression: { - ExpressionPtr var = e->getNthExpr(0); + case Expression::KindOfUnaryOpExpression: + ExpressionPtr var = e->getStoreVariable(); if (var && var->getContext() & (Expression::AssignmentLHS| Expression::OprLValue)) { processAccessChain(var); @@ -1383,7 +1374,7 @@ ExpressionPtr AliasManager::canonicalizeNode( value = value->replaceValue( canonicalizeRecurNonNull( value->makeConstant(m_arp, "null"))); - a->setNthKid(1, value); + a->setValue(value); a->recomputeEffects(); setChanged(); } else { @@ -1394,7 +1385,7 @@ ExpressionPtr AliasManager::canonicalizeNode( a = spc(AssignmentExpression, a->clone()); el->addElement(a); el->addElement(a->getValue()); - a->setNthKid(1, value->makeConstant(m_arp, "null")); + a->setValue(value->makeConstant(m_arp, "null")); rep->setReplacement(el); m_replaced++; } @@ -1567,8 +1558,8 @@ ExpressionPtr AliasManager::canonicalizeNode( Expression::UnsetContext))) { rep = ae->clone(); ae->setContext(Expression::DeadStore); - ae->setNthKid(1, ae->makeConstant(m_arp, "null")); - ae->setNthKid(0, ae->makeConstant(m_arp, "null")); + ae->setValue(ae->makeConstant(m_arp, "null")); + ae->setVariable(ae->makeConstant(m_arp, "null")); e->recomputeEffects(); m_replaced++; return e->replaceValue(canonicalizeRecurNonNull(rep)); @@ -1703,13 +1694,9 @@ ExpressionPtr AliasManager::canonicalizeNode( if (interf == SameAccess) { switch (alt->getKindOf()) { case Expression::KindOfAssignmentExpression: - alt = spc(AssignmentExpression,alt)->getVariable(); - break; case Expression::KindOfBinaryOpExpression: - alt = spc(BinaryOpExpression,alt)->getExp1(); - break; case Expression::KindOfUnaryOpExpression: - alt = spc(UnaryOpExpression,alt)->getExpression(); + alt = alt->getStoreVariable(); break; default: break; @@ -1750,6 +1737,8 @@ ExpressionPtr AliasManager::canonicalizeNode( } void AliasManager::canonicalizeKid(ConstructPtr c, ExpressionPtr kid, int i) { + assert(c->getNthKid(i) == kid); + if (kid) { StatementPtr sp(dpc(Statement, c)); if (sp) beginInExpression(sp, kid); @@ -1769,6 +1758,8 @@ void AliasManager::canonicalizeKid(ConstructPtr c, ExpressionPtr kid, int i) { } int AliasManager::canonicalizeKid(ConstructPtr c, ConstructPtr kid, int i) { + assert(c->getNthKid(i) == kid); + int ret = FallThrough; if (kid) { ExpressionPtr e = dpc(Expression, kid); @@ -1802,30 +1793,29 @@ ExpressionPtr AliasManager::canonicalizeRecur(ExpressionPtr e) { bool setInCall = true; switch (e->getKindOf()) { - case Expression::KindOfQOpExpression: - canonicalizeKid(e, e->getNthExpr(0), 0); + case Expression::KindOfQOpExpression: { + QOpExpressionPtr qe(spc(QOpExpression, e)); + canonicalizeKid(e, qe->getCondition(), 0); beginScope(); - if (ExpressionPtr e1 = e->getNthExpr(1)) { + if (ExpressionPtr e1 = qe->getYes()) { canonicalizeKid(e, e1, 1); resetScope(); } - canonicalizeKid(e, e->getNthExpr(2), 2); + canonicalizeKid(e, qe->getNo(), 2); endScope(); return canonicalizeNode(e); - - case Expression::KindOfBinaryOpExpression: - { - BinaryOpExpressionPtr binop(spc(BinaryOpExpression, e)); - if (binop->isShortCircuitOperator()) { - canonicalizeKid(e, e->getNthExpr(0), 0); - beginScope(); - canonicalizeKid(e, e->getNthExpr(1), 1); - endScope(); - return canonicalizeNode(e); - } + } + case Expression::KindOfBinaryOpExpression: { + BinaryOpExpressionPtr binop(spc(BinaryOpExpression, e)); + if (binop->isShortCircuitOperator()) { + canonicalizeKid(e, binop->getExp1(), 0); + beginScope(); + canonicalizeKid(e, binop->getExp2(), 1); + endScope(); + return canonicalizeNode(e); } break; - + } case Expression::KindOfExpressionList: delayVars = false; break; @@ -1937,42 +1927,42 @@ StatementPtr AliasManager::canonicalizeRecur(StatementPtr s, int &ret) { // and fall through break; - case Statement::KindOfIfStatement: - { - StatementPtr iflist = spc(Statement, s->getNthKid(0)); - if (iflist) { - for (int i = 0, n = iflist->getKidCount(); i < n; i++) { - StatementPtr ifstmt = spc(Statement, iflist->getNthKid(i)); - ExpressionPtr cond = spc(Expression, ifstmt->getNthKid(0)); - canonicalizeKid(ifstmt, cond, 0); - if (!i) beginScope(); - beginScope(); - canonicalizeKid(ifstmt, ifstmt->getNthKid(1), 1); - endScope(); - if (i+1 < n) resetScope(); - } + case Statement::KindOfIfStatement: { + IfStatementPtr is = spc(IfStatement, s); + StatementListPtr iflist = is->getIfBranches(); + if (iflist) { + for (int i = 0, n = iflist->getKidCount(); i < n; i++) { + IfBranchStatementPtr ifstmt = spc(IfBranchStatement, (*iflist)[i]); + canonicalizeKid(ifstmt, ifstmt->getCondition(), 0); + if (!i) beginScope(); + beginScope(); + canonicalizeKid(ifstmt, ifstmt->getStmt(), 1); endScope(); + if (i+1 < n) resetScope(); } - ret = FallThrough; - start = nkid; + endScope(); } + ret = FallThrough; + start = nkid; break; + } case Statement::KindOfIfBranchStatement: always_assert(0); break; - case Statement::KindOfForStatement: - canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0); + case Statement::KindOfForStatement: { + ForStatementPtr fs(spc(ForStatement, s)); + canonicalizeKid(s, fs->getInitExp(), 0); clear(); - canonicalizeKid(s, spc(Expression,s->getNthKid(1)), 1); - canonicalizeKid(s, s->getNthKid(2), 2); + canonicalizeKid(s, fs->getCondExp(), 1); + canonicalizeKid(s, fs->getBody(), 2); clear(); - canonicalizeKid(s, spc(Expression,s->getNthKid(3)), 3); + canonicalizeKid(s, fs->getIncExp(), 3); ret = Converge; start = nkid; break; - + } case Statement::KindOfWhileStatement: case Statement::KindOfDoStatement: case Statement::KindOfForEachStatement: @@ -1980,27 +1970,27 @@ StatementPtr AliasManager::canonicalizeRecur(StatementPtr s, int &ret) { ret = Converge; break; - case Statement::KindOfSwitchStatement: - canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0); + case Statement::KindOfSwitchStatement: { + SwitchStatementPtr ss(spc(SwitchStatement, s)); + canonicalizeKid(s, ss->getExp(), 0); clear(); start = 1; ret = Converge; break; - + } case Statement::KindOfCaseStatement: case Statement::KindOfLabelStatement: clear(); break; - case Statement::KindOfReturnStatement: - { - canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0); + case Statement::KindOfReturnStatement: { + ReturnStatementPtr rs(spc(ReturnStatement, s)); + canonicalizeKid(s, rs->getRetExp(), 0); killLocals(); ret = FallThrough; start = nkid; break; } - case Statement::KindOfBreakStatement: case Statement::KindOfContinueStatement: case Statement::KindOfGotoStatement: @@ -2126,7 +2116,10 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) { case Statement::KindOfGlobalStatement: case Statement::KindOfStaticStatement: { - ExpressionListPtr vars = dpc(ExpressionList, s->getNthKid(0)); + ExpressionListPtr vars = (skind == Statement::KindOfGlobalStatement) + ? spc(GlobalStatement, s)->getVars() + : spc(StaticStatement, s)->getVars(); + for (int i = 0, n = vars->getCount(); i < n; i++) { ExpressionPtr e = (*vars)[i]; if (AssignmentExpressionPtr ae = dpc(AssignmentExpression, e)) { @@ -2182,14 +2175,13 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) { } break; case Statement::KindOfForEachStatement: { - SimpleVariablePtr name = - dpc(SimpleVariable, s->getNthKid(ForEachStatement::NameExpr)); + ForEachStatementPtr fs(static_pointer_cast(s)); + SimpleVariablePtr name = dpc(SimpleVariable, fs->getNameExp()); if (name) { Symbol *sym = name->getSymbol(); sym->setNeeded(); } - SimpleVariablePtr value = - dpc(SimpleVariable, s->getNthKid(ForEachStatement::ValueExpr)); + SimpleVariablePtr value = dpc(SimpleVariable, fs->getValueExp()); if (value) { Symbol *sym = value->getSymbol(); sym->setNeeded(); @@ -2403,14 +2395,14 @@ int AliasManager::collectAliasInfoRecur(ConstructPtr cs, bool unused) { } break; } - - case Expression::KindOfQOpExpression: + case Expression::KindOfQOpExpression: { + QOpExpressionPtr q(spc(QOpExpression, e)); if (unused) { - if (ExpressionPtr t1 = e->getNthExpr(1)) t1->setUnused(true); - e->getNthExpr(2)->setUnused(true); + if (ExpressionPtr t1 = q->getYes()) t1->setUnused(true); + q->getNo()->setUnused(true); } break; - + } default: break; } @@ -2969,8 +2961,9 @@ private: if (!e) return ExpressionPtr(); if (FunctionWalker::SkipRecurse(e)) return ExpressionPtr(); - int loopCondIdx = -1, loopBodyIdx = -1; - std::vector needed; + ExpressionPtr loopCond; + StatementPtr loopBody; + std::vector needed; switch (e->getKindOf()) { case Statement::KindOfIfStatement: { @@ -3042,46 +3035,45 @@ private: } } return ExpressionPtr(); - case Statement::KindOfForStatement: - loopCondIdx = ForStatement::CondExpr; - loopBodyIdx = ForStatement::BodyStmt; - needed.push_back(ForStatement::InitExpr); - needed.push_back(ForStatement::IncExpr); + case Statement::KindOfForStatement: { + ForStatementPtr fs(static_pointer_cast(e)); + loopCond = fs->getCondExp(); + loopBody = fs->getBody(); + needed.push_back(fs->getInitExp()); + needed.push_back(fs->getIncExp()); goto loop_stmt; - case Statement::KindOfWhileStatement: - loopCondIdx = WhileStatement::CondExpr; - loopBodyIdx = WhileStatement::BodyStmt; + } + case Statement::KindOfWhileStatement: { + WhileStatementPtr ws(static_pointer_cast(e)); + loopCond = ws->getCondExp(); + loopBody = ws->getBody(); goto loop_stmt; - case Statement::KindOfDoStatement: - loopCondIdx = DoStatement::CondExpr; - loopBodyIdx = DoStatement::BodyStmt; + } + case Statement::KindOfDoStatement: { + DoStatementPtr ds(static_pointer_cast(e)); + loopCond = ds->getCondExp(); + loopBody = ds->getBody(); + } loop_stmt: { - assert(loopCondIdx >= 0); - assert(loopBodyIdx >= 0); - if (e->getNthKid(loopCondIdx)) { + if (loopCond) { bool passStmt; bool negate; - ExpressionPtr after(createTypeAssertions( - spc(Expression, e->getNthKid(loopCondIdx)), passStmt, negate)); + ExpressionPtr after(createTypeAssertions(loopCond, passStmt, negate)); if (after && !negate) { - insertTypeAssertion( - after, dpc(Statement, e->getNthKid(loopBodyIdx))); + insertTypeAssertion(after, loopBody); } } - for (std::vector::const_iterator it = needed.begin(); - it != needed.end(); - ++it) { - ExpressionPtr k(dpc(Expression, e->getNthKid(*it))); + for (auto it = needed.begin(); it != needed.end(); ++it) { + ExpressionPtr k(dpc(Expression, *it)); if (k) { bool passStmt; bool negate; createTypeAssertions(k, passStmt, negate); } } - ConstructPtr body(e->getNthKid(loopBodyIdx)); - createTypeAssertions(dpc(Statement, body)); + createTypeAssertions(loopBody); } return ExpressionPtr(); case Statement::KindOfStatementList: @@ -3906,7 +3898,8 @@ void AliasManager::invalidateChainRoots(StatementPtr s) { // otherwise we'd have to declare all CSE temps like: // declare_temps; // do { ... } while (cond); - disableCSE(s->getNthStmt(DoStatement::BodyStmt)); + DoStatementPtr ds(static_pointer_cast(s)); + disableCSE(ds->getBody()); } // fall through default: @@ -3917,47 +3910,56 @@ void AliasManager::invalidateChainRoots(StatementPtr s) { } } -void AliasManager::nullSafeDisableCSE(StatementPtr parent, int kid) { +void AliasManager::nullSafeDisableCSE(StatementPtr parent, ExpressionPtr kid) { assert(parent); - ConstructPtr c(parent->getNthKid(kid)); - if (!c) return; - ExpressionPtr e(dpc(Expression, c)); - assert(e); - e->disableCSE(); + if (!kid) return; + kid->disableCSE(); } void AliasManager::disableCSE(StatementPtr s) { if (!s) return; switch (s->getKindOf()) { - case Statement::KindOfIfBranchStatement: - nullSafeDisableCSE(s, 0); + case Statement::KindOfIfBranchStatement: { + IfBranchStatementPtr is(static_pointer_cast(s)); + nullSafeDisableCSE(s, is->getCondition()); break; - case Statement::KindOfSwitchStatement: - nullSafeDisableCSE(s, 0); + } + case Statement::KindOfSwitchStatement: { + SwitchStatementPtr ss(static_pointer_cast(s)); + nullSafeDisableCSE(s, ss->getExp()); break; - case Statement::KindOfForStatement: - nullSafeDisableCSE(s, ForStatement::InitExpr); - nullSafeDisableCSE(s, ForStatement::CondExpr); - nullSafeDisableCSE(s, ForStatement::IncExpr); + } + case Statement::KindOfForStatement: { + ForStatementPtr fs(static_pointer_cast(s)); + nullSafeDisableCSE(s, fs->getInitExp()); + nullSafeDisableCSE(s, fs->getCondExp()); + nullSafeDisableCSE(s, fs->getIncExp()); break; - case Statement::KindOfForEachStatement: - nullSafeDisableCSE(s, ForEachStatement::ArrayExpr); - nullSafeDisableCSE(s, ForEachStatement::NameExpr); - nullSafeDisableCSE(s, ForEachStatement::ValueExpr); + } + case Statement::KindOfForEachStatement: { + ForEachStatementPtr fs(static_pointer_cast(s)); + nullSafeDisableCSE(s, fs->getArrayExp()); + nullSafeDisableCSE(s, fs->getNameExp()); + nullSafeDisableCSE(s, fs->getValueExp()); break; - case Statement::KindOfWhileStatement: - nullSafeDisableCSE(s, WhileStatement::CondExpr); + } + case Statement::KindOfWhileStatement: { + WhileStatementPtr ws(static_pointer_cast(s)); + nullSafeDisableCSE(s, ws->getCondExp()); break; - case Statement::KindOfDoStatement: - nullSafeDisableCSE(s, DoStatement::CondExpr); + } + case Statement::KindOfDoStatement: { + DoStatementPtr ds(static_pointer_cast(s)); + nullSafeDisableCSE(s, ds->getCondExp()); break; + } default: for (int i = s->getKidCount(); i--; ) { ConstructPtr c(s->getNthKid(i)); if (StatementPtr skid = dpc(Statement, c)) { disableCSE(skid); } else { - nullSafeDisableCSE(s, i); + nullSafeDisableCSE(s, dpc(Expression, c)); } } break; @@ -4101,38 +4103,42 @@ void AliasManager::stringOptsRecur(StatementPtr s) { } break; - case Statement::KindOfForStatement: - stringOptsRecur(spc(Expression,s->getNthKid(0)), true); + case Statement::KindOfForStatement: { + ForStatementPtr fs = spc(ForStatement, s); + stringOptsRecur(fs->getInitExp(), true); pushStringScope(s); - stringOptsRecur(spc(Expression,s->getNthKid(1)), false); - stringOptsRecur(spc(Statement, s->getNthKid(2))); - stringOptsRecur(spc(Expression,s->getNthKid(3)), true); + stringOptsRecur(fs->getCondExp(), false); + stringOptsRecur(fs->getBody()); + stringOptsRecur(fs->getIncExp(), true); popStringScope(s); return; - - case Statement::KindOfWhileStatement: + } + case Statement::KindOfWhileStatement: { + WhileStatementPtr ws = spc(WhileStatement, s); pushStringScope(s); - stringOptsRecur(spc(Expression,s->getNthKid(0)), false); - stringOptsRecur(spc(Statement, s->getNthKid(1))); + stringOptsRecur(ws->getCondExp(), false); + stringOptsRecur(ws->getBody()); popStringScope(s); return; - - case Statement::KindOfDoStatement: + } + case Statement::KindOfDoStatement: { + DoStatementPtr ds = spc(DoStatement, s); pushStringScope(s); - stringOptsRecur(spc(Statement, s->getNthKid(0))); - stringOptsRecur(spc(Expression,s->getNthKid(1)), false); + stringOptsRecur(ds->getBody()); + stringOptsRecur(ds->getCondExp(), false); popStringScope(s); return; - - case Statement::KindOfForEachStatement: - stringOptsRecur(spc(Expression,s->getNthKid(0)), false); - stringOptsRecur(spc(Expression,s->getNthKid(1)), false); - stringOptsRecur(spc(Expression,s->getNthKid(2)), false); + } + case Statement::KindOfForEachStatement: { + ForEachStatementPtr fs = spc(ForEachStatement, s); + stringOptsRecur(fs->getArrayExp(), false); + stringOptsRecur(fs->getNameExp(), false); + stringOptsRecur(fs->getValueExp(), false); pushStringScope(s); - stringOptsRecur(spc(Statement, s->getNthKid(3))); + stringOptsRecur(fs->getBody()); popStringScope(s); return; - + } case Statement::KindOfExpStatement: stringOptsRecur(spc(ExpStatement,s)->getExpression(), true); return; diff --git a/hphp/compiler/analysis/alias_manager.h b/hphp/compiler/analysis/alias_manager.h index 2aa9f8a40..4f39d5057 100644 --- a/hphp/compiler/analysis/alias_manager.h +++ b/hphp/compiler/analysis/alias_manager.h @@ -205,7 +205,7 @@ class AliasManager { StatementPtr canonicalizeRecur(StatementPtr e, int &ret); void invalidateChainRoots(StatementPtr s); - void nullSafeDisableCSE(StatementPtr parent, int kid); + void nullSafeDisableCSE(StatementPtr parent, ExpressionPtr kid); void disableCSE(StatementPtr s); void createCFG(MethodStatementPtr m); void deleteCFG(); diff --git a/hphp/compiler/analysis/control_flow.cpp b/hphp/compiler/analysis/control_flow.cpp index e20227fa7..3eb9ba558 100644 --- a/hphp/compiler/analysis/control_flow.cpp +++ b/hphp/compiler/analysis/control_flow.cpp @@ -329,9 +329,10 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) { } case Statement::KindOfForStatement: { - ConstructRawPtr cond(s->getNthKid(ForStatement::CondExpr)); - ConstructRawPtr body(s->getNthKid(ForStatement::BodyStmt)); - ConstructRawPtr incr(s->getNthKid(ForStatement::IncExpr)); + ForStatementPtr fs(static_pointer_cast(s)); + ConstructRawPtr body(fs->getBody()); + ConstructRawPtr cond(fs->getCondExp()); + ConstructRawPtr incr(fs->getIncExp()); if (cond) addEdge(cond, AfterConstruct, s, AfterConstruct); ConstructRawPtr end = incr ? incr : body ? body : cond; ConstructRawPtr start = cond ? cond : body ? body : incr; @@ -341,8 +342,9 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) { } case Statement::KindOfWhileStatement: { - ConstructRawPtr cond(s->getNthKid(WhileStatement::CondExpr)); - ConstructRawPtr body(s->getNthKid(WhileStatement::BodyStmt)); + WhileStatementPtr ws(static_pointer_cast(s)); + ConstructRawPtr body(ws->getBody()); + ConstructRawPtr cond(ws->getCondExp()); addEdge(cond, AfterConstruct, s, AfterConstruct); addEdge(body ? body : cond, AfterConstruct, cond, BeforeConstruct); noFallThrough(s); @@ -350,15 +352,16 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) { } case Statement::KindOfDoStatement: { - ConstructRawPtr cond(s->getNthKid(DoStatement::CondExpr)); - addEdge(cond, AfterConstruct, s, BeforeConstruct); + DoStatementPtr ds(static_pointer_cast(s)); + addEdge(ds->getCondExp(), AfterConstruct, s, BeforeConstruct); break; } case Statement::KindOfForEachStatement: { - ConstructRawPtr body(s->getNthKid(ForEachStatement::BodyStmt)); - ConstructRawPtr name(s->getNthKid(ForEachStatement::NameExpr)); - ConstructRawPtr value(s->getNthKid(ForEachStatement::ValueExpr)); + ForEachStatementPtr fs(static_pointer_cast(s)); + ConstructRawPtr body(fs->getBody()); + ConstructRawPtr name(fs->getNameExp()); + ConstructRawPtr value(fs->getValueExp()); ConstructRawPtr begin = name ? name : value; ConstructRawPtr end = body ? body : value; addEdge(end, AfterConstruct, begin, BeforeConstruct); @@ -450,23 +453,31 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) { } else { ConstructRawPtr kid; switch (l->getKindOf()) { - case Statement::KindOfForEachStatement: - kid = l->getNthKid(ForEachStatement::NameExpr); + case Statement::KindOfForEachStatement: { + ForEachStatementPtr fs(static_pointer_cast(l)); + kid = fs->getNameExp(); if (!kid) { - kid = l->getNthKid(ForEachStatement::ValueExpr); + kid = fs->getValueExp(); } break; - case Statement::KindOfForStatement: - kid = l->getNthKid(ForStatement::IncExpr); - if (!kid) kid = l->getNthKid(ForStatement::CondExpr); - if (!kid) kid = l->getNthKid(ForStatement::BodyStmt); + } + case Statement::KindOfForStatement: { + ForStatementPtr fs(static_pointer_cast(l)); + kid = fs->getIncExp(); + if (!kid) kid = fs->getCondExp(); + if (!kid) kid = fs->getBody(); break; - case Statement::KindOfWhileStatement: - kid = l->getNthKid(WhileStatement::CondExpr); + } + case Statement::KindOfWhileStatement: { + WhileStatementPtr ws(static_pointer_cast(l)); + kid = ws->getCondExp(); break; - case Statement::KindOfDoStatement: - kid = l->getNthKid(DoStatement::CondExpr); + } + case Statement::KindOfDoStatement: { + DoStatementPtr ds(static_pointer_cast(l)); + kid = ds->getCondExp(); break; + } default: always_assert(0); } @@ -495,36 +506,36 @@ int ControlFlowBuilder::before(ConstructRawPtr cp) { } else { ExpressionPtr e(dynamic_pointer_cast(cp)); switch (e->getKindOf()) { - case Expression::KindOfBinaryOpExpression: - { - BinaryOpExpressionPtr b( - static_pointer_cast(e)); - if (b->isShortCircuitOperator()) { - ConstructPtr trueBranch, falseBranch; - ConstructLocation tLoc, fLoc; - getTrueFalseBranches(0, trueBranch, tLoc, falseBranch, fLoc); - assert(trueBranch); - assert(falseBranch); - if (b->isLogicalOrOperator()) { - addEdge(e->getNthExpr(0), AfterConstruct, trueBranch, tLoc); - } else { - addEdge(e->getNthExpr(0), AfterConstruct, falseBranch, fLoc); - } + case Expression::KindOfBinaryOpExpression: { + BinaryOpExpressionPtr b(static_pointer_cast(e)); + if (b->isShortCircuitOperator()) { + ConstructPtr trueBranch, falseBranch; + ConstructLocation tLoc, fLoc; + getTrueFalseBranches(0, trueBranch, tLoc, falseBranch, fLoc); + assert(trueBranch); + assert(falseBranch); + if (b->isLogicalOrOperator()) { + addEdge(b->getExp1(), AfterConstruct, trueBranch, tLoc); + } else { + addEdge(b->getExp1(), AfterConstruct, falseBranch, fLoc); } } break; - case Expression::KindOfQOpExpression: - if (ExpressionPtr e1 = e->getNthExpr(1)) { - addEdge(e->getNthExpr(0), AfterConstruct, - e->getNthExpr(2), BeforeConstruct); + } + case Expression::KindOfQOpExpression: { + QOpExpressionPtr q(static_pointer_cast(e)); + if (ExpressionPtr e1 = q->getYes()) { + addEdge(q->getCondition(), AfterConstruct, + q->getNo(), BeforeConstruct); addEdge(e1, AfterConstruct, - e->getNthExpr(2), AfterConstruct); + q->getNo(), AfterConstruct); noFallThrough(e1); } else { - addEdge(e->getNthExpr(0), AfterConstruct, - e->getNthExpr(2), AfterConstruct); + addEdge(q->getCondition(), AfterConstruct, + q->getNo(), AfterConstruct); } break; + } default: break; } @@ -586,32 +597,36 @@ void ControlFlowBuilder::getTrueFalseBranches( ConstructPtr c(top(level)); if (StatementPtr s = dynamic_pointer_cast(c)) { - int kidBodyIdx = -1; + StatementPtr kidBody; switch (s->getKindOf()) { - case Statement::KindOfForStatement: + case Statement::KindOfForStatement: { // examine which context we're in - { - ConstructPtr kid(top(level - 1)); - if (kid == s->getNthKid(ForStatement::InitExpr)) { - ; // just do the default case - } else if (kid == s->getNthKid(ForStatement::CondExpr)) { - kidBodyIdx = ForStatement::BodyStmt; - goto loop_stmt; - } else if (kid == s->getNthKid(ForStatement::IncExpr)) { - ; // just do the default case - } else { - assert(false); - } + ForStatementPtr fs(static_pointer_cast(s)); + ConstructPtr kid(top(level - 1)); + if (kid == fs->getInitExp()) { + ; // just do the default case + } else if (kid == fs->getCondExp()) { + kidBody = fs->getBody(); + goto loop_stmt; + } else if (kid == fs->getIncExp()) { + ; // just do the default case + } else { + assert(false); } break; - case Statement::KindOfWhileStatement: - kidBodyIdx = WhileStatement::BodyStmt; + } + case Statement::KindOfWhileStatement: { + WhileStatementPtr ws(static_pointer_cast(s)); + kidBody = ws->getBody(); goto loop_stmt; - case Statement::KindOfDoStatement: - kidBodyIdx = DoStatement::BodyStmt; + } + case Statement::KindOfDoStatement: { + DoStatementPtr ds(static_pointer_cast(s)); + kidBody = ds->getBody(); + } loop_stmt: if (!trueBranch) { - trueBranch = s->getNthKid(kidBodyIdx); + trueBranch = kidBody; tLoc = BeforeConstruct; } if (!falseBranch) { diff --git a/hphp/compiler/analysis/data_flow.cpp b/hphp/compiler/analysis/data_flow.cpp index 804cad4ae..12913f05a 100644 --- a/hphp/compiler/analysis/data_flow.cpp +++ b/hphp/compiler/analysis/data_flow.cpp @@ -350,12 +350,13 @@ void DataFlowWalker::process(ExpressionPtr e, bool doAccessChains) { case Expression::KindOfAssignmentExpression: case Expression::KindOfBinaryOpExpression: case Expression::KindOfUnaryOpExpression: { - ExpressionPtr var = e->getNthExpr(0); + ExpressionPtr var = e->getStoreVariable(); if (var && var->getContext() & (Expression::AssignmentLHS| Expression::OprLValue)) { processAccessChain(var); processAccess(var); } + // fall through } default: processAccess(e); diff --git a/hphp/compiler/analysis/emitter.cpp b/hphp/compiler/analysis/emitter.cpp index 3b4612677..b5e05e1ee 100644 --- a/hphp/compiler/analysis/emitter.cpp +++ b/hphp/compiler/analysis/emitter.cpp @@ -1980,7 +1980,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { // Dynamic break/continue. if (n == 0) { // Depth can't be statically determined. - visit(bs->getNthKid(0)); + visit(bs->getExp()); emitConvertToCell(e); } else { // Dynamic break/continue with statically known depth. @@ -2002,6 +2002,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { } case Statement::KindOfDoStatement: { + DoStatementPtr ds(static_pointer_cast(s)); Label top(e); Label condition; Label exit; @@ -2009,12 +2010,11 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { Label cntHand; { CONTROL_BODY(exit, condition, brkHand, cntHand); - visit(node->getNthKid(DoStatement::BodyStmt)); + visit(ds->getBody()); } condition.set(e); { - ExpressionPtr c(static_pointer_cast( - node->getNthKid(DoStatement::CondExpr))); + ExpressionPtr c = ds->getCondExp(); Emitter condEmitter(c, m_ue, *this); visitIfCondition(c, condEmitter, top, exit, false); } @@ -2060,15 +2060,16 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { } case Statement::KindOfExpStatement: { - assert(node->getKidCount() == 1); - if (visit(node->getNthKid(0))) { + ExpStatementPtr es(static_pointer_cast(s)); + if (visit(es->getExpression())) { emitPop(e); } return false; } case Statement::KindOfForStatement: { - if (visit(node->getNthKid(ForStatement::InitExpr))) { + ForStatementPtr fs(static_pointer_cast(s)); + if (visit(fs->getInitExp())) { emitPop(e); } Label preCond(e); @@ -2076,20 +2077,18 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { Label fail; Label brkHand; Label cntHand; - if (ConstructPtr n = node->getNthKid(ForStatement::CondExpr)) { + if (ExpressionPtr condExp = fs->getCondExp()) { Label tru; - Emitter condEmitter(static_pointer_cast(n), - m_ue, *this); - visitIfCondition(static_pointer_cast(n), - condEmitter, tru, fail, true); + Emitter condEmitter(condExp, m_ue, *this); + visitIfCondition(condExp, condEmitter, tru, fail, true); if (tru.isUsed()) tru.set(e); } { CONTROL_BODY(fail, preInc, brkHand, cntHand); - visit(node->getNthKid(ForStatement::BodyStmt)); + visit(fs->getBody()); } preInc.set(e); - if (visit(node->getNthKid(ForStatement::IncExpr))) { + if (visit(fs->getIncExp())) { emitPop(e); } e.Jmp(preCond); @@ -2411,7 +2410,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { TryStatementPtr ts = static_pointer_cast(node); Offset start = m_ue.bcPos(); - visit(ts->getNthKid(0)); + visit(ts->getBody()); // include the jump out of the try-catch block in the // exception handler address range e.Jmp(after); @@ -2467,21 +2466,21 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) { } case Statement::KindOfWhileStatement: { + WhileStatementPtr ws(static_pointer_cast(s)); Label preCond(e); Label fail; Label brkHand; Label cntHand; { Label tru; - ExpressionPtr c(static_pointer_cast( - node->getNthKid(WhileStatement::CondExpr))); + ExpressionPtr c(ws->getCondExp()); Emitter condEmitter(c, m_ue, *this); visitIfCondition(c, condEmitter, tru, fail, true); if (tru.isUsed()) tru.set(e); } { CONTROL_BODY(fail, preCond, brkHand, cntHand); - visit(node->getNthKid(WhileStatement::BodyStmt)); + visit(ws->getBody()); } e.Jmp(preCond); emitBreakHandler(e, fail, preCond, brkHand, cntHand); @@ -6335,14 +6334,10 @@ class ForeachIterGuard { }; void EmitterVisitor::emitForeach(Emitter& e, ForEachStatementPtr fe) { - ExpressionPtr ae(static_pointer_cast( - fe->getNthKid(ForEachStatement::ArrayExpr))); - ExpressionPtr val(static_pointer_cast( - fe->getNthKid(ForEachStatement::ValueExpr))); - ExpressionPtr key(static_pointer_cast( - fe->getNthKid(ForEachStatement::NameExpr))); - StatementPtr body(static_pointer_cast( - fe->getNthKid(ForEachStatement::BodyStmt))); + ExpressionPtr ae(fe->getArrayExp()); + ExpressionPtr val(fe->getValueExp()); + ExpressionPtr key(fe->getNameExp()); + StatementPtr body(fe->getBody()); int keyTempLocal; int valTempLocal; bool strong = fe->isStrong(); diff --git a/hphp/compiler/analysis/expr_dict.cpp b/hphp/compiler/analysis/expr_dict.cpp index fd105ec6b..79101d7bb 100644 --- a/hphp/compiler/analysis/expr_dict.cpp +++ b/hphp/compiler/analysis/expr_dict.cpp @@ -313,7 +313,7 @@ void ExprDict::updateAccess(ExpressionPtr e) { BitOps::set_bit(aid, m_altered, true); } if (!(cls & Expression::Store) || - a != e->getNthExpr(0)) { + a != e->getStoreVariable()) { a->clearAvailable(); m_avlAccess[i] = m_avlAccess[--n]; m_avlAccess.resize(n); diff --git a/hphp/compiler/analysis/symbol_table.cpp b/hphp/compiler/analysis/symbol_table.cpp index ebedc6299..6c38414cb 100644 --- a/hphp/compiler/analysis/symbol_table.cpp +++ b/hphp/compiler/analysis/symbol_table.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -295,20 +296,18 @@ void Symbol::serializeParam(JSON::DocTarget::OutputStream &out) const { static inline std::string ExtractDocComment(ExpressionPtr e) { if (!e) return ""; switch (e->getKindOf()) { - case Expression::KindOfAssignmentExpression: - return ExtractDocComment(e->getNthExpr(0)); - case Expression::KindOfSimpleVariable: - { - SimpleVariablePtr sv( - static_pointer_cast(e)); - return sv->getDocComment(); - } - case Expression::KindOfConstantExpression: - { - ConstantExpressionPtr ce( - static_pointer_cast(e)); - return ce->getDocComment(); - } + case Expression::KindOfAssignmentExpression: { + AssignmentExpressionPtr ae(static_pointer_cast(e)); + return ExtractDocComment(ae->getVariable()); + } + case Expression::KindOfSimpleVariable: { + SimpleVariablePtr sv(static_pointer_cast(e)); + return sv->getDocComment(); + } + case Expression::KindOfConstantExpression: { + ConstantExpressionPtr ce(static_pointer_cast(e)); + return ce->getDocComment(); + } default: return ""; } return ""; diff --git a/hphp/compiler/expression/assignment_expression.h b/hphp/compiler/expression/assignment_expression.h index efd2e621b..8f0b2e3dc 100644 --- a/hphp/compiler/expression/assignment_expression.h +++ b/hphp/compiler/expression/assignment_expression.h @@ -45,7 +45,9 @@ public: } ExpressionPtr getVariable() { return m_variable;} + ExpressionPtr getStoreVariable() const { return m_variable; } ExpressionPtr getValue() { return m_value;} + void setVariable(ExpressionPtr v) { m_variable = v; } void setValue(ExpressionPtr v) { m_value = v; } int getLocalEffects() const; diff --git a/hphp/compiler/expression/binary_op_expression.h b/hphp/compiler/expression/binary_op_expression.h index bc0d2d76b..4cc35c733 100644 --- a/hphp/compiler/expression/binary_op_expression.h +++ b/hphp/compiler/expression/binary_op_expression.h @@ -41,6 +41,7 @@ public: virtual bool isRefable(bool checkError = false) const; bool isShortCircuitOperator() const; bool isLogicalOrOperator() const; + ExpressionPtr getStoreVariable() const { return m_exp1;} ExpressionPtr getExp1() { return m_exp1;} ExpressionPtr getExp2() { return m_exp2;} int getOp() const { return m_op;} diff --git a/hphp/compiler/expression/expression.cpp b/hphp/compiler/expression/expression.cpp index 62fcad2d9..13a809f4b 100644 --- a/hphp/compiler/expression/expression.cpp +++ b/hphp/compiler/expression/expression.cpp @@ -144,7 +144,7 @@ bool Expression::hasSubExpr(ExpressionPtr sub) const { Expression::ExprClass Expression::getExprClass() const { ExprClass cls = Classes[m_kindOf]; if (cls == Update) { - ExpressionPtr k = getNthExpr(0); + ExpressionPtr k = getStoreVariable(); if (!k || !(k->hasContext(OprLValue))) cls = Expression::None; } return cls; diff --git a/hphp/compiler/expression/expression.h b/hphp/compiler/expression/expression.h index d38729242..40b1ea0be 100644 --- a/hphp/compiler/expression/expression.h +++ b/hphp/compiler/expression/expression.h @@ -180,6 +180,7 @@ public: bool hasError(Error error) const { return m_error & error; } ExprClass getExprClass() const; + virtual ExpressionPtr getStoreVariable() const { return ExpressionPtr(); } void setArgNum(int n); /** diff --git a/hphp/compiler/expression/unary_op_expression.h b/hphp/compiler/expression/unary_op_expression.h index b0463fd6f..d628cf46d 100644 --- a/hphp/compiler/expression/unary_op_expression.h +++ b/hphp/compiler/expression/unary_op_expression.h @@ -50,6 +50,7 @@ public: virtual bool getScalarValue(Variant &value); ExpressionPtr getExpression() { return m_exp;} + ExpressionPtr getStoreVariable() const { return m_exp;} int getOp() const { return m_op;} bool isLogicalNot() const { return m_op == '!'; } bool isCast() const; diff --git a/hphp/compiler/statement/do_statement.cpp b/hphp/compiler/statement/do_statement.cpp index 21b2bd09c..9b5d3077b 100644 --- a/hphp/compiler/statement/do_statement.cpp +++ b/hphp/compiler/statement/do_statement.cpp @@ -50,9 +50,9 @@ void DoStatement::analyzeProgram(AnalysisResultPtr ar) { ConstructPtr DoStatement::getNthKid(int n) const { switch (n) { - case BodyStmt: + case 0: return m_stmt; - case CondExpr: + case 1: return m_condition; default: assert(false); @@ -67,10 +67,10 @@ int DoStatement::getKidCount() const { void DoStatement::setNthKid(int n, ConstructPtr cp) { switch (n) { - case BodyStmt: + case 0: m_stmt = boost::dynamic_pointer_cast(cp); break; - case CondExpr: + case 1: m_condition = boost::dynamic_pointer_cast(cp); break; default: diff --git a/hphp/compiler/statement/do_statement.h b/hphp/compiler/statement/do_statement.h index 60520c769..7fe76f90f 100644 --- a/hphp/compiler/statement/do_statement.h +++ b/hphp/compiler/statement/do_statement.h @@ -26,11 +26,13 @@ DECLARE_BOOST_TYPES(DoStatement); class DoStatement : public LoopStatement { public: - enum { BodyStmt, CondExpr }; DoStatement(STATEMENT_CONSTRUCTOR_PARAMETERS, StatementPtr stmt, ExpressionPtr condition); DECLARE_STATEMENT_VIRTUAL_FUNCTIONS; + + ExpressionPtr getCondExp() const { return m_condition; } + StatementPtr getBody() const { return m_stmt; } virtual bool hasDecl() const { return m_stmt && m_stmt->hasDecl(); } virtual bool hasRetExp() const { return m_stmt && m_stmt->hasRetExp(); } virtual int getRecursiveCount() const { diff --git a/hphp/compiler/statement/for_statement.cpp b/hphp/compiler/statement/for_statement.cpp index 57a169cd9..eb4fb50a3 100644 --- a/hphp/compiler/statement/for_statement.cpp +++ b/hphp/compiler/statement/for_statement.cpp @@ -68,13 +68,13 @@ void ForStatement::analyzeProgram(AnalysisResultPtr ar) { ConstructPtr ForStatement::getNthKid(int n) const { switch (n) { - case InitExpr: + case 0: return m_exp1; - case CondExpr: + case 1: return m_exp2; - case BodyStmt: + case 2: return m_stmt; - case IncExpr: + case 3: return m_exp3; default: assert(false); @@ -89,16 +89,16 @@ int ForStatement::getKidCount() const { void ForStatement::setNthKid(int n, ConstructPtr cp) { switch (n) { - case InitExpr: + case 0: m_exp1 = boost::dynamic_pointer_cast(cp); break; - case CondExpr: + case 1: m_exp2 = boost::dynamic_pointer_cast(cp); break; - case BodyStmt: + case 2: m_stmt = boost::dynamic_pointer_cast(cp); break; - case IncExpr: + case 3: m_exp3 = boost::dynamic_pointer_cast(cp); break; default: diff --git a/hphp/compiler/statement/for_statement.h b/hphp/compiler/statement/for_statement.h index 983d184ad..c80368e2b 100644 --- a/hphp/compiler/statement/for_statement.h +++ b/hphp/compiler/statement/for_statement.h @@ -26,18 +26,22 @@ DECLARE_BOOST_TYPES(ForStatement); class ForStatement : public LoopStatement { public: - enum { InitExpr, CondExpr, BodyStmt, IncExpr }; ForStatement(STATEMENT_CONSTRUCTOR_PARAMETERS, ExpressionPtr exp1, ExpressionPtr exp2, ExpressionPtr exp3, StatementPtr stmt); DECLARE_STATEMENT_VIRTUAL_FUNCTIONS; + + ExpressionPtr getInitExp() const { return m_exp1; } + ExpressionPtr getCondExp() const { return m_exp2; } + ExpressionPtr getIncExp() const { return m_exp3; } + StatementPtr getBody() const { return m_stmt; } virtual bool hasDecl() const { return m_stmt && m_stmt->hasDecl(); } virtual bool hasRetExp() const { return m_stmt && m_stmt->hasRetExp(); } virtual int getRecursiveCount() const { return 1 + (m_stmt ? m_stmt->getRecursiveCount() : 0); } - virtual bool kidUnused(int i) const { return i == InitExpr || i == IncExpr; } + virtual bool kidUnused(int i) const { return i == 0 || i == 3; } private: ExpressionPtr m_exp1; ExpressionPtr m_exp2; diff --git a/hphp/compiler/statement/foreach_statement.cpp b/hphp/compiler/statement/foreach_statement.cpp index 947f393c0..72be4aa25 100644 --- a/hphp/compiler/statement/foreach_statement.cpp +++ b/hphp/compiler/statement/foreach_statement.cpp @@ -79,13 +79,13 @@ void ForEachStatement::analyzeProgram(AnalysisResultPtr ar) { ConstructPtr ForEachStatement::getNthKid(int n) const { switch (n) { - case ArrayExpr: + case 0: return m_array; - case NameExpr: + case 1: return m_name; - case ValueExpr: + case 2: return m_value; - case BodyStmt: + case 3: return m_stmt; default: assert(false); @@ -100,16 +100,16 @@ int ForEachStatement::getKidCount() const { void ForEachStatement::setNthKid(int n, ConstructPtr cp) { switch (n) { - case ArrayExpr: + case 0: m_array = boost::dynamic_pointer_cast(cp); break; - case NameExpr: + case 1: m_name = boost::dynamic_pointer_cast(cp); break; - case ValueExpr: + case 2: m_value = boost::dynamic_pointer_cast(cp); break; - case BodyStmt: + case 3: m_stmt = boost::dynamic_pointer_cast(cp); break; default: diff --git a/hphp/compiler/statement/foreach_statement.h b/hphp/compiler/statement/foreach_statement.h index 282c2fb19..db0a108c5 100644 --- a/hphp/compiler/statement/foreach_statement.h +++ b/hphp/compiler/statement/foreach_statement.h @@ -26,13 +26,16 @@ DECLARE_BOOST_TYPES(ForEachStatement); class ForEachStatement : public LoopStatement { public: - enum { ArrayExpr, NameExpr, ValueExpr, BodyStmt }; ForEachStatement(STATEMENT_CONSTRUCTOR_PARAMETERS, ExpressionPtr array, ExpressionPtr name, bool nameRef, ExpressionPtr value, bool valueRef, StatementPtr stmt); DECLARE_STATEMENT_VIRTUAL_FUNCTIONS; + ExpressionPtr getArrayExp() const { return m_array; } + ExpressionPtr getNameExp() const { return m_name; } + ExpressionPtr getValueExp() const { return m_value; } + StatementPtr getBody() const { return m_stmt; } virtual bool hasDecl() const { return m_stmt && m_stmt->hasDecl(); } virtual bool hasRetExp() const { return m_stmt && m_stmt->hasRetExp(); } virtual int getRecursiveCount() const { diff --git a/hphp/compiler/statement/while_statement.cpp b/hphp/compiler/statement/while_statement.cpp index 5c05ca4a4..fbad22241 100644 --- a/hphp/compiler/statement/while_statement.cpp +++ b/hphp/compiler/statement/while_statement.cpp @@ -50,9 +50,9 @@ void WhileStatement::analyzeProgram(AnalysisResultPtr ar) { ConstructPtr WhileStatement::getNthKid(int n) const { switch (n) { - case CondExpr: + case 0: return m_condition; - case BodyStmt: + case 1: return m_stmt; default: assert(false); @@ -67,10 +67,10 @@ int WhileStatement::getKidCount() const { void WhileStatement::setNthKid(int n, ConstructPtr cp) { switch (n) { - case CondExpr: + case 0: m_condition = boost::dynamic_pointer_cast(cp); break; - case BodyStmt: + case 1: m_stmt = boost::dynamic_pointer_cast(cp); break; default: diff --git a/hphp/compiler/statement/while_statement.h b/hphp/compiler/statement/while_statement.h index 431f12632..d768443e7 100644 --- a/hphp/compiler/statement/while_statement.h +++ b/hphp/compiler/statement/while_statement.h @@ -26,11 +26,13 @@ DECLARE_BOOST_TYPES(WhileStatement); class WhileStatement : public LoopStatement { public: - enum { CondExpr, BodyStmt }; WhileStatement(STATEMENT_CONSTRUCTOR_PARAMETERS, ExpressionPtr condition, StatementPtr stmt); DECLARE_STATEMENT_VIRTUAL_FUNCTIONS; + + ExpressionPtr getCondExp() const { return m_condition; } + StatementPtr getBody() const { return m_stmt; } virtual bool hasDecl() const { return m_stmt && m_stmt->hasDecl(); } virtual bool hasRetExp() const { return m_stmt && m_stmt->hasRetExp(); } virtual int getRecursiveCount() const {