std::string SimpleVariable::getAssignableCPPVariable(AnalysisResultPtr ar)
  const {
  VariableTablePtr variables = getScope()->getVariables();
  if (m_this) {
    if (!hasAnyContext(OprLValue | AssignmentLHS) &&
        variables->getAttribute(VariableTable::ContainsLDynamicVariable)) {
      ASSERT(m_sym);
      const string &namePrefix = getNamePrefix();
      return namePrefix + variables->getVariablePrefix(m_sym) + "this";
    }
    return "";
  } else if (m_superGlobal) {
    const string &name = variables->getGlobalVariableName(ar, m_name);
    return string("g->") + name.c_str();
  } else if (m_globals) {
    return "get_global_array_wrapper()";
  } else {
    ASSERT(m_sym);
    const string &prefix0 = getNamePrefix();
    const char *prefix1 =
      getScope()->getVariables()->getVariablePrefix(m_sym);
    return prefix0 + prefix1 +
           CodeGenerator::FormatLabel(m_name);
  }
}
void SimpleVariable::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) {
  VariableTablePtr variables = getScope()->getVariables();
  if (m_this) {
    ASSERT((getContext() & ObjectContext) == 0);
    if (hasContext(OprLValue) || hasContext(AssignmentLHS)) {
      cg_printf("throw_assign_this()");
      return;
    }
    if (variables->getAttribute(VariableTable::ContainsLDynamicVariable)) {
      ASSERT(m_sym);
      const string &namePrefix = getNamePrefix();
      cg_printf("%s%sthis",
                namePrefix.c_str(),
                variables->getVariablePrefix(m_sym));
    } else if (hasContext(DeepOprLValue) ||
               hasContext(DeepAssignmentLHS) ||
               hasContext(LValue)) {
      // $this[] op= ...; or $this[] = ...
      cg_printf("Variant(GET_THIS())");
    } else {
      ClassScopePtr cls = getOriginalClass();
      if (!cls || cls->derivedByDynamic()) {
        cg_printf("Object(GET_THIS())");
      } else {
        cg_printf("GET_THIS_TYPED(%s)", cls->getId().c_str());
      }
    }
  } else if (m_superGlobal) {
    const string &name = variables->getGlobalVariableName(ar, m_name);
    cg_printf("g->%s", name.c_str());
  } else if (m_globals) {
    cg_printf("get_global_array_wrapper()");
  } else {
    ASSERT(m_sym);
    bool sw = false;
    if (m_sym->isShrinkWrapped() &&
        m_context == Declaration) {
      ASSERT(!getFunctionScope()->isGenerator());
      TypePtr type = m_sym->getFinalType();
      type->outputCPPDecl(cg, ar, getScope());
      sw = true;
      cg_printf(" ");
    }
    const string &prefix0 = getNamePrefix();
    const char *prefix1   = variables->getVariablePrefix(m_sym);
    cg_printf("%s%s%s",
              prefix0.c_str(),
              prefix1,
              CodeGenerator::FormatLabel(m_name).c_str());
    if (m_originalSym) {
      cg.printf(" /* %s */", m_originalSym->getName().c_str());
    }
    if (sw) {
      TypePtr type = m_sym->getFinalType();
      const char *initializer = type->getCPPInitializer();
      if (initializer) {
        cg_printf(" = %s", initializer);
      }
    }
  }
}