summaryrefslogtreecommitdiff
path: root/lldb/source/Core/ValueObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/ValueObject.cpp')
-rw-r--r--lldb/source/Core/ValueObject.cpp121
1 files changed, 82 insertions, 39 deletions
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 74176eeace3a..1dd9a6cf62c3 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -22,9 +22,9 @@
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/TypeFormat.h"
#include "lldb/DataFormatters/TypeSummary.h"
-#include "lldb/DataFormatters/TypeValidator.h"
#include "lldb/DataFormatters/ValueObjectPrinter.h"
#include "lldb/Expression/ExpressionVariable.h"
+#include "lldb/Host/Config.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/CompilerType.h"
@@ -82,13 +82,12 @@ ValueObject::ValueObject(ValueObject &parent)
m_parent(&parent), m_root(nullptr),
m_update_point(parent.GetUpdatePoint()), 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_validation_result(),
- m_manager(parent.GetManager()), m_children(), m_synthetic_children(),
- m_dynamic_value(nullptr), m_synthetic_value(nullptr),
- m_deref_valobj(nullptr), m_format(eFormatDefault),
- m_last_format(eFormatDefault), m_last_format_mgr_revision(0),
- m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(),
- m_type_validator_sp(), m_user_id_of_forced_summary(),
+ m_summary_str(), m_object_desc_str(), m_manager(parent.GetManager()),
+ m_children(), m_synthetic_children(), m_dynamic_value(nullptr),
+ m_synthetic_value(nullptr), m_deref_valobj(nullptr),
+ m_format(eFormatDefault), m_last_format(eFormatDefault),
+ m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(),
+ m_synthetic_children_sp(), m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
m_value_checksum(),
m_preferred_display_language(lldb::eLanguageTypeUnknown),
@@ -100,6 +99,8 @@ ValueObject::ValueObject(ValueObject &parent)
m_did_calculate_complete_objc_class_type(false),
m_is_synthetic_children_generated(
parent.m_is_synthetic_children_generated) {
+ m_data.SetByteOrder(parent.GetDataExtractor().GetByteOrder());
+ m_data.SetAddressByteSize(parent.GetDataExtractor().GetAddressByteSize());
m_manager->ManageObject(this);
}
@@ -110,12 +111,12 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope,
m_parent(nullptr), m_root(nullptr), m_update_point(exe_scope), 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_validation_result(), m_manager(), m_children(), m_synthetic_children(),
+ m_manager(), m_children(), m_synthetic_children(),
m_dynamic_value(nullptr), m_synthetic_value(nullptr),
m_deref_valobj(nullptr), m_format(eFormatDefault),
m_last_format(eFormatDefault), m_last_format_mgr_revision(0),
m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(),
- m_type_validator_sp(), m_user_id_of_forced_summary(),
+ m_user_id_of_forced_summary(),
m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
m_value_checksum(),
m_preferred_display_language(lldb::eLanguageTypeUnknown),
@@ -126,6 +127,14 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope,
m_is_getting_summary(false),
m_did_calculate_complete_objc_class_type(false),
m_is_synthetic_children_generated(false) {
+ if (exe_scope) {
+ TargetSP target_sp(exe_scope->CalculateTarget());
+ if (target_sp) {
+ const ArchSpec &arch = target_sp->GetArchitecture();
+ m_data.SetByteOrder(arch.GetByteOrder());
+ m_data.SetAddressByteSize(arch.GetAddressByteSize());
+ }
+ }
m_manager = new ValueObjectManager();
m_manager->ManageObject(this);
}
@@ -133,6 +142,58 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope,
// Destructor
ValueObject::~ValueObject() {}
+void ValueObject::UpdateChildrenAddressType() {
+ Value::ValueType value_type = m_value.GetValueType();
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ const bool process_is_alive = process && process->IsAlive();
+ const uint32_t type_info = GetCompilerType().GetTypeInfo();
+ const bool is_pointer_or_ref =
+ (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
+
+ switch (value_type) {
+ case Value::eValueTypeFileAddress:
+ // If this type is a pointer, then its children will be considered load
+ // addresses if the pointer or reference is dereferenced, but only if
+ // the process is alive.
+ //
+ // There could be global variables like in the following code:
+ // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
+ // Foo g_foo1;
+ // Foo g_foo2;
+ // LinkedListNode g_second_node = { &g_foo2, NULL };
+ // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
+ //
+ // When we aren't running, we should be able to look at these variables
+ // using the "target variable" command. Children of the "g_first_node"
+ // always will be of the same address type as the parent. But children
+ // of the "next" member of LinkedListNode will become load addresses if
+ // we have a live process, or remain a file address if it was a file
+ // address.
+ if (process_is_alive && is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeFile);
+ break;
+ case Value::eValueTypeHostAddress:
+ // Same as above for load addresses, except children of pointer or refs
+ // are always load addresses. Host addresses are used to store freeze
+ // dried variables. If this type is a struct, the entire struct
+ // contents will be copied into the heap of the
+ // LLDB process, but we do not currently follow any pointers.
+ if (is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeHost);
+ break;
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ break;
+ }
+}
+
bool ValueObject::UpdateValueIfNeeded(bool update_format) {
bool did_change_formats = false;
@@ -195,6 +256,7 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) {
SetValueIsValid(success);
if (success) {
+ UpdateChildrenAddressType();
const uint64_t max_checksum_size = 128;
m_data.Checksum(m_value_checksum, max_checksum_size);
} else {
@@ -241,11 +303,10 @@ bool ValueObject::UpdateFormatsIfNeeded() {
SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
SetSummaryFormat(
DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
-#ifndef LLDB_DISABLE_PYTHON
+#if LLDB_ENABLE_PYTHON
SetSyntheticChildren(
DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
#endif
- SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
}
return any_change;
@@ -526,6 +587,10 @@ ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name,
std::vector<uint32_t> child_indexes;
bool omit_empty_base_classes = true;
+
+ if (!GetCompilerType().IsValid())
+ return ValueObjectSP();
+
const size_t num_child_indexes =
GetCompilerType().GetIndexOfChildMemberWithName(
name.GetCString(), omit_empty_base_classes, child_indexes);
@@ -1037,23 +1102,6 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
return {total_bytes_read, was_capped};
}
-std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() {
- if (!UpdateValueIfNeeded(true))
- return {TypeValidatorResult::Success,
- ""}; // not the validator's job to discuss update problems
-
- if (m_validation_result.hasValue())
- return m_validation_result.getValue();
-
- if (!m_type_validator_sp)
- return {TypeValidatorResult::Success, ""}; // no validator no failure
-
- auto outcome = m_type_validator_sp->FormatObject(this);
-
- return (m_validation_result = {outcome.m_result, outcome.m_message})
- .getValue();
-}
-
const char *ValueObject::GetObjectDescription() {
if (!UpdateValueIfNeeded(true))
return nullptr;
@@ -1970,15 +2018,14 @@ bool ValueObject::GetBaseClassPath(Stream &s) {
bool parent_had_base_class =
GetParent() && GetParent()->GetBaseClassPath(s);
CompilerType compiler_type = GetCompilerType();
- std::string cxx_class_name;
- bool this_had_base_class =
- ClangASTContext::GetCXXClassName(compiler_type, cxx_class_name);
- if (this_had_base_class) {
+ llvm::Optional<std::string> cxx_class_name =
+ ClangASTContext::GetCXXClassName(compiler_type);
+ if (cxx_class_name) {
if (parent_had_base_class)
s.PutCString("::");
- s.PutCString(cxx_class_name);
+ s.PutCString(cxx_class_name.getValue());
}
- return parent_had_base_class || this_had_base_class;
+ return parent_had_base_class || cxx_class_name;
}
return false;
}
@@ -3063,10 +3110,6 @@ void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
if (m_synthetic_value)
m_synthetic_value = nullptr;
}
-
- if ((clear_mask & eClearUserVisibleDataItemsValidator) ==
- eClearUserVisibleDataItemsValidator)
- m_validation_result.reset();
}
SymbolContextScope *ValueObject::GetSymbolContextScope() {