void StatementList::analyzeProgramImpl(AnalysisResultPtr ar) { m_included = true; for (unsigned int i = 0; i < m_stmts.size(); i++) { StatementPtr stmt = m_stmts[i]; // effect testing if (ar->getPhase() == AnalysisResult::AnalyzeAll) { if (!stmt->hasEffect() && !stmt->hasDecl() && !stmt->is(Statement::KindOfStatementList)) { Compiler::Error(Compiler::StatementHasNoEffect, stmt); } if (stmt->is(Statement::KindOfExpStatement)) { static_pointer_cast<ExpStatement>(stmt)->analyzeShortCircuit(ar); } } bool scopeStmt = stmt->is(Statement::KindOfFunctionStatement) || stmt->is(Statement::KindOfClassStatement) || stmt->is(Statement::KindOfInterfaceStatement); if (ar->getPhase() != AnalysisResult::AnalyzeTopLevel || !scopeStmt) { /* Recurse when analyzing include/all OR when not a scope */ stmt->analyzeProgram(ar); } } }
void StatementList::analyzeProgram(AnalysisResultPtr ar) { m_included = true; for (unsigned int i = 0; i < m_stmts.size(); i++) { StatementPtr stmt = m_stmts[i]; // effect testing if (ar->getPhase() == AnalysisResult::AnalyzeAll) { if (!stmt->hasEffect() && !stmt->hasDecl() && !stmt->is(Statement::KindOfStatementList)) { Compiler::Error(Compiler::StatementHasNoEffect, stmt); } } stmt->analyzeProgram(ar); } }
StatementPtr IfStatement::preOptimize(AnalysisResultConstPtr ar) { if (ar->getPhase() < AnalysisResult::FirstPreOptimize) { return StatementPtr(); } // we cannot optimize away the code inside if statement, because // there may be a goto that goes into if statement. if (hasReachableLabel()) { return StatementPtr(); } bool changed = false; int i; int j; Variant value; bool hoist = false; for (i = 0; i < m_stmts->getCount(); i++) { IfBranchStatementPtr branch = dynamic_pointer_cast<IfBranchStatement>((*m_stmts)[i]); ExpressionPtr condition = branch->getCondition(); if (!condition) { StatementPtr stmt = branch->getStmt(); if (stmt) { if (!i && ((getFunctionScope() && !getFunctionScope()->inPseudoMain()) || !stmt->hasDecl())) { hoist = true; break; } if (stmt->is(KindOfIfStatement)) { StatementListPtr sub_stmts = dynamic_pointer_cast<IfStatement>(stmt)->m_stmts; m_stmts->removeElement(i); changed = true; for (j = 0; j < sub_stmts->getCount(); j++) { m_stmts->insertElement((*sub_stmts)[j], i++); } } } break; } else if (condition->getEffectiveScalar(value)) { if (value.toBoolean()) { hoist = !i && ((getFunctionScope() && !getFunctionScope()->inPseudoMain()) || !branch->hasDecl()); break; } else if (!condition->hasEffect()) { m_stmts->removeElement(i--); changed = true; } else if (branch->getStmt()) { branch->clearStmt(); changed = true; } } } if (!changed && i && i == m_stmts->getCount()) return StatementPtr(); // either else branch or if (true) branch without further declarations i++; while (i < m_stmts->getCount()) { m_stmts->removeElement(i); changed = true; } // if there is only one branch left, return stmt. if (hoist) { IfBranchStatementPtr branch = dynamic_pointer_cast<IfBranchStatement>((*m_stmts)[0]); return branch->getStmt() ? branch->getStmt() : NULL_STATEMENT(); } else if (m_stmts->getCount() == 0) { return NULL_STATEMENT(); } else { return changed ? static_pointer_cast<Statement>(shared_from_this()) : StatementPtr(); } }