Convert ValueObject to explicitly maintain the Execution Context in which they were created, and then use that when they update themselves. That means all the ValueObject evaluate me type functions that used to require a Frame object now do not. I didn't remove the SBValue API's that take this now useless frame, but I added ones that don't require the frame, and marked the SBFrame taking ones as deprecated.

llvm-svn: 128593
This commit is contained in:
Jim Ingham 2011-03-31 00:19:25 +00:00
parent 3a195b7e78
commit 6035b67d2c
26 changed files with 1046 additions and 460 deletions

View File

@ -46,7 +46,10 @@ public:
GetByteSize ();
bool
IsInScope (const lldb::SBFrame &frame);
IsInScope (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames.
bool
IsInScope ();
lldb::Format
GetFormat () const;
@ -55,25 +58,43 @@ public:
SetFormat (lldb::Format format);
const char *
GetValue (const lldb::SBFrame &frame);
GetValue (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames.
const char *
GetValue ();
ValueType
GetValueType ();
bool
GetValueDidChange (const lldb::SBFrame &frame);
const char *
GetSummary (const lldb::SBFrame &frame);
const char *
GetObjectDescription (const lldb::SBFrame &frame);
const char *
GetLocation (const lldb::SBFrame &frame);
GetValueDidChange (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames.
bool
SetValueFromCString (const lldb::SBFrame &frame, const char *value_str);
GetValueDidChange ();
const char *
GetSummary (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames.
const char *
GetSummary ();
const char *
GetObjectDescription (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames.
const char *
GetObjectDescription ();
const char *
GetLocation (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames.
const char *
GetLocation ();
bool
SetValueFromCString (const lldb::SBFrame &frame, const char *value_str); // DEPRECATED - SBValues know their own frames.
bool
SetValueFromCString (const char *value_str);
lldb::SBValue
GetChildAtIndex (uint32_t idx);

View File

@ -24,13 +24,171 @@
#include "lldb/Core/ConstString.h"
#include "lldb/Core/UserID.h"
#include "lldb/Core/Value.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/ExecutionContextScope.h"
#include "lldb/Target/StackID.h"
namespace lldb_private {
/// ValueObject:
/// This abstract class provides an interface to a particular value, be it a register, a local or global variable,
/// that is evaluated in some particular scope. The ValueObject also has the capibility of being the "child" of
/// some other variable object, and in turn of having children.
/// If a ValueObject is a root variable object - having no parent - then it must be constructed with respect to some
/// particular ExecutionContextScope. If it is a child, it inherits the ExecutionContextScope from its parent.
/// The ValueObject will update itself if necessary before fetching its value, summary, object description, etc.
/// But it will always update itself in the ExecutionContextScope with which it was originally created.
class ValueObject : public UserID
{
public:
class EvaluationPoint
{
public:
EvaluationPoint ();
EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected = false);
EvaluationPoint (const EvaluationPoint &rhs);
~EvaluationPoint ();
ExecutionContextScope *
GetExecutionContextScope ();
Target *
GetTarget () const
{
return m_target_sp.get();
}
Process *
GetProcess () const
{
return m_process_sp.get();
}
// Set the EvaluationPoint to the values in exe_scope,
// Return true if the Evaluation Point changed.
// Since the ExecutionContextScope is always going to be valid currently,
// the Updated Context will also always be valid.
bool
SetContext (ExecutionContextScope *exe_scope);
void
SetIsConstant ()
{
SetUpdated();
m_stop_id = LLDB_INVALID_UID;
}
bool
IsConstant () const
{
return m_stop_id == LLDB_INVALID_UID;
}
lldb::user_id_t
GetUpdateID () const
{
return m_stop_id;
}
void
SetUpdateID (lldb::user_id_t new_id)
{
m_stop_id = new_id;
}
bool
IsFirstEvaluation () const
{
return m_first_update;
}
void
SetNeedsUpdate ()
{
m_needs_update = true;
}
void
SetUpdated ()
{
m_first_update = false;
m_needs_update = false;
}
bool
NeedsUpdating()
{
SyncWithProcessState();
return m_needs_update;
}
bool
IsValid ()
{
if (m_stop_id == LLDB_INVALID_UID)
return false;
else if (SyncWithProcessState ())
{
if (m_stop_id == LLDB_INVALID_UID)
return false;
}
return true;
}
void
SetInvalid ()
{
// Use the stop id to mark us as invalid, leave the thread id and the stack id around for logging and
// history purposes.
m_stop_id = LLDB_INVALID_UID;
// Can't update an invalid state.
m_needs_update = false;
// m_thread_id = LLDB_INVALID_THREAD_ID;
// m_stack_id.Clear();
}
private:
bool
SyncWithProcessState ();
ExecutionContextScope *m_exe_scope; // This is not the way to store the evaluation point state, it is just
// a cache of the lookup, and gets thrown away when we update.
bool m_needs_update;
bool m_first_update;
lldb::TargetSP m_target_sp;
lldb::ProcessSP m_process_sp;
lldb::user_id_t m_thread_id;
StackID m_stack_id;
lldb::user_id_t m_stop_id; // This is the stop id when this ValueObject was last evaluated.
};
const EvaluationPoint &
GetUpdatePoint () const
{
return m_update_point;
}
EvaluationPoint &
GetUpdatePoint ()
{
return m_update_point;
}
ExecutionContextScope *
GetExecutionContextScope ()
{
return m_update_point.GetExecutionContextScope();
}
friend class ValueObjectList;
virtual ~ValueObject();
@ -50,30 +208,11 @@ public:
virtual lldb::ValueType
GetValueType() const = 0;
protected:
// Should only be called by ValueObject::GetNumChildren()
virtual uint32_t
CalculateNumChildren() = 0;
public:
virtual ConstString
GetTypeName() = 0;
virtual lldb::LanguageType
GetObjectRuntimeLanguage();
virtual void
UpdateValue (ExecutionContextScope *exe_scope) = 0;
//------------------------------------------------------------------
// Sublasses can implement the functions below if they need to.
//------------------------------------------------------------------
protected:
// Should only be called by ValueObject::GetChildAtIndex()
virtual lldb::ValueObjectSP
CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
public:
virtual bool
IsPointerType ();
@ -103,7 +242,7 @@ public:
GetExpressionPath (Stream &s, bool qualify_cxx_base_classes);
virtual bool
IsInScope (StackFrame *frame)
IsInScope ()
{
return true;
}
@ -133,10 +272,10 @@ public:
}
virtual const char *
GetValueAsCString (ExecutionContextScope *exe_scope);
GetValueAsCString ();
virtual bool
SetValueFromCString (ExecutionContextScope *exe_scope, const char *value_str);
SetValueFromCString (const char *value_str);
//------------------------------------------------------------------
// The functions below should NOT be modified by sublasses
@ -150,10 +289,10 @@ public:
lldb::ValueObjectSP
GetChildAtIndex (uint32_t idx, bool can_create);
lldb::ValueObjectSP
virtual lldb::ValueObjectSP
GetChildMemberWithName (const ConstString &name, bool can_create);
uint32_t
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
uint32_t
@ -166,29 +305,25 @@ public:
GetValue();
bool
ResolveValue (ExecutionContextScope *exe_scope, Scalar &scalar);
ResolveValue (Scalar &scalar);
const char *
GetLocationAsCString (ExecutionContextScope *exe_scope);
GetLocationAsCString ();
const char *
GetSummaryAsCString (ExecutionContextScope *exe_scope);
GetSummaryAsCString ();
const char *
GetObjectDescription (ExecutionContextScope *exe_scope);
lldb::user_id_t
GetUpdateID() const;
GetObjectDescription ();
bool
GetValueIsValid () const;
bool
GetValueDidChange (ExecutionContextScope *exe_scope);
GetValueDidChange ();
bool
UpdateValueIfNeeded (ExecutionContextScope *exe_scope);
UpdateValueIfNeeded ();
const DataExtractor &
GetDataExtractor () const;
@ -216,7 +351,7 @@ public:
}
virtual lldb::ValueObjectSP
CreateConstantValue (ExecutionContextScope *exe_scope, const ConstString &name);
CreateConstantValue (const ConstString &name);
virtual lldb::ValueObjectSP
Dereference (Error &error);
@ -239,7 +374,6 @@ public:
static void
DumpValueObject (Stream &s,
ExecutionContextScope *exe_scope,
ValueObject *valobj,
const char *root_valobj_name,
uint32_t ptr_depth,
@ -254,13 +388,13 @@ public:
bool
GetIsConstant () const
{
return m_update_id == LLDB_INVALID_UID;
return m_update_point.IsConstant();
}
void
SetIsConstant ()
{
m_update_id = LLDB_INVALID_UID;
m_update_point.SetIsConstant();
}
lldb::Format
@ -303,12 +437,9 @@ protected:
// Classes that inherit from ValueObject can see and modify these
//------------------------------------------------------------------
ValueObject* m_parent; // The parent value object, or NULL if this has no parent
lldb::user_id_t m_update_id; // An integer that specifies the update number for this value in
// this value object list. If this value object is asked to update itself
// it will first check if the update ID match the value object
// list update number. If the update numbers match, no update is
// needed, if it does not match, this value object should update its
// the next time it is asked.
EvaluationPoint m_update_point; // Stores both the stop id and the full context at which this value was last
// updated. When we are asked to update the value object, we check whether
// the context & stop id are the same before updating.
ConstString m_name; // The name of this object
DataExtractor m_data; // A data extractor that can be used to extract the value.
Value m_value;
@ -333,10 +464,35 @@ protected:
friend class CommandObjectExpression;
friend class ClangExpressionVariable;
friend class Target;
friend class ValueObjectChild;
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
ValueObject (ValueObject *parent);
// Use the no-argument constructor to make a constant variable object (with no ExecutionContextScope.)
ValueObject();
// Use this constructor to create a "root variable object". The ValueObject will be locked to this context
// through-out its lifespan.
ValueObject (ExecutionContextScope *exe_scope);
// Use this constructor to create a ValueObject owned by another ValueObject. It will inherit the ExecutionContext
// of its parent.
ValueObject (ValueObject &parent);
virtual bool
UpdateValue () = 0;
// Should only be called by ValueObject::GetChildAtIndex()
virtual lldb::ValueObjectSP
CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
// Should only be called by ValueObject::GetNumChildren()
virtual uint32_t
CalculateNumChildren() = 0;
void
SetName (const char *name);

View File

@ -24,7 +24,7 @@ namespace lldb_private {
class ValueObjectChild : public ValueObject
{
public:
ValueObjectChild (ValueObject *parent,
ValueObjectChild (ValueObject &parent,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
@ -83,11 +83,8 @@ public:
virtual ConstString
GetTypeName();
virtual void
UpdateValue (ExecutionContextScope *exe_scope);
virtual bool
IsInScope (StackFrame *frame);
IsInScope ();
virtual bool
IsBaseClass ()
@ -102,6 +99,9 @@ public:
}
protected:
virtual bool
UpdateValue ();
clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from
void *m_clang_type; // The type of the child in question within the parent (m_parent_sp)
ConstString m_type_name;

View File

@ -24,22 +24,26 @@ namespace lldb_private {
class ValueObjectConstResult : public ValueObject
{
public:
ValueObjectConstResult (lldb::ByteOrder byte_order,
ValueObjectConstResult (ExecutionContextScope *exe_scope,
lldb::ByteOrder byte_order,
uint32_t addr_byte_size);
ValueObjectConstResult (clang::ASTContext *clang_ast,
ValueObjectConstResult (ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
const DataExtractor &data);
ValueObjectConstResult (clang::ASTContext *clang_ast,
ValueObjectConstResult (ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
const lldb::DataBufferSP &result_data_sp,
lldb::ByteOrder byte_order,
uint8_t addr_size);
ValueObjectConstResult (clang::ASTContext *clang_ast,
ValueObjectConstResult (ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
lldb::addr_t address,
@ -47,7 +51,8 @@ public:
uint8_t addr_byte_size);
// When an expression fails to evaluate, we return an error
ValueObjectConstResult (const Error& error);
ValueObjectConstResult (ExecutionContextScope *exe_scope,
const Error& error);
virtual ~ValueObjectConstResult();
@ -69,11 +74,8 @@ public:
virtual ConstString
GetTypeName();
virtual void
UpdateValue (ExecutionContextScope *exe_scope);
virtual bool
IsInScope (StackFrame *frame);
IsInScope ();
virtual bool
SetClangAST (clang::ASTContext *ast)
@ -86,6 +88,9 @@ public:
SetByteSize (size_t size);
protected:
virtual bool
UpdateValue ();
clang::ASTContext *m_clang_ast; // The clang AST that the clang type comes from
ConstString m_type_name;
uint32_t m_byte_size;

View File

@ -26,7 +26,7 @@ namespace lldb_private {
class ValueObjectRegisterContext : public ValueObject
{
public:
ValueObjectRegisterContext (ValueObject *parent, lldb::RegisterContextSP &reg_ctx_sp);
ValueObjectRegisterContext (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp);
virtual
~ValueObjectRegisterContext();
@ -52,14 +52,14 @@ public:
virtual uint32_t
CalculateNumChildren();
virtual void
UpdateValue (ExecutionContextScope *exe_scope);
virtual lldb::ValueObjectSP
CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
protected:
lldb::RegisterContextSP m_reg_ctx;
virtual bool
UpdateValue ();
lldb::RegisterContextSP m_reg_ctx_sp;
private:
//------------------------------------------------------------------
@ -71,7 +71,7 @@ private:
class ValueObjectRegisterSet : public ValueObject
{
public:
ValueObjectRegisterSet (ValueObject *parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx);
ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx);
virtual
~ValueObjectRegisterSet();
@ -97,15 +97,21 @@ public:
virtual uint32_t
CalculateNumChildren();
virtual void
UpdateValue (ExecutionContextScope *exe_scope);
virtual lldb::ValueObjectSP
CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index);
virtual lldb::ValueObjectSP
GetChildMemberWithName (const ConstString &name, bool can_create);
virtual uint32_t
GetIndexOfChildWithName (const ConstString &name);
protected:
virtual bool
UpdateValue ();
lldb::RegisterContextSP m_reg_ctx;
lldb::RegisterContextSP m_reg_ctx_sp;
const RegisterSet *m_reg_set;
uint32_t m_reg_set_idx;
@ -119,7 +125,8 @@ private:
class ValueObjectRegister : public ValueObject
{
public:
ValueObjectRegister (ValueObject *parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num);
ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num);
ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num);
virtual
~ValueObjectRegister();
@ -145,18 +152,19 @@ public:
virtual uint32_t
CalculateNumChildren();
virtual void
UpdateValue (ExecutionContextScope *exe_scope);
protected:
virtual bool
UpdateValue ();
lldb::RegisterContextSP m_reg_ctx;
lldb::RegisterContextSP m_reg_ctx_sp;
const RegisterInfo *m_reg_info;
uint32_t m_reg_num;
ConstString m_type_name;
void *m_clang_type;
private:
void
ConstructObject ();
//------------------------------------------------------------------
// For ValueObject only
//------------------------------------------------------------------

View File

@ -25,7 +25,7 @@ namespace lldb_private {
class ValueObjectVariable : public ValueObject
{
public:
ValueObjectVariable (const lldb::VariableSP &var_sp);
ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp);
virtual
~ValueObjectVariable();
@ -48,13 +48,12 @@ public:
virtual lldb::ValueType
GetValueType() const;
virtual void
UpdateValue (ExecutionContextScope *exe_scope);
virtual bool
IsInScope (StackFrame *frame);
IsInScope ();
protected:
virtual bool
UpdateValue ();
lldb::VariableSP m_variable_sp; ///< The variable that this value object is based upon

View File

@ -61,7 +61,7 @@ class ValueObjectConstResult;
class ClangExpressionVariable
{
public:
ClangExpressionVariable(lldb::ByteOrder byte_order, uint32_t addr_byte_size);
ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size);
ClangExpressionVariable(const lldb::ValueObjectSP &valobj_sp);
@ -345,9 +345,9 @@ public:
/// Create a new variable in the list and return its index
//----------------------------------------------------------------------
lldb::ClangExpressionVariableSP
CreateVariable (lldb::ByteOrder byte_order, uint32_t addr_byte_size)
CreateVariable (ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size)
{
lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(byte_order, addr_byte_size));
lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
m_variables.push_back(var_sp);
return var_sp;
}
@ -363,12 +363,13 @@ public:
lldb::ClangExpressionVariableSP
CreateVariable (const ConstString &name,
CreateVariable (ExecutionContextScope *exe_scope,
const ConstString &name,
const TypeFromUser& user_type,
lldb::ByteOrder byte_order,
uint32_t addr_byte_size)
{
lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(byte_order, addr_byte_size));
lldb::ClangExpressionVariableSP var_sp(new ClangExpressionVariable(exe_scope, byte_order, addr_byte_size));
var_sp->SetName (name);
var_sp->SetClangType (user_type.GetOpaqueQualType());
var_sp->SetClangAST (user_type.GetASTContext());

View File

@ -36,7 +36,8 @@ public:
CreatePersistentVariable (const lldb::ValueObjectSP &valobj_sp);
lldb::ClangExpressionVariableSP
CreatePersistentVariable (const ConstString &name,
CreatePersistentVariable (ExecutionContextScope *exe_scope,
const ConstString &name,
const TypeFromUser& user_type,
lldb::ByteOrder byte_order,
uint32_t addr_byte_size);

View File

@ -79,6 +79,7 @@ public:
ExecutionContextScope *
GetBestExecutionContextScope () const;
//------------------------------------------------------------------
// Member variables
//------------------------------------------------------------------

View File

@ -75,6 +75,23 @@ public:
m_symbol_scope = symbol_scope;
}
void
Clear ()
{
m_pc = LLDB_INVALID_ADDRESS;
m_cfa = LLDB_INVALID_ADDRESS;
m_symbol_scope = NULL;
}
bool
IsValid ()
{
if (m_pc == LLDB_INVALID_ADDRESS && m_cfa == LLDB_INVALID_ADDRESS)
return false;
else
return true;
}
void
Dump (Stream *s);

View File

@ -369,7 +369,7 @@ SBFrame::FindVariable (const char *name)
SBValue sb_value;
if (var_sp)
*sb_value = ValueObjectSP (new ValueObjectVariable (var_sp));
*sb_value = ValueObjectSP (new ValueObjectVariable (m_opaque_sp.get(), var_sp));
LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
@ -416,7 +416,7 @@ SBFrame::FindValue (const char *name, ValueType value_type)
variable_sp->GetScope() == value_type &&
variable_sp->GetName() == const_name)
{
*sb_value = ValueObjectSP (new ValueObjectVariable (variable_sp));
*sb_value = ValueObjectSP (new ValueObjectVariable (m_opaque_sp.get(), variable_sp));
break;
}
}
@ -437,7 +437,7 @@ SBFrame::FindValue (const char *name, ValueType value_type)
((reg_info->name && strcasecmp (reg_info->name, name) == 0) ||
(reg_info->alt_name && strcasecmp (reg_info->alt_name, name) == 0)))
{
*sb_value = ValueObjectSP (new ValueObjectRegister (NULL, reg_ctx, reg_idx));
*sb_value = ValueObjectSP (new ValueObjectRegister (m_opaque_sp.get(), reg_ctx, reg_idx));
}
}
}
@ -457,7 +457,7 @@ SBFrame::FindValue (const char *name, ValueType value_type)
((reg_set->name && strcasecmp (reg_set->name, name) == 0) ||
(reg_set->short_name && strcasecmp (reg_set->short_name, name) == 0)))
{
*sb_value = ValueObjectSP (new ValueObjectRegisterSet (NULL, reg_ctx, set_idx));
*sb_value = ValueObjectSP (new ValueObjectRegisterSet (m_opaque_sp.get(), reg_ctx, set_idx));
}
}
}
@ -651,7 +651,7 @@ SBFrame::GetRegisters ()
const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
{
value_list.Append(ValueObjectSP (new ValueObjectRegisterSet (NULL, reg_ctx, set_idx)));
value_list.Append(ValueObjectSP (new ValueObjectRegisterSet (m_opaque_sp.get(), reg_ctx, set_idx)));
}
}
}

View File

@ -137,17 +137,20 @@ SBValue::GetByteSize ()
bool
SBValue::IsInScope (const SBFrame &sb_frame)
{
return IsInScope();
}
bool
SBValue::IsInScope ()
{
bool result = false;
if (m_opaque_sp)
{
StackFrame *frame = sb_frame.get();
if (frame)
{
Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
result = m_opaque_sp->IsInScope (frame);
}
if (m_opaque_sp->GetUpdatePoint().GetTarget())
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
result = m_opaque_sp->IsInScope ();
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
@ -159,24 +162,27 @@ SBValue::IsInScope (const SBFrame &sb_frame)
const char *
SBValue::GetValue (const SBFrame &sb_frame)
{
return GetValue();
}
const char *
SBValue::GetValue ()
{
const char *cstr = NULL;
if (m_opaque_sp)
{
StackFrame *frame = sb_frame.get();
if (frame)
{
Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
cstr = m_opaque_sp->GetValueAsCString (frame);
}
if (m_opaque_sp->GetUpdatePoint().GetTarget())
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
cstr = m_opaque_sp->GetValueAsCString ();
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
if (cstr)
log->Printf ("SBValue(%p)::GetValue (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
log->Printf ("SBValue(%p)::GetValue => \"%s\"", m_opaque_sp.get(), cstr);
else
log->Printf ("SBValue(%p)::GetValue (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
log->Printf ("SBValue(%p)::GetValue => NULL", m_opaque_sp.get());
}
return cstr;
@ -209,108 +215,123 @@ SBValue::GetValueType ()
const char *
SBValue::GetObjectDescription (const SBFrame &sb_frame)
{
return GetObjectDescription ();
}
const char *
SBValue::GetObjectDescription ()
{
const char *cstr = NULL;
if ( m_opaque_sp)
if (m_opaque_sp)
{
StackFrame *frame = sb_frame.get();
if (frame)
{
Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
cstr = m_opaque_sp->GetObjectDescription (frame);
}
if (m_opaque_sp->GetUpdatePoint().GetTarget())
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
cstr = m_opaque_sp->GetObjectDescription ();
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
if (cstr)
log->Printf ("SBValue(%p)::GetObjectDescription (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
log->Printf ("SBValue(%p)::GetObjectDescription => \"%s\"", m_opaque_sp.get(), cstr);
else
log->Printf ("SBValue(%p)::GetObjectDescription (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
log->Printf ("SBValue(%p)::GetObjectDescription => NULL", m_opaque_sp.get());
}
return cstr;
}
bool
SBValue::GetValueDidChange (const SBFrame &sb_frame)
{
return GetValueDidChange ();
}
bool
SBValue::GetValueDidChange ()
{
bool result = false;
if (m_opaque_sp)
{
StackFrame *frame = sb_frame.get();
if (frame)
{
Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
result = m_opaque_sp->GetValueDidChange (frame);
}
if (m_opaque_sp->GetUpdatePoint().GetTarget())
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
result = m_opaque_sp->GetValueDidChange ();
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBValue(%p)::GetValueDidChange (SBFrame(%p)) => %i", m_opaque_sp.get(), sb_frame.get(), result);
log->Printf ("SBValue(%p)::GetValueDidChange => %i", m_opaque_sp.get(), result);
return result;
}
const char *
SBValue::GetSummary (const SBFrame &sb_frame)
{
return GetSummary ();
}
const char *
SBValue::GetSummary ()
{
const char *cstr = NULL;
if (m_opaque_sp)
{
StackFrame *frame = sb_frame.get();
if (frame)
{
Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
cstr = m_opaque_sp->GetSummaryAsCString(frame);
}
if (m_opaque_sp->GetUpdatePoint().GetTarget())
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
cstr = m_opaque_sp->GetSummaryAsCString();
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
if (cstr)
log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr);
else
log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get());
}
return cstr;
}
const char *
SBValue::GetLocation (const SBFrame &sb_frame)
{
return GetLocation ();
}
const char *
SBValue::GetLocation ()
{
const char *cstr = NULL;
if (m_opaque_sp)
{
StackFrame *frame = sb_frame.get();
if (frame)
{
Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
cstr = m_opaque_sp->GetLocationAsCString(frame);
}
if (m_opaque_sp->GetUpdatePoint().GetTarget())
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
cstr = m_opaque_sp->GetLocationAsCString();
}
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
if (cstr)
log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => \"%s\"", m_opaque_sp.get(), sb_frame.get(), cstr);
log->Printf ("SBValue(%p)::GetSummary => \"%s\"", m_opaque_sp.get(), cstr);
else
log->Printf ("SBValue(%p)::GetSummary (SBFrame(%p)) => NULL", m_opaque_sp.get(), sb_frame.get());
log->Printf ("SBValue(%p)::GetSummary => NULL", m_opaque_sp.get());
}
return cstr;
}
bool
SBValue::SetValueFromCString (const SBFrame &sb_frame, const char *value_str)
{
return SetValueFromCString (value_str);
}
bool
SBValue::SetValueFromCString (const char *value_str)
{
bool success = false;
if (m_opaque_sp)
{
StackFrame *frame = sb_frame.get();
if (frame)
{
Mutex::Locker api_locker (frame->GetThread().GetProcess().GetTarget().GetAPIMutex());
success = m_opaque_sp->SetValueFromCString (frame, value_str);
}
if (m_opaque_sp->GetUpdatePoint().GetTarget())
Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTarget()->GetAPIMutex());
success = m_opaque_sp->SetValueFromCString (value_str);
}
return success;
}

View File

@ -257,7 +257,6 @@ CommandObjectExpression::EvaluateExpression
result_valobj_sp->SetFormat (m_options.format);
ValueObject::DumpValueObject (output_stream,
m_exe_ctx.GetBestExecutionContextScope(),
result_valobj_sp.get(), // Variable object to dump
result_valobj_sp->GetName().GetCString(),// Root object name
0, // Pointer depth to traverse (zero means stop at pointers)

View File

@ -501,7 +501,6 @@ public:
}
ValueObject::DumpValueObject (result.GetOutputStream(),
exe_ctx.frame,
valobj_sp.get(),
name_cstr,
m_options.ptr_depth,
@ -563,7 +562,6 @@ public:
}
ValueObject::DumpValueObject (result.GetOutputStream(),
exe_ctx.frame,
valobj_sp.get(),
var_sp->GetName().AsCString(),
m_options.ptr_depth,
@ -608,7 +606,6 @@ public:
s.PutCString (": ");
}
ValueObject::DumpValueObject (result.GetOutputStream(),
exe_ctx.frame,
valobj_sp.get(),
valobj_sp->GetParent() ? name_cstr : NULL,
ptr_depth,
@ -686,7 +683,7 @@ public:
// When dumping all variables, don't print any variables
// that are not in scope to avoid extra unneeded output
if (valobj_sp->IsInScope (exe_ctx.frame))
if (valobj_sp->IsInScope ())
{
if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
{
@ -694,7 +691,6 @@ public:
s.PutCString (": ");
}
ValueObject::DumpValueObject (result.GetOutputStream(),
exe_ctx.frame,
valobj_sp.get(),
name_cstr,
m_options.ptr_depth,

View File

@ -45,10 +45,9 @@ static lldb::user_id_t g_value_obj_uid = 0;
//----------------------------------------------------------------------
// ValueObject constructor
//----------------------------------------------------------------------
ValueObject::ValueObject (ValueObject *parent) :
ValueObject::ValueObject (ValueObject &parent) :
UserID (++g_value_obj_uid), // Unique identifier for every value object
m_parent (parent),
m_update_id (0), // Value object lists always start at 1, value objects start at zero
m_parent (&parent),
m_name (),
m_data (),
m_value (),
@ -67,7 +66,37 @@ ValueObject::ValueObject (ValueObject *parent) :
m_children_count_valid (false),
m_old_value_valid (false),
m_pointers_point_to_load_addrs (false),
m_is_deref_of_parent (false)
m_is_deref_of_parent (false),
m_update_point (parent.GetUpdatePoint ())
{
}
//----------------------------------------------------------------------
// ValueObject constructor
//----------------------------------------------------------------------
ValueObject::ValueObject (ExecutionContextScope *exe_scope) :
UserID (++g_value_obj_uid), // Unique identifier for every value object
m_parent (NULL),
m_name (),
m_data (),
m_value (),
m_error (),
m_value_str (),
m_old_value_str (),
m_location_str (),
m_summary_str (),
m_object_desc_str (),
m_children (),
m_synthetic_children (),
m_dynamic_value_sp (),
m_format (eFormatDefault),
m_value_is_valid (false),
m_value_did_change (false),
m_children_count_valid (false),
m_old_value_valid (false),
m_pointers_point_to_load_addrs (false),
m_is_deref_of_parent (false),
m_update_point (exe_scope)
{
}
@ -78,68 +107,53 @@ ValueObject::~ValueObject ()
{
}
user_id_t
ValueObject::GetUpdateID() const
{
return m_update_id;
}
bool
ValueObject::UpdateValueIfNeeded (ExecutionContextScope *exe_scope)
ValueObject::UpdateValueIfNeeded ()
{
// If this is a constant value, then our success is predicated on whether
// we have an error or not
if (GetIsConstant())
return m_error.Success();
if (exe_scope)
bool first_update = m_update_point.IsFirstEvaluation();
if (m_update_point.NeedsUpdating())
{
Process *process = exe_scope->CalculateProcess();
if (process)
m_update_point.SetUpdated();
// Save the old value using swap to avoid a string copy which
// also will clear our m_value_str
if (m_value_str.empty())
{
const user_id_t stop_id = process->GetStopID();
if (m_update_id != stop_id)
{
bool first_update = m_update_id == 0;
// Save the old value using swap to avoid a string copy which
// also will clear our m_value_str
if (m_value_str.empty())
{
m_old_value_valid = false;
}
else
{
m_old_value_valid = true;
m_old_value_str.swap (m_value_str);
m_value_str.clear();
}
m_location_str.clear();
m_summary_str.clear();
m_object_desc_str.clear();
m_old_value_valid = false;
}
else
{
m_old_value_valid = true;
m_old_value_str.swap (m_value_str);
m_value_str.clear();
}
m_location_str.clear();
m_summary_str.clear();
m_object_desc_str.clear();
const bool value_was_valid = GetValueIsValid();
SetValueDidChange (false);
const bool value_was_valid = GetValueIsValid();
SetValueDidChange (false);
m_error.Clear();
m_error.Clear();
// Call the pure virtual function to update the value
UpdateValue (exe_scope);
// Update the fact that we tried to update the value for this
// value object whether or not we succeed
m_update_id = stop_id;
bool success = m_error.Success();
SetValueIsValid (success);
if (first_update)
SetValueDidChange (false);
else if (!m_value_did_change && success == false)
{
// The value wasn't gotten successfully, so we mark this
// as changed if the value used to be valid and now isn't
SetValueDidChange (value_was_valid);
}
}
// Call the pure virtual function to update the value
bool success = UpdateValue ();
SetValueIsValid (success);
if (first_update)
SetValueDidChange (false);
else if (!m_value_did_change && success == false)
{
// The value wasn't gotten successfully, so we mark this
// as changed if the value used to be valid and now isn't
SetValueDidChange (value_was_valid);
}
}
return m_error.Success();
@ -170,9 +184,9 @@ ValueObject::GetName() const
}
const char *
ValueObject::GetLocationAsCString (ExecutionContextScope *exe_scope)
ValueObject::GetLocationAsCString ()
{
if (UpdateValueIfNeeded(exe_scope))
if (UpdateValueIfNeeded())
{
if (m_location_str.empty())
{
@ -227,10 +241,12 @@ ValueObject::GetValue() const
}
bool
ValueObject::ResolveValue (ExecutionContextScope *exe_scope, Scalar &scalar)
ValueObject::ResolveValue (Scalar &scalar)
{
ExecutionContext exe_ctx;
exe_scope->CalculateExecutionContext(exe_ctx);
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope)
exe_scope->CalculateExecutionContext(exe_ctx);
scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
return scalar.IsValid();
}
@ -249,9 +265,9 @@ ValueObject::SetValueIsValid (bool b)
}
bool
ValueObject::GetValueDidChange (ExecutionContextScope *exe_scope)
ValueObject::GetValueDidChange ()
{
GetValueAsCString (exe_scope);
GetValueAsCString ();
return m_value_did_change;
}
@ -398,7 +414,7 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
if (!child_name_str.empty())
child_name.SetCString (child_name_str.c_str());
valobj_sp.reset (new ValueObjectChild (this,
valobj_sp.reset (new ValueObjectChild (*this,
clang_ast,
child_clang_type,
child_name,
@ -415,9 +431,9 @@ ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int3
}
const char *
ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
ValueObject::GetSummaryAsCString ()
{
if (UpdateValueIfNeeded (exe_scope))
if (UpdateValueIfNeeded ())
{
if (m_summary_str.empty())
{
@ -432,132 +448,136 @@ ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
GetClangAST(),
&elem_or_pointee_clang_type));
if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
ClangASTContext::IsCharType (elem_or_pointee_clang_type))
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope)
{
Process *process = exe_scope->CalculateProcess();
if (process != NULL)
if (type_flags.AnySet (ClangASTContext::eTypeIsArray | ClangASTContext::eTypeIsPointer) &&
ClangASTContext::IsCharType (elem_or_pointee_clang_type))
{
lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
AddressType cstr_address_type = eAddressTypeInvalid;
Process *process = exe_scope->CalculateProcess();
if (process != NULL)
{
lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS;
AddressType cstr_address_type = eAddressTypeInvalid;
size_t cstr_len = 0;
if (type_flags.Test (ClangASTContext::eTypeIsArray))
{
// We have an array
cstr_len = ClangASTContext::GetArraySize (clang_type);
cstr_address = GetAddressOf (cstr_address_type, true);
}
else
{
// We have a pointer
cstr_address = GetPointerValue (cstr_address_type, true);
}
if (cstr_address != LLDB_INVALID_ADDRESS)
{
DataExtractor data;
size_t bytes_read = 0;
std::vector<char> data_buffer;
Error error;
if (cstr_len > 0)
size_t cstr_len = 0;
if (type_flags.Test (ClangASTContext::eTypeIsArray))
{
data_buffer.resize(cstr_len);
data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
if (bytes_read > 0)
{
sstr << '"';
data.Dump (&sstr,
0, // Start offset in "data"
eFormatChar, // Print as characters
1, // Size of item (1 byte for a char!)
bytes_read, // How many bytes to print?
UINT32_MAX, // num per line
LLDB_INVALID_ADDRESS,// base address
0, // bitfield bit size
0); // bitfield bit offset
sstr << '"';
}
// We have an array
cstr_len = ClangASTContext::GetArraySize (clang_type);
cstr_address = GetAddressOf (cstr_address_type, true);
}
else
{
const size_t k_max_buf_size = 256;
data_buffer.resize (k_max_buf_size + 1);
// NULL terminate in case we don't get the entire C string
data_buffer.back() = '\0';
sstr << '"';
data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
{
size_t len = strlen(&data_buffer.front());
if (len == 0)
break;
if (len > bytes_read)
len = bytes_read;
data.Dump (&sstr,
0, // Start offset in "data"
eFormatChar, // Print as characters
1, // Size of item (1 byte for a char!)
len, // How many bytes to print?
UINT32_MAX, // num per line
LLDB_INVALID_ADDRESS,// base address
0, // bitfield bit size
0); // bitfield bit offset
if (len < k_max_buf_size)
break;
cstr_address += k_max_buf_size;
}
sstr << '"';
// We have a pointer
cstr_address = GetPointerValue (cstr_address_type, true);
}
}
}
if (sstr.GetSize() > 0)
m_summary_str.assign (sstr.GetData(), sstr.GetSize());
}
else if (ClangASTContext::IsFunctionPointerType (clang_type))
{
AddressType func_ptr_address_type = eAddressTypeInvalid;
lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
{
switch (func_ptr_address_type)
{
case eAddressTypeInvalid:
case eAddressTypeFile:
break;
case eAddressTypeLoad:
if (cstr_address != LLDB_INVALID_ADDRESS)
{
Address so_addr;
Target *target = exe_scope->CalculateTarget();
if (target && target->GetSectionLoadList().IsEmpty() == false)
DataExtractor data;
size_t bytes_read = 0;
std::vector<char> data_buffer;
Error error;
if (cstr_len > 0)
{
if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
data_buffer.resize(cstr_len);
data.SetData (&data_buffer.front(), data_buffer.size(), lldb::endian::InlHostByteOrder());
bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), cstr_len, error);
if (bytes_read > 0)
{
so_addr.Dump (&sstr,
exe_scope,
Address::DumpStyleResolvedDescription,
Address::DumpStyleSectionNameOffset);
sstr << '"';
data.Dump (&sstr,
0, // Start offset in "data"
eFormatChar, // Print as characters
1, // Size of item (1 byte for a char!)
bytes_read, // How many bytes to print?
UINT32_MAX, // num per line
LLDB_INVALID_ADDRESS,// base address
0, // bitfield bit size
0); // bitfield bit offset
sstr << '"';
}
}
}
break;
else
{
const size_t k_max_buf_size = 256;
data_buffer.resize (k_max_buf_size + 1);
// NULL terminate in case we don't get the entire C string
data_buffer.back() = '\0';
case eAddressTypeHost:
break;
sstr << '"';
data.SetData (&data_buffer.front(), data_buffer.size(), endian::InlHostByteOrder());
while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
{
size_t len = strlen(&data_buffer.front());
if (len == 0)
break;
if (len > bytes_read)
len = bytes_read;
data.Dump (&sstr,
0, // Start offset in "data"
eFormatChar, // Print as characters
1, // Size of item (1 byte for a char!)
len, // How many bytes to print?
UINT32_MAX, // num per line
LLDB_INVALID_ADDRESS,// base address
0, // bitfield bit size
0); // bitfield bit offset
if (len < k_max_buf_size)
break;
cstr_address += k_max_buf_size;
}
sstr << '"';
}
}
}
if (sstr.GetSize() > 0)
m_summary_str.assign (sstr.GetData(), sstr.GetSize());
}
if (sstr.GetSize() > 0)
else if (ClangASTContext::IsFunctionPointerType (clang_type))
{
m_summary_str.assign (1, '(');
m_summary_str.append (sstr.GetData(), sstr.GetSize());
m_summary_str.append (1, ')');
AddressType func_ptr_address_type = eAddressTypeInvalid;
lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
{
switch (func_ptr_address_type)
{
case eAddressTypeInvalid:
case eAddressTypeFile:
break;
case eAddressTypeLoad:
{
Address so_addr;
Target *target = exe_scope->CalculateTarget();
if (target && target->GetSectionLoadList().IsEmpty() == false)
{
if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
{
so_addr.Dump (&sstr,
exe_scope,
Address::DumpStyleResolvedDescription,
Address::DumpStyleSectionNameOffset);
}
}
}
break;
case eAddressTypeHost:
break;
}
}
if (sstr.GetSize() > 0)
{
m_summary_str.assign (1, '(');
m_summary_str.append (sstr.GetData(), sstr.GetSize());
m_summary_str.append (1, ')');
}
}
}
}
@ -569,14 +589,18 @@ ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
}
const char *
ValueObject::GetObjectDescription (ExecutionContextScope *exe_scope)
ValueObject::GetObjectDescription ()
{
if (!m_object_desc_str.empty())
return m_object_desc_str.c_str();
if (!GetValueIsValid())
if (!UpdateValueIfNeeded ())
return NULL;
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope == NULL)
return NULL;
Process *process = exe_scope->CalculateProcess();
if (process == NULL)
return NULL;
@ -613,12 +637,12 @@ ValueObject::GetObjectDescription (ExecutionContextScope *exe_scope)
}
const char *
ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope)
ValueObject::GetValueAsCString ()
{
// If our byte size is zero this is an aggregate type that has children
if (ClangASTContext::IsAggregateType (GetClangType()) == false)
{
if (UpdateValueIfNeeded(exe_scope))
if (UpdateValueIfNeeded())
{
if (m_value_str.empty())
{
@ -744,11 +768,11 @@ ValueObject::GetPointerValue (AddressType &address_type, bool scalar_is_load_add
}
bool
ValueObject::SetValueFromCString (ExecutionContextScope *exe_scope, const char *value_str)
ValueObject::SetValueFromCString (const char *value_str)
{
// Make sure our value is up to date first so that our location and location
// type is valid.
if (!UpdateValueIfNeeded(exe_scope))
if (!UpdateValueIfNeeded())
return false;
uint32_t count = 0;
@ -833,7 +857,7 @@ ValueObject::Write ()
{
// Clear the update ID so the next time we try and read the value
// we try and read it again.
m_update_id = 0;
m_update_point.SetNeedsUpdate();
// TODO: when Value has a method to write a value back, call it from here.
return false;
@ -1035,7 +1059,6 @@ void
ValueObject::DumpValueObject
(
Stream &s,
ExecutionContextScope *exe_scope,
ValueObject *valobj,
const char *root_valobj_name,
uint32_t ptr_depth,
@ -1048,7 +1071,7 @@ ValueObject::DumpValueObject
bool flat_output
)
{
if (valobj)
if (valobj && valobj->UpdateValueIfNeeded ())
{
clang_type_t clang_type = valobj->GetClangType();
@ -1063,7 +1086,7 @@ ValueObject::DumpValueObject
{
if (show_location)
{
s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope));
s.Printf("%s: ", valobj->GetLocationAsCString());
}
s.Indent();
@ -1086,7 +1109,7 @@ ValueObject::DumpValueObject
s.Printf ("%s =", name_cstr);
}
if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame()))
if (!scope_already_checked && !valobj->IsInScope())
{
err_cstr = "error: out of scope";
}
@ -1096,7 +1119,7 @@ ValueObject::DumpValueObject
if (err_cstr == NULL)
{
val_cstr = valobj->GetValueAsCString(exe_scope);
val_cstr = valobj->GetValueAsCString();
err_cstr = valobj->GetError().AsCString();
}
@ -1109,7 +1132,7 @@ ValueObject::DumpValueObject
const bool is_ref = type_flags.Test (ClangASTContext::eTypeIsReference);
if (print_valobj)
{
const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope);
const char *sum_cstr = valobj->GetSummaryAsCString();
if (val_cstr)
s.Printf(" %s", val_cstr);
@ -1119,7 +1142,7 @@ ValueObject::DumpValueObject
if (use_objc)
{
const char *object_desc = valobj->GetObjectDescription(exe_scope);
const char *object_desc = valobj->GetObjectDescription();
if (object_desc)
s.Printf(" %s\n", object_desc);
else
@ -1185,7 +1208,6 @@ ValueObject::DumpValueObject
if (child_sp.get())
{
DumpValueObject (s,
exe_scope,
child_sp.get(),
NULL,
(is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
@ -1236,31 +1258,37 @@ ValueObject::DumpValueObject
ValueObjectSP
ValueObject::CreateConstantValue (ExecutionContextScope *exe_scope, const ConstString &name)
ValueObject::CreateConstantValue (const ConstString &name)
{
ValueObjectSP valobj_sp;
if (UpdateValueIfNeeded(exe_scope) && m_error.Success())
if (UpdateValueIfNeeded() && m_error.Success())
{
ExecutionContext exe_ctx;
exe_scope->CalculateExecutionContext(exe_ctx);
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (exe_scope)
{
ExecutionContext exe_ctx;
exe_scope->CalculateExecutionContext(exe_ctx);
clang::ASTContext *ast = GetClangAST ();
clang::ASTContext *ast = GetClangAST ();
DataExtractor data;
data.SetByteOrder (m_data.GetByteOrder());
data.SetAddressByteSize(m_data.GetAddressByteSize());
DataExtractor data;
data.SetByteOrder (m_data.GetByteOrder());
data.SetAddressByteSize(m_data.GetAddressByteSize());
m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
m_error = m_value.GetValueAsData (&exe_ctx, ast, data, 0);
valobj_sp.reset (new ValueObjectConstResult (ast,
GetClangType(),
name,
data));
valobj_sp.reset (new ValueObjectConstResult (exe_scope,
ast,
GetClangType(),
name,
data));
}
}
else
if (!valobj_sp)
{
valobj_sp.reset (new ValueObjectConstResult (m_error));
valobj_sp.reset (new ValueObjectConstResult (NULL, m_error));
}
return valobj_sp;
}
@ -1304,7 +1332,7 @@ ValueObject::Dereference (Error &error)
if (!child_name_str.empty())
child_name.SetCString (child_name_str.c_str());
valobj_sp.reset (new ValueObjectChild (this,
valobj_sp.reset (new ValueObjectChild (*this,
clang_ast,
child_clang_type,
child_name,
@ -1366,7 +1394,8 @@ ValueObject::AddressOf (Error &error)
{
std::string name (1, '&');
name.append (m_name.AsCString(""));
valobj_sp.reset (new ValueObjectConstResult (ast,
valobj_sp.reset (new ValueObjectConstResult (GetExecutionContextScope(),
ast,
ClangASTContext::CreatePointerType (ast, clang_type),
ConstString (name.c_str()),
addr,
@ -1380,3 +1409,247 @@ ValueObject::AddressOf (Error &error)
return valobj_sp;
}
ValueObject::EvaluationPoint::EvaluationPoint () :
m_stop_id (0),
m_thread_id (LLDB_INVALID_UID)
{
}
ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
m_stop_id (0),
m_thread_id (LLDB_INVALID_UID),
m_needs_update (true),
m_first_update (true)
{
ExecutionContext exe_ctx;
ExecutionContextScope *computed_exe_scope = exe_scope; // If use_selected is true, we may find a better scope,
// and if so we want to cache that not the original.
if (exe_scope)
exe_scope->CalculateExecutionContext(exe_ctx);
if (exe_ctx.target != NULL)
{
m_target_sp = exe_ctx.target->GetSP();
if (exe_ctx.process == NULL)
m_process_sp = exe_ctx.target->GetProcessSP();
else
m_process_sp = exe_ctx.process->GetSP();
if (m_process_sp != NULL)
{
m_stop_id = m_process_sp->GetStopID();
Thread *thread = NULL;
if (exe_ctx.thread == NULL)
{
if (use_selected)
{
thread = m_process_sp->GetThreadList().GetSelectedThread().get();
if (thread)
computed_exe_scope = thread;
}
}
else
thread = exe_ctx.thread;
if (thread != NULL)
{
m_thread_id = thread->GetIndexID();
if (exe_ctx.frame == NULL)
{
if (use_selected)
{
StackFrame *frame = exe_ctx.thread->GetSelectedFrame().get();
if (frame)
{
m_stack_id = frame->GetStackID();
computed_exe_scope = frame;
}
}
}
else
m_stack_id = exe_ctx.frame->GetStackID();
}
}
}
m_exe_scope = computed_exe_scope;
}
ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
m_exe_scope (rhs.m_exe_scope),
m_target_sp (rhs.m_target_sp),
m_process_sp (rhs.m_process_sp),
m_thread_id (rhs.m_thread_id),
m_stack_id (rhs.m_stack_id),
m_needs_update(true),
m_first_update(true),
m_stop_id (0)
{
}
ValueObject::EvaluationPoint::~EvaluationPoint ()
{
}
ExecutionContextScope *
ValueObject::EvaluationPoint::GetExecutionContextScope ()
{
// We have to update before giving out the scope, or we could be handing out stale pointers.
SyncWithProcessState();
return m_exe_scope;
}
// This function checks the EvaluationPoint against the current process state. If the current
// state matches the evaluation point, or the evaluation point is already invalid, then we return
// false, meaning "no change". If the current state is different, we update our state, and return
// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
// future calls to NeedsUpdate will return true.
bool
ValueObject::EvaluationPoint::SyncWithProcessState()
{
// If we're already invalid, we don't need to do anything, and nothing has changed:
if (m_stop_id == LLDB_INVALID_UID)
{
// Can't update with an invalid state.
m_needs_update = false;
return false;
}
// If we don't have a process nothing can change.
if (!m_process_sp)
return false;
// If our stop id is the current stop ID, nothing has changed:
if (m_stop_id == m_process_sp->GetStopID())
return false;
m_stop_id = m_process_sp->GetStopID();
m_needs_update = true;
m_exe_scope = m_process_sp.get();
// Something has changed, so we will return true. Now make sure the thread & frame still exist, and if either
// doesn't, mark ourselves as invalid.
if (m_thread_id != LLDB_INVALID_THREAD_ID)
{
Thread *our_thread = m_process_sp->GetThreadList().FindThreadByIndexID (m_thread_id).get();
if (our_thread == NULL)
SetInvalid();
else
{
m_exe_scope = our_thread;
if (m_stack_id.IsValid())
{
StackFrame *our_frame = our_thread->GetFrameWithStackID (m_stack_id).get();
if (our_frame == NULL)
SetInvalid();
else
m_exe_scope = our_frame;
}
}
}
return true;
}
bool
ValueObject::EvaluationPoint::SetContext (ExecutionContextScope *exe_scope)
{
if (!IsValid())
return false;
bool needs_update = false;
m_exe_scope = NULL;
// The target has to be non-null, and the
Target *target = exe_scope->CalculateTarget();
if (target != NULL)
{
Target *old_target = m_target_sp.get();
assert (target == old_target);
Process *process = exe_scope->CalculateProcess();
if (process != NULL)
{
// FOR NOW - assume you can't update variable objects across process boundaries.
Process *old_process = m_process_sp.get();
assert (process == old_process);
lldb::user_id_t stop_id = process->GetStopID();
if (stop_id != m_stop_id)
{
needs_update = true;
m_stop_id = stop_id;
}
// See if we're switching the thread or stack context. If no thread is given, this is
// being evaluated in a global context.
Thread *thread = exe_scope->CalculateThread();
if (thread != NULL)
{
lldb::user_id_t new_thread_index = thread->GetIndexID();
if (new_thread_index != m_thread_id)
{
needs_update = true;
m_thread_id = new_thread_index;
m_stack_id.Clear();
}
StackFrame *new_frame = exe_scope->CalculateStackFrame();
if (new_frame != NULL)
{
if (new_frame->GetStackID() != m_stack_id)
{
needs_update = true;
m_stack_id = new_frame->GetStackID();
}
}
else
{
m_stack_id.Clear();
needs_update = true;
}
}
else
{
// If this had been given a thread, and now there is none, we should update.
// Otherwise we don't have to do anything.
if (m_thread_id != LLDB_INVALID_UID)
{
m_thread_id = LLDB_INVALID_UID;
m_stack_id.Clear();
needs_update = true;
}
}
}
else
{
// If there is no process, then we don't need to update anything.
// But if we're switching from having a process to not, we should try to update.
if (m_process_sp.get() != NULL)
{
needs_update = true;
m_process_sp.reset();
m_thread_id = LLDB_INVALID_UID;
m_stack_id.Clear();
}
}
}
else
{
// If there's no target, nothing can change so we don't need to update anything.
// But if we're switching from having a target to not, we should try to update.
if (m_target_sp.get() != NULL)
{
needs_update = true;
m_target_sp.reset();
m_process_sp.reset();
m_thread_id = LLDB_INVALID_UID;
m_stack_id.Clear();
}
}
if (!m_needs_update)
m_needs_update = needs_update;
return needs_update;
}

View File

@ -26,7 +26,7 @@ using namespace lldb_private;
ValueObjectChild::ValueObjectChild
(
ValueObject* parent,
ValueObject &parent,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
@ -89,15 +89,15 @@ ValueObjectChild::GetTypeName()
return m_type_name;
}
void
ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope)
bool
ValueObjectChild::UpdateValue ()
{
m_error.Clear();
SetValueIsValid (false);
ValueObject* parent = m_parent;
if (parent)
{
if (parent->UpdateValueIfNeeded(exe_scope))
if (parent->UpdateValue())
{
m_value.SetContext(Value::eContextTypeClangType, m_clang_type);
@ -168,7 +168,7 @@ ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope)
if (m_error.Success())
{
ExecutionContext exe_ctx (exe_scope);
ExecutionContext exe_ctx (GetExecutionContextScope());
m_error = m_value.GetValueAsData (&exe_ctx, GetClangAST (), m_data, 0);
}
}
@ -181,11 +181,13 @@ ValueObjectChild::UpdateValue (ExecutionContextScope *exe_scope)
{
m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
}
return m_error.Success();
}
bool
ValueObjectChild::IsInScope (StackFrame *frame)
ValueObjectChild::IsInScope ()
{
return m_parent->IsInScope (frame);
return m_parent->IsInScope ();
}

View File

@ -28,10 +28,11 @@ using namespace lldb_private;
ValueObjectConstResult::ValueObjectConstResult
(
ExecutionContextScope *exe_scope,
ByteOrder byte_order,
uint32_t addr_byte_size
) :
ValueObject (NULL),
ValueObject (exe_scope),
m_clang_ast (NULL),
m_type_name (),
m_byte_size (0)
@ -45,12 +46,13 @@ ValueObjectConstResult::ValueObjectConstResult
ValueObjectConstResult::ValueObjectConstResult
(
ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
const DataExtractor &data
) :
ValueObject (NULL),
ValueObject (exe_scope),
m_clang_ast (clang_ast),
m_type_name (),
m_byte_size (0)
@ -67,6 +69,7 @@ ValueObjectConstResult::ValueObjectConstResult
ValueObjectConstResult::ValueObjectConstResult
(
ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
@ -74,7 +77,7 @@ ValueObjectConstResult::ValueObjectConstResult
lldb::ByteOrder data_byte_order,
uint8_t data_addr_size
) :
ValueObject (NULL),
ValueObject (exe_scope),
m_clang_ast (clang_ast),
m_type_name (),
m_byte_size (0)
@ -93,6 +96,7 @@ ValueObjectConstResult::ValueObjectConstResult
ValueObjectConstResult::ValueObjectConstResult
(
ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
@ -100,7 +104,7 @@ ValueObjectConstResult::ValueObjectConstResult
AddressType address_type,
uint8_t addr_byte_size
) :
ValueObject (NULL),
ValueObject (exe_scope),
m_clang_ast (clang_ast),
m_type_name (),
m_byte_size (0)
@ -124,8 +128,10 @@ ValueObjectConstResult::ValueObjectConstResult
m_pointers_point_to_load_addrs = true;
}
ValueObjectConstResult::ValueObjectConstResult (const Error& error) :
ValueObject (NULL),
ValueObjectConstResult::ValueObjectConstResult (
ExecutionContextScope *exe_scope,
const Error& error) :
ValueObject (exe_scope),
m_clang_ast (NULL),
m_type_name (),
m_byte_size (0)
@ -188,16 +194,17 @@ ValueObjectConstResult::GetTypeName()
return m_type_name;
}
void
ValueObjectConstResult::UpdateValue (ExecutionContextScope *exe_scope)
bool
ValueObjectConstResult::UpdateValue ()
{
// Const value is always valid
SetValueIsValid (true);
return true;
}
bool
ValueObjectConstResult::IsInScope (StackFrame *frame)
ValueObjectConstResult::IsInScope ()
{
// A const result value is always in scope since it serializes all
// information needed to contain the constant value.

View File

@ -29,9 +29,9 @@ using namespace lldb_private;
#pragma mark ValueObjectRegisterContext
ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject *parent, RegisterContextSP &reg_ctx) :
ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP &reg_ctx) :
ValueObject (parent),
m_reg_ctx (reg_ctx)
m_reg_ctx_sp (reg_ctx)
{
assert (reg_ctx);
m_name.SetCString("Registers");
@ -58,7 +58,7 @@ ValueObjectRegisterContext::GetTypeName()
uint32_t
ValueObjectRegisterContext::CalculateNumChildren()
{
return m_reg_ctx->GetRegisterSetCount();
return m_reg_ctx_sp->GetRegisterSetCount();
}
clang::ASTContext *
@ -73,17 +73,26 @@ ValueObjectRegisterContext::GetByteSize()
return 0;
}
void
ValueObjectRegisterContext::UpdateValue (ExecutionContextScope *exe_scope)
bool
ValueObjectRegisterContext::UpdateValue ()
{
m_error.Clear();
ExecutionContextScope *exe_scope = GetExecutionContextScope();
StackFrame *frame = exe_scope->CalculateStackFrame();
if (frame)
m_reg_ctx = frame->GetRegisterContext();
m_reg_ctx_sp = frame->GetRegisterContext();
else
m_reg_ctx.reset();
m_reg_ctx_sp.reset();
SetValueIsValid (m_reg_ctx.get() != NULL);
if (m_reg_ctx_sp.get() == NULL)
{
SetValueIsValid (false);
m_error.SetErrorToGenericError();
}
else
SetValueIsValid (true);
return m_error.Success();
}
ValueObjectSP
@ -93,7 +102,7 @@ ValueObjectRegisterContext::CreateChildAtIndex (uint32_t idx, bool synthetic_arr
const uint32_t num_children = GetNumChildren();
if (idx < num_children)
valobj_sp.reset (new ValueObjectRegisterSet(this, m_reg_ctx, idx));
valobj_sp.reset (new ValueObjectRegisterSet(GetExecutionContextScope(), m_reg_ctx_sp, idx));
return valobj_sp;
}
@ -101,9 +110,9 @@ ValueObjectRegisterContext::CreateChildAtIndex (uint32_t idx, bool synthetic_arr
#pragma mark -
#pragma mark ValueObjectRegisterSet
ValueObjectRegisterSet::ValueObjectRegisterSet (ValueObject *parent, lldb::RegisterContextSP &reg_ctx, uint32_t reg_set_idx) :
ValueObject (parent),
m_reg_ctx (reg_ctx),
ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_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)
{
@ -134,7 +143,7 @@ ValueObjectRegisterSet::GetTypeName()
uint32_t
ValueObjectRegisterSet::CalculateNumChildren()
{
const RegisterSet *reg_set = m_reg_ctx->GetRegisterSet(m_reg_set_idx);
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
if (reg_set)
return reg_set->num_registers;
return 0;
@ -152,22 +161,23 @@ ValueObjectRegisterSet::GetByteSize()
return 0;
}
void
ValueObjectRegisterSet::UpdateValue (ExecutionContextScope *exe_scope)
bool
ValueObjectRegisterSet::UpdateValue ()
{
m_error.Clear();
SetValueDidChange (false);
ExecutionContextScope *exe_scope = GetExecutionContextScope();
StackFrame *frame = exe_scope->CalculateStackFrame();
if (frame == NULL)
m_reg_ctx.reset();
m_reg_ctx_sp.reset();
else
{
m_reg_ctx = frame->GetRegisterContext ();
if (m_reg_ctx)
m_reg_ctx_sp = frame->GetRegisterContext ();
if (m_reg_ctx_sp)
{
const RegisterSet *reg_set = m_reg_ctx->GetRegisterSet (m_reg_set_idx);
const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
if (reg_set == NULL)
m_reg_ctx.reset();
m_reg_ctx_sp.reset();
else if (m_reg_set != reg_set)
{
SetValueDidChange (true);
@ -175,15 +185,17 @@ ValueObjectRegisterSet::UpdateValue (ExecutionContextScope *exe_scope)
}
}
}
if (m_reg_ctx)
if (m_reg_ctx_sp)
{
SetValueIsValid (true);
}
else
{
SetValueIsValid (false);
m_error.SetErrorToGenericError ();
m_children.clear();
}
return m_error.Success();
}
@ -191,29 +203,47 @@ ValueObjectSP
ValueObjectRegisterSet::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
ValueObjectSP valobj_sp;
if (m_reg_ctx && m_reg_set)
if (m_reg_ctx_sp && m_reg_set)
{
const uint32_t num_children = GetNumChildren();
if (idx < num_children)
valobj_sp.reset (new ValueObjectRegister(this, m_reg_ctx, m_reg_set->registers[idx]));
valobj_sp.reset (new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]));
}
return valobj_sp;
}
lldb::ValueObjectSP
ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
{
ValueObjectSP valobj_sp;
if (m_reg_ctx_sp && m_reg_set)
{
const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
if (reg_info != NULL)
valobj_sp.reset (new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]));
}
return valobj_sp;
}
uint32_t
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;
}
#pragma mark -
#pragma mark ValueObjectRegister
ValueObjectRegister::ValueObjectRegister (ValueObject *parent, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
ValueObject (parent),
m_reg_ctx (reg_ctx),
m_reg_info (NULL),
m_reg_num (reg_num),
m_type_name (),
m_clang_type (NULL)
void
ValueObjectRegister::ConstructObject ()
{
assert (reg_ctx);
m_reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_num);
m_reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_num);
if (m_reg_info)
{
if (m_reg_info->name)
@ -223,6 +253,30 @@ ValueObjectRegister::ValueObjectRegister (ValueObject *parent, lldb::RegisterCon
}
}
ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
ValueObject (parent),
m_reg_ctx_sp (reg_ctx),
m_reg_info (NULL),
m_reg_num (reg_num),
m_type_name (),
m_clang_type (NULL)
{
assert (reg_ctx);
ConstructObject();
}
ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
ValueObject (exe_scope),
m_reg_ctx_sp (reg_ctx),
m_reg_info (NULL),
m_reg_num (reg_num),
m_type_name (),
m_clang_type (NULL)
{
assert (reg_ctx);
ConstructObject();
}
ValueObjectRegister::~ValueObjectRegister()
{
}
@ -232,7 +286,7 @@ ValueObjectRegister::GetClangType ()
{
if (m_clang_type == NULL && m_reg_info)
{
Process *process = m_reg_ctx->CalculateProcess ();
Process *process = m_reg_ctx_sp->CalculateProcess ();
if (process)
{
Module *exe_module = process->GetTarget().GetExecutableModule ().get();
@ -262,7 +316,7 @@ ValueObjectRegister::CalculateNumChildren()
clang::ASTContext *
ValueObjectRegister::GetClangAST ()
{
Process *process = m_reg_ctx->CalculateProcess ();
Process *process = m_reg_ctx_sp->CalculateProcess ();
if (process)
{
Module *exe_module = process->GetTarget().GetExecutableModule ().get();
@ -278,17 +332,18 @@ ValueObjectRegister::GetByteSize()
return m_reg_info->byte_size;
}
void
ValueObjectRegister::UpdateValue (ExecutionContextScope *exe_scope)
bool
ValueObjectRegister::UpdateValue ()
{
m_error.Clear();
ExecutionContextScope *exe_scope = GetExecutionContextScope();
StackFrame *frame = exe_scope->CalculateStackFrame();
if (frame)
{
m_reg_ctx = frame->GetRegisterContext();
if (m_reg_ctx)
m_reg_ctx_sp = frame->GetRegisterContext();
if (m_reg_ctx_sp)
{
const RegisterInfo *reg_info = m_reg_ctx->GetRegisterInfoAtIndex(m_reg_num);
const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_num);
if (m_reg_info != reg_info)
{
m_reg_info = reg_info;
@ -304,23 +359,26 @@ ValueObjectRegister::UpdateValue (ExecutionContextScope *exe_scope)
}
else
{
m_reg_ctx.reset();
m_reg_ctx_sp.reset();
m_reg_info = NULL;
}
if (m_reg_ctx && m_reg_info)
if (m_reg_ctx_sp && m_reg_info)
{
if (m_reg_ctx->ReadRegisterBytes (m_reg_num, m_data))
if (m_reg_ctx_sp->ReadRegisterBytes (m_reg_num, m_data))
{
m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)m_reg_info);
m_value.SetValueType(Value::eValueTypeHostAddress);
m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
SetValueIsValid (true);
return;
return true;
}
}
SetValueIsValid (false);
m_error.SetErrorToGenericError ();
return false;
}

View File

@ -32,8 +32,8 @@
using namespace lldb_private;
ValueObjectVariable::ValueObjectVariable (const lldb::VariableSP &var_sp) :
ValueObject(NULL),
ValueObjectVariable::ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) :
ValueObject(exe_scope),
m_variable_sp(var_sp)
{
// Do not attempt to construct one of these objects with no variable!
@ -93,8 +93,8 @@ ValueObjectVariable::GetValueType() const
return lldb::eValueTypeInvalid;
}
void
ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
bool
ValueObjectVariable::UpdateValue ()
{
SetValueIsValid (false);
m_error.Clear();
@ -102,7 +102,7 @@ ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
Variable *variable = m_variable_sp.get();
DWARFExpression &expr = variable->LocationExpression();
lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
ExecutionContext exe_ctx (exe_scope);
ExecutionContext exe_ctx (GetExecutionContextScope());
if (exe_ctx.target)
{
@ -192,13 +192,22 @@ ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
SetValueIsValid (m_error.Success());
}
return m_error.Success();
}
bool
ValueObjectVariable::IsInScope (StackFrame *frame)
ValueObjectVariable::IsInScope ()
{
ExecutionContextScope *exe_scope = GetExecutionContextScope();
if (!exe_scope)
return true;
StackFrame *frame = exe_scope->CalculateStackFrame();
if (!frame)
return true;
return m_variable_sp->IsInScope (frame);
}

View File

@ -131,18 +131,19 @@ ClangExpressionDeclMap::BuildIntegerVariable (const ConstString &name,
const llvm::APInt& value)
{
assert (m_parser_vars.get());
clang::ASTContext *context(m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
ExecutionContext *exe_ctx = m_parser_vars->m_exe_ctx;
clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
TypeFromUser user_type(ClangASTContext::CopyType(context,
type.GetASTContext(),
type.GetOpaqueQualType()),
context);
if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (name,
if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx->GetBestExecutionContextScope (),
name,
user_type,
m_parser_vars->m_exe_ctx->process->GetByteOrder(),
m_parser_vars->m_exe_ctx->process->GetAddressByteSize()))
exe_ctx->process->GetByteOrder(),
exe_ctx->process->GetAddressByteSize()))
return lldb::ClangExpressionVariableSP();
ClangExpressionVariableSP pvar_sp (m_parser_vars->m_persistent_vars->GetVariable(name));
@ -156,7 +157,7 @@ ClangExpressionDeclMap::BuildIntegerVariable (const ConstString &name,
uint64_t value64 = value.getLimitedValue();
ByteOrder byte_order = m_parser_vars->m_exe_ctx->process->GetByteOrder();
ByteOrder byte_order = exe_ctx->process->GetByteOrder();
size_t num_val_bytes = sizeof(value64);
size_t num_data_bytes = pvar_sp->GetByteSize();
@ -209,18 +210,20 @@ ClangExpressionDeclMap::AddPersistentVariable
assert (m_parser_vars.get());
lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
ExecutionContext *exe_ctx = m_parser_vars->m_exe_ctx;
clang::ASTContext *context(m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
TypeFromUser user_type(ClangASTContext::CopyType(context,
parser_type.GetASTContext(),
parser_type.GetOpaqueQualType()),
context);
if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (name,
if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx->GetBestExecutionContextScope (),
name,
user_type,
m_parser_vars->m_exe_ctx->process->GetByteOrder(),
m_parser_vars->m_exe_ctx->process->GetAddressByteSize()))
exe_ctx->process->GetByteOrder(),
exe_ctx->process->GetAddressByteSize()))
return false;
ClangExpressionVariableSP var_sp (m_parser_vars->m_persistent_vars->GetVariable(name));
@ -986,7 +989,8 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
// If the reference comes from the program, then the ClangExpressionVariable's
// live variable data hasn't been set up yet. Do this now.
var_sp->m_live_sp.reset(new lldb_private::ValueObjectConstResult(var_sp->GetTypeFromUser().GetASTContext(),
var_sp->m_live_sp.reset(new lldb_private::ValueObjectConstResult(exe_ctx.GetBestExecutionContextScope (),
var_sp->GetTypeFromUser().GetASTContext(),
var_sp->GetTypeFromUser().GetOpaqueQualType(),
var_sp->GetName(),
mem,
@ -1080,7 +1084,8 @@ ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
// Put the location of the spare memory into the live data of the ValueObject.
var_sp->m_live_sp.reset(new lldb_private::ValueObjectConstResult(var_sp->GetTypeFromUser().GetASTContext(),
var_sp->m_live_sp.reset(new lldb_private::ValueObjectConstResult(exe_ctx.GetBestExecutionContextScope(),
var_sp->GetTypeFromUser().GetASTContext(),
var_sp->GetTypeFromUser().GetOpaqueQualType(),
var_sp->GetName(),
mem,
@ -1344,7 +1349,8 @@ ClangExpressionDeclMap::DoMaterializeOneVariable
// Put the location of the spare memory into the live data of the ValueObject.
expr_var->m_live_sp.reset(new lldb_private::ValueObjectConstResult(type.GetASTContext(),
expr_var->m_live_sp.reset(new lldb_private::ValueObjectConstResult(exe_ctx.GetBestExecutionContextScope(),
type.GetASTContext(),
type.GetOpaqueQualType(),
name,
mem,
@ -1920,7 +1926,8 @@ ClangExpressionDeclMap::AddOneVariable (NameSearchContext &context, Variable* va
NamedDecl *var_decl = context.AddVarDecl(ClangASTContext::CreateLValueReferenceType(pt.GetASTContext(), pt.GetOpaqueQualType()));
std::string decl_name(context.m_decl_name.getAsString());
ConstString entity_name(decl_name.c_str());
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (entity_name,
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->GetBestExecutionContextScope (),
entity_name,
ut,
m_parser_vars->m_exe_ctx->process->GetByteOrder(),
m_parser_vars->m_exe_ctx->process->GetAddressByteSize()));
@ -2002,7 +2009,8 @@ ClangExpressionDeclMap::AddOneRegister (NameSearchContext &context,
NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->process->GetByteOrder(),
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->GetBestExecutionContextScope(),
m_parser_vars->m_exe_ctx->process->GetByteOrder(),
m_parser_vars->m_exe_ctx->process->GetAddressByteSize()));
assert (entity.get());
std::string decl_name(context.m_decl_name.getAsString());
@ -2098,7 +2106,8 @@ ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
fun_location->SetValueType(Value::eValueTypeLoadAddress);
fun_location->GetScalar() = load_addr;
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->process->GetByteOrder(),
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx->GetBestExecutionContextScope (),
m_parser_vars->m_exe_ctx->process->GetByteOrder(),
m_parser_vars->m_exe_ctx->process->GetAddressByteSize()));
assert (entity.get());
std::string decl_name(context.m_decl_name.getAsString());

View File

@ -25,10 +25,10 @@
using namespace lldb_private;
using namespace clang;
ClangExpressionVariable::ClangExpressionVariable(lldb::ByteOrder byte_order, uint32_t addr_byte_size) :
ClangExpressionVariable::ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size) :
m_parser_vars(),
m_jit_vars (),
m_frozen_sp (new ValueObjectConstResult(byte_order, addr_byte_size)),
m_frozen_sp (new ValueObjectConstResult(exe_scope, byte_order, addr_byte_size)),
m_flags (EVNone)
{
}

View File

@ -30,12 +30,16 @@ ClangPersistentVariables::CreatePersistentVariable (const lldb::ValueObjectSP &v
}
ClangExpressionVariableSP
ClangPersistentVariables::CreatePersistentVariable (const ConstString &name, const TypeFromUser& user_type, lldb::ByteOrder byte_order, uint32_t addr_byte_size)
ClangPersistentVariables::CreatePersistentVariable (ExecutionContextScope *exe_scope,
const ConstString &name,
const TypeFromUser& user_type,
lldb::ByteOrder byte_order,
uint32_t addr_byte_size)
{
ClangExpressionVariableSP var_sp (GetVariable(name));
if (!var_sp)
var_sp = CreateVariable(name, user_type, byte_order, addr_byte_size);
var_sp = CreateVariable(exe_scope, name, user_type, byte_order, addr_byte_size);
return var_sp;
}

View File

@ -570,7 +570,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
{
error.SetErrorString ("Must have a process to evaluate expressions.");
result_valobj_sp.reset (new ValueObjectConstResult (error));
result_valobj_sp.reset (new ValueObjectConstResult (NULL, error));
return eExecutionSetupError;
}
@ -590,7 +590,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
else
error.SetErrorString (install_errors.GetString().c_str());
result_valobj_sp.reset (new ValueObjectConstResult (error));
result_valobj_sp.reset (new ValueObjectConstResult (NULL, error));
return eExecutionSetupError;
}
@ -658,7 +658,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
result_valobj_sp = expr_result->GetValueObject();
if (log)
log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString(exe_ctx.GetBestExecutionContextScope()));
log->Printf("== [ClangUserExpression::Evaluate] Execution completed normally with result %s ==", result_valobj_sp->GetValueAsCString());
}
else
{
@ -672,7 +672,7 @@ ClangUserExpression::Evaluate (ExecutionContext &exe_ctx,
}
if (result_valobj_sp.get() == NULL)
result_valobj_sp.reset (new ValueObjectConstResult (error));
result_valobj_sp.reset (new ValueObjectConstResult (NULL, error));
return execution_results;
}

View File

@ -923,7 +923,7 @@ Process::LoadImage (const FileSpec &image_spec, Error &error)
if (result_valobj_sp->GetError().Success())
{
Scalar scalar;
if (result_valobj_sp->ResolveValue (frame_sp.get(), scalar))
if (result_valobj_sp->ResolveValue (scalar))
{
addr_t image_ptr = scalar.ULongLong(LLDB_INVALID_ADDRESS);
if (image_ptr != 0 && image_ptr != LLDB_INVALID_ADDRESS)
@ -989,7 +989,7 @@ Process::UnloadImage (uint32_t image_token)
if (result_valobj_sp->GetError().Success())
{
Scalar scalar;
if (result_valobj_sp->ResolveValue (frame_sp.get(), scalar))
if (result_valobj_sp->ResolveValue (scalar))
{
if (scalar.UInt(1))
{

View File

@ -810,7 +810,7 @@ StackFrame::GetValueObjectForFrameVariable (const VariableSP &variable_sp)
{
if (m_variable_list_value_objects.GetSize() < num_variables)
m_variable_list_value_objects.Resize(num_variables);
valobj_sp.reset (new ValueObjectVariable (variable_sp));
valobj_sp.reset (new ValueObjectVariable (this, variable_sp));
m_variable_list_value_objects.SetValueObjectAtIndex (var_idx, valobj_sp);
}
}

View File

@ -926,8 +926,7 @@ Target::EvaluateExpression
const_valobj_sp->SetName (persistent_variable_name);
}
else
const_valobj_sp = result_valobj_sp->CreateConstantValue (exe_ctx.GetBestExecutionContextScope(),
persistent_variable_name);
const_valobj_sp = result_valobj_sp->CreateConstantValue (persistent_variable_name);
lldb::ValueObjectSP live_valobj_sp = result_valobj_sp;