static int cloneStmtsForInline(InlineCloneInfo &info, StatementPtr s, const std::string &prefix, AnalysisResultConstPtr ar, FunctionScopePtr scope) { switch (s->getKindOf()) { case Statement::KindOfStatementList: { for (int i = 0, n = s->getKidCount(); i < n; ++i) { if (int ret = cloneStmtsForInline(info, s->getNthStmt(i), prefix, ar, scope)) { return ret; } } return 0; } case Statement::KindOfExpStatement: info.elist->addElement(cloneForInline( info, dynamic_pointer_cast<ExpStatement>(s)-> getExpression(), prefix, ar, scope)); return 0; case Statement::KindOfReturnStatement: { ExpressionPtr exp = dynamic_pointer_cast<ReturnStatement>(s)->getRetExp(); if (exp) { exp = cloneForInline(info, exp, prefix, ar, scope); if (exp->hasContext(Expression::RefValue)) { exp->clearContext(Expression::RefValue); if (exp->isRefable()) exp->setContext(Expression::LValue); } info.elist->addElement(exp); return 1; } return -1; } default: not_reached(); } return 1; }
void ClassStatement::GetCtorAndInitInfo( StatementPtr s, bool &needsCppCtor, bool &needsInit) { if (!s) return; switch (s->getKindOf()) { case Statement::KindOfStatementList: { StatementListPtr stmts = static_pointer_cast<StatementList>(s); for (int i = 0; i < stmts->getCount(); i++) { GetCtorAndInitInfo((*stmts)[i], needsCppCtor, needsInit); } } break; case Statement::KindOfClassVariable: { ClassVariablePtr cv = static_pointer_cast<ClassVariable>(s); cv->getCtorAndInitInfo(needsCppCtor, needsInit); } break; default: break; } }
void AliasManager::collectAliasInfoRecur(ConstructPtr cs) { if (!cs) { return; } if (StatementPtr s = dpc(Statement, cs)) { switch (s->getKindOf()) { case Statement::KindOfFunctionStatement: case Statement::KindOfMethodStatement: case Statement::KindOfClassStatement: case Statement::KindOfInterfaceStatement: return; default: break; } } int nkid = cs->getKidCount(); for (int i = 0; i < nkid; i++) { ConstructPtr kid = cs->getNthKid(i); if (kid) { collectAliasInfoRecur(kid); } } if (ExpressionPtr e = dpc(Expression, cs)) { int context = e->getContext(); switch (e->getKindOf()) { case Expression::KindOfAssignmentExpression: { AssignmentExpressionPtr ae = spc(AssignmentExpression, e); ExpressionPtr var = ae->getVariable(); ExpressionPtr val = ae->getValue(); if (var->is(Expression::KindOfSimpleVariable)) { const std::string &name = spc(SimpleVariable, var)->getName(); AliasInfo &ai = m_aliasInfo[name]; if (val->getContext() & Expression::RefValue) { ai.setIsRefTo(); m_variables->addUsed(name); } else { Expression::checkUsed(m_arp, var, val); } } } break; case Expression::KindOfListAssignment: { ListAssignmentPtr la = spc(ListAssignment, e); ExpressionListPtr vars = la->getVariables(); for (int i = vars->getCount(); i--; ) { ExpressionPtr v = (*vars)[i]; if (v && v->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr sv = spc(SimpleVariable, v); m_variables->addUsed(sv->getName()); } } } break; case Expression::KindOfSimpleVariable: { const std::string &name = spc(SimpleVariable, e)->getName(); if (context & Expression::RefValue) { AliasInfo &ai = m_aliasInfo[name]; ai.addRefLevel(0); } if (!(context & (Expression::AssignmentLHS | Expression::UnsetContext))) { m_variables->addUsed(name); } } break; case Expression::KindOfDynamicVariable: if (context & Expression::RefValue) { m_wildRefs = true; } break; case Expression::KindOfArrayElementExpression: { int n = 1; while (n < 10 && e->is(Expression::KindOfArrayElementExpression)) { e = spc(ArrayElementExpression, e)->getVariable(); } if (e->is(Expression::KindOfSimpleVariable)) { const std::string &name = spc(SimpleVariable, e)->getName(); if (context & Expression::RefValue) { AliasInfo &ai = m_aliasInfo[name]; ai.addRefLevel(n); } m_variables->addUsed(name); // need this for UnsetContext } } break; case Expression::KindOfObjectPropertyExpression: { e = spc(ObjectPropertyExpression, e)->getObject(); if (e->is(Expression::KindOfSimpleVariable)) { const std::string &name = spc(SimpleVariable, e)->getName(); if (context & Expression::RefValue) { AliasInfo &ai = m_aliasInfo[name]; ai.addRefLevel(1); } m_variables->addUsed(name); // need this for UnsetContext } } break; default: break; } } else { StatementPtr s = spc(Statement, cs); switch (s->getKindOf()) { case Statement::KindOfCatchStatement: { const std::string &name = spc(CatchStatement, s)->getVariable(); m_variables->addUsed(name); break; } default: break; } } }
int AliasManager::canonicalizeRecur(StatementPtr s) { if (!s) return FallThrough; Statement::KindOf stype = s->getKindOf(); int ret = FallThrough; int start = 0; switch (stype) { case Statement::KindOfFunctionStatement: case Statement::KindOfMethodStatement: case Statement::KindOfClassStatement: case Statement::KindOfInterfaceStatement: // Dont handle nested functions // they will be dealt with by another // top level call to optimize return ret; case Statement::KindOfStaticStatement: clear(); ret = Converge; break; case Statement::KindOfClassVariable: clear(); ret = Branch; case Statement::KindOfClassConstant: case Statement::KindOfGlobalStatement: case Statement::KindOfEchoStatement: case Statement::KindOfUnsetStatement: case Statement::KindOfExpStatement: case Statement::KindOfStatementList: case Statement::KindOfBlockStatement: case Statement::KindOfTryStatement: // No special action, just execute // 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(); canonicalizeRecur(spc(Statement, ifstmt->getNthKid(1))); endScope(); if (i+1 < n) resetScope(); } endScope(); } ret = Converge; return FallThrough; } break; case Statement::KindOfIfBranchStatement: assert(0); break; case Statement::KindOfForStatement: canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0); clear(); canonicalizeKid(s, spc(Expression,s->getNthKid(1)), 1); canonicalizeRecur(spc(Statement, s->getNthKid(2))); clear(); canonicalizeKid(s, spc(Expression,s->getNthKid(3)), 3); return Converge; case Statement::KindOfWhileStatement: case Statement::KindOfDoStatement: case Statement::KindOfForEachStatement: clear(); ret = Converge; break; case Statement::KindOfSwitchStatement: canonicalizeKid(s, spc(Expression,s->getNthKid(0)), 0); clear(); start = 1; ret = Converge; break; case Statement::KindOfCaseStatement: clear(); break; case Statement::KindOfBreakStatement: case Statement::KindOfContinueStatement: case Statement::KindOfReturnStatement: ret = Branch; break; case Statement::KindOfCatchStatement: clear(); ret = Converge; break; case Statement::KindOfThrowStatement: ret = Branch; break; } int nkid = s->getKidCount(); for (int i = start; i < nkid; i++) { ConstructPtr cp = s->getNthKid(i); if (!cp) { continue; } if (StatementPtr skid = dpc(Statement, cp)) { int action = canonicalizeRecur(skid); switch (action) { case FallThrough: case CondBranch: break; case Branch: clear(); break; case Converge: clear(); break; } } else { canonicalizeKid(s, spc(Expression, cp), i); } } return ret; }