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); } } }
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); }
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); }