bool UnaryOpExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar, int state) { if (m_op == T_ISSET && m_exp && m_exp->is(Expression::KindOfExpressionList)) { ExpressionListPtr exps = dynamic_pointer_cast<ExpressionList>(m_exp); int count = exps->getCount(); if (count > 1) { bool fix_e1 = (*exps)[0]->preOutputCPP(cg, ar, 0); bool inExpression = ar->inExpression(); ar->setInExpression(false); bool fix_en = false; for (int i = 1; i < count; i++) { if ((*exps)[i]->preOutputCPP(cg, ar, 0)) { fix_en = true; break; } } ar->setInExpression(inExpression); if (inExpression && fix_en) { ar->wrapExpressionBegin(cg); std::string tmp = genCPPTemp(cg, ar); cg.printf("bool %s = (", tmp.c_str()); (*exps)[0]->outputCPPExistTest(cg, ar, m_op); cg.printf(");\n"); for (int i = 1; i < count; i++) { cg.indentBegin("if (%s) {\n", tmp.c_str()); ExpressionPtr e = (*exps)[i]; e->preOutputCPP(cg, ar, 0); cg.printf("%s = (", tmp.c_str()); e->outputCPPExistTest(cg, ar, m_op); cg.printf(");\n"); } for (int i = 1; i < count; i++) { cg.indentEnd("}\n"); } m_cppTemp = tmp; } else if (state & FixOrder) { preOutputStash(cg, ar, state); fix_e1 = true; } return fix_e1 || fix_en; } } return Expression::preOutputCPP(cg, ar, state); }
bool ExpressionList::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar, int state) { if (m_kind == ListKindParam && !m_arrayElements) { return Expression::preOutputCPP(cg, ar, state|StashKidVars); } bool inExpression = ar->inExpression(); ar->setInExpression(false); bool ret = false; if (m_arrayElements) { ret = Expression::preOutputCPP(cg, ar, state); } else { for (unsigned int i = 0; i < m_exps.size(); i++) { if (m_exps[i]->preOutputCPP(cg, ar, 0)) { ret = true; break; } } } if (!inExpression) return ret; ar->setInExpression(true); if (!ret) return false; ar->wrapExpressionBegin(cg); if (m_arrayElements) { setCPPTemp(genCPPTemp(cg, ar)); outputCPPInternal(cg, ar, true, true); } else { for (unsigned int i = 0, n = m_exps.size(); i < n; i++) { ExpressionPtr e = m_exps[i]; e->preOutputCPP(cg, ar, state); if (i < n - 1) { if (e->outputCPPUnneeded(cg, ar)) { cg.printf(";\n"); } e->setCPPTemp("/**/"); } } } return true; }
bool UnaryOpExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar, int state) { if (m_op == T_ISSET && m_exp && m_exp->is(Expression::KindOfExpressionList)) { ExpressionListPtr exps = dynamic_pointer_cast<ExpressionList>(m_exp); int count = exps->getCount(); if (count > 1) { bool fix_e1 = (*exps)[0]->preOutputCPP(cg, ar, 0); bool inExpression = ar->inExpression(); ar->setInExpression(false); bool fix_en = false; for (int i = 1; i < count; i++) { if ((*exps)[i]->preOutputCPP(cg, ar, 0)) { fix_en = true; break; } } ar->setInExpression(inExpression); if (inExpression && fix_en) { ar->wrapExpressionBegin(cg); std::string tmp = genCPPTemp(cg, ar); cg_printf("bool %s = (", tmp.c_str()); (*exps)[0]->outputCPPExistTest(cg, ar, m_op); cg_printf(");\n"); for (int i = 1; i < count; i++) { cg_indentBegin("if (%s) {\n", tmp.c_str()); ExpressionPtr e = (*exps)[i]; e->preOutputCPP(cg, ar, 0); cg_printf("%s = (", tmp.c_str()); e->outputCPPExistTest(cg, ar, m_op); cg_printf(");\n"); } for (int i = 1; i < count; i++) { cg_indentEnd("}\n"); } m_cppTemp = tmp; } else if (state & FixOrder) { preOutputStash(cg, ar, state); fix_e1 = true; } return fix_e1 || fix_en; } } if (m_op == '@') { if (isUnused()) m_exp->setUnused(true); bool inExpression = ar->inExpression(); bool doit = state & FixOrder; if (!doit) { ar->setInExpression(false); if (m_exp->preOutputCPP(cg, ar, state)) { doit = true; } ar->setInExpression(inExpression); } if (doit && inExpression) { cg_printf("%s%d.enable();\n", Option::SilencerPrefix, m_silencer); m_exp->preOutputCPP(cg, ar, 0); int s = m_silencer; m_silencer = -1; this->preOutputStash(cg, ar, state | FixOrder); m_silencer = s; cg_printf("%s%d.disable();\n", Option::SilencerPrefix, m_silencer); } return doit; } else if (m_op == T_PRINT && m_exp && !m_exp->hasEffect()) { ExpressionPtrVec ev; bool hasVoid = false; if (BinaryOpExpression::getConcatList(ev, m_exp, hasVoid) > 1 || hasVoid ) { if (!ar->inExpression()) return true; ar->wrapExpressionBegin(cg); for (int i = 0, s = ev.size(); i < s; i++) { ExpressionPtr e = ev[i]; e->preOutputCPP(cg, ar, 0); cg_printf("print("); e->outputCPP(cg, ar); cg_printf(");\n"); } m_cppTemp = "1"; return true; } } return Expression::preOutputCPP(cg, ar, state); }
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]; 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; }
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; }
bool BinaryOpExpression::preOutputCPP(CodeGenerator &cg, AnalysisResultPtr ar, int state) { if (isOpEqual()) return Expression::preOutputCPP(cg, ar, state); bool effect2 = m_exp2->hasEffect(); const char *prefix = 0; if (effect2 || m_exp1->hasEffect()) { ExpressionPtr self = static_pointer_cast<Expression>(shared_from_this()); ExpressionPtrVec ev; bool hasVoid = false; int numConcat = 0; bool ok = false; if (m_op == '.') { numConcat = getConcatList(ev, self, hasVoid); ok = hasVoid || (numConcat > MAX_CONCAT_ARGS && (!Option::GenConcat || cg.getOutput() == CodeGenerator::SystemCPP)); } else if (effect2 && m_op == T_CONCAT_EQUAL) { prefix = stringBufferPrefix(cg, ar, m_exp1); ok = prefix; if (!ok) { if (m_exp1->is(KindOfSimpleVariable)) { ok = true; ev.push_back(m_exp1); numConcat++; } } numConcat += getConcatList(ev, m_exp2, hasVoid); } if (ok) { if (!cg.inExpression()) return true; cg.wrapExpressionBegin(); std::string buf; if (prefix) { SimpleVariablePtr sv(static_pointer_cast<SimpleVariable>(m_exp1)); buf = stringBufferName(Option::TempPrefix, prefix, sv->getName().c_str()); m_cppTemp = "/**/"; } else if (numConcat) { buf = m_cppTemp = genCPPTemp(cg, ar); buf += "_buf"; cg_printf("StringBuffer %s;\n", buf.c_str()); } else { m_cppTemp = "\"\""; } for (size_t i = 0; i < ev.size(); i++) { ExpressionPtr exp = ev[i]; bool is_void = !exp->getActualType(); exp->preOutputCPP(cg, ar, 0); if (!is_void) { cg_printf("%s.append(", buf.c_str()); outputStringExpr(cg, ar, exp, true); cg_printf(")"); } else { exp->outputCPPUnneeded(cg, ar); } cg_printf(";\n"); } if (numConcat && !prefix) { cg_printf("CStrRef %s(%s.detach());\n", m_cppTemp.c_str(), buf.c_str()); if (m_op == T_CONCAT_EQUAL) { m_exp1->outputCPP(cg, ar); cg_printf(" = %s;\n", m_cppTemp.c_str()); } } return true; } } if (!isShortCircuitOperator()) { return Expression::preOutputCPP(cg, ar, state); } if (!effect2) { return m_exp1->preOutputCPP(cg, ar, state); } bool fix_e1 = m_exp1->preOutputCPP(cg, ar, 0); if (!cg.inExpression()) { return fix_e1 || m_exp2->preOutputCPP(cg, ar, 0); } cg.setInExpression(false); bool fix_e2 = m_exp2->preOutputCPP(cg, ar, 0); cg.setInExpression(true); if (fix_e2) { cg.wrapExpressionBegin(); std::string tmp = genCPPTemp(cg, ar); cg_printf("bool %s = (", tmp.c_str()); m_exp1->outputCPP(cg, ar); cg_printf(");\n"); cg_indentBegin("if (%s%s) {\n", m_op == T_LOGICAL_OR || m_op == T_BOOLEAN_OR ? "!" : "", tmp.c_str()); m_exp2->preOutputCPP(cg, ar, 0); cg_printf("%s = (", tmp.c_str()); m_exp2->outputCPP(cg, ar); cg_printf(");\n"); cg_indentEnd("}\n"); m_cppTemp = tmp; } else if (state & FixOrder) { preOutputStash(cg, ar, state); fix_e1 = true; } return fix_e1 || fix_e2; }