示例#1
0
bool ListAssignment::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                  int state) {
  assert(m_array);

  if (!cg.inExpression()) return true;

  if (m_variables) {
    preOutputVariables(cg, ar, m_variables->hasEffect() ||
                       m_array->hasEffect() ? FixOrder : 0);
  }
  m_array->preOutputCPP(cg, ar, 0);

  bool isArray = false, notArray = false;
  bool simpleVar = m_array->is(KindOfSimpleVariable) &&
    !static_pointer_cast<SimpleVariable>(m_array)->getAlwaysStash();
  bool needsUse = false;
  if (TypePtr type = m_array->getActualType()) {
    isArray = type->is(Type::KindOfArray);
    notArray = !isArray &&
      (type->isPrimitive() ||
       m_rhsKind == Null ||
      (m_rhsKind == Checked && (type->is(Type::KindOfString) ||
                                type->is(Type::KindOfObject))));
  }
  cg.wrapExpressionBegin();
  if (outputLineMap(cg, ar)) cg_printf("0);\n");
  if (notArray && isUnused()) {
    if (m_array->outputCPPUnneeded(cg, ar)) cg_printf(";\n");
    m_cppTemp = "null";
  } else {
    m_cppTemp = genCPPTemp(cg, ar);
    needsUse = simpleVar || m_array->isTemporary();
    const char *decl;
    if (isArray && m_array->getCPPType()->is(Type::KindOfArray)) {
      decl = needsUse ? "CArrRef" : "Array";
    } else {
      decl = needsUse ? "CVarRef" : "Variant";
    }
    cg_printf("%s %s((", decl, m_cppTemp.c_str());
    m_array->outputCPP(cg, ar);
    cg_printf("));\n");
  }
  std::string tmp;
  if (notArray) {
    tmp = "null_variant";
    if (needsUse) cg_printf("id(%s);\n", m_cppTemp.c_str());
    needsUse = false;
  } else if (m_rhsKind != Checked || isArray) {
    tmp = m_cppTemp;
  } else {
    tmp = genCPPTemp(cg, ar);
    cg_printf("CVarRef %s(f_is_array(%s)?%s:null_variant);\n",
              tmp.c_str(), m_cppTemp.c_str(), m_cppTemp.c_str());
    needsUse = true;
  }
  if (!outputCPPAssignment(cg, ar, tmp, simpleVar) && needsUse) {
    cg_printf("id(%s);\n", tmp.c_str());
  }

  return true;
}
void ArrayElementExpression::outputCodeModel(CodeGenerator &cg) {
  if (m_offset) {
    cg.printObjectHeader("BinaryOpExpression", 4);
    cg.printPropertyHeader("expression1");
    m_variable->outputCodeModel(cg);
    cg.printPropertyHeader("expression2");
    cg.printExpression(m_offset, false);
    cg.printPropertyHeader("operation");
    cg.printValue(PHP_ARRAY_ELEMENT);
    cg.printPropertyHeader("sourceLocation");
    cg.printLocation(this);
    cg.printObjectFooter();
  } else {
    cg.printObjectHeader("UnaryOpExpression", 3);
    cg.printPropertyHeader("expression");
    m_variable->outputCodeModel(cg);
    cg.printPropertyHeader("operation");
    cg.printValue(PHP_ARRAY_APPEND_POINT_OP);
    cg.printPropertyHeader("sourceLocation");
    cg.printLocation(this);
    cg.printObjectFooter();
  }
}
示例#3
0
文件: switch.cpp 项目: casadi/casadi
 void Switch::codegen_declarations(CodeGenerator& g) const {
   for (casadi_int k=0; k<=f_.size(); ++k) {
     const Function& fk = k<f_.size() ? f_[k] : f_def_;
     g.add_dependency(fk);
   }
 }
bool DynamicFunctionCall::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                       int state) {
    bool nonStatic = !m_class && m_className.empty();
    if (!nonStatic && !m_class && !m_classScope && !isRedeclared()) {
        // call to an unknown class
        // set m_noStatic to avoid pointlessly wrapping the call
        // in STATIC_CLASS_NAME_CALL()
        m_noStatic = true;
        cg.pushCallInfo(-1);
        bool ret = FunctionCall::preOutputCPP(cg, ar, state);
        cg.popCallInfo();
        return ret;
    }
    // Short circuit out if inExpression() returns false
    if (!cg.inExpression()) return true;

    cg.wrapExpressionBegin();

    m_ciTemp = cg.createNewLocalId(shared_from_this());

    if (!m_classScope && !m_className.empty() && m_cppTemp.empty() &&
            !isSelf() && ! isParent() && !isStatic()) {
        // Create a temporary to hold the class name, in case it is not a
        // StaticString.
        m_clsNameTemp = cg.createNewLocalId(shared_from_this());
        cg_printf("CStrRef clsName%d(", m_clsNameTemp);
        cg_printString(m_origClassName, ar, shared_from_this());
        cg_printf(");\n");
    }

    if (m_class) {
        int s = m_class->hasEffect() || m_nameExp->hasEffect() ?
                FixOrder : 0;
        m_class->preOutputCPP(cg, ar, s);
    }
    m_nameExp->preOutputCPP(cg, ar, 0);

    if (nonStatic) {
        cg_printf("const CallInfo *cit%d;\n", m_ciTemp);
        cg_printf("void *vt%d;\n", m_ciTemp);
        cg_printf("get_call_info_or_fail(cit%d, vt%d, ", m_ciTemp, m_ciTemp);

        if (m_nameExp->is(Expression::KindOfSimpleVariable)) {
            m_nameExp->outputCPP(cg, ar);
        } else {
            cg_printf("(");
            m_nameExp->outputCPP(cg, ar);
            cg_printf(")");
        }
        cg_printf(");\n");
    } else {
        cg_printf("MethodCallPackage mcp%d;\n", m_ciTemp);
        if (m_class) {
            if (m_class->is(KindOfScalarExpression)) {
                ASSERT(strcasecmp(dynamic_pointer_cast<ScalarExpression>(m_class)->
                                  getString().c_str(), "static") == 0);
                cg_printf("CStrRef cls%d = "
                          "FrameInjection::GetStaticClassName(fi.getThreadInfo())",
                          m_ciTemp);
            } else {
                cg_printf("C%sRef cls%d = ",
                          m_class->getActualType() &&
                          m_class->getActualType()->is(Type::KindOfString) ?
                          "Str" : "Var", m_ciTemp);
                m_class->outputCPP(cg, ar);
            }
        } else if (m_classScope) {
            cg_printf("CStrRef cls%d = ", m_ciTemp);
            cg_printString(m_classScope->getId(), ar, shared_from_this());
        } else {
            cg_printf("CStrRef cls%d = ", m_ciTemp);
            cg_printString(m_className, ar, shared_from_this());
        }
        cg_printf(";\n");

        cg_printf("CStrRef mth%d = ", m_ciTemp);
        if (m_nameExp->is(Expression::KindOfSimpleVariable)) {
            m_nameExp->outputCPP(cg, ar);
        } else {
            cg_printf("(");
            m_nameExp->outputCPP(cg, ar);
            cg_printf(")");
        }
        cg_printf(";\n");

        bool dynamic = true;
        if (!m_class) {
            ClassScopeRawPtr origClass = getOriginalClass();
            if (!origClass) {
                dynamic = false;
            } else {
                FunctionScopeRawPtr origFunc = getOriginalFunction();
                if (origFunc) {
                    if (origFunc->isStatic() ||
                            (m_classScope != origClass &&
                             (m_className.empty() || !origClass->derivesFrom(
                                  ar, m_className, true, true)))) {
                        dynamic = false;
                    }
                }
            }
        }

        if (dynamic) {
            if ((m_class && (!m_class->getActualType() ||
                             !m_class->getActualType()->is(Type::KindOfString))) ||
                    !getOriginalFunction() ||
                    !getOriginalClass() ||
                    getOriginalFunction()->isStatic()) {
                cg_printf("mcp%d.dynamicNamedCall(cls%d, mth%d);\n",
                          m_ciTemp, m_ciTemp, m_ciTemp);
            } else {
                cg_printf("mcp%d.isObj = true;\n", m_ciTemp);
                cg_printf("mcp%d.rootObj = this;\n", m_ciTemp);
                cg_printf("mcp%d.name = &mth%d;\n", m_ciTemp, m_ciTemp);
                cg_printf("o_get_call_info_ex(cls%d, mcp%d);\n", m_ciTemp, m_ciTemp);
            }
        } else {
            cg_printf("mcp%d.staticMethodCall(cls%d, mth%d);\n",
                      m_ciTemp,
                      m_ciTemp, m_ciTemp);

            if (m_classScope) {
                cg_printf("%s%s.%sget_call_info(mcp%d);\n",
                          Option::ClassStaticsCallbackPrefix,
                          m_classScope->getId().c_str(),
                          Option::ObjectStaticPrefix, m_ciTemp);
            } else if (isRedeclared()) {
                cg_printf("g->%s%s->%sget_call_info(mcp%d);\n",
                          Option::ClassStaticsCallbackPrefix, m_className.c_str(),
                          Option::ObjectStaticPrefix, m_ciTemp);
            } else {
                assert(false);
            }
        }
        cg_printf("const CallInfo *cit%d = mcp%d.ci;\n", m_ciTemp, m_ciTemp);
    }

    if (m_params && m_params->getCount() > 0) {
        cg.pushCallInfo(m_ciTemp);
        m_params->preOutputCPP(cg, ar, 0);
        cg.popCallInfo();
    }

    if (state & FixOrder) {
        cg.pushCallInfo(m_ciTemp);
        preOutputStash(cg, ar, state);
        cg.popCallInfo();
    }

    return true;
}
示例#5
0
void MethodStatement::outputCodeModel(CodeGenerator &cg) {
  auto isAnonymous = ParserBase::IsClosureName(m_originalName);
  auto numProps = 4;
  if (m_attrList != nullptr) numProps++;
  if (m_ref) numProps++;
  if (m_params != nullptr) numProps++;
  if (m_retTypeAnnotation != nullptr) numProps++;
  if (!m_docComment.empty()) numProps++;
  cg.printObjectHeader("FunctionStatement", numProps);
  if (m_attrList != nullptr) {
    cg.printPropertyHeader("attributes");
    cg.printExpressionVector(m_attrList);
  }
  cg.printPropertyHeader("modifiers");
  m_modifiers->outputCodeModel(cg);
  if (m_ref) {
    cg.printPropertyHeader("returnsReference");
    cg.printBool(true);
  }
  cg.printPropertyHeader("name");
  cg.printValue(isAnonymous ? "" : m_originalName);
  //TODO: type parameters (task 3262469)
  if (m_params != nullptr) {
    cg.printPropertyHeader("parameters");
    cg.printExpressionVector(m_params);
  }
  if (m_retTypeAnnotation != nullptr) {
    cg.printPropertyHeader("returnType");
    m_retTypeAnnotation->outputCodeModel(cg);
  }
  cg.printPropertyHeader("block");
  if (m_stmt != nullptr) {
    auto stmt = m_stmt;
    if (m_autoPropCount > 0) {
      stmt = static_pointer_cast<StatementList>(stmt->clone());
      for (int i = m_autoPropCount; i > 0; i--) {
        stmt->removeElement(0);
      }
    }
    cg.printAsEnclosedBlock(stmt);
  } else {
    cg.printAsBlock(nullptr);
  }
  cg.printPropertyHeader("sourceLocation");
  cg.printLocation(this);
  if (!m_docComment.empty()) {
    cg.printPropertyHeader("comments");
    cg.printValue(m_docComment);
  }
  cg.printObjectFooter();
}
示例#6
0
 virtual PPMutationListener *GetPPMutationListener() {
     return CG->GetPPMutationListener();
 }
示例#7
0
 virtual bool shouldSkipFunctionBody(Decl *D) {
     return CG->shouldSkipFunctionBody(D);
 }
示例#8
0
 virtual void HandleInterestingDecl(DeclGroupRef D) {
     CG->HandleInterestingDecl(D);
 }
示例#9
0
 virtual void HandleTranslationUnit(ASTContext &Ctx) {
     Decl * Decl = Visitor.GetLivenessFunction();
     DeclGroupRef R = DeclGroupRef::Create(Ctx, &Decl, 1);
     CG->HandleTopLevelDecl(R);
     CG->HandleTranslationUnit(Ctx);
 }
示例#10
0
 virtual void Initialize(ASTContext &Context) {
     Visitor.SetContext(&Context);
     CG->Initialize(Context);
 }
示例#11
0
 virtual bool HandleTopLevelDecl(DeclGroupRef D) {
     for (DeclGroupRef::iterator b = D.begin(), e = D.end();
             b != e; ++b)
         Visitor.TraverseDecl(*b);
     return CG->HandleTopLevelDecl(D);
 }
示例#12
0
void ClassStatement::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  ClassScopeRawPtr classScope = getClassScope();
  if (cg.getContext() == CodeGenerator::NoContext) {
    if (classScope->isRedeclaring()) {
      cg_printf("g->%s%s = ClassStaticsPtr(NEW(%s%s)());\n",
                Option::ClassStaticsObjectPrefix,
                cg.formatLabel(m_name).c_str(),
                Option::ClassStaticsPrefix, classScope->getId(cg).c_str());
      cg_printf("g->%s%s = &%s%s;\n",
                Option::ClassStaticsCallbackPrefix,
                cg.formatLabel(m_name).c_str(),
                Option::ClassWrapperFunctionPrefix,
                classScope->getId(cg).c_str());
    }
    if (classScope->isVolatile()) {
      cg_printf("g->CDEC(%s) = true;\n", m_name.c_str());
    }
    const vector<string> &bases = classScope->getBases();
    for (vector<string>::const_iterator it = bases.begin();
         it != bases.end(); ++it) {
      ClassScopePtr base = ar->findClass(*it);
      if (base && base->isVolatile()) {
        cg_printf("checkClassExists(");
        cg_printString(base->getOriginalName(), ar, shared_from_this());
        string lname = Util::toLower(base->getOriginalName());
        cg_printf(", &%s->CDEC(%s), %s->FVF(__autoload));\n",
                  cg.getGlobals(ar), cg.formatLabel(lname).c_str(),
                  cg.getGlobals(ar));
      }
    }
    return;
  }

  if (cg.getContext() != CodeGenerator::CppForwardDeclaration) {
    printSource(cg);
  }

  string clsNameStr = classScope->getId(cg);
  const char *clsName = clsNameStr.c_str();
  bool redeclared = classScope->isRedeclaring();
  switch (cg.getContext()) {
  case CodeGenerator::CppDeclaration:
    {
      if (Option::GenerateCPPMacros) {
        classScope->outputForwardDeclaration(cg);
      }

      bool system = cg.getOutput() == CodeGenerator::SystemCPP;
      ClassScopePtr parCls;
      if (!m_parent.empty()) {
        parCls = ar->findClass(m_parent);
        if (parCls && parCls->isRedeclaring()) parCls.reset();
      }
      if (Option::GenerateCppLibCode) {
        cg.printDocComment(classScope->getDocComment());
      }
      cg_printf("class %s%s", Option::ClassPrefix, clsName);
      if (!m_parent.empty() && classScope->derivesDirectlyFrom(m_parent)) {
        if (!parCls) {
          cg_printf(" : public DynamicObjectData");
        } else {
          cg_printf(" : public %s%s", Option::ClassPrefix,
                    parCls->getId(cg).c_str());
        }
      } else {
        if (classScope->derivesFromRedeclaring()) {
          cg_printf(" : public DynamicObjectData");
        } else if (system) {
          cg_printf(" : public ExtObjectData");
        } else {
          cg_printf(" : public ObjectData");
        }
      }
      if (m_base && Option::UseVirtualDispatch) {
        for (int i = 0; i < m_base->getCount(); i++) {
          ScalarExpressionPtr exp =
            dynamic_pointer_cast<ScalarExpression>((*m_base)[i]);
          const char *intf = exp->getString().c_str();
          ClassScopePtr intfClassScope = ar->findClass(intf);
          if (intfClassScope && !intfClassScope->isRedeclaring() &&
              classScope->derivesDirectlyFrom(intf) &&
              (!parCls || !parCls->derivesFrom(ar, intf, true, false))) {
            string id = intfClassScope->getId(cg);
            cg_printf(", public %s%s", Option::ClassPrefix, id.c_str());
          }
        }
      }
      cg_indentBegin(" {\n");
      cg_printf("public:\n");

      cg.printSection("Properties");
      classScope->getVariables()->outputCPPPropertyDecl(cg, ar,
          classScope->derivesFromRedeclaring());

      if (Option::GenerateCppLibCode) {
        cg.printSection("Methods");
        classScope->outputMethodWrappers(cg, ar);
        cg.printSection(">>>>>>>>>> Internal Implementation <<<<<<<<<<");
        cg_printf("// NOTE: Anything below is subject to change. "
                  "Use everything above instead.\n");
      }

      cg.printSection("Class Map");
      if (Option::GenerateCPPMacros) {
        cg_printf("virtual bool o_instanceof(CStrRef s) const;\n");
      }

      if (Option::GenerateCPPMacros) {
        bool dyn = (!parCls && !m_parent.empty()) ||
          classScope->derivesFromRedeclaring() ==
          ClassScope::DirectFromRedeclared;
        bool idyn = parCls && classScope->derivesFromRedeclaring() ==
          ClassScope::IndirectFromRedeclared;
        bool redec = classScope->isRedeclaring();
        if (!classScope->derivesFromRedeclaring()) {
          outputCPPClassDecl(cg, ar, clsName, m_originalName.c_str(),
                             parCls ? parCls->getId(cg).c_str()
                                    : "ObjectData");
        } else {
          cg_printf("DECLARE_DYNAMIC_CLASS(%s, %s, %s)\n", clsName,
                    m_originalName.c_str(),
                    dyn || !parCls ? "DynamicObjectData" :
                    parCls->getId(cg).c_str());
        }
        if (system || Option::EnableEval >= Option::LimitedEval) {
          cg_printf("DECLARE_INVOKES_FROM_EVAL\n");
        }

        bool hasGet = classScope->getAttribute(
          ClassScope::HasUnknownPropGetter);
        bool hasSet = classScope->getAttribute(
          ClassScope::HasUnknownPropSetter);
        bool hasCall = classScope->getAttribute(
          ClassScope::HasUnknownMethodHandler);
        bool hasCallStatic = classScope->getAttribute(
          ClassScope::HasUnknownStaticMethodHandler);

        if (dyn || idyn || redec || hasGet || hasSet ||
            hasCall || hasCallStatic) {
          if (redec && classScope->derivedByDynamic()) {
            cg_printf("DECLARE_ROOT;\n");
             if (!dyn && !idyn) {
               cg_printf("private: ObjectData* root;\n");
               cg_printf("public:\n");
               cg_printf("virtual ObjectData *getRoot() { return root; }\n");
             }
          }

          string conInit = "";
          bool hasParam = false;
          if (dyn) {
            conInit = " : DynamicObjectData(\"" + m_parent + "\", r)";
            hasParam = true;
          } else if (idyn) {
            conInit = " : " + string(Option::ClassPrefix) + parCls->getId(cg) +
              "(r ? r : this)";
            hasParam = true;
          } else {
            if (redec && classScope->derivedByDynamic()) {
              conInit = " : root(r ? r : this)";
            }
            hasParam = true;
          }

          cg_indentBegin("%s%s(%s)%s {%s",
                         Option::ClassPrefix, clsName,
                         hasParam ? "ObjectData* r = NULL" : "",
                         conInit.c_str(),
                         hasGet || hasSet || hasCall || hasCallStatic ?
                         "\n" : "");
          if (hasGet) cg_printf("setAttribute(UseGet);\n");
          if (hasSet) cg_printf("setAttribute(UseSet);\n");
          if (hasCall) cg_printf("setAttribute(HasCall);\n");
          if (hasCallStatic) cg_printf("setAttribute(HasCallStatic);\n");
          cg_indentEnd("}\n");
        }
      }

      cg_printf("void init();\n");

      if (classScope->needLazyStaticInitializer()) {
        cg_printf("static GlobalVariables *lazy_initializer"
                  "(GlobalVariables *g);\n");
      }

      if (!classScope->getAttribute(ClassScope::HasConstructor)) {
        FunctionScopePtr func = classScope->findFunction(ar, "__construct",
                                                         false);
        if (func && !func->isAbstract() && !classScope->isInterface()) {
          func->outputCPPCreateDecl(cg, ar);
        }
      }
      if (classScope->getAttribute(ClassScope::HasDestructor)) {
        cg_printf("public: virtual void destruct();\n");
      }

      // doCall
      if (classScope->getAttribute(ClassScope::HasUnknownMethodHandler)) {
        cg_printf("Variant doCall(Variant v_name, Variant v_arguments, "
                  "bool fatal);\n");
      }

      if (classScope->isRedeclaring() &&
          !classScope->derivesFromRedeclaring() &&
          classScope->derivedByDynamic()) {
        cg_printf("Variant doRootCall(Variant v_name, Variant v_arguments, "
                  "bool fatal);\n");
      }

      if (m_stmt) m_stmt->outputCPP(cg, ar);
      {
        set<string> done;
        classScope->outputCPPStaticMethodWrappers(cg, ar, done, clsName);
      }

      if (cg.getOutput() == CodeGenerator::SystemCPP &&
          ar->isBaseSysRsrcClass(clsName) &&
          !classScope->hasProperty("rsrc")) {
        cg_printf("public: Variant %srsrc;\n", Option::PropertyPrefix);
      }
      if (Option::GenerateCPPMacros) {
        classScope->outputCPPJumpTableDecl(cg, ar);
      }
      cg_indentEnd("};\n");

      if (redeclared) {
        cg_indentBegin("class %s%s : public ClassStatics {\n",
                       Option::ClassStaticsPrefix, clsName);
        cg_printf("public:\n");
        cg_printf("DECLARE_OBJECT_ALLOCATION(%s%s);\n",
                  Option::ClassStaticsPrefix, clsName);
        cg_printf("%s%s() : ClassStatics(%d) {}\n",
                  Option::ClassStaticsPrefix, clsName,
                  classScope->getRedeclaringId());
        cg_indentBegin("Variant %sgetInit(CStrRef s) {\n",
                       Option::ObjectStaticPrefix);
        cg_printf("return %s%s::%sgetInit(s);\n", Option::ClassPrefix,
                  clsName, Option::ObjectStaticPrefix);
        cg_indentEnd("}\n");
        cg_indentBegin("Variant %sget(CStrRef s) {\n",
                       Option::ObjectStaticPrefix);
        cg_printf("return %s%s::%sget(s);\n", Option::ClassPrefix,
                  clsName, Option::ObjectStaticPrefix);
        cg_indentEnd("}\n");
        cg_indentBegin("Variant &%slval(CStrRef s) {\n",
                  Option::ObjectStaticPrefix);
        cg_printf("return %s%s::%slval(s);\n", Option::ClassPrefix,
                  clsName, Option::ObjectStaticPrefix);
        cg_indentEnd("}\n");
        cg_indentBegin("Object createOnly(ObjectData* root = NULL) {\n");
        cg_printf("Object r((NEW(%s%s)(root)));\n", Option::ClassPrefix,
            clsName);
        cg_printf("r->init();\n");
        cg_printf("return r;\n");
        cg_indentEnd("}\n");
        cg_indentBegin("Variant %sconstant(const char* s) {\n",
                       Option::ObjectStaticPrefix);
        cg_printf("return %s%s::%sconstant(s);\n", Option::ClassPrefix,
                  clsName, Option::ObjectStaticPrefix);
        cg_indentEnd("}\n");
        cg_indentBegin("Variant %sinvoke_from_eval(const char *c, "
                       "const char *s, Eval::VariableEnvironment &env, "
                       "const Eval::FunctionCallExpression *call, "
                       "int64 hash = -1, bool fatal = true) "
                       "{\n",
                       Option::ObjectStaticPrefix);
        cg_printf("return %s%s::%sinvoke_from_eval(c, s, env, call, hash, "
                  "fatal);\n",
                  Option::ClassPrefix, clsName,
                  Option::ObjectStaticPrefix);
        cg_indentEnd("}\n");
        cg_indentBegin("bool %sget_call_info(MethodCallPackage &mcp, "
          "int64 hash = -1) {\n",
            Option::ObjectStaticPrefix);
        cg_printf("return %s%s::%sget_call_info(mcp, hash);\n",
            Option::ClassPrefix, clsName, Option::ObjectStaticPrefix);
        cg_indentEnd("}\n");
        cg_indentEnd("};\n");
      }

      if (m_stmt) {
        cg.setContext(CodeGenerator::CppClassConstantsDecl);
        m_stmt->outputCPP(cg, ar);
        cg.setContext(CodeGenerator::CppDeclaration);
      }

      classScope->outputCPPGlobalTableWrappersDecl(cg, ar);
    }
    break;
  case CodeGenerator::CppImplementation:
    if (m_stmt) {
      cg.setContext(CodeGenerator::CppClassConstantsImpl);
      m_stmt->outputCPP(cg, ar);
      cg.setContext(CodeGenerator::CppImplementation);
    }

    classScope->outputCPPSupportMethodsImpl(cg, ar);

    if (redeclared) {
      cg_printf("IMPLEMENT_OBJECT_ALLOCATION(%s%s);\n",
                Option::ClassStaticsPrefix, clsName);
    }

    cg_indentBegin("void %s%s::init() {\n",
                   Option::ClassPrefix, clsName);
    if (!m_parent.empty()) {
      if (classScope->derivesFromRedeclaring() ==
          ClassScope::DirectFromRedeclared) {
        cg_printf("parent->init();\n");
      } else {

        ClassScopePtr parCls = ar->findClass(m_parent);
        cg_printf("%s%s::init();\n", Option::ClassPrefix,
                  parCls->getId(cg).c_str());
      }
    }
    if (classScope->getVariables()->
        getAttribute(VariableTable::NeedGlobalPointer)) {
      cg.printDeclareGlobals();
    }
    cg.setContext(CodeGenerator::CppConstructor);
    if (m_stmt) m_stmt->outputCPP(cg, ar);

    // This is lame. Exception base class needs to prepare stacktrace outside
    // of its PHP constructor. Every subclass of exception also needs this
    // stacktrace, so we're adding an artificial __init__ in exception.php
    // and calling it here.
    if (m_name == "exception") {
      cg_printf("{CountableHelper h(this); t___init__();}\n");
    }

    cg_indentEnd("}\n");

    if (classScope->needStaticInitializer()) {
      cg_indentBegin("void %s%s::os_static_initializer() {\n",
                     Option::ClassPrefix, clsName);
      cg.printDeclareGlobals();
      cg.setContext(CodeGenerator::CppStaticInitializer);
      if (m_stmt) m_stmt->outputCPP(cg, ar);
      cg_indentEnd("}\n");
      cg_indentBegin("void %s%s() {\n",
                     Option::ClassStaticInitializerPrefix, clsName);
      cg_printf("%s%s::os_static_initializer();\n",  Option::ClassPrefix,
                clsName);
      cg_indentEnd("}\n");
    }
    if (classScope->needLazyStaticInitializer()) {
      cg_indentBegin("GlobalVariables *%s%s::lazy_initializer("
                     "GlobalVariables *g) {\n", Option::ClassPrefix, clsName);
      cg_indentBegin("if (!g->%s%s) {\n",
                     Option::ClassStaticInitializerFlagPrefix, clsName);
      cg_printf("g->%s%s = true;\n", Option::ClassStaticInitializerFlagPrefix,
                clsName);
      cg.setContext(CodeGenerator::CppLazyStaticInitializer);
      if (m_stmt) m_stmt->outputCPP(cg, ar);
      cg_indentEnd("}\n");
      cg_printf("return g;\n");
      cg_indentEnd("}\n");
    }
    cg.setContext(CodeGenerator::CppImplementation);
    if (m_stmt) m_stmt->outputCPP(cg, ar);

    break;
  case CodeGenerator::CppFFIDecl:
  case CodeGenerator::CppFFIImpl:
    if (m_stmt) m_stmt->outputCPP(cg, ar);
    break;
  case CodeGenerator::JavaFFI:
    {
      if (classScope->isRedeclaring()) break;

      // TODO support PHP namespaces, once HPHP supports it
      string packageName = Option::JavaFFIRootPackage;
      string packageDir = packageName;
      Util::replaceAll(packageDir, ".", "/");

      string outputDir = ar->getOutputPath() + "/" + Option::FFIFilePrefix +
        packageDir + "/";
      Util::mkdir(outputDir);

      // uses a different cg to generate a separate file for each PHP class
      // also, uses the original capitalized class name
      string clsFile = outputDir + getOriginalName() + ".java";
      ofstream fcls(clsFile.c_str());
      CodeGenerator cgCls(&fcls, CodeGenerator::FileCPP);
      cgCls.setContext(CodeGenerator::JavaFFI);

      cgCls.printf("package %s;\n\n", packageName.c_str());
      cgCls.printf("import hphp.*;\n\n");

      printSource(cgCls);

      string clsModifier;
      switch (m_type) {
      case T_CLASS:
        break;
      case T_ABSTRACT:
        clsModifier = "abstract ";
        break;
      case T_FINAL:
        clsModifier = "final ";
        break;
      }
      cgCls.printf("public %sclass %s ", clsModifier.c_str(),
                   getOriginalName().c_str());

      ClassScopePtr parCls;
      if (!m_parent.empty()) parCls = ar->findClass(m_parent);
      if (!m_parent.empty() && classScope->derivesDirectlyFrom(m_parent)
          && parCls && parCls->isUserClass() && !parCls->isRedeclaring()) {
        // system classes are not supported in static FFI translation
        // they shouldn't appear as superclasses as well
        cgCls.printf("extends %s", parCls->getOriginalName().c_str());
      }
      else {
        cgCls.printf("extends HphpObject");
      }
      if (m_base) {
        bool first = true;
        for (int i = 0; i < m_base->getCount(); i++) {
          ScalarExpressionPtr exp =
            dynamic_pointer_cast<ScalarExpression>((*m_base)[i]);
          const char *intf = exp->getString().c_str();
          ClassScopePtr intfClassScope = ar->findClass(intf);
          if (intfClassScope && classScope->derivesFrom(ar, intf, false, false)
           && intfClassScope->isUserClass()) {
            if (first) {
              cgCls.printf(" implements ");
              first = false;
            }
            else {
              cgCls.printf(", ");
            }
            cgCls.printf(intfClassScope->getOriginalName().c_str());
          }
        }
      }

      cgCls.indentBegin(" {\n");

      // constructor for initializing the variant pointer
      cgCls.printf("protected %s(long ptr) { super(ptr); }\n\n",
                   getOriginalName().c_str());

      FunctionScopePtr cons = classScope->findConstructor(ar, true);
      if (cons && !cons->isAbstract() || m_type != T_ABSTRACT) {
        // if not an abstract class and not having an explicit constructor,
        // adds a default constructor
        outputJavaFFIConstructor(cgCls, ar, cons);
      }

      if (m_stmt) m_stmt->outputCPP(cgCls, ar);
      cgCls.indentEnd("}\n");

      fcls.close();
    }
    break;
  case CodeGenerator::JavaFFICppDecl:
  case CodeGenerator::JavaFFICppImpl:
    {
      if (classScope->isRedeclaring()) break;

      if (m_stmt) m_stmt->outputCPP(cg, ar);
      FunctionScopePtr cons = classScope->findConstructor(ar, true);
      if (cons && !cons->isAbstract() || m_type != T_ABSTRACT) {
        outputJavaFFICPPCreator(cg, ar, cons);
      }
    }
    break;
  default:
    ASSERT(false);
    break;
  }
}
示例#13
0
void ClassStatement::outputCPPClassDecl(CodeGenerator &cg,
                                        AnalysisResultPtr ar,
                                        const char *clsName,
                                        const char *originalName,
                                        const char *parent) {
  ClassScopeRawPtr classScope = getClassScope();
  VariableTablePtr variables = classScope->getVariables();
  ConstantTablePtr constants = classScope->getConstants();
  if (variables->hasAllJumpTables() && constants->hasJumpTable() &&
      classScope->hasAllJumpTables()) {
    cg_printf("DECLARE_CLASS(%s, %s, %s)\n", clsName, originalName, parent);
    return;
  }

  // Now we start to break down DECLARE_CLASS into lines of code that could
  // be generated differently...

  cg_printf("DECLARE_CLASS_COMMON(%s, %s)\n", clsName,
            cg.escapeLabel(originalName).c_str());
  cg_printf("DECLARE_INVOKE_EX%s(%s, %s, %s)\n",
      Option::UseMethodIndex ? "WITH_INDEX" : "", clsName,
            cg.escapeLabel(originalName).c_str(), parent);

  cg.printSection("DECLARE_STATIC_PROP_OPS");
  cg_printf("public:\n");
  if (classScope->needStaticInitializer()) {
    cg_printf("static void os_static_initializer();\n");
  }
  if (variables->hasJumpTable(VariableTable::JumpTableClassStaticGetInit)) {
    cg_printf("static Variant os_getInit(CStrRef s);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_GETINIT_%s 1\n", clsName);
  }
  if (variables->hasJumpTable(VariableTable::JumpTableClassStaticGet)) {
    cg_printf("static Variant os_get(CStrRef s);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_GET_%s 1\n", clsName);
  }
  if (variables->hasJumpTable(VariableTable::JumpTableClassStaticLval)) {
    cg_printf("static Variant &os_lval(CStrRef s);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_LVAL_%s 1\n", clsName);
  }
  if (constants->hasJumpTable()) {
    cg_printf("static Variant os_constant(const char *s);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_CONSTANT_%s 1\n", clsName);
  }

  cg.printSection("DECLARE_INSTANCE_PROP_OPS");
  cg_printf("public:\n");

  if (variables->hasJumpTable(VariableTable::JumpTableClassGetArray)) {
    cg_printf("virtual void o_getArray(Array &props, bool pubOnly = false) "
              "const;\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_GETARRAY_%s 1\n", clsName);
  }
  if (variables->hasJumpTable(VariableTable::JumpTableClassSetArray)) {
    cg_printf("virtual void o_setArray(CArrRef props);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_SETARRAY_%s 1\n", clsName);
  }

  if (variables->hasJumpTable(VariableTable::JumpTableClassRealProp)) {
    cg_printf("virtual Variant *o_realProp(CStrRef s, int flags,\n");
    cg_printf("                            CStrRef context = null_string) "
              "const;\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_realProp_%s 1\n", clsName);
  }
  if (variables->hasNonStaticPrivate()) {
    cg_printf("Variant *o_realPropPrivate(CStrRef s, int flags) const;\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_realProp_PRIVATE_%s 1\n", clsName);
  }

  cg.printSection("DECLARE_INSTANCE_PUBLIC_PROP_OPS");
  cg_printf("public:\n");
  if (variables->hasJumpTable(VariableTable::JumpTableClassRealPropPublic)) {
    cg_printf("virtual Variant *o_realPropPublic(CStrRef s, "
              "int flags) const;\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_realProp_PUBLIC_%s 1\n", clsName);
  }

  cg.printSection("DECLARE_COMMON_INVOKE");
  cg.printf("static bool os_get_call_info(MethodCallPackage &mcp, "
      "int64 hash = -1);\n");
  if (Option::UseMethodIndex) {
    cg.printf("virtual bool o_get_call_info_with_index(MethodCallPackage &mcp,"
        " MethodIndex mi, int64 hash = -1);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_STATIC_INVOKE_%s 1\n", clsName);
  }
  if (classScope->hasJumpTable(ClassScope::JumpTableInvoke)) {
    cg.printf("virtual bool o_get_call_info(MethodCallPackage &mcp, "
        "int64 hash = -1);\n");
  } else {
    cg_printf("#define OMIT_JUMP_TABLE_CLASS_INVOKE_%s 1\n", clsName);
  }

  cg_printf("\n");
  cg_printf("public:\n");
}
示例#14
0
bool QOpExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                 int state) {
  if (!hasEffect()) {
    return Expression::preOutputCPP(cg, ar, state);
  }

  bool fix_condition = m_condition->preOutputCPP(cg, ar, 0);
  if (!cg.inExpression()) {
    return fix_condition || (state & FixOrder) ||
      (!m_expYes || m_expYes->preOutputCPP(cg, ar, 0)) ||
      m_expNo->preOutputCPP(cg, ar, 0);
  }

  cg.setInExpression(false);
  bool fix_yes = (!m_expYes || m_expYes->preOutputCPP(cg, ar, 0));
  bool fix_no = m_expNo->preOutputCPP(cg, ar, 0);
  cg.setInExpression(true);

  if (fix_yes || fix_no) {
    cg.wrapExpressionBegin();
    if (isUnused()) {
      cg_printf("if (");
      wrapBoolean(cg, ar, m_condition);
      cg_indentBegin(") {\n");
      if (m_expYes) {
        m_expYes->preOutputCPP(cg, ar, 0);
        if (m_expYes->outputCPPUnneeded(cg, ar)) cg_printf(";\n");
      }
      cg_indentEnd("\n");
      cg_indentBegin("} else {\n");
      m_expNo->preOutputCPP(cg, ar, 0);
      if (m_expNo->outputCPPUnneeded(cg, ar)) cg_printf(";\n");
      cg_indentEnd("}\n");
      m_cppValue = "null_variant";
    } else {
      std::string tmp = genCPPTemp(cg, ar);

      if (m_expYes) {
        TypePtr typeYes = m_expYes->getActualType();
        TypePtr typeNo = m_expNo->getActualType();
        TypePtr type =
          typeYes && typeNo && Type::SameType(typeYes, typeNo) &&
          !typeYes->is(Type::KindOfVariant) &&
          m_expYes->isLiteralString() == m_expNo->isLiteralString() ?
          typeYes : Type::Variant;

        type->outputCPPDecl(cg, ar, getScope());
        cg_printf(" %s;\n", tmp.c_str());
        cg_printf("if (");
        wrapBoolean(cg, ar, m_condition);
        cg_indentBegin(") {\n");
        m_expYes->preOutputCPP(cg, ar, 0);
        cg_printf("%s = (", tmp.c_str());
        m_expYes->outputCPP(cg, ar);
        cg_indentEnd(");\n");
      } else {
        TypePtr typeYes = m_condition->getActualType();
        TypePtr typeNo = m_expNo->getActualType();
        TypePtr type =
          typeYes && typeNo && Type::SameType(typeYes, typeNo) &&
          !typeYes->is(Type::KindOfVariant) &&
          m_condition->isLiteralString() == m_expNo->isLiteralString() ?
          typeYes : Type::Variant;

        type->outputCPPDecl(cg, ar, getScope());
        cg_printf(" %s = ", tmp.c_str());
        m_condition->outputCPP(cg, ar);
        cg_printf(";\n");
        cg_printf("if (toBoolean(%s)) {\n", tmp.c_str());
      }

      cg_indentBegin("} else {\n");
      m_expNo->preOutputCPP(cg, ar, 0);
      cg_printf("%s = (", tmp.c_str());
      m_expNo->outputCPP(cg, ar);
      cg_printf(");\n");
      cg_indentEnd("}\n");
      m_cppValue = tmp;
    }
  } else if (state & FixOrder) {
    preOutputStash(cg, ar, state);
    return true;
  }
  return false;
}
示例#15
0
 virtual ASTDeserializationListener *GetASTDeserializationListener() {
     return CG->GetASTDeserializationListener();
 }
示例#16
0
 virtual void HandleTagDeclDefinition(TagDecl *D) {
     CG->HandleTagDeclDefinition(D);
 }
示例#17
0
 virtual void PrintStats() {
     CG->PrintStats();
 }
示例#18
0
 virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {
     CG->HandleCXXImplicitFunctionInstantiation(D);
 }
示例#19
0
 virtual void HandleImplicitImportDecl(ImportDecl *D) {
     CG->HandleImplicitImportDecl(D);
 }
示例#20
0
 virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
     CG->HandleTopLevelDeclInObjCContainer(D);
 }
示例#21
0
bool ExpressionList::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                  int state) {
  if (m_kind == ListKindParam && !m_arrayElements) {
    return Expression::preOutputCPP(cg, ar, state|StashKidVars);
  }

  unsigned n = m_exps.size();
  bool inExpression = cg.inExpression();
  if (!inExpression && (state & FixOrder)) {
    return true;
  }

  cg.setInExpression(false);
  bool ret = false;
  if (m_arrayElements) {
    /*
     * would like to do:
     *  ret = Expression::preOutputCPP(cg, ar, state);
     * but icc has problems with the generated code.
     */
    ret = hasEffect();
  } else if (n > 1 && m_kind == ListKindLeft) {
    ret = true;
  } else {
    for (unsigned int i = 0; i < n; i++) {
      if (m_exps[i]->preOutputCPP(cg, ar, 0)) {
        ret = true;
        break;
      }
    }
    if (!ret) {
      ExpressionPtr e = m_exps[n - 1];
      if (hasContext(LValue) && !hasAnyContext(RefValue|InvokeArgument) &&
          !(e->hasContext(LValue) &&
            !e->hasAnyContext(RefValue|InvokeArgument))) {
        ret = true;
      } else if (hasContext(RefValue) &&
                 !e->hasAllContext(LValue|ReturnContext) &&
                 !e->hasContext(RefValue)) {
        ret = true;
      }
    }
  }

  if (!inExpression) return ret;

  cg.setInExpression(true);
  if (!ret) {
    if (state & FixOrder) {
      preOutputStash(cg, ar, state);
      return true;
    }
    return false;
  }

  cg.wrapExpressionBegin();
  if (m_arrayElements) {
    setCPPTemp(genCPPTemp(cg, ar));
    outputCPPInternal(cg, ar, true, true);
  } else {
    unsigned ix = isUnused() ? (unsigned)-1 :
      m_kind == ListKindLeft ? 0 : n - 1;
    for (unsigned int i = 0; i < n; i++) {
      ExpressionPtr e = m_exps[i];
      if (i != ix) e->setUnused(true);
      e->preOutputCPP(cg, ar, i == ix ? state : 0);
      if (i != ix) {
        if (e->outputCPPUnneeded(cg, ar)) {
          cg_printf(";\n");
        }
        e->setCPPTemp("/**/");
        continue;
      }
      /*
        We inlined a by-value function into the rhs of a by-ref assignment.
      */
      bool noRef = hasContext(RefValue) &&
        !e->hasAllContext(LValue|ReturnContext) &&
        !e->hasContext(RefValue) &&
        !e->isTemporary() &&
        Type::IsMappedToVariant(e->getActualType());
      /*
        If we need a non-const reference, but the expression is
        going to generate a const reference, fix it
      */
      bool lvSwitch =
        hasContext(LValue) && !hasAnyContext(RefValue|InvokeArgument) &&
        !(e->hasContext(LValue) &&
          !e->hasAnyContext(RefValue|InvokeArgument));

      if (e->hasAllContext(LValue|ReturnContext) && i + 1 == n) {
        e->clearContext(ReturnContext);
      }

      if (noRef || lvSwitch || (!i && n > 1)) {
        e->Expression::preOutputStash(cg, ar, state | FixOrder | StashAll);
        if (!(state & FixOrder)) {
          cg_printf("id(%s);\n", e->cppTemp().c_str());
        }
      }
      if (e->hasCPPTemp() &&
          Type::SameType(e->getGenType(), getGenType())) {
        string t = e->cppTemp();
        if (noRef) {
          cg_printf("CVarRef %s_nr = wrap_variant(%s);\n",
                    t.c_str(), t.c_str());
          t += "_nr";
        }

        if (lvSwitch) {
          cg_printf("Variant &%s_lv = const_cast<Variant&>(%s);\n",
                    t.c_str(), t.c_str());
          t += "_lv";
        }
        setCPPTemp(t);
      }
    }
  }
  return true;
}
示例#22
0
 virtual void CompleteTentativeDefinition(VarDecl *D) {
     CG->CompleteTentativeDefinition(D);
 }
示例#23
0
void ClassStatement::outputCodeModel(CodeGenerator &cg) {
  auto numProps = 4;
  if (m_attrList != nullptr) numProps++;
  if (m_type == T_ABSTRACT || m_type == T_FINAL) numProps++;
  if (!m_parent.empty()) numProps++;
  if (m_base != nullptr) numProps++;
  if (m_stmt != nullptr) numProps++;
  if (!m_docComment.empty()) numProps++;

  cg.printObjectHeader("TypeStatement", numProps);
  if (m_attrList != nullptr) {
    cg.printPropertyHeader("attributes");
    cg.printExpressionVector(m_attrList);
  }
  if (m_type == T_ABSTRACT) {
    cg.printPropertyHeader("modifiers");
    cg.printModifierVector("abstract");
  } else if (m_type == T_FINAL) {
    cg.printPropertyHeader("modifiers");
    cg.printModifierVector("final");
  }
  cg.printPropertyHeader("kind");
  if (m_type == T_TRAIT) {
    cg.printValue(PHP_TRAIT);
  } else {
    cg.printValue(PHP_CLASS);
  }
  cg.printPropertyHeader("name");
  cg.printValue(m_originalName);
  //TODO: type parameters (task 3262469)
  if (!m_parent.empty()) {
    cg.printPropertyHeader("baseClass");
    cg.printTypeExpression(m_originalParent);
  }
  if (m_base != nullptr) {
    cg.printPropertyHeader("interfaces");
    cg.printExpressionVector(m_base);
  }
  if (m_stmt != nullptr) {
    cg.printPropertyHeader("block");
    cg.printAsBlock(m_stmt);
  }
  cg.printPropertyHeader("sourceLocation");
  cg.printLocation(this->getLocation());
  if (!m_docComment.empty()) {
    cg.printPropertyHeader("comments");
    cg.printValue(m_docComment);
  }
  cg.printObjectFooter();
}
示例#24
0
 virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {
     CG->HandleCXXStaticMemberVarInstantiation(D);
 }
void FunctionStatement::outputCPPImpl(CodeGenerator &cg,
                                      AnalysisResultPtr ar) {
  CodeGenerator::Context context = cg.getContext();

  FunctionScopeRawPtr funcScope = getFunctionScope();
  string fname = funcScope->getId();
  bool pseudoMain = funcScope->inPseudoMain();
  string origFuncName = !pseudoMain ? funcScope->getOriginalName() :
          ("run_init::" + funcScope->getContainingFile()->getName());

  if (outputFFI(cg, ar)) return;

  if (context == CodeGenerator::NoContext) {
    if (funcScope->isVolatile()) {
      string rname = CodeGenerator::FormatLabel(m_name);
      if (funcScope->isRedeclaring()) {
        cg.printf("g->GCI(%s) = &%s%s;\n", rname.c_str(),
                  Option::CallInfoPrefix, fname.c_str());
      }
      cg_printf("g->declareFunctionLit(");
      cg_printString(m_name, ar, shared_from_this());
      cg_printf(");\n");
      cg_printf("g->FVF(%s) = true;\n", rname.c_str());
    }
    return;
  }

  if (context == CodeGenerator::CppDeclaration &&
      !funcScope->isInlined()) return;

  if (context == CodeGenerator::CppPseudoMain &&
      (!pseudoMain || getFileScope()->canUseDummyPseudoMain(ar))) {
    return;
  }
  if (context == CodeGenerator::CppImplementation &&
      (funcScope->isInlined() || pseudoMain)) return;

  cg.setPHPLineNo(-1);

  if (pseudoMain && !Option::GenerateCPPMain) {
    if (context == CodeGenerator::CppPseudoMain) {
      if (cg.getOutput() != CodeGenerator::SystemCPP) {
        cg.setContext(CodeGenerator::NoContext); // no inner functions/classes
        funcScope->getVariables()->setAttribute(VariableTable::ForceGlobal);
        outputCPPStmt(cg, ar);
        funcScope->getVariables()->clearAttribute(VariableTable::ForceGlobal);
        cg.setContext(CodeGenerator::CppPseudoMain);
        return;
      }
    } else if (context == CodeGenerator::CppForwardDeclaration &&
               cg.getOutput() != CodeGenerator::SystemCPP) {
      return;
    }
  }

  if (context == CodeGenerator::CppImplementation) {
    printSource(cg);
  } else if (context == CodeGenerator::CppForwardDeclaration &&
             Option::GenerateCppLibCode) {
    cg_printf("\n");
    printSource(cg);
    cg.printDocComment(funcScope->getDocComment());
  }

  bool isWrapper = context == CodeGenerator::CppTypedParamsWrapperDecl ||
    context == CodeGenerator::CppTypedParamsWrapperImpl;

  bool needsWrapper = isWrapper ||
    (Option::HardTypeHints && funcScope->needsTypeCheckWrapper());

  int startLineImplementation = -1;
  if (context == CodeGenerator::CppDeclaration ||
      context == CodeGenerator::CppImplementation ||
      context == CodeGenerator::CppPseudoMain) {
    startLineImplementation = cg.getLineNo(CodeGenerator::PrimaryStream);
  }

  if (funcScope->isInlined()) cg_printf("inline ");

  TypePtr type = funcScope->getReturnType();
  if (type) {
    bool isHeader = cg.isFileOrClassHeader();
    cg.setFileOrClassHeader(true);
    type->outputCPPDecl(cg, ar, getScope());
    cg.setFileOrClassHeader(isHeader);
  } else {
    cg_printf("void");
  }

  if (Option::FunctionSections.find(origFuncName) !=
      Option::FunctionSections.end()) {
    string funcSection = Option::FunctionSections[origFuncName];
    if (!funcSection.empty()) {
      cg_printf(" __attribute__ ((section (\".text.%s\")))",
                funcSection.c_str());
    }
  }

  if (pseudoMain) {
    cg_printf(" %s%s(", Option::PseudoMainPrefix,
              funcScope->getContainingFile()->pseudoMainName().c_str());
  } else {
    cg_printf(" %s%s(",
              needsWrapper && !isWrapper ?
              Option::TypedFunctionPrefix : Option::FunctionPrefix,
              fname.c_str());
  }

  switch (context) {
    case CodeGenerator::CppForwardDeclaration:
    case CodeGenerator::CppTypedParamsWrapperDecl:
      funcScope->outputCPPParamsDecl(cg, ar, m_params, true);
      if (!isWrapper) {
        int opt = Option::GetOptimizationLevel(m_cppLength);
        if (opt < 3) cg_printf(") __attribute__((optimize(%d))", opt);
      }
      cg_printf(");\n");
      if (!isWrapper) {
        if (funcScope->hasDirectInvoke()) {
          cg_printf("Variant %s%s(void *extra, CArrRef params);\n",
                    Option::InvokePrefix, fname.c_str());
        }
        if (needsWrapper) {
          cg.setContext(CodeGenerator::CppTypedParamsWrapperDecl);
          outputCPPImpl(cg, ar);
          cg.setContext(context);
        }
      }
      break;
    case CodeGenerator::CppDeclaration:
    case CodeGenerator::CppImplementation:
    case CodeGenerator::CppPseudoMain:
    case CodeGenerator::CppTypedParamsWrapperImpl:
    {
      funcScope->outputCPPParamsDecl(cg, ar, m_params, false);
      cg_indentBegin(") {\n");
      if (!isWrapper) {
        const char *suffix =
          (cg.getOutput() == CodeGenerator::SystemCPP ? "_BUILTIN" : "");
        if (pseudoMain) {
          cg_printf("PSEUDOMAIN_INJECTION%s(%s, %s%s);\n",
                    suffix, origFuncName.c_str(), Option::PseudoMainPrefix,
                    funcScope->getContainingFile()->pseudoMainName().c_str());
        } else {
          if (m_stmt->hasBody()) {
            if (suffix[0] == '\0' && !funcScope->needsCheckMem()) {
              suffix = "_NOMEM";
            }
            const string &name = funcScope->getInjectionId();
            cg_printf("FUNCTION_INJECTION%s(%s);\n", suffix, name.c_str());
          }
          outputCPPArgInjections(cg, ar, origFuncName.c_str(),
                                 ClassScopePtr(), funcScope);
        }
        funcScope->outputCPP(cg, ar);
        if (funcScope->needsRefTemp()) cg.genReferenceTemp(shared_from_this());
        cg.setContext(CodeGenerator::NoContext); // no inner functions/classes
        outputCPPStmt(cg, ar);
        if (funcScope->needsRefTemp()) cg.clearRefereceTemp();
        cg_indentEnd("}\n");
        ASSERT(startLineImplementation >= 0);
        m_cppLength = cg.getLineNo(CodeGenerator::PrimaryStream)
                      - startLineImplementation;
        if (needsWrapper) {
          cg.setContext(CodeGenerator::CppTypedParamsWrapperImpl);
          outputCPPImpl(cg, ar);
        }
        cg.setContext(context);
      } else {
        outputCPPTypeCheckWrapper(cg, ar);
        cg_indentEnd("}\n");
      }
      cg.printImplSplitter();
    }
    break;
    default:
      ASSERT(false);
  }
}
示例#26
0
 virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {
     CG->HandleVTable(RD, DefinitionRequired);
 }
示例#27
0
void MethodStatement::outputCodeModel(CodeGenerator &cg) {
  auto numProps = 3;
  if (m_attrList != nullptr) numProps++;
  if (m_ref) numProps++;
  if (m_params != nullptr) numProps++;
  if (m_retTypeAnnotation != nullptr) numProps++;
  if (m_stmt != nullptr) numProps++;
  if (!m_docComment.empty()) numProps++;
  cg.printObjectHeader("FunctionStatement", numProps);
  if (m_attrList != nullptr) {
    cg.printPropertyHeader("attributes");
    cg.printExpressionVector(m_attrList);
  }
  cg.printPropertyHeader("modifiers");
  m_modifiers->outputCodeModel(cg);
  if (m_ref) {
    cg.printPropertyHeader("returnsReference");
    cg.printValue(m_ref);
  }
  cg.printPropertyHeader("name");
  cg.printValue(m_originalName);
  //TODO: type parameters (task 3262469)
  if (m_params != nullptr) {
    cg.printPropertyHeader("parameters");
    cg.printExpressionVector(m_params);
  }
  if (m_retTypeAnnotation != nullptr) {
    cg.printPropertyHeader("returnType");
    m_retTypeAnnotation->outputCodeModel(cg);
  }
  if (m_stmt != nullptr) {
    cg.printPropertyHeader("block");
    cg.printAsBlock(m_stmt);
  }
  cg.printPropertyHeader("location");
  cg.printLocation(this->getLocation());
  if (!m_docComment.empty()) {
    cg.printPropertyHeader("comments");
    cg.printValue(m_docComment);
  }
  cg.printObjectFooter();
}
示例#28
0
 virtual ASTMutationListener *GetASTMutationListener() {
     return CG->GetASTMutationListener();
 }
示例#29
0
文件: switch.cpp 项目: casadi/casadi
  void Switch::codegen_body(CodeGenerator& g) const {
    // Project arguments with different sparsity
    if (project_in_) {
      // Project one or more argument
      g.local("i", "casadi_int");
      g << "const casadi_real** arg1 = arg + " << n_in_ << ";\n";
    }

    // Temporary memory for results with different sparsity
    if (project_out_) {
      // Project one or more results
      g.local("i", "casadi_int");
      g << "casadi_real** res1 = res + " << n_out_ << ";\n";
    }

    if (project_in_)
      g  << "for (i=0; i<" << n_in_-1 << "; ++i) arg1[i]=arg[i+1];\n";

    if (project_out_)
      g  << "for (i=0; i<" << n_out_ << "; ++i) res1[i]=res[i];\n";

    // Codegen condition
    bool if_else = f_.size()==1;
    g.add_auxiliary(CodeGenerator::AUX_TO_INT);
    g << (if_else ? "if" : "switch")  << " (arg[0] ? casadi_to_int(*arg[0]) : 0) {\n";

    // Loop over cases/functions
    for (casadi_int k=0; k<=f_.size(); ++k) {

      // For if,  reverse order
      casadi_int k1 = if_else ? 1-k : k;

      if (!if_else) {
        // Codegen cases
        if (k1<f_.size()) {
          g << "case " << k1 << ":\n";
        } else {
          g << "default:\n";
        }
      } else if (k1==0) {
        // Else
        g << "} else {\n";
      }

      // Get the function:
      const Function& fk = k1<f_.size() ? f_[k1] : f_def_;
      if (fk.is_null()) {
        g << "return 1;\n";
      } else {
        // Project arguments with different sparsity
        for (casadi_int i=0; i<n_in_-1; ++i) {
          const Sparsity& f_sp = fk.sparsity_in(i);
          const Sparsity& sp = sparsity_in_[i+1];
          if (f_sp!=sp) {
            if (f_sp.nnz()==0) {
              g << "arg1[" << i << "]=0;\n";
            } else {
              g.local("t", "casadi_real", "*");
              g << "t=w, w+=" << f_sp.nnz() << ";\n"
                << g.project("arg1[" + str(i) + "]", sp, "t", f_sp, "w") << "\n"
                << "arg1[" << i << "]=t;\n";
            }
          }
        }

        // Temporary memory for results with different sparsity
        for (casadi_int i=0; i<n_out_; ++i) {
          const Sparsity& f_sp = fk.sparsity_out(i);
          const Sparsity& sp = sparsity_out_[i];
          if (f_sp!=sp) {
            if (f_sp.nnz()==0) {
              g << "res1[" << i << "]=0;\n";
            } else {
              g << "res1[" << i << "]=w, w+=" << f_sp.nnz() << ";\n";
            }
          }
        }

        // Function call
        g << "if (" << g(fk, project_in_ ? "arg1" : "arg+1",
                         project_out_ ? "res1" : "res",
                         "iw", "w") << ") return 1;\n";

        // Project results with different sparsity
        for (casadi_int i=0; i<n_out_; ++i) {
          const Sparsity& f_sp = fk.sparsity_out(i);
          const Sparsity& sp = sparsity_out_[i];
          if (f_sp!=sp) {
            g << g.project("res1[" + str(i) + "]", f_sp,
                           "res[" + str(i) + "]", sp, "w") << "\n";
          }
        }

        // Break (if switch)
        if (!if_else) g << "break;\n";
      }
    }

    // End switch/else
    g << "}\n";
  }
示例#30
0
bool ExpressionList::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar,
                                  int state) {
  if (m_kind == ListKindParam && !m_arrayElements) {
    return Expression::preOutputCPP(cg, ar, state|StashKidVars);
  }

  unsigned n = m_exps.size();
  bool inExpression = cg.inExpression();
  if (!inExpression && (state & FixOrder)) {
    return true;
  }

  cg.setInExpression(false);
  bool ret = false;
  if (m_arrayElements) {
    /*
     * would like to do:
     *  ret = Expression::preOutputCPP(cg, ar, state);
     * but icc has problems with the generated code.
     */
    ret = hasEffect();
  } else if (n > 1 && m_kind == ListKindLeft) {
    ret = true;
  } else {
    for (unsigned int i = 0; i < n; i++) {
      if (m_exps[i]->preOutputCPP(cg, ar, 0)) {
        ret = true;
        break;
      }
    }
  }

  if (!inExpression) return ret;

  cg.setInExpression(true);
  if (!ret) {
    if (state & FixOrder) {
      preOutputStash(cg, ar, state);
      return true;
    }
    return false;
  }

  cg.wrapExpressionBegin();
  if (m_arrayElements) {
    setCPPTemp(genCPPTemp(cg, ar));
    outputCPPInternal(cg, ar, true, true);
  } else {
    unsigned ix = m_kind == ListKindLeft ? 0 : n - 1;
    for (unsigned int i = 0; i < n; i++) {
      ExpressionPtr e = m_exps[i];
      e->preOutputCPP(cg, ar, i == ix ? state : 0);
      if (i != ix) {
        if (e->outputCPPUnneeded(cg, ar)) {
          cg_printf(";\n");
        }
        e->setCPPTemp("/**/");
      } else if (e->hasCPPTemp() && Type::SameType(e->getType(), getType())) {
        setCPPTemp(e->cppTemp());
      } else if (!i && n > 1) {
        e->Expression::preOutputStash(cg, ar, state | FixOrder);
        if (!(state & FixOrder)) {
          cg_printf("id(%s);\n", e->cppTemp().c_str());
        }
        setCPPTemp(e->cppTemp());
      }
    }
  }
  return true;
}