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