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