Exemple #1
0
void FunctionScope::RecordFunctionInfo(std::string fname,
                                       FunctionScopePtr func) {
    VariableTablePtr variables = func->getVariables();
    if (Option::WholeProgram) {
        Lock lock(s_refParamInfoLock);
        FunctionInfoPtr &info = s_refParamInfo[fname];
        if (!info) {
            info = std::make_shared<FunctionInfo>();
        }
        if (func->isStatic()) {
            info->setMaybeStatic();
        }
        if (func->isRefReturn()) {
            info->setMaybeRefReturn();
        }
        if (func->isReferenceVariableArgument()) {
            info->setRefVarArg(func->getMaxParamCount());
        }
        for (int i = 0; i < func->getMaxParamCount(); i++) {
            if (func->isRefParam(i)) info->setRefParam(i);
        }
    }
    auto limit = func->getDeclParamCount();
    for (int i = 0; i < limit; i++) {
        variables->addParam(func->getParamName(i),
                            AnalysisResultPtr(), ConstructPtr());
    }
}
void FunctionScope::RecordRefParamInfo(string fname, FunctionScopePtr func) {
  RefParamInfoPtr info = s_refParamInfo[fname];
  if (!info) {
    info = RefParamInfoPtr(new RefParamInfo());
    s_refParamInfo[fname] = info;
  }
  if (func->isReferenceVariableArgument()) {
    info->setRefVarArg(func->getMaxParamCount());
  }
  VariableTablePtr variables = func->getVariables();
  for (int i = 0; i < func->getMaxParamCount(); i++) {
    if (func->isRefParam(i)) info->setRefParam(i);
    variables->addParam(func->getParamName(i),
                        TypePtr(), AnalysisResultPtr(), ConstructPtr());
  }
}
TypePtr ParameterExpression::inferTypes(AnalysisResultPtr ar, TypePtr type,
                                        bool coerce) {
  ASSERT(type->is(Type::KindOfSome) || type->is(Type::KindOfAny));
  TypePtr ret = getTypeSpec(ar, true);

  if (m_defaultValue && !m_ref) {
    ret = m_defaultValue->inferAndCheck(ar, ret, false);
  }

  // parameters are like variables, but we need to remember these are
  // parameters so when variable table is generated, they are not generated
  // as declared variables.
  VariableTablePtr variables = ar->getScope()->getVariables();
  if (ar->isFirstPass()) {
    ret = variables->addParam(m_name, ret, ar, shared_from_this());
  } else {
    // Functions that can be called dynamically have to have
    // variant parameters, even if they have a type hint
    if (ar->getFunctionScope()->isDynamic() ||
        ar->getFunctionScope()->isRedeclaring() ||
        ar->getFunctionScope()->isVirtual()) {
      variables->forceVariant(ar, m_name, VariableTable::AnyVars);
    }
    int p;
    ret = variables->checkVariable(m_name, ret, true, ar, shared_from_this(),
                                   p);
    if (ar->isSecondPass() && ret->is(Type::KindOfSome)) {
      // This is probably too conservative. The problem is that
      // a function never called will have parameter types of Any.
      // Functions that it calls won't be able to accept variant unless
      // it is forced here.
      variables->forceVariant(ar, m_name, VariableTable::AnyVars);
      ret = Type::Variant;
    } else if (ar->getPhase() == AnalysisResult::LastInference &&
               !ret->getName().empty()) {
      addUserClass(ar, ret->getName(), true);
    }
  }
  return ret;
}