ValueObjectSP GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e) { ValueObjectSP target = EvaluateExpr(e->GetX()); if (!target) return nullptr; return target->Dereference(m_error); }
ValueObjectSP GoUserExpression::GoInterpreter::VisitSelectorExpr(const lldb_private::GoASTSelectorExpr *e) { ValueObjectSP target = EvaluateExpr(e->GetX()); if (target) { if (target->GetCompilerType().IsPointerType()) { target = target->Dereference(m_error); if (m_error.Fail()) return nullptr; } ConstString field(e->GetSel()->GetName().m_value); ValueObjectSP result = target->GetChildMemberWithName(field, true); if (!result) m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString()); return result; } if (const GoASTIdent *package = llvm::dyn_cast<GoASTIdent>(e->GetX())) { if (VariableSP global = FindGlobalVariable(m_exe_ctx.GetTargetSP(), package->GetName().m_value + "." + e->GetSel()->GetName().m_value)) { if (m_frame) { m_error.Clear(); return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic); } } } if (const GoASTBasicLit *packageLit = llvm::dyn_cast<GoASTBasicLit>(e->GetX())) { if (packageLit->GetValue().m_type == GoLexer::LIT_STRING) { std::string value = packageLit->GetValue().m_value.str(); value = value.substr(1, value.size() - 2); if (VariableSP global = FindGlobalVariable(m_exe_ctx.GetTargetSP(), value + "." + e->GetSel()->GetName().m_value)) { if (m_frame) { m_error.Clear(); return m_frame->TrackGlobalVariable(global, m_use_dynamic); } } } } // EvaluateExpr should have already set m_error. return target; }
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; }