Esempio n. 1
0
void StaticStatement::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  BlockScopePtr scope = getScope();
  if (scope->inPseudoMain()) {
    if (m_exp->getCount() > 1) cg_indentBegin("{\n");
    for (int i = 0; i < m_exp->getCount(); i++) {
      ExpressionPtr exp = (*m_exp)[i];
      if (exp->is(Expression::KindOfAssignmentExpression)) {
        exp->outputCPP(cg, ar);
        cg_printf(";\n");
      } else {
        ASSERT(false);
      }
    }
    if (m_exp->getCount() > 1) cg_indentEnd("}\n");
    return;
  }

  VariableTablePtr variables = scope->getVariables();
  if (m_exp->getCount() > 1) cg_indentBegin("{\n");
  for (int i = 0; i < m_exp->getCount(); i++) {
    ExpressionPtr exp = (*m_exp)[i];
    if (exp->is(Expression::KindOfAssignmentExpression)) {
      AssignmentExpressionPtr assignment_exp =
        dynamic_pointer_cast<AssignmentExpression>(exp);
      ExpressionPtr variable = assignment_exp->getVariable();
      SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable);
      assert(var->hasContext(Expression::Declaration));
      const std::string &name = var->getName();

      if (variables->needLocalCopy(name)) {
        ASSERT(var->hasAssignableCPPVariable());
        cg_printf("%s.assignRef(%s%s);\n",
                  var->getAssignableCPPVariable(ar).c_str(),
                  Option::StaticVariablePrefix, name.c_str());
      }

      cg_indentBegin("if (!%s%s%s) {\n", Option::InitPrefix,
                     Option::StaticVariablePrefix, name.c_str());
      exp->outputCPP(cg, ar);
      cg_printf(";\n");
      cg_printf("%s%s%s = true;\n", Option::InitPrefix,
                Option::StaticVariablePrefix, name.c_str());
      cg_indentEnd("}\n");
    } else {
      ASSERT(false);
    }
  }
  if (m_exp->getCount() > 1) cg_indentEnd("}\n");
}
void StaticStatement::inferTypes(AnalysisResultPtr ar) {
  BlockScopePtr scope = ar->getScope();
  if (scope->inPseudoMain()) { // static just means to unset at global level
    for (int i = 0; i < m_exp->getCount(); i++) {
      ExpressionPtr exp = (*m_exp)[i];
      if (exp->is(Expression::KindOfAssignmentExpression)) {
        AssignmentExpressionPtr assignment_exp =
          dynamic_pointer_cast<AssignmentExpression>(exp);
        ExpressionPtr variable = assignment_exp->getVariable();
        if (variable->is(Expression::KindOfSimpleVariable)) {
          SimpleVariablePtr var =
            dynamic_pointer_cast<SimpleVariable>(variable);
          var->setContext(Expression::Declaration);
          scope->getVariables()->forceVariant(ar, var->getName(),
                                              VariableTable::AnyStaticVars);
        } else {
          ASSERT(false);
        }
      } else {
        // Expression was optimized away; remove it
        m_exp->removeElement(i--);
      }
    }
    m_exp->inferTypes(ar, Type::Any, true);
    return;
  }
  scope->getVariables()->setAttribute(VariableTable::InsideStaticStatement);
  for (int i = 0; i < m_exp->getCount(); i++) {
    ExpressionPtr exp = (*m_exp)[i];
    VariableTablePtr variables = scope->getVariables();
    if (exp->is(Expression::KindOfAssignmentExpression)) {
      AssignmentExpressionPtr assignment_exp =
        dynamic_pointer_cast<AssignmentExpression>(exp);
      ExpressionPtr variable = assignment_exp->getVariable();
      if (variable->is(Expression::KindOfSimpleVariable)) {
        SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable);
        var->setContext(Expression::Declaration);
        const std::string &name = var->getName();
        /* If we have already seen this variable in the current scope and
           it is not a static variable, record this variable as "redeclared"
           to force Variant type.
         */
        if (ar->isFirstPass()) {
          variables->checkRedeclared(name, KindOfStaticStatement);
        }
        /* If this is not a top-level static statement, the variable also
           needs to be Variant type. This should not be a common use case in
           php code.
         */
        if (!isTopLevel()) {
          variables->addNestedStatic(name);
        }

        if (variables->needLocalCopy(name)) {
          variables->forceVariant(ar, name, VariableTable::AnyStaticVars);
        }
      } else {
        ASSERT(false);
      }
    } else {
      // Expression was optimized away; remove it
      m_exp->removeElement(i--);
      continue;
    }
    exp->inferAndCheck(ar, Type::Any, false);
  }
  scope->getVariables()->clearAttribute(VariableTable::InsideStaticStatement);
}