2010-06-08 16:52:24 +00:00
|
|
|
//===-- ValueObjectRegister.cpp ---------------------------------*- C++ -*-===//
|
|
|
|
|
//
|
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
|
//
|
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
#include "lldb/Core/ValueObjectRegister.h"
|
|
|
|
|
|
|
|
|
|
#include "lldb/Core/Module.h"
|
2018-11-11 23:16:43 +00:00
|
|
|
#include "lldb/Core/Value.h"
|
2016-09-06 20:57:50 +00:00
|
|
|
#include "lldb/Symbol/CompilerType.h"
|
2018-11-11 23:16:43 +00:00
|
|
|
#include "lldb/Symbol/TypeSystem.h"
|
2010-06-08 16:52:24 +00:00
|
|
|
#include "lldb/Target/ExecutionContext.h"
|
|
|
|
|
#include "lldb/Target/Process.h"
|
|
|
|
|
#include "lldb/Target/RegisterContext.h"
|
2018-11-11 23:16:43 +00:00
|
|
|
#include "lldb/Target/StackFrame.h"
|
2010-06-08 16:52:24 +00:00
|
|
|
#include "lldb/Target/Target.h"
|
2018-11-11 23:16:43 +00:00
|
|
|
#include "lldb/Utility/DataExtractor.h"
|
|
|
|
|
#include "lldb/Utility/Scalar.h"
|
|
|
|
|
#include "lldb/Utility/Status.h"
|
|
|
|
|
#include "lldb/Utility/Stream.h"
|
2017-04-06 21:28:29 +00:00
|
|
|
|
2018-11-11 23:16:43 +00:00
|
|
|
#include "llvm/ADT/StringRef.h"
|
2017-04-06 21:28:29 +00:00
|
|
|
|
2018-11-11 23:16:43 +00:00
|
|
|
#include <assert.h>
|
|
|
|
|
#include <memory>
|
2017-04-06 21:28:29 +00:00
|
|
|
|
|
|
|
|
namespace lldb_private {
|
|
|
|
|
class ExecutionContextScope;
|
|
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
|
|
|
|
|
#pragma mark ValueObjectRegisterContext
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegisterContext::ValueObjectRegisterContext(
|
|
|
|
|
ValueObject &parent, RegisterContextSP ®_ctx)
|
|
|
|
|
: ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
|
|
|
|
|
assert(reg_ctx);
|
|
|
|
|
m_name.SetCString("Registers");
|
|
|
|
|
SetValueIsValid(true);
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegisterContext::~ValueObjectRegisterContext() {}
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() {
|
|
|
|
|
return CompilerType();
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); }
|
2012-03-30 02:04:38 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ConstString ValueObjectRegisterContext::GetDisplayTypeName() {
|
|
|
|
|
return ConstString();
|
Introduce the concept of a "display name" for types
Rationale:
Pretty simply, the idea is that sometimes type names are way too long and contain way too many details for the average developer to care about. For instance, a plain ol' vector of int might be shown as
std::__1::vector<int, std::__1::allocator<....
rather than the much simpler std::vector<int> form, which is what most developers would actually type in their code
Proposed solution:
Introduce a notion of "display name" and a corresponding API GetDisplayTypeName() to return such a crafted for visual representation type name
Obviously, the display name and the fully qualified (or "true") name are not necessarily the same - that's the whole point
LLDB could choose to pick the "display name" as its one true notion of a type name, and if somebody really needs the fully qualified version of it, let them deal with the problem
Or, LLDB could rename what it currently calls the "type name" to be the "display name", and add new APIs for the fully qualified name, making the display name the default choice
The choice that I am making here is that the type name will keep meaning the same, and people who want a type name suited for display will explicitly ask for one
It is the less risky/disruptive choice - and it should eventually make it fairly obvious when someone is asking for the wrong type
Caveats:
- for now, GetDisplayTypeName() == GetTypeName(), there is no logic to produce customized display type names yet.
- while the fully-qualified type name is still the main key to the kingdom of data formatters, if we start showing custom names to people, those should match formatters
llvm-svn: 209072
2014-05-17 19:14:17 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
|
|
|
|
|
return ConstString();
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) {
|
|
|
|
|
auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
|
|
|
|
|
return reg_set_count <= max ? reg_set_count : max;
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; }
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
bool ValueObjectRegisterContext::UpdateValue() {
|
|
|
|
|
m_error.Clear();
|
|
|
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
|
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
|
|
|
if (frame)
|
|
|
|
|
m_reg_ctx_sp = frame->GetRegisterContext();
|
|
|
|
|
else
|
|
|
|
|
m_reg_ctx_sp.reset();
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
if (m_reg_ctx_sp.get() == NULL) {
|
|
|
|
|
SetValueIsValid(false);
|
|
|
|
|
m_error.SetErrorToGenericError();
|
|
|
|
|
} else
|
|
|
|
|
SetValueIsValid(true);
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
return m_error.Success();
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
|
|
|
|
|
size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
|
|
|
|
|
ValueObject *new_valobj = NULL;
|
|
|
|
|
|
|
|
|
|
const size_t num_children = GetNumChildren();
|
|
|
|
|
if (idx < num_children) {
|
|
|
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
|
|
|
new_valobj = new ValueObjectRegisterSet(
|
|
|
|
|
exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new_valobj;
|
|
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
#pragma mark ValueObjectRegisterSet
|
|
|
|
|
|
2011-04-22 23:53:53 +00:00
|
|
|
ValueObjectSP
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
|
|
|
|
|
lldb::RegisterContextSP ®_ctx_sp,
|
|
|
|
|
uint32_t set_idx) {
|
|
|
|
|
return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
|
2011-04-22 23:53:53 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
|
|
|
|
|
lldb::RegisterContextSP ®_ctx,
|
|
|
|
|
uint32_t reg_set_idx)
|
|
|
|
|
: ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(NULL),
|
|
|
|
|
m_reg_set_idx(reg_set_idx) {
|
|
|
|
|
assert(reg_ctx);
|
|
|
|
|
m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
|
|
|
|
|
if (m_reg_set) {
|
|
|
|
|
m_name.SetCString(m_reg_set->name);
|
|
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegisterSet::~ValueObjectRegisterSet() {}
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
|
|
|
|
|
return CompilerType();
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
|
|
|
|
|
return ConstString();
|
2012-03-30 02:04:38 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
|
|
|
|
|
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
|
|
|
|
|
if (reg_set) {
|
|
|
|
|
auto reg_count = reg_set->num_registers;
|
|
|
|
|
return reg_count <= max ? reg_count : max;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
bool ValueObjectRegisterSet::UpdateValue() {
|
|
|
|
|
m_error.Clear();
|
|
|
|
|
SetValueDidChange(false);
|
|
|
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
|
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
|
|
|
if (frame == NULL)
|
|
|
|
|
m_reg_ctx_sp.reset();
|
|
|
|
|
else {
|
|
|
|
|
m_reg_ctx_sp = frame->GetRegisterContext();
|
|
|
|
|
if (m_reg_ctx_sp) {
|
|
|
|
|
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
|
|
|
|
|
if (reg_set == NULL)
|
2011-03-31 00:19:25 +00:00
|
|
|
m_reg_ctx_sp.reset();
|
2016-09-06 20:57:50 +00:00
|
|
|
else if (m_reg_set != reg_set) {
|
|
|
|
|
SetValueDidChange(true);
|
|
|
|
|
m_name.SetCString(reg_set->name);
|
|
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
2016-09-06 20:57:50 +00:00
|
|
|
}
|
|
|
|
|
if (m_reg_ctx_sp) {
|
|
|
|
|
SetValueIsValid(true);
|
|
|
|
|
} else {
|
|
|
|
|
SetValueIsValid(false);
|
|
|
|
|
m_error.SetErrorToGenericError();
|
|
|
|
|
m_children.Clear();
|
|
|
|
|
}
|
|
|
|
|
return m_error.Success();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
|
|
|
|
|
size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
|
|
|
|
|
ValueObject *valobj = NULL;
|
|
|
|
|
if (m_reg_ctx_sp && m_reg_set) {
|
|
|
|
|
const size_t num_children = GetNumChildren();
|
|
|
|
|
if (idx < num_children)
|
|
|
|
|
valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
|
|
|
|
|
m_reg_set->registers[idx]);
|
|
|
|
|
}
|
|
|
|
|
return valobj;
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2011-03-31 00:19:25 +00:00
|
|
|
lldb::ValueObjectSP
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegisterSet::GetChildMemberWithName(const ConstString &name,
|
|
|
|
|
bool can_create) {
|
|
|
|
|
ValueObject *valobj = NULL;
|
|
|
|
|
if (m_reg_ctx_sp && m_reg_set) {
|
|
|
|
|
const RegisterInfo *reg_info =
|
|
|
|
|
m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
|
|
|
|
|
if (reg_info != NULL)
|
|
|
|
|
valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
|
|
|
|
|
reg_info->kinds[eRegisterKindLLDB]);
|
|
|
|
|
}
|
|
|
|
|
if (valobj)
|
|
|
|
|
return valobj->GetSP();
|
|
|
|
|
else
|
|
|
|
|
return ValueObjectSP();
|
2011-03-31 00:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
2013-01-25 18:06:21 +00:00
|
|
|
size_t
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegisterSet::GetIndexOfChildWithName(const ConstString &name) {
|
|
|
|
|
if (m_reg_ctx_sp && m_reg_set) {
|
|
|
|
|
const RegisterInfo *reg_info =
|
|
|
|
|
m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
|
|
|
|
|
if (reg_info != NULL)
|
|
|
|
|
return reg_info->kinds[eRegisterKindLLDB];
|
|
|
|
|
}
|
|
|
|
|
return UINT32_MAX;
|
2011-03-31 00:19:25 +00:00
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
|
|
|
|
|
#pragma mark -
|
|
|
|
|
#pragma mark ValueObjectRegister
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
|
|
|
|
|
const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
|
|
|
|
|
if (reg_info) {
|
|
|
|
|
m_reg_info = *reg_info;
|
|
|
|
|
if (reg_info->name)
|
|
|
|
|
m_name.SetCString(reg_info->name);
|
|
|
|
|
else if (reg_info->alt_name)
|
|
|
|
|
m_name.SetCString(reg_info->alt_name);
|
|
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
|
|
|
|
|
lldb::RegisterContextSP ®_ctx_sp,
|
|
|
|
|
uint32_t reg_num)
|
|
|
|
|
: ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
|
|
|
|
|
m_reg_value(), m_type_name(), m_compiler_type() {
|
|
|
|
|
assert(reg_ctx_sp.get());
|
|
|
|
|
ConstructObject(reg_num);
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
|
|
|
|
|
lldb::RegisterContextSP ®_ctx_sp,
|
|
|
|
|
uint32_t reg_num) {
|
|
|
|
|
return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
|
|
|
|
|
lldb::RegisterContextSP ®_ctx,
|
|
|
|
|
uint32_t reg_num)
|
|
|
|
|
: ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
|
|
|
|
|
m_reg_value(), m_type_name(), m_compiler_type() {
|
|
|
|
|
assert(reg_ctx);
|
|
|
|
|
ConstructObject(reg_num);
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
ValueObjectRegister::~ValueObjectRegister() {}
|
2010-06-08 16:52:24 +00:00
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
|
|
|
|
|
if (!m_compiler_type.IsValid()) {
|
2012-02-17 07:49:44 +00:00
|
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
2016-09-06 20:57:50 +00:00
|
|
|
Target *target = exe_ctx.GetTargetPtr();
|
|
|
|
|
if (target) {
|
|
|
|
|
Module *exe_module = target->GetExecutableModulePointer();
|
|
|
|
|
if (exe_module) {
|
|
|
|
|
TypeSystem *type_system =
|
|
|
|
|
exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
|
|
|
|
|
if (type_system)
|
|
|
|
|
m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize(
|
|
|
|
|
m_reg_info.encoding, m_reg_info.byte_size * 8);
|
|
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
2016-09-06 20:57:50 +00:00
|
|
|
}
|
|
|
|
|
return m_compiler_type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ConstString ValueObjectRegister::GetTypeName() {
|
|
|
|
|
if (m_type_name.IsEmpty())
|
|
|
|
|
m_type_name = GetCompilerType().GetConstTypeName();
|
|
|
|
|
return m_type_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
|
2018-11-05 20:49:07 +00:00
|
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
|
|
|
auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
|
2016-09-06 20:57:50 +00:00
|
|
|
return children_count <= max ? children_count : max;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
|
|
|
|
|
|
|
|
|
|
bool ValueObjectRegister::UpdateValue() {
|
|
|
|
|
m_error.Clear();
|
|
|
|
|
ExecutionContext exe_ctx(GetExecutionContextRef());
|
|
|
|
|
StackFrame *frame = exe_ctx.GetFramePtr();
|
|
|
|
|
if (frame == NULL) {
|
|
|
|
|
m_reg_ctx_sp.reset();
|
|
|
|
|
m_reg_value.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_reg_ctx_sp) {
|
|
|
|
|
RegisterValue m_old_reg_value(m_reg_value);
|
|
|
|
|
if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
|
|
|
|
|
if (m_reg_value.GetData(m_data)) {
|
|
|
|
|
Process *process = exe_ctx.GetProcessPtr();
|
|
|
|
|
if (process)
|
|
|
|
|
m_data.SetAddressByteSize(process->GetAddressByteSize());
|
|
|
|
|
m_value.SetContext(Value::eContextTypeRegisterInfo,
|
|
|
|
|
(void *)&m_reg_info);
|
|
|
|
|
m_value.SetValueType(Value::eValueTypeHostAddress);
|
|
|
|
|
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
|
|
|
|
|
SetValueIsValid(true);
|
|
|
|
|
SetValueDidChange(!(m_old_reg_value == m_reg_value));
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
2016-09-06 20:57:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetValueIsValid(false);
|
|
|
|
|
m_error.SetErrorToGenericError();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ValueObjectRegister::SetValueFromCString(const char *value_str,
|
2017-05-12 04:51:55 +00:00
|
|
|
Status &error) {
|
2016-09-06 20:57:50 +00:00
|
|
|
// The new value will be in the m_data. Copy that into our register value.
|
2016-11-17 23:47:31 +00:00
|
|
|
error =
|
|
|
|
|
m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
|
2016-09-06 20:57:50 +00:00
|
|
|
if (error.Success()) {
|
|
|
|
|
if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
|
|
|
|
|
SetNeedsUpdate();
|
|
|
|
|
return true;
|
|
|
|
|
} else
|
|
|
|
|
return false;
|
|
|
|
|
} else
|
2011-03-31 00:19:25 +00:00
|
|
|
return false;
|
2010-06-08 16:52:24 +00:00
|
|
|
}
|
|
|
|
|
|
2017-05-12 04:51:55 +00:00
|
|
|
bool ValueObjectRegister::SetData(DataExtractor &data, Status &error) {
|
2016-09-06 20:57:50 +00:00
|
|
|
error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
|
|
|
|
|
if (error.Success()) {
|
|
|
|
|
if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
|
|
|
|
|
SetNeedsUpdate();
|
|
|
|
|
return true;
|
|
|
|
|
} else
|
|
|
|
|
return false;
|
|
|
|
|
} else
|
2011-08-16 03:49:01 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
|
|
|
|
|
if (UpdateValueIfNeeded(
|
|
|
|
|
false)) // make sure that you are up to date before returning anything
|
|
|
|
|
return m_reg_value.GetScalarValue(scalar);
|
|
|
|
|
return false;
|
2012-08-24 18:21:05 +00:00
|
|
|
}
|
|
|
|
|
|
2016-09-06 20:57:50 +00:00
|
|
|
void ValueObjectRegister::GetExpressionPath(Stream &s,
|
|
|
|
|
bool qualify_cxx_base_classes,
|
|
|
|
|
GetExpressionPathFormat epformat) {
|
|
|
|
|
s.Printf("$%s", m_reg_info.name);
|
|
|
|
|
}
|