예제 #1
0
void GlobalStatement::inferTypes(AnalysisResultPtr ar) {
  IMPLEMENT_INFER_AND_CHECK_ASSERT(getScope());

  BlockScopePtr scope = getScope();
  for (int i = 0; i < m_exp->getCount(); i++) {
    ExpressionPtr exp = (*m_exp)[i];
    VariableTablePtr variables = scope->getVariables();
    variables->setAttribute(VariableTable::NeedGlobalPointer);
    if (exp->is(Expression::KindOfSimpleVariable)) {
      SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(exp);
      const std::string &name = var->getName();
      /* If we have already seen this variable in the current scope and
         it is not a global variable, record this variable as "redeclared"
         which will force Variant type.
       */
      variables->setAttribute(VariableTable::InsideGlobalStatement);
      variables->checkRedeclared(name, KindOfGlobalStatement);
      variables->addLocalGlobal(name);
      var->setContext(Expression::Declaration);
      var->inferAndCheck(ar, Type::Any, true);
      variables->forceVariant(ar, name, VariableTable::AnyVars);
      variables->clearAttribute(VariableTable::InsideGlobalStatement);
    } else {
      variables->forceVariants(ar, VariableTable::AnyVars);
      variables->setAttribute(VariableTable::ContainsLDynamicVariable);
      assert(exp->is(Expression::KindOfDynamicVariable));
      exp->inferAndCheck(ar, Type::Any, true);
    }
  }
}
예제 #2
0
void GlobalStatement::inferTypes(AnalysisResultPtr ar) {
  BlockScopePtr scope = ar->getScope();
  scope->getVariables()->setAttribute(VariableTable::InsideGlobalStatement);
  for (int i = 0; i < m_exp->getCount(); i++) {
    ExpressionPtr exp = (*m_exp)[i];
    if (exp->is(Expression::KindOfSimpleVariable)) {
      SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(exp);
      VariableTablePtr variables = scope->getVariables();
      const std::string &name = var->getName();
      /* If we have already seen this variable in the current scope and
         it is not a global variable, record this variable as "redeclared"
         which will force Variant type.
       */
      variables->checkRedeclared(name, KindOfGlobalStatement);

      /* If this is not a top-level global statement, the variable also
         needs to be Variant type. This should not be a common use case in
         php code.
       */
      if (!isTopLevel()) {
        variables->addNestedGlobal(name);
      }
      var->setContext(Expression::Declaration);
      var->inferAndCheck(ar, NEW_TYPE(Any), true);

      if (variables->needLocalCopy(name)) {
        variables->forceVariant(ar, name);
        variables->setAttribute(VariableTable::NeedGlobalPointer);
      }

      ConstructPtr decl =
        ar->getVariables()->getDeclaration(var->getName());
      if (decl) {
        ar->getDependencyGraph()->add(DependencyGraph::KindOfGlobalVariable,
                                      ar->getName(),
                                      var->getName(), var,
                                      var->getName(), decl);
      }
    } else {
      if (ar->isFirstPass()) {
        ar->getCodeError()->record(shared_from_this(), CodeError::UseDynamicGlobal, exp);
      }
      m_dynamicGlobal = true;
    }
  }
  FunctionScopePtr func = ar->getFunctionScope();
  scope->getVariables()->clearAttribute(VariableTable::InsideGlobalStatement);
}
예제 #3
0
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);
}