示例#1
0
ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr(
    const lldb_private::GoASTCallExpr *e) {
  ValueObjectSP x = EvaluateExpr(e->GetFun());
  if (x || e->NumArgs() != 1) {
    m_error.SetErrorStringWithFormat("Code execution not supported");
    return nullptr;
  }
  m_error.Clear();
  CompilerType type = EvaluateType(e->GetFun());
  if (!type) {
    return nullptr;
  }
  ValueObjectSP value = EvaluateExpr(e->GetArgs(0));
  if (!value)
    return nullptr;
  // TODO: Handle special conversions
  return value->Cast(type);
}
ValueObjectSP
GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e)
{
    ValueObjectSP val;
    if (m_frame)
    {
        VariableSP var_sp;
        std::string varname = e->GetName().m_value.str();
        if (varname.size() > 1 && varname[0] == '$')
        {
            RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext();
            const RegisterInfo *reg = reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1);
            if (reg)
            {
                std::string type;
                switch (reg->encoding)
                {
                    case lldb::eEncodingSint:
                        type.append("int");
                        break;
                    case lldb::eEncodingUint:
                        type.append("uint");
                        break;
                    case lldb::eEncodingIEEE754:
                        type.append("float");
                        break;
                    default:
                        m_error.SetErrorString("Invaild register encoding");
                        return nullptr;
                }
                switch (reg->byte_size)
                {
                    case 8:
                        type.append("64");
                        break;
                    case 4:
                        type.append("32");
                        break;
                    case 2:
                        type.append("16");
                        break;
                    case 1:
                        type.append("8");
                        break;
                    default:
                        m_error.SetErrorString("Invaild register size");
                        return nullptr;
                }
                ValueObjectSP regVal =
                    ValueObjectRegister::Create(m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]);
                CompilerType goType = LookupType(m_frame->CalculateTarget(), ConstString(type));
                if (regVal)
                {
                    regVal = regVal->Cast(goType);
                    return regVal;
                }
            }
            m_error.SetErrorString("Invaild register name");
            return nullptr;
        }
        VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false));
        if (var_list_sp)
        {
            var_sp = var_list_sp->FindVariable(ConstString(varname));
            if (var_sp)
                val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
            else
            {
                // When a variable is on the heap instead of the stack, go records a variable
                // '&x' instead of 'x'.
                var_sp = var_list_sp->FindVariable(ConstString("&" + varname));
                if (var_sp)
                {
                    val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic);
                    if (val)
                        val = val->Dereference(m_error);
                    if (m_error.Fail())
                        return nullptr;
                }
            }
        }
        if (!val)
        {
            m_error.Clear();
            TargetSP target = m_frame->CalculateTarget();
            if (!target)
            {
                m_error.SetErrorString("No target");
                return nullptr;
            }
            var_sp = FindGlobalVariable(target, m_package + "." + e->GetName().m_value);
            if (var_sp)
                return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic);
        }
    }
    if (!val)
        m_error.SetErrorStringWithFormat("Unknown variable %s", e->GetName().m_value.str().c_str());
    return val;
}