diff options
26 files changed, 1034 insertions, 448 deletions
diff --git a/lldb/include/lldb/API/SBValue.h b/lldb/include/lldb/API/SBValue.h index 0624be8cfe7..08ec657151f 100644 --- a/lldb/include/lldb/API/SBValue.h +++ b/lldb/include/lldb/API/SBValue.h @@ -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); + GetValueDidChange (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. + bool + GetValueDidChange (); + + const char * + GetSummary (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. + const char * - GetSummary (const lldb::SBFrame &frame); + GetSummary (); const char * - GetObjectDescription (const lldb::SBFrame &frame); + GetObjectDescription (const lldb::SBFrame &frame); // DEPRECATED - SBValues know their own frames. + + const char * + GetObjectDescription (); const char * - GetLocation (const lldb::SBFrame &frame); + 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 lldb::SBFrame &frame, const char *value_str); + SetValueFromCString (const char *value_str); lldb::SBValue GetChildAtIndex (uint32_t idx); diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 7f123fa9103..b0a8028fe27 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -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); diff --git a/lldb/include/lldb/Core/ValueObjectChild.h b/lldb/include/lldb/Core/ValueObjectChild.h index ae32e3f0b92..f83068b9b68 100644 --- a/lldb/include/lldb/Core/ValueObjectChild.h +++ b/lldb/include/lldb/Core/ValueObjectChild.h @@ -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; diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h index f21a7975303..6fca731047f 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -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; diff --git a/lldb/include/lldb/Core/ValueObjectRegister.h b/lldb/include/lldb/Core/ValueObjectRegister.h index 47b47f6ab4d..2cd22f54708 100644 --- a/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/lldb/include/lldb/Core/ValueObjectRegister.h @@ -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 //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Core/ValueObjectVariable.h b/lldb/include/lldb/Core/ValueObjectVariable.h index d86155f186c..bb09382439b 100644 --- a/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/lldb/include/lldb/Core/ValueObjectVariable.h @@ -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 diff --git a/lldb/include/lldb/Expression/ClangExpressionVariable.h b/lldb/include/lldb/Expression/ClangExpressionVariable.h index be5082fb786..dc6b7f8ed14 100644 --- a/lldb/include/lldb/Expression/ClangExpressionVariable.h +++ b/lldb/include/lldb/Expression/ClangExpressionVariable.h @@ -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()); diff --git a/lldb/include/lldb/Expression/ClangPersistentVariables.h b/lldb/include/lldb/Expression/ClangPersistentVariables.h index 65b367d16c7..21884ca5f8a 100644 --- a/lldb/include/lldb/Expression/ClangPersistentVariables.h +++ b/lldb/include/lldb/Expression/ClangPersistentVariables.h @@ -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); diff --git a/lldb/include/lldb/Target/ExecutionContext.h b/lldb/include/lldb/Target/ExecutionContext.h index cc925cff997..304120c9d20 100644 --- a/lldb/include/lldb/Target/ExecutionContext.h +++ b/lldb/include/lldb/Target/ExecutionContext.h @@ -79,6 +79,7 @@ public: ExecutionContextScope * GetBestExecutionContextScope () const; + //------------------------------------------------------------------ // Member variables //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Target/StackID.h b/lldb/include/lldb/Target/StackID.h index 4baad51bbae..cac57da0114 100644 --- a/lldb/include/lldb/Target/StackID.h +++ b/lldb/include/lldb/Target/StackID.h @@ -76,6 +76,23 @@ public: } 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); //------------------------------------------------------------------ diff --git a/lldb/source/API/SBFrame.cpp b/lldb/source/API/SBFrame.cpp index 1ba1e7a11b1..e51c2ecfcfb 100644 --- a/lldb/source/API/SBFrame.cpp +++ b/lldb/source/API/SBFrame.cpp @@ -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))); } } } diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 547e94326e4..a607841a527 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -138,16 +138,19 @@ 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)); @@ -160,23 +163,26 @@ 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; @@ -210,23 +216,26 @@ 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; } @@ -234,19 +243,22 @@ SBValue::GetObjectDescription (const SBFrame &sb_frame) 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; } @@ -254,23 +266,26 @@ SBValue::GetValueDidChange (const SBFrame &sb_frame) 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; } @@ -278,23 +293,26 @@ SBValue::GetSummary (const SBFrame &sb_frame) 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; } @@ -302,15 +320,18 @@ SBValue::GetLocation (const SBFrame &sb_frame) 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; } diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index fd9271b3b5e..220801f132c 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -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) diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 25f7638ef7d..8c83b674fc3 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -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, diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 948ace752d1..783a24c1b74 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -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,79 +66,94 @@ 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 ()) { } //---------------------------------------------------------------------- -// Destructor +// ValueObject constructor //---------------------------------------------------------------------- -ValueObject::~ValueObject () +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) { } -user_id_t -ValueObject::GetUpdateID() const +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +ValueObject::~ValueObject () { - 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; - - size_t cstr_len = 0; - if (type_flags.Test (ClangASTContext::eTypeIsArray)) + Process *process = exe_scope->CalculateProcess(); + if (process != NULL) { - // 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) + lldb::addr_t cstr_address = LLDB_INVALID_ADDRESS; + AddressType cstr_address_type = eAddressTypeInvalid; + + 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'; + // 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) + { + 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 << '"'; + } + } + 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 << '"'; + 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; + 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 << '"'; } - sstr << '"'; } } + + if (sstr.GetSize() > 0) + m_summary_str.assign (sstr.GetData(), sstr.GetSize()); } - - 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) + else if (ClangASTContext::IsFunctionPointerType (clang_type)) { - switch (func_ptr_address_type) - { - case eAddressTypeInvalid: - case eAddressTypeFile: - break; + AddressType func_ptr_address_type = eAddressTypeInvalid; + lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true); - case eAddressTypeLoad: + if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS) + { + switch (func_ptr_address_type) { - Address so_addr; - Target *target = exe_scope->CalculateTarget(); - if (target && target->GetSectionLoadList().IsEmpty() == false) + case eAddressTypeInvalid: + case eAddressTypeFile: + break; + + case eAddressTypeLoad: { - if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr)) + Address so_addr; + Target *target = exe_scope->CalculateTarget(); + if (target && target->GetSectionLoadList().IsEmpty() == false) { - so_addr.Dump (&sstr, - exe_scope, - Address::DumpStyleResolvedDescription, - Address::DumpStyleSectionNameOffset); + if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr)) + { + so_addr.Dump (&sstr, + exe_scope, + Address::DumpStyleResolvedDescription, + Address::DumpStyleSectionNameOffset); + } } } - } - break; + break; - case eAddressTypeHost: - 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, ')'); } - } - 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; +} diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp index bf896abe9ba..fc5f6c850f5 100644 --- a/lldb/source/Core/ValueObjectChild.cpp +++ b/lldb/source/Core/ValueObjectChild.cpp @@ -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 (); } diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index 55273a9a7be..ff5d265a4f8 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -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. diff --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp index bd58bd92c80..979c28c996f 100644 --- a/lldb/source/Core/ValueObjectRegister.cpp +++ b/lldb/source/Core/ValueObjectRegister.cpp @@ -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; } diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index c85f558dbfe..7bab591105b 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -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); } diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index d528d380ae0..411651fa5da 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -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()); diff --git a/lldb/source/Expression/ClangExpressionVariable.cpp b/lldb/source/Expression/ClangExpressionVariable.cpp index c5bc5c48ef6..7cb25e3eafb 100644 --- a/lldb/source/Expression/ClangExpressionVariable.cpp +++ b/lldb/source/Expression/ClangExpressionVariable.cpp @@ -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) { } diff --git a/lldb/source/Expression/ClangPersistentVariables.cpp b/lldb/source/Expression/ClangPersistentVariables.cpp index d5ab9e53e55..c4bf88502f4 100644 --- a/lldb/source/Expression/ClangPersistentVariables.cpp +++ b/lldb/source/Expression/ClangPersistentVariables.cpp @@ -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; } diff --git a/lldb/source/Expression/ClangUserExpression.cpp b/lldb/source/Expression/ClangUserExpression.cpp index dda810ef7b5..d560e0fc42d 100644 --- a/lldb/source/Expression/ClangUserExpression.cpp +++ b/lldb/source/Expression/ClangUserExpression.cpp @@ -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; } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 74f5fc31c38..1b0a864ba4b 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -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)) { diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 603e9e6abca..0d0c0e8ec61 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -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); } } diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 5663961edf8..882ff6a1635 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -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; |