forked from OSchip/llvm-project
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:
parent
3a195b7e78
commit
6035b67d2c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace lldb_private {
|
|||
class ValueObjectRegisterContext : public ValueObject
|
||||
{
|
||||
public:
|
||||
ValueObjectRegisterContext (ValueObject *parent, lldb::RegisterContextSP ®_ctx_sp);
|
||||
ValueObjectRegisterContext (ValueObject &parent, lldb::RegisterContextSP ®_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 ®_ctx_sp, uint32_t set_idx);
|
||||
ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_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 ®_ctx_sp, uint32_t reg_num);
|
||||
ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num);
|
||||
ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_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
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -79,6 +79,7 @@ public:
|
|||
|
||||
ExecutionContextScope *
|
||||
GetBestExecutionContextScope () const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Member variables
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -29,9 +29,9 @@ using namespace lldb_private;
|
|||
|
||||
#pragma mark ValueObjectRegisterContext
|
||||
|
||||
ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject *parent, RegisterContextSP ®_ctx) :
|
||||
ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP ®_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 ®_ctx, uint32_t reg_set_idx) :
|
||||
ValueObject (parent),
|
||||
m_reg_ctx (reg_ctx),
|
||||
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)
|
||||
{
|
||||
|
@ -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 ®_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 ®_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 ®_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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue