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.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@128593 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp
index 1ba1e7a..e51c2ec 100644
--- a/source/API/SBFrame.cpp
+++ b/source/API/SBFrame.cpp
@@ -369,7 +369,7 @@
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 @@
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 @@
((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 @@
((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 @@
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/source/API/SBValue.cpp b/source/API/SBValue.cpp
index 547e943..a607841 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -138,16 +138,19 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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/source/Commands/CommandObjectExpression.cpp b/source/Commands/CommandObjectExpression.cpp
index fd9271b..220801f 100644
--- a/source/Commands/CommandObjectExpression.cpp
+++ b/source/Commands/CommandObjectExpression.cpp
@@ -257,7 +257,6 @@
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/source/Commands/CommandObjectFrame.cpp b/source/Commands/CommandObjectFrame.cpp
index 25f7638..8c83b67 100644
--- a/source/Commands/CommandObjectFrame.cpp
+++ b/source/Commands/CommandObjectFrame.cpp
@@ -501,7 +501,6 @@
}
ValueObject::DumpValueObject (result.GetOutputStream(),
- exe_ctx.frame,
valobj_sp.get(),
name_cstr,
m_options.ptr_depth,
@@ -563,7 +562,6 @@
}
ValueObject::DumpValueObject (result.GetOutputStream(),
- exe_ctx.frame,
valobj_sp.get(),
var_sp->GetName().AsCString(),
m_options.ptr_depth,
@@ -608,7 +606,6 @@
s.PutCString (": ");
}
ValueObject::DumpValueObject (result.GetOutputStream(),
- exe_ctx.frame,
valobj_sp.get(),
valobj_sp->GetParent() ? name_cstr : NULL,
ptr_depth,
@@ -686,7 +683,7 @@
// 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 @@
s.PutCString (": ");
}
ValueObject::DumpValueObject (result.GetOutputStream(),
- exe_ctx.frame,
valobj_sp.get(),
name_cstr,
m_options.ptr_depth,
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index 948ace7..783a24c 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -45,10 +45,9 @@
//----------------------------------------------------------------------
// 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 @@
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 @@
{
}
-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 @@
}
const char *
-ValueObject::GetLocationAsCString (ExecutionContextScope *exe_scope)
+ValueObject::GetLocationAsCString ()
{
- if (UpdateValueIfNeeded(exe_scope))
+ if (UpdateValueIfNeeded())
{
if (m_location_str.empty())
{
@@ -227,10 +241,12 @@
}
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 @@
}
bool
-ValueObject::GetValueDidChange (ExecutionContextScope *exe_scope)
+ValueObject::GetValueDidChange ()
{
- GetValueAsCString (exe_scope);
+ GetValueAsCString ();
return m_value_did_change;
}
@@ -398,7 +414,7 @@
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 @@
}
const char *
-ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
+ValueObject::GetSummaryAsCString ()
{
- if (UpdateValueIfNeeded (exe_scope))
+ if (UpdateValueIfNeeded ())
{
if (m_summary_str.empty())
{
@@ -432,132 +448,136 @@
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 @@
}
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 @@
}
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 @@
}
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 @@
{
// 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 @@
ValueObject::DumpValueObject
(
Stream &s,
- ExecutionContextScope *exe_scope,
ValueObject *valobj,
const char *root_valobj_name,
uint32_t ptr_depth,
@@ -1048,7 +1071,7 @@
bool flat_output
)
{
- if (valobj)
+ if (valobj && valobj->UpdateValueIfNeeded ())
{
clang_type_t clang_type = valobj->GetClangType();
@@ -1063,7 +1086,7 @@
{
if (show_location)
{
- s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope));
+ s.Printf("%s: ", valobj->GetLocationAsCString());
}
s.Indent();
@@ -1086,7 +1109,7 @@
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 @@
if (err_cstr == NULL)
{
- val_cstr = valobj->GetValueAsCString(exe_scope);
+ val_cstr = valobj->GetValueAsCString();
err_cstr = valobj->GetError().AsCString();
}
@@ -1109,7 +1132,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp
index bf896ab..fc5f6c8 100644
--- a/source/Core/ValueObjectChild.cpp
+++ b/source/Core/ValueObjectChild.cpp
@@ -26,7 +26,7 @@
ValueObjectChild::ValueObjectChild
(
- ValueObject* parent,
+ ValueObject &parent,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
@@ -89,15 +89,15 @@
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 @@
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 @@
{
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/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp
index 55273a9..ff5d265 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -28,10 +28,11 @@
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
(
+ 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
(
+ ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
@@ -74,7 +77,7 @@
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
(
+ ExecutionContextScope *exe_scope,
clang::ASTContext *clang_ast,
void *clang_type,
const ConstString &name,
@@ -100,7 +104,7 @@
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 @@
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 @@
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/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp
index bd58bd9..979c28c 100644
--- a/source/Core/ValueObjectRegister.cpp
+++ b/source/Core/ValueObjectRegister.cpp
@@ -29,9 +29,9 @@
#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 @@
uint32_t
ValueObjectRegisterContext::CalculateNumChildren()
{
- return m_reg_ctx->GetRegisterSetCount();
+ return m_reg_ctx_sp->GetRegisterSetCount();
}
clang::ASTContext *
@@ -73,17 +73,26 @@
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 @@
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 @@
#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 @@
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 @@
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 @@
}
}
}
- 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 @@
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::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 @@
{
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 @@
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 @@
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 @@
}
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/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp
index c85f558..7bab591 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/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 @@
return lldb::eValueTypeInvalid;
}
-void
-ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
+bool
+ValueObjectVariable::UpdateValue ()
{
SetValueIsValid (false);
m_error.Clear();
@@ -102,7 +102,7 @@
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 @@
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/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index d528d38..411651f 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -131,18 +131,19 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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/source/Expression/ClangExpressionVariable.cpp b/source/Expression/ClangExpressionVariable.cpp
index c5bc5c4..7cb25e3 100644
--- a/source/Expression/ClangExpressionVariable.cpp
+++ b/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/source/Expression/ClangPersistentVariables.cpp b/source/Expression/ClangPersistentVariables.cpp
index d5ab9e5..c4bf885 100644
--- a/source/Expression/ClangPersistentVariables.cpp
+++ b/source/Expression/ClangPersistentVariables.cpp
@@ -30,12 +30,16 @@
}
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/source/Expression/ClangUserExpression.cpp b/source/Expression/ClangUserExpression.cpp
index dda810e..d560e0f 100644
--- a/source/Expression/ClangUserExpression.cpp
+++ b/source/Expression/ClangUserExpression.cpp
@@ -570,7 +570,7 @@
{
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 @@
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 @@
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 @@
}
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/source/Target/Process.cpp b/source/Target/Process.cpp
index 74f5fc3..1b0a864 100644
--- a/source/Target/Process.cpp
+++ b/source/Target/Process.cpp
@@ -923,7 +923,7 @@
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 @@
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/source/Target/StackFrame.cpp b/source/Target/StackFrame.cpp
index 603e9e6..0d0c0e8 100644
--- a/source/Target/StackFrame.cpp
+++ b/source/Target/StackFrame.cpp
@@ -810,7 +810,7 @@
{
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/source/Target/Target.cpp b/source/Target/Target.cpp
index 5663961..882ff6a 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -926,8 +926,7 @@
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;