1ac7ddfbfSEd Maste //===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste
10ac7ddfbfSEd Maste #include "lldb/Core/ValueObject.h"
11ac7ddfbfSEd Maste
12*b5893f02SDimitry Andric #include "lldb/Core/Address.h"
13ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
14ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectCast.h"
15ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectChild.h"
16ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectConstResult.h"
17ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectDynamicValue.h"
18ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectMemory.h"
19ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectSyntheticFilter.h"
20ac7ddfbfSEd Maste #include "lldb/DataFormatters/DataVisualization.h"
21*b5893f02SDimitry Andric #include "lldb/DataFormatters/DumpValueObjectOptions.h"
22*b5893f02SDimitry Andric #include "lldb/DataFormatters/FormatManager.h"
237aa51b79SEd Maste #include "lldb/DataFormatters/StringPrinter.h"
24*b5893f02SDimitry Andric #include "lldb/DataFormatters/TypeFormat.h"
25*b5893f02SDimitry Andric #include "lldb/DataFormatters/TypeSummary.h"
26*b5893f02SDimitry Andric #include "lldb/DataFormatters/TypeValidator.h"
2735617911SEd Maste #include "lldb/DataFormatters/ValueObjectPrinter.h"
28*b5893f02SDimitry Andric #include "lldb/Expression/ExpressionVariable.h"
29ac7ddfbfSEd Maste #include "lldb/Symbol/ClangASTContext.h"
307aa51b79SEd Maste #include "lldb/Symbol/CompileUnit.h"
31435933ddSDimitry Andric #include "lldb/Symbol/CompilerType.h"
32*b5893f02SDimitry Andric #include "lldb/Symbol/Declaration.h"
33*b5893f02SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
34ac7ddfbfSEd Maste #include "lldb/Symbol/Type.h"
35ac7ddfbfSEd Maste #include "lldb/Target/ExecutionContext.h"
369f2f44ceSEd Maste #include "lldb/Target/Language.h"
37ac7ddfbfSEd Maste #include "lldb/Target/LanguageRuntime.h"
38ac7ddfbfSEd Maste #include "lldb/Target/ObjCLanguageRuntime.h"
39ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
40*b5893f02SDimitry Andric #include "lldb/Target/StackFrame.h"
41ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
42ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
43*b5893f02SDimitry Andric #include "lldb/Target/ThreadList.h"
44*b5893f02SDimitry Andric #include "lldb/Utility/DataBuffer.h"
45f678e45dSDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
46*b5893f02SDimitry Andric #include "lldb/Utility/Flags.h"
47f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
48*b5893f02SDimitry Andric #include "lldb/Utility/Logging.h"
49*b5893f02SDimitry Andric #include "lldb/Utility/Scalar.h"
50*b5893f02SDimitry Andric #include "lldb/Utility/SharingPtr.h"
51*b5893f02SDimitry Andric #include "lldb/Utility/Stream.h"
52f678e45dSDimitry Andric #include "lldb/Utility/StreamString.h"
53*b5893f02SDimitry Andric #include "lldb/lldb-private-types.h"
54f678e45dSDimitry Andric
55*b5893f02SDimitry Andric #include "llvm/Support/Compiler.h"
56f678e45dSDimitry Andric
57*b5893f02SDimitry Andric #include <algorithm>
58*b5893f02SDimitry Andric #include <cstdint>
59*b5893f02SDimitry Andric #include <cstdlib>
60*b5893f02SDimitry Andric #include <memory>
61*b5893f02SDimitry Andric #include <tuple>
62f678e45dSDimitry Andric
63*b5893f02SDimitry Andric #include <assert.h>
64*b5893f02SDimitry Andric #include <inttypes.h>
65*b5893f02SDimitry Andric #include <stdio.h>
66*b5893f02SDimitry Andric #include <string.h>
67f678e45dSDimitry Andric
68f678e45dSDimitry Andric namespace lldb_private {
69f678e45dSDimitry Andric class ExecutionContextScope;
70f678e45dSDimitry Andric }
71f678e45dSDimitry Andric namespace lldb_private {
72f678e45dSDimitry Andric class SymbolContextScope;
73f678e45dSDimitry Andric }
74ac7ddfbfSEd Maste
75ac7ddfbfSEd Maste using namespace lldb;
76ac7ddfbfSEd Maste using namespace lldb_private;
77ac7ddfbfSEd Maste using namespace lldb_utility;
78ac7ddfbfSEd Maste
79ac7ddfbfSEd Maste static user_id_t g_value_obj_uid = 0;
80ac7ddfbfSEd Maste
81ac7ddfbfSEd Maste //----------------------------------------------------------------------
82ac7ddfbfSEd Maste // ValueObject constructor
83ac7ddfbfSEd Maste //----------------------------------------------------------------------
ValueObject(ValueObject & parent)84435933ddSDimitry Andric ValueObject::ValueObject(ValueObject &parent)
85435933ddSDimitry Andric : UserID(++g_value_obj_uid), // Unique identifier for every value object
86435933ddSDimitry Andric m_parent(&parent), m_root(NULL), m_update_point(parent.GetUpdatePoint()),
87435933ddSDimitry Andric m_name(), m_data(), m_value(), m_error(), m_value_str(),
88435933ddSDimitry Andric m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(),
89435933ddSDimitry Andric m_validation_result(), m_manager(parent.GetManager()), m_children(),
90435933ddSDimitry Andric m_synthetic_children(), m_dynamic_value(NULL), m_synthetic_value(NULL),
91435933ddSDimitry Andric m_deref_valobj(NULL), m_format(eFormatDefault),
92435933ddSDimitry Andric m_last_format(eFormatDefault), m_last_format_mgr_revision(0),
93435933ddSDimitry Andric m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(),
94435933ddSDimitry Andric m_type_validator_sp(), m_user_id_of_forced_summary(),
95ac7ddfbfSEd Maste m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
967aa51b79SEd Maste m_value_checksum(),
971c3bbb01SEd Maste m_preferred_display_language(lldb::eLanguageTypeUnknown),
98435933ddSDimitry Andric m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
99435933ddSDimitry Andric m_children_count_valid(false), m_old_value_valid(false),
100435933ddSDimitry Andric m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
101435933ddSDimitry Andric m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
102ac7ddfbfSEd Maste m_is_getting_summary(false),
1037aa51b79SEd Maste m_did_calculate_complete_objc_class_type(false),
104435933ddSDimitry Andric m_is_synthetic_children_generated(
105435933ddSDimitry Andric parent.m_is_synthetic_children_generated) {
106ac7ddfbfSEd Maste m_manager->ManageObject(this);
107ac7ddfbfSEd Maste }
108ac7ddfbfSEd Maste
109ac7ddfbfSEd Maste //----------------------------------------------------------------------
110ac7ddfbfSEd Maste // ValueObject constructor
111ac7ddfbfSEd Maste //----------------------------------------------------------------------
ValueObject(ExecutionContextScope * exe_scope,AddressType child_ptr_or_ref_addr_type)112ac7ddfbfSEd Maste ValueObject::ValueObject(ExecutionContextScope *exe_scope,
113435933ddSDimitry Andric AddressType child_ptr_or_ref_addr_type)
114435933ddSDimitry Andric : UserID(++g_value_obj_uid), // Unique identifier for every value object
115435933ddSDimitry Andric m_parent(NULL), m_root(NULL), m_update_point(exe_scope), m_name(),
116435933ddSDimitry Andric m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(),
117435933ddSDimitry Andric m_location_str(), m_summary_str(), m_object_desc_str(),
118435933ddSDimitry Andric m_validation_result(), m_manager(), m_children(), m_synthetic_children(),
119435933ddSDimitry Andric m_dynamic_value(NULL), m_synthetic_value(NULL), m_deref_valobj(NULL),
120435933ddSDimitry Andric m_format(eFormatDefault), m_last_format(eFormatDefault),
121435933ddSDimitry Andric m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(),
122435933ddSDimitry Andric m_synthetic_children_sp(), m_type_validator_sp(),
123ac7ddfbfSEd Maste m_user_id_of_forced_summary(),
124ac7ddfbfSEd Maste m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
1257aa51b79SEd Maste m_value_checksum(),
1261c3bbb01SEd Maste m_preferred_display_language(lldb::eLanguageTypeUnknown),
127435933ddSDimitry Andric m_language_flags(0), m_value_is_valid(false), m_value_did_change(false),
128435933ddSDimitry Andric m_children_count_valid(false), m_old_value_valid(false),
129435933ddSDimitry Andric m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
130435933ddSDimitry Andric m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
131ac7ddfbfSEd Maste m_is_getting_summary(false),
1327aa51b79SEd Maste m_did_calculate_complete_objc_class_type(false),
133435933ddSDimitry Andric m_is_synthetic_children_generated(false) {
134ac7ddfbfSEd Maste m_manager = new ValueObjectManager();
135ac7ddfbfSEd Maste m_manager->ManageObject(this);
136ac7ddfbfSEd Maste }
137ac7ddfbfSEd Maste
138ac7ddfbfSEd Maste //----------------------------------------------------------------------
139ac7ddfbfSEd Maste // Destructor
140ac7ddfbfSEd Maste //----------------------------------------------------------------------
~ValueObject()141435933ddSDimitry Andric ValueObject::~ValueObject() {}
142ac7ddfbfSEd Maste
UpdateValueIfNeeded(bool update_format)143435933ddSDimitry Andric bool ValueObject::UpdateValueIfNeeded(bool update_format) {
144ac7ddfbfSEd Maste
145ac7ddfbfSEd Maste bool did_change_formats = false;
146ac7ddfbfSEd Maste
147ac7ddfbfSEd Maste if (update_format)
148ac7ddfbfSEd Maste did_change_formats = UpdateFormatsIfNeeded();
149ac7ddfbfSEd Maste
1504ba319b5SDimitry Andric // If this is a constant value, then our success is predicated on whether we
1514ba319b5SDimitry Andric // have an error or not
152435933ddSDimitry Andric if (GetIsConstant()) {
15335617911SEd Maste // if you are constant, things might still have changed behind your back
154435933ddSDimitry Andric // (e.g. you are a frozen object and things have changed deeper than you
1554ba319b5SDimitry Andric // cared to freeze-dry yourself) in this case, your value has not changed,
1564ba319b5SDimitry Andric // but "computed" entries might have, so you might now have a different
1574ba319b5SDimitry Andric // summary, or a different object description. clear these so we will
1584ba319b5SDimitry Andric // recompute them
159ac7ddfbfSEd Maste if (update_format && !did_change_formats)
160435933ddSDimitry Andric ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
161435933ddSDimitry Andric eClearUserVisibleDataItemsDescription);
162ac7ddfbfSEd Maste return m_error.Success();
163ac7ddfbfSEd Maste }
164ac7ddfbfSEd Maste
1657aa51b79SEd Maste bool first_update = IsChecksumEmpty();
166ac7ddfbfSEd Maste
167435933ddSDimitry Andric if (NeedsUpdating()) {
168ac7ddfbfSEd Maste m_update_point.SetUpdated();
169ac7ddfbfSEd Maste
1704ba319b5SDimitry Andric // Save the old value using swap to avoid a string copy which also will
1714ba319b5SDimitry Andric // clear our m_value_str
172435933ddSDimitry Andric if (m_value_str.empty()) {
173ac7ddfbfSEd Maste m_old_value_valid = false;
174435933ddSDimitry Andric } else {
175ac7ddfbfSEd Maste m_old_value_valid = true;
176ac7ddfbfSEd Maste m_old_value_str.swap(m_value_str);
177ac7ddfbfSEd Maste ClearUserVisibleData(eClearUserVisibleDataItemsValue);
178ac7ddfbfSEd Maste }
179ac7ddfbfSEd Maste
180ac7ddfbfSEd Maste ClearUserVisibleData();
181ac7ddfbfSEd Maste
182435933ddSDimitry Andric if (IsInScope()) {
183ac7ddfbfSEd Maste const bool value_was_valid = GetValueIsValid();
184ac7ddfbfSEd Maste SetValueDidChange(false);
185ac7ddfbfSEd Maste
186ac7ddfbfSEd Maste m_error.Clear();
187ac7ddfbfSEd Maste
188ac7ddfbfSEd Maste // Call the pure virtual function to update the value
1897aa51b79SEd Maste
1907aa51b79SEd Maste bool need_compare_checksums = false;
1917aa51b79SEd Maste llvm::SmallVector<uint8_t, 16> old_checksum;
1927aa51b79SEd Maste
193435933ddSDimitry Andric if (!first_update && CanProvideValue()) {
1947aa51b79SEd Maste need_compare_checksums = true;
1957aa51b79SEd Maste old_checksum.resize(m_value_checksum.size());
196435933ddSDimitry Andric std::copy(m_value_checksum.begin(), m_value_checksum.end(),
197435933ddSDimitry Andric old_checksum.begin());
1987aa51b79SEd Maste }
1997aa51b79SEd Maste
200ac7ddfbfSEd Maste bool success = UpdateValue();
201ac7ddfbfSEd Maste
202ac7ddfbfSEd Maste SetValueIsValid(success);
203ac7ddfbfSEd Maste
204435933ddSDimitry Andric if (success) {
2057aa51b79SEd Maste const uint64_t max_checksum_size = 128;
206435933ddSDimitry Andric m_data.Checksum(m_value_checksum, max_checksum_size);
207435933ddSDimitry Andric } else {
2087aa51b79SEd Maste need_compare_checksums = false;
2097aa51b79SEd Maste m_value_checksum.clear();
2107aa51b79SEd Maste }
2117aa51b79SEd Maste
212435933ddSDimitry Andric assert(!need_compare_checksums ||
213435933ddSDimitry Andric (!old_checksum.empty() && !m_value_checksum.empty()));
2147aa51b79SEd Maste
215ac7ddfbfSEd Maste if (first_update)
216ac7ddfbfSEd Maste SetValueDidChange(false);
217*b5893f02SDimitry Andric else if (!m_value_did_change && !success) {
2184ba319b5SDimitry Andric // The value wasn't gotten successfully, so we mark this as changed if
2194ba319b5SDimitry Andric // the value used to be valid and now isn't
220ac7ddfbfSEd Maste SetValueDidChange(value_was_valid);
221435933ddSDimitry Andric } else if (need_compare_checksums) {
222435933ddSDimitry Andric SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
223435933ddSDimitry Andric m_value_checksum.size()));
2247aa51b79SEd Maste }
2257aa51b79SEd Maste
226435933ddSDimitry Andric } else {
227ac7ddfbfSEd Maste m_error.SetErrorString("out of scope");
228ac7ddfbfSEd Maste }
229ac7ddfbfSEd Maste }
230ac7ddfbfSEd Maste return m_error.Success();
231ac7ddfbfSEd Maste }
232ac7ddfbfSEd Maste
UpdateFormatsIfNeeded()233435933ddSDimitry Andric bool ValueObject::UpdateFormatsIfNeeded() {
2349f2f44ceSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
235ac7ddfbfSEd Maste if (log)
236435933ddSDimitry Andric log->Printf("[%s %p] checking for FormatManager revisions. ValueObject "
237435933ddSDimitry Andric "rev: %d - Global rev: %d",
2380127ef0fSEd Maste GetName().GetCString(), static_cast<void *>(this),
239ac7ddfbfSEd Maste m_last_format_mgr_revision,
240ac7ddfbfSEd Maste DataVisualization::GetCurrentRevision());
241ac7ddfbfSEd Maste
242ac7ddfbfSEd Maste bool any_change = false;
243ac7ddfbfSEd Maste
244435933ddSDimitry Andric if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
2450127ef0fSEd Maste m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
2460127ef0fSEd Maste any_change = true;
2470127ef0fSEd Maste
24835617911SEd Maste SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
249435933ddSDimitry Andric SetSummaryFormat(
250435933ddSDimitry Andric DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
251ac7ddfbfSEd Maste #ifndef LLDB_DISABLE_PYTHON
252435933ddSDimitry Andric SetSyntheticChildren(
253435933ddSDimitry Andric DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
254ac7ddfbfSEd Maste #endif
2557aa51b79SEd Maste SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
256ac7ddfbfSEd Maste }
257ac7ddfbfSEd Maste
258ac7ddfbfSEd Maste return any_change;
259ac7ddfbfSEd Maste }
260ac7ddfbfSEd Maste
SetNeedsUpdate()261435933ddSDimitry Andric void ValueObject::SetNeedsUpdate() {
262ac7ddfbfSEd Maste m_update_point.SetNeedsUpdate();
263435933ddSDimitry Andric // We have to clear the value string here so ConstResult children will notice
2644ba319b5SDimitry Andric // if their values are changed by hand (i.e. with SetValueAsCString).
265ac7ddfbfSEd Maste ClearUserVisibleData(eClearUserVisibleDataItemsValue);
266ac7ddfbfSEd Maste }
267ac7ddfbfSEd Maste
ClearDynamicTypeInformation()268435933ddSDimitry Andric void ValueObject::ClearDynamicTypeInformation() {
26935617911SEd Maste m_children_count_valid = false;
270ac7ddfbfSEd Maste m_did_calculate_complete_objc_class_type = false;
271ac7ddfbfSEd Maste m_last_format_mgr_revision = 0;
2729f2f44ceSEd Maste m_override_type = CompilerType();
273ac7ddfbfSEd Maste SetValueFormat(lldb::TypeFormatImplSP());
274ac7ddfbfSEd Maste SetSummaryFormat(lldb::TypeSummaryImplSP());
275ac7ddfbfSEd Maste SetSyntheticChildren(lldb::SyntheticChildrenSP());
276ac7ddfbfSEd Maste }
277ac7ddfbfSEd Maste
MaybeCalculateCompleteType()278435933ddSDimitry Andric CompilerType ValueObject::MaybeCalculateCompleteType() {
2799f2f44ceSEd Maste CompilerType compiler_type(GetCompilerTypeImpl());
280ac7ddfbfSEd Maste
281435933ddSDimitry Andric if (m_did_calculate_complete_objc_class_type) {
282ac7ddfbfSEd Maste if (m_override_type.IsValid())
283ac7ddfbfSEd Maste return m_override_type;
284ac7ddfbfSEd Maste else
2859f2f44ceSEd Maste return compiler_type;
286ac7ddfbfSEd Maste }
287ac7ddfbfSEd Maste
2889f2f44ceSEd Maste CompilerType class_type;
289ac7ddfbfSEd Maste bool is_pointer_type = false;
290ac7ddfbfSEd Maste
291435933ddSDimitry Andric if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) {
292ac7ddfbfSEd Maste is_pointer_type = true;
293435933ddSDimitry Andric } else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) {
2949f2f44ceSEd Maste class_type = compiler_type;
295435933ddSDimitry Andric } else {
2969f2f44ceSEd Maste return compiler_type;
297ac7ddfbfSEd Maste }
298ac7ddfbfSEd Maste
299ac7ddfbfSEd Maste m_did_calculate_complete_objc_class_type = true;
300ac7ddfbfSEd Maste
301435933ddSDimitry Andric if (class_type) {
302ac7ddfbfSEd Maste ConstString class_name(class_type.GetConstTypeName());
303ac7ddfbfSEd Maste
304435933ddSDimitry Andric if (class_name) {
305435933ddSDimitry Andric ProcessSP process_sp(
306435933ddSDimitry Andric GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
307ac7ddfbfSEd Maste
308435933ddSDimitry Andric if (process_sp) {
309435933ddSDimitry Andric ObjCLanguageRuntime *objc_language_runtime(
310435933ddSDimitry Andric process_sp->GetObjCLanguageRuntime());
311ac7ddfbfSEd Maste
312435933ddSDimitry Andric if (objc_language_runtime) {
313435933ddSDimitry Andric TypeSP complete_objc_class_type_sp =
314435933ddSDimitry Andric objc_language_runtime->LookupInCompleteClassCache(class_name);
315ac7ddfbfSEd Maste
316435933ddSDimitry Andric if (complete_objc_class_type_sp) {
317435933ddSDimitry Andric CompilerType complete_class(
318435933ddSDimitry Andric complete_objc_class_type_sp->GetFullCompilerType());
319ac7ddfbfSEd Maste
320435933ddSDimitry Andric if (complete_class.GetCompleteType()) {
321435933ddSDimitry Andric if (is_pointer_type) {
322ac7ddfbfSEd Maste m_override_type = complete_class.GetPointerType();
323435933ddSDimitry Andric } else {
324ac7ddfbfSEd Maste m_override_type = complete_class;
325ac7ddfbfSEd Maste }
326ac7ddfbfSEd Maste
327ac7ddfbfSEd Maste if (m_override_type.IsValid())
328ac7ddfbfSEd Maste return m_override_type;
329ac7ddfbfSEd Maste }
330ac7ddfbfSEd Maste }
331ac7ddfbfSEd Maste }
332ac7ddfbfSEd Maste }
333ac7ddfbfSEd Maste }
334ac7ddfbfSEd Maste }
3359f2f44ceSEd Maste return compiler_type;
336ac7ddfbfSEd Maste }
337ac7ddfbfSEd Maste
GetCompilerType()338435933ddSDimitry Andric CompilerType ValueObject::GetCompilerType() {
339ac7ddfbfSEd Maste return MaybeCalculateCompleteType();
340ac7ddfbfSEd Maste }
341ac7ddfbfSEd Maste
GetTypeImpl()342435933ddSDimitry Andric TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); }
34335617911SEd Maste
GetDataExtractor()344435933ddSDimitry Andric DataExtractor &ValueObject::GetDataExtractor() {
345ac7ddfbfSEd Maste UpdateValueIfNeeded(false);
346ac7ddfbfSEd Maste return m_data;
347ac7ddfbfSEd Maste }
348ac7ddfbfSEd Maste
GetError()3495517e702SDimitry Andric const Status &ValueObject::GetError() {
350ac7ddfbfSEd Maste UpdateValueIfNeeded(false);
351ac7ddfbfSEd Maste return m_error;
352ac7ddfbfSEd Maste }
353ac7ddfbfSEd Maste
GetName() const354435933ddSDimitry Andric const ConstString &ValueObject::GetName() const { return m_name; }
355435933ddSDimitry Andric
GetLocationAsCString()356435933ddSDimitry Andric const char *ValueObject::GetLocationAsCString() {
357435933ddSDimitry Andric return GetLocationAsCStringImpl(m_value, m_data);
358ac7ddfbfSEd Maste }
359ac7ddfbfSEd Maste
GetLocationAsCStringImpl(const Value & value,const DataExtractor & data)360435933ddSDimitry Andric const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
361435933ddSDimitry Andric const DataExtractor &data) {
362435933ddSDimitry Andric if (UpdateValueIfNeeded(false)) {
363435933ddSDimitry Andric if (m_location_str.empty()) {
364ac7ddfbfSEd Maste StreamString sstr;
365ac7ddfbfSEd Maste
366ac7ddfbfSEd Maste Value::ValueType value_type = value.GetValueType();
367ac7ddfbfSEd Maste
368435933ddSDimitry Andric switch (value_type) {
369ac7ddfbfSEd Maste case Value::eValueTypeScalar:
370ac7ddfbfSEd Maste case Value::eValueTypeVector:
371435933ddSDimitry Andric if (value.GetContextType() == Value::eContextTypeRegisterInfo) {
372ac7ddfbfSEd Maste RegisterInfo *reg_info = value.GetRegisterInfo();
373435933ddSDimitry Andric if (reg_info) {
374ac7ddfbfSEd Maste if (reg_info->name)
375ac7ddfbfSEd Maste m_location_str = reg_info->name;
376ac7ddfbfSEd Maste else if (reg_info->alt_name)
377ac7ddfbfSEd Maste m_location_str = reg_info->alt_name;
378ac7ddfbfSEd Maste if (m_location_str.empty())
379435933ddSDimitry Andric m_location_str = (reg_info->encoding == lldb::eEncodingVector)
380435933ddSDimitry Andric ? "vector"
381435933ddSDimitry Andric : "scalar";
382ac7ddfbfSEd Maste }
383ac7ddfbfSEd Maste }
384ac7ddfbfSEd Maste if (m_location_str.empty())
385435933ddSDimitry Andric m_location_str =
386435933ddSDimitry Andric (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
387ac7ddfbfSEd Maste break;
388ac7ddfbfSEd Maste
389ac7ddfbfSEd Maste case Value::eValueTypeLoadAddress:
390ac7ddfbfSEd Maste case Value::eValueTypeFileAddress:
391435933ddSDimitry Andric case Value::eValueTypeHostAddress: {
392ac7ddfbfSEd Maste uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
393435933ddSDimitry Andric sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
394435933ddSDimitry Andric value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
395435933ddSDimitry Andric m_location_str = sstr.GetString();
396435933ddSDimitry Andric } break;
397ac7ddfbfSEd Maste }
398ac7ddfbfSEd Maste }
399ac7ddfbfSEd Maste }
400ac7ddfbfSEd Maste return m_location_str.c_str();
401ac7ddfbfSEd Maste }
402ac7ddfbfSEd Maste
GetValue()403435933ddSDimitry Andric Value &ValueObject::GetValue() { return m_value; }
404ac7ddfbfSEd Maste
GetValue() const405435933ddSDimitry Andric const Value &ValueObject::GetValue() const { return m_value; }
406ac7ddfbfSEd Maste
ResolveValue(Scalar & scalar)407435933ddSDimitry Andric bool ValueObject::ResolveValue(Scalar &scalar) {
408435933ddSDimitry Andric if (UpdateValueIfNeeded(
409435933ddSDimitry Andric false)) // make sure that you are up to date before returning anything
410ac7ddfbfSEd Maste {
411ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
412ac7ddfbfSEd Maste Value tmp_value(m_value);
413ac7ddfbfSEd Maste scalar = tmp_value.ResolveValue(&exe_ctx);
414435933ddSDimitry Andric if (scalar.IsValid()) {
415ac7ddfbfSEd Maste const uint32_t bitfield_bit_size = GetBitfieldBitSize();
416ac7ddfbfSEd Maste if (bitfield_bit_size)
417435933ddSDimitry Andric return scalar.ExtractBitfield(bitfield_bit_size,
418435933ddSDimitry Andric GetBitfieldBitOffset());
419ac7ddfbfSEd Maste return true;
420ac7ddfbfSEd Maste }
421ac7ddfbfSEd Maste }
422ac7ddfbfSEd Maste return false;
423ac7ddfbfSEd Maste }
424ac7ddfbfSEd Maste
IsLogicalTrue(Status & error)4255517e702SDimitry Andric bool ValueObject::IsLogicalTrue(Status &error) {
426435933ddSDimitry Andric if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
4279f2f44ceSEd Maste LazyBool is_logical_true = language->IsLogicalTrue(*this, error);
428435933ddSDimitry Andric switch (is_logical_true) {
4299f2f44ceSEd Maste case eLazyBoolYes:
4309f2f44ceSEd Maste case eLazyBoolNo:
4319f2f44ceSEd Maste return (is_logical_true == true);
4329f2f44ceSEd Maste case eLazyBoolCalculate:
4339f2f44ceSEd Maste break;
4349f2f44ceSEd Maste }
4359f2f44ceSEd Maste }
4369f2f44ceSEd Maste
4379f2f44ceSEd Maste Scalar scalar_value;
4389f2f44ceSEd Maste
439435933ddSDimitry Andric if (!ResolveValue(scalar_value)) {
4409f2f44ceSEd Maste error.SetErrorString("failed to get a scalar result");
4419f2f44ceSEd Maste return false;
4429f2f44ceSEd Maste }
4439f2f44ceSEd Maste
4449f2f44ceSEd Maste bool ret;
445*b5893f02SDimitry Andric ret = scalar_value.ULongLong(1) != 0;
4469f2f44ceSEd Maste error.Clear();
4479f2f44ceSEd Maste return ret;
4489f2f44ceSEd Maste }
4499f2f44ceSEd Maste
GetValueIsValid() const450435933ddSDimitry Andric bool ValueObject::GetValueIsValid() const { return m_value_is_valid; }
451ac7ddfbfSEd Maste
SetValueIsValid(bool b)452435933ddSDimitry Andric void ValueObject::SetValueIsValid(bool b) { m_value_is_valid = b; }
453ac7ddfbfSEd Maste
GetValueDidChange()454435933ddSDimitry Andric bool ValueObject::GetValueDidChange() { return m_value_did_change; }
455ac7ddfbfSEd Maste
SetValueDidChange(bool value_changed)456435933ddSDimitry Andric void ValueObject::SetValueDidChange(bool value_changed) {
457ac7ddfbfSEd Maste m_value_did_change = value_changed;
458ac7ddfbfSEd Maste }
459ac7ddfbfSEd Maste
GetChildAtIndex(size_t idx,bool can_create)460435933ddSDimitry Andric ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
461ac7ddfbfSEd Maste ValueObjectSP child_sp;
462ac7ddfbfSEd Maste // We may need to update our value if we are dynamic
463ac7ddfbfSEd Maste if (IsPossibleDynamicType())
464ac7ddfbfSEd Maste UpdateValueIfNeeded(false);
465435933ddSDimitry Andric if (idx < GetNumChildren()) {
466ac7ddfbfSEd Maste // Check if we have already made the child value object?
467435933ddSDimitry Andric if (can_create && !m_children.HasChildAtIndex(idx)) {
468ac7ddfbfSEd Maste // No we haven't created the child at this index, so lets have our
469ac7ddfbfSEd Maste // subclass do it and cache the result for quick future access.
470ac7ddfbfSEd Maste m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
471ac7ddfbfSEd Maste }
472ac7ddfbfSEd Maste
473ac7ddfbfSEd Maste ValueObject *child = m_children.GetChildAtIndex(idx);
474ac7ddfbfSEd Maste if (child != NULL)
475ac7ddfbfSEd Maste return child->GetSP();
476ac7ddfbfSEd Maste }
477ac7ddfbfSEd Maste return child_sp;
478ac7ddfbfSEd Maste }
479ac7ddfbfSEd Maste
480ac7ddfbfSEd Maste lldb::ValueObjectSP
GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,size_t * index_of_error)48151690af2SDimitry Andric ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
482435933ddSDimitry Andric size_t *index_of_error) {
483ac7ddfbfSEd Maste if (idxs.size() == 0)
484ac7ddfbfSEd Maste return GetSP();
485ac7ddfbfSEd Maste ValueObjectSP root(GetSP());
486435933ddSDimitry Andric for (size_t idx : idxs) {
487ac7ddfbfSEd Maste root = root->GetChildAtIndex(idx, true);
488435933ddSDimitry Andric if (!root) {
489ac7ddfbfSEd Maste if (index_of_error)
490ac7ddfbfSEd Maste *index_of_error = idx;
491ac7ddfbfSEd Maste return root;
492ac7ddfbfSEd Maste }
493ac7ddfbfSEd Maste }
494ac7ddfbfSEd Maste return root;
495ac7ddfbfSEd Maste }
496ac7ddfbfSEd Maste
GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t,bool>> idxs,size_t * index_of_error)497435933ddSDimitry Andric lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
49851690af2SDimitry Andric llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) {
499ac7ddfbfSEd Maste if (idxs.size() == 0)
500ac7ddfbfSEd Maste return GetSP();
501ac7ddfbfSEd Maste ValueObjectSP root(GetSP());
502435933ddSDimitry Andric for (std::pair<size_t, bool> idx : idxs) {
503ac7ddfbfSEd Maste root = root->GetChildAtIndex(idx.first, idx.second);
504435933ddSDimitry Andric if (!root) {
505ac7ddfbfSEd Maste if (index_of_error)
506ac7ddfbfSEd Maste *index_of_error = idx.first;
507ac7ddfbfSEd Maste return root;
508ac7ddfbfSEd Maste }
509ac7ddfbfSEd Maste }
510ac7ddfbfSEd Maste return root;
511ac7ddfbfSEd Maste }
512ac7ddfbfSEd Maste
51335617911SEd Maste lldb::ValueObjectSP
GetChildAtNamePath(llvm::ArrayRef<ConstString> names,ConstString * name_of_error)51451690af2SDimitry Andric ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
515435933ddSDimitry Andric ConstString *name_of_error) {
51635617911SEd Maste if (names.size() == 0)
51735617911SEd Maste return GetSP();
51835617911SEd Maste ValueObjectSP root(GetSP());
519435933ddSDimitry Andric for (ConstString name : names) {
52035617911SEd Maste root = root->GetChildMemberWithName(name, true);
521435933ddSDimitry Andric if (!root) {
52235617911SEd Maste if (name_of_error)
52335617911SEd Maste *name_of_error = name;
52435617911SEd Maste return root;
52535617911SEd Maste }
52635617911SEd Maste }
52735617911SEd Maste return root;
52835617911SEd Maste }
52935617911SEd Maste
GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString,bool>> names,ConstString * name_of_error)530435933ddSDimitry Andric lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
53151690af2SDimitry Andric llvm::ArrayRef<std::pair<ConstString, bool>> names,
532435933ddSDimitry Andric ConstString *name_of_error) {
53335617911SEd Maste if (names.size() == 0)
53435617911SEd Maste return GetSP();
53535617911SEd Maste ValueObjectSP root(GetSP());
536435933ddSDimitry Andric for (std::pair<ConstString, bool> name : names) {
53735617911SEd Maste root = root->GetChildMemberWithName(name.first, name.second);
538435933ddSDimitry Andric if (!root) {
53935617911SEd Maste if (name_of_error)
54035617911SEd Maste *name_of_error = name.first;
54135617911SEd Maste return root;
54235617911SEd Maste }
54335617911SEd Maste }
54435617911SEd Maste return root;
54535617911SEd Maste }
54635617911SEd Maste
GetIndexOfChildWithName(const ConstString & name)547435933ddSDimitry Andric size_t ValueObject::GetIndexOfChildWithName(const ConstString &name) {
548ac7ddfbfSEd Maste bool omit_empty_base_classes = true;
549435933ddSDimitry Andric return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
550435933ddSDimitry Andric omit_empty_base_classes);
551ac7ddfbfSEd Maste }
552ac7ddfbfSEd Maste
GetChildMemberWithName(const ConstString & name,bool can_create)553435933ddSDimitry Andric ValueObjectSP ValueObject::GetChildMemberWithName(const ConstString &name,
554435933ddSDimitry Andric bool can_create) {
5554ba319b5SDimitry Andric // when getting a child by name, it could be buried inside some base classes
5564ba319b5SDimitry Andric // (which really aren't part of the expression path), so we need a vector of
5574ba319b5SDimitry Andric // indexes that can get us down to the correct child
558ac7ddfbfSEd Maste ValueObjectSP child_sp;
559ac7ddfbfSEd Maste
560ac7ddfbfSEd Maste // We may need to update our value if we are dynamic
561ac7ddfbfSEd Maste if (IsPossibleDynamicType())
562ac7ddfbfSEd Maste UpdateValueIfNeeded(false);
563ac7ddfbfSEd Maste
564ac7ddfbfSEd Maste std::vector<uint32_t> child_indexes;
565ac7ddfbfSEd Maste bool omit_empty_base_classes = true;
566435933ddSDimitry Andric const size_t num_child_indexes =
567435933ddSDimitry Andric GetCompilerType().GetIndexOfChildMemberWithName(
568435933ddSDimitry Andric name.GetCString(), omit_empty_base_classes, child_indexes);
569435933ddSDimitry Andric if (num_child_indexes > 0) {
570ac7ddfbfSEd Maste std::vector<uint32_t>::const_iterator pos = child_indexes.begin();
571ac7ddfbfSEd Maste std::vector<uint32_t>::const_iterator end = child_indexes.end();
572ac7ddfbfSEd Maste
573ac7ddfbfSEd Maste child_sp = GetChildAtIndex(*pos, can_create);
574435933ddSDimitry Andric for (++pos; pos != end; ++pos) {
575435933ddSDimitry Andric if (child_sp) {
576ac7ddfbfSEd Maste ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create));
577ac7ddfbfSEd Maste child_sp = new_child_sp;
578435933ddSDimitry Andric } else {
579ac7ddfbfSEd Maste child_sp.reset();
580ac7ddfbfSEd Maste }
581ac7ddfbfSEd Maste }
582ac7ddfbfSEd Maste }
583ac7ddfbfSEd Maste return child_sp;
584ac7ddfbfSEd Maste }
585ac7ddfbfSEd Maste
GetNumChildren(uint32_t max)586435933ddSDimitry Andric size_t ValueObject::GetNumChildren(uint32_t max) {
587ac7ddfbfSEd Maste UpdateValueIfNeeded();
5889f2f44ceSEd Maste
589435933ddSDimitry Andric if (max < UINT32_MAX) {
590435933ddSDimitry Andric if (m_children_count_valid) {
5919f2f44ceSEd Maste size_t children_count = m_children.GetChildrenCount();
5929f2f44ceSEd Maste return children_count <= max ? children_count : max;
593435933ddSDimitry Andric } else
5949f2f44ceSEd Maste return CalculateNumChildren(max);
5959f2f44ceSEd Maste }
5969f2f44ceSEd Maste
597435933ddSDimitry Andric if (!m_children_count_valid) {
598ac7ddfbfSEd Maste SetNumChildren(CalculateNumChildren());
599ac7ddfbfSEd Maste }
600ac7ddfbfSEd Maste return m_children.GetChildrenCount();
601ac7ddfbfSEd Maste }
602ac7ddfbfSEd Maste
MightHaveChildren()603435933ddSDimitry Andric bool ValueObject::MightHaveChildren() {
604ac7ddfbfSEd Maste bool has_children = false;
605ac7ddfbfSEd Maste const uint32_t type_info = GetTypeInfo();
606435933ddSDimitry Andric if (type_info) {
607435933ddSDimitry Andric if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
608ac7ddfbfSEd Maste has_children = true;
609435933ddSDimitry Andric } else {
610ac7ddfbfSEd Maste has_children = GetNumChildren() > 0;
611ac7ddfbfSEd Maste }
612ac7ddfbfSEd Maste return has_children;
613ac7ddfbfSEd Maste }
614ac7ddfbfSEd Maste
615ac7ddfbfSEd Maste // Should only be called by ValueObject::GetNumChildren()
SetNumChildren(size_t num_children)616435933ddSDimitry Andric void ValueObject::SetNumChildren(size_t num_children) {
617ac7ddfbfSEd Maste m_children_count_valid = true;
618ac7ddfbfSEd Maste m_children.SetChildrenCount(num_children);
619ac7ddfbfSEd Maste }
620ac7ddfbfSEd Maste
SetName(const ConstString & name)621435933ddSDimitry Andric void ValueObject::SetName(const ConstString &name) { m_name = name; }
622ac7ddfbfSEd Maste
CreateChildAtIndex(size_t idx,bool synthetic_array_member,int32_t synthetic_index)623435933ddSDimitry Andric ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
624435933ddSDimitry Andric bool synthetic_array_member,
625435933ddSDimitry Andric int32_t synthetic_index) {
626ac7ddfbfSEd Maste ValueObject *valobj = NULL;
627ac7ddfbfSEd Maste
628ac7ddfbfSEd Maste bool omit_empty_base_classes = true;
629ac7ddfbfSEd Maste bool ignore_array_bounds = synthetic_array_member;
630ac7ddfbfSEd Maste std::string child_name_str;
631ac7ddfbfSEd Maste uint32_t child_byte_size = 0;
632ac7ddfbfSEd Maste int32_t child_byte_offset = 0;
633ac7ddfbfSEd Maste uint32_t child_bitfield_bit_size = 0;
634ac7ddfbfSEd Maste uint32_t child_bitfield_bit_offset = 0;
635ac7ddfbfSEd Maste bool child_is_base_class = false;
636ac7ddfbfSEd Maste bool child_is_deref_of_parent = false;
6379f2f44ceSEd Maste uint64_t language_flags = 0;
638ac7ddfbfSEd Maste
639*b5893f02SDimitry Andric const bool transparent_pointers = !synthetic_array_member;
6409f2f44ceSEd Maste CompilerType child_compiler_type;
641ac7ddfbfSEd Maste
642ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
643ac7ddfbfSEd Maste
644435933ddSDimitry Andric child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(
645435933ddSDimitry Andric &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
646435933ddSDimitry Andric ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
647435933ddSDimitry Andric child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
648435933ddSDimitry Andric child_is_deref_of_parent, this, language_flags);
649435933ddSDimitry Andric if (child_compiler_type) {
650ac7ddfbfSEd Maste if (synthetic_index)
651ac7ddfbfSEd Maste child_byte_offset += child_byte_size * synthetic_index;
652ac7ddfbfSEd Maste
653ac7ddfbfSEd Maste ConstString child_name;
654ac7ddfbfSEd Maste if (!child_name_str.empty())
655ac7ddfbfSEd Maste child_name.SetCString(child_name_str.c_str());
656ac7ddfbfSEd Maste
657435933ddSDimitry Andric valobj = new ValueObjectChild(
658435933ddSDimitry Andric *this, child_compiler_type, child_name, child_byte_size,
659435933ddSDimitry Andric child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
660435933ddSDimitry Andric child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
6619f2f44ceSEd Maste language_flags);
662ac7ddfbfSEd Maste }
663ac7ddfbfSEd Maste
664ac7ddfbfSEd Maste return valobj;
665ac7ddfbfSEd Maste }
666ac7ddfbfSEd Maste
GetSummaryAsCString(TypeSummaryImpl * summary_ptr,std::string & destination,lldb::LanguageType lang)667435933ddSDimitry Andric bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
6689f2f44ceSEd Maste std::string &destination,
669435933ddSDimitry Andric lldb::LanguageType lang) {
670435933ddSDimitry Andric return GetSummaryAsCString(summary_ptr, destination,
671435933ddSDimitry Andric TypeSummaryOptions().SetLanguage(lang));
6727aa51b79SEd Maste }
6737aa51b79SEd Maste
GetSummaryAsCString(TypeSummaryImpl * summary_ptr,std::string & destination,const TypeSummaryOptions & options)674435933ddSDimitry Andric bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
6757aa51b79SEd Maste std::string &destination,
676435933ddSDimitry Andric const TypeSummaryOptions &options) {
677ac7ddfbfSEd Maste destination.clear();
678ac7ddfbfSEd Maste
6794ba319b5SDimitry Andric // ideally we would like to bail out if passing NULL, but if we do so we end
6804ba319b5SDimitry Andric // up not providing the summary for function pointers anymore
681ac7ddfbfSEd Maste if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
682ac7ddfbfSEd Maste return false;
683ac7ddfbfSEd Maste
684ac7ddfbfSEd Maste m_is_getting_summary = true;
685ac7ddfbfSEd Maste
6869f2f44ceSEd Maste TypeSummaryOptions actual_options(options);
6879f2f44ceSEd Maste
6889f2f44ceSEd Maste if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
6899f2f44ceSEd Maste actual_options.SetLanguage(GetPreferredDisplayLanguage());
6909f2f44ceSEd Maste
691435933ddSDimitry Andric // this is a hot path in code and we prefer to avoid setting this string all
6924ba319b5SDimitry Andric // too often also clearing out other information that we might care to see in
6934ba319b5SDimitry Andric // a crash log. might be useful in very specific situations though.
694435933ddSDimitry Andric /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
695435933ddSDimitry Andric Summary provider's description is %s",
696ac7ddfbfSEd Maste GetTypeName().GetCString(),
697ac7ddfbfSEd Maste GetName().GetCString(),
698ac7ddfbfSEd Maste summary_ptr->GetDescription().c_str());*/
699ac7ddfbfSEd Maste
700435933ddSDimitry Andric if (UpdateValueIfNeeded(false) && summary_ptr) {
701ac7ddfbfSEd Maste if (HasSyntheticValue())
702435933ddSDimitry Andric m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
703435933ddSDimitry Andric // the synthetic children being
704435933ddSDimitry Andric // up-to-date (e.g. ${svar%#})
7059f2f44ceSEd Maste summary_ptr->FormatObject(this, destination, actual_options);
706ac7ddfbfSEd Maste }
707ac7ddfbfSEd Maste m_is_getting_summary = false;
708ac7ddfbfSEd Maste return !destination.empty();
709ac7ddfbfSEd Maste }
710ac7ddfbfSEd Maste
GetSummaryAsCString(lldb::LanguageType lang)711435933ddSDimitry Andric const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
712435933ddSDimitry Andric if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
7139f2f44ceSEd Maste TypeSummaryOptions summary_options;
7149f2f44ceSEd Maste summary_options.SetLanguage(lang);
715435933ddSDimitry Andric GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
7169f2f44ceSEd Maste summary_options);
717ac7ddfbfSEd Maste }
718ac7ddfbfSEd Maste if (m_summary_str.empty())
719ac7ddfbfSEd Maste return NULL;
720ac7ddfbfSEd Maste return m_summary_str.c_str();
721ac7ddfbfSEd Maste }
722ac7ddfbfSEd Maste
GetSummaryAsCString(std::string & destination,const TypeSummaryOptions & options)723435933ddSDimitry Andric bool ValueObject::GetSummaryAsCString(std::string &destination,
724435933ddSDimitry Andric const TypeSummaryOptions &options) {
725435933ddSDimitry Andric return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
7267aa51b79SEd Maste }
7277aa51b79SEd Maste
IsCStringContainer(bool check_pointer)728435933ddSDimitry Andric bool ValueObject::IsCStringContainer(bool check_pointer) {
7299f2f44ceSEd Maste CompilerType pointee_or_element_compiler_type;
7309f2f44ceSEd Maste const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
7317aa51b79SEd Maste bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
7329f2f44ceSEd Maste pointee_or_element_compiler_type.IsCharType());
733ac7ddfbfSEd Maste if (!is_char_arr_ptr)
734ac7ddfbfSEd Maste return false;
735ac7ddfbfSEd Maste if (!check_pointer)
736ac7ddfbfSEd Maste return true;
7377aa51b79SEd Maste if (type_flags.Test(eTypeIsArray))
738ac7ddfbfSEd Maste return true;
739ac7ddfbfSEd Maste addr_t cstr_address = LLDB_INVALID_ADDRESS;
740ac7ddfbfSEd Maste AddressType cstr_address_type = eAddressTypeInvalid;
741ac7ddfbfSEd Maste cstr_address = GetAddressOf(true, &cstr_address_type);
742ac7ddfbfSEd Maste return (cstr_address != LLDB_INVALID_ADDRESS);
743ac7ddfbfSEd Maste }
744ac7ddfbfSEd Maste
GetPointeeData(DataExtractor & data,uint32_t item_idx,uint32_t item_count)745435933ddSDimitry Andric size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
746435933ddSDimitry Andric uint32_t item_count) {
7479f2f44ceSEd Maste CompilerType pointee_or_element_compiler_type;
7489f2f44ceSEd Maste const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
7497aa51b79SEd Maste const bool is_pointer_type = type_info & eTypeIsPointer;
7507aa51b79SEd Maste const bool is_array_type = type_info & eTypeIsArray;
751ac7ddfbfSEd Maste if (!(is_pointer_type || is_array_type))
752ac7ddfbfSEd Maste return 0;
753ac7ddfbfSEd Maste
754ac7ddfbfSEd Maste if (item_count == 0)
755ac7ddfbfSEd Maste return 0;
756ac7ddfbfSEd Maste
7571c3bbb01SEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
7581c3bbb01SEd Maste
759*b5893f02SDimitry Andric llvm::Optional<uint64_t> item_type_size =
760*b5893f02SDimitry Andric pointee_or_element_compiler_type.GetByteSize(
761435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope());
762*b5893f02SDimitry Andric if (!item_type_size)
763*b5893f02SDimitry Andric return 0;
764*b5893f02SDimitry Andric const uint64_t bytes = item_count * *item_type_size;
765*b5893f02SDimitry Andric const uint64_t offset = item_idx * *item_type_size;
766ac7ddfbfSEd Maste
767ac7ddfbfSEd Maste if (item_idx == 0 && item_count == 1) // simply a deref
768ac7ddfbfSEd Maste {
769435933ddSDimitry Andric if (is_pointer_type) {
7705517e702SDimitry Andric Status error;
771ac7ddfbfSEd Maste ValueObjectSP pointee_sp = Dereference(error);
772ac7ddfbfSEd Maste if (error.Fail() || pointee_sp.get() == NULL)
773ac7ddfbfSEd Maste return 0;
7740127ef0fSEd Maste return pointee_sp->GetData(data, error);
775435933ddSDimitry Andric } else {
776ac7ddfbfSEd Maste ValueObjectSP child_sp = GetChildAtIndex(0, true);
777ac7ddfbfSEd Maste if (child_sp.get() == NULL)
778ac7ddfbfSEd Maste return 0;
7795517e702SDimitry Andric Status error;
7800127ef0fSEd Maste return child_sp->GetData(data, error);
781ac7ddfbfSEd Maste }
782ac7ddfbfSEd Maste return true;
783435933ddSDimitry Andric } else /* (items > 1) */
784ac7ddfbfSEd Maste {
7855517e702SDimitry Andric Status error;
786ac7ddfbfSEd Maste lldb_private::DataBufferHeap *heap_buf_ptr = NULL;
787435933ddSDimitry Andric lldb::DataBufferSP data_sp(heap_buf_ptr =
788435933ddSDimitry Andric new lldb_private::DataBufferHeap());
789ac7ddfbfSEd Maste
790ac7ddfbfSEd Maste AddressType addr_type;
791435933ddSDimitry Andric lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
792435933ddSDimitry Andric : GetAddressOf(true, &addr_type);
793ac7ddfbfSEd Maste
794435933ddSDimitry Andric switch (addr_type) {
795435933ddSDimitry Andric case eAddressTypeFile: {
796ac7ddfbfSEd Maste ModuleSP module_sp(GetModule());
797435933ddSDimitry Andric if (module_sp) {
798ac7ddfbfSEd Maste addr = addr + offset;
799ac7ddfbfSEd Maste Address so_addr;
800ac7ddfbfSEd Maste module_sp->ResolveFileAddress(addr, so_addr);
801ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
802ac7ddfbfSEd Maste Target *target = exe_ctx.GetTargetPtr();
803435933ddSDimitry Andric if (target) {
804ac7ddfbfSEd Maste heap_buf_ptr->SetByteSize(bytes);
805435933ddSDimitry Andric size_t bytes_read = target->ReadMemory(
806435933ddSDimitry Andric so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
807435933ddSDimitry Andric if (error.Success()) {
808ac7ddfbfSEd Maste data.SetData(data_sp);
809ac7ddfbfSEd Maste return bytes_read;
810ac7ddfbfSEd Maste }
811ac7ddfbfSEd Maste }
812ac7ddfbfSEd Maste }
813435933ddSDimitry Andric } break;
814435933ddSDimitry Andric case eAddressTypeLoad: {
815ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
816ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
817435933ddSDimitry Andric if (process) {
818ac7ddfbfSEd Maste heap_buf_ptr->SetByteSize(bytes);
819435933ddSDimitry Andric size_t bytes_read = process->ReadMemory(
820435933ddSDimitry Andric addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
821435933ddSDimitry Andric if (error.Success() || bytes_read > 0) {
822ac7ddfbfSEd Maste data.SetData(data_sp);
823ac7ddfbfSEd Maste return bytes_read;
824ac7ddfbfSEd Maste }
825ac7ddfbfSEd Maste }
826435933ddSDimitry Andric } break;
827435933ddSDimitry Andric case eAddressTypeHost: {
828*b5893f02SDimitry Andric auto max_bytes =
829435933ddSDimitry Andric GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
830*b5893f02SDimitry Andric if (max_bytes && *max_bytes > offset) {
831*b5893f02SDimitry Andric size_t bytes_read = std::min<uint64_t>(*max_bytes - offset, bytes);
8321c3bbb01SEd Maste addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
8339f2f44ceSEd Maste if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
8341c3bbb01SEd Maste break;
835ac7ddfbfSEd Maste heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
836ac7ddfbfSEd Maste data.SetData(data_sp);
837ac7ddfbfSEd Maste return bytes_read;
838ac7ddfbfSEd Maste }
839435933ddSDimitry Andric } break;
840ac7ddfbfSEd Maste case eAddressTypeInvalid:
841ac7ddfbfSEd Maste break;
842ac7ddfbfSEd Maste }
843ac7ddfbfSEd Maste }
844ac7ddfbfSEd Maste return 0;
845ac7ddfbfSEd Maste }
846ac7ddfbfSEd Maste
GetData(DataExtractor & data,Status & error)8475517e702SDimitry Andric uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
848ac7ddfbfSEd Maste UpdateValueIfNeeded(false);
849ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
8500127ef0fSEd Maste error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
851435933ddSDimitry Andric if (error.Fail()) {
852435933ddSDimitry Andric if (m_data.GetByteSize()) {
853ac7ddfbfSEd Maste data = m_data;
8549f2f44ceSEd Maste error.Clear();
855ac7ddfbfSEd Maste return data.GetByteSize();
856435933ddSDimitry Andric } else {
857ac7ddfbfSEd Maste return 0;
858ac7ddfbfSEd Maste }
859ac7ddfbfSEd Maste }
860ac7ddfbfSEd Maste data.SetAddressByteSize(m_data.GetAddressByteSize());
861ac7ddfbfSEd Maste data.SetByteOrder(m_data.GetByteOrder());
862ac7ddfbfSEd Maste return data.GetByteSize();
863ac7ddfbfSEd Maste }
864ac7ddfbfSEd Maste
SetData(DataExtractor & data,Status & error)8655517e702SDimitry Andric bool ValueObject::SetData(DataExtractor &data, Status &error) {
866ac7ddfbfSEd Maste error.Clear();
867ac7ddfbfSEd Maste // Make sure our value is up to date first so that our location and location
868ac7ddfbfSEd Maste // type is valid.
869435933ddSDimitry Andric if (!UpdateValueIfNeeded(false)) {
870ac7ddfbfSEd Maste error.SetErrorString("unable to read value");
871ac7ddfbfSEd Maste return false;
872ac7ddfbfSEd Maste }
873ac7ddfbfSEd Maste
874ac7ddfbfSEd Maste uint64_t count = 0;
8759f2f44ceSEd Maste const Encoding encoding = GetCompilerType().GetEncoding(count);
876ac7ddfbfSEd Maste
877ac7ddfbfSEd Maste const size_t byte_size = GetByteSize();
878ac7ddfbfSEd Maste
879ac7ddfbfSEd Maste Value::ValueType value_type = m_value.GetValueType();
880ac7ddfbfSEd Maste
881435933ddSDimitry Andric switch (value_type) {
882435933ddSDimitry Andric case Value::eValueTypeScalar: {
8835517e702SDimitry Andric Status set_error =
884435933ddSDimitry Andric m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
885ac7ddfbfSEd Maste
886435933ddSDimitry Andric if (!set_error.Success()) {
887435933ddSDimitry Andric error.SetErrorStringWithFormat("unable to set scalar value: %s",
888435933ddSDimitry Andric set_error.AsCString());
889ac7ddfbfSEd Maste return false;
890ac7ddfbfSEd Maste }
891435933ddSDimitry Andric } break;
892435933ddSDimitry Andric case Value::eValueTypeLoadAddress: {
893ac7ddfbfSEd Maste // If it is a load address, then the scalar value is the storage location
894ac7ddfbfSEd Maste // of the data, and we have to shove this value down to that load location.
895ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
896ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
897435933ddSDimitry Andric if (process) {
898ac7ddfbfSEd Maste addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
899435933ddSDimitry Andric size_t bytes_written = process->WriteMemory(
900435933ddSDimitry Andric target_addr, data.GetDataStart(), byte_size, error);
901ac7ddfbfSEd Maste if (!error.Success())
902ac7ddfbfSEd Maste return false;
903435933ddSDimitry Andric if (bytes_written != byte_size) {
904ac7ddfbfSEd Maste error.SetErrorString("unable to write value to memory");
905ac7ddfbfSEd Maste return false;
906ac7ddfbfSEd Maste }
907ac7ddfbfSEd Maste }
908435933ddSDimitry Andric } break;
909435933ddSDimitry Andric case Value::eValueTypeHostAddress: {
910435933ddSDimitry Andric // If it is a host address, then we stuff the scalar as a DataBuffer into
911435933ddSDimitry Andric // the Value's data.
912ac7ddfbfSEd Maste DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
913ac7ddfbfSEd Maste m_data.SetData(buffer_sp, 0);
914435933ddSDimitry Andric data.CopyByteOrderedData(0, byte_size,
915ac7ddfbfSEd Maste const_cast<uint8_t *>(m_data.GetDataStart()),
916435933ddSDimitry Andric byte_size, m_data.GetByteOrder());
917ac7ddfbfSEd Maste m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
918435933ddSDimitry Andric } break;
919ac7ddfbfSEd Maste case Value::eValueTypeFileAddress:
920ac7ddfbfSEd Maste case Value::eValueTypeVector:
921ac7ddfbfSEd Maste break;
922ac7ddfbfSEd Maste }
923ac7ddfbfSEd Maste
9244ba319b5SDimitry Andric // If we have reached this point, then we have successfully changed the
9254ba319b5SDimitry Andric // value.
926ac7ddfbfSEd Maste SetNeedsUpdate();
927ac7ddfbfSEd Maste return true;
928ac7ddfbfSEd Maste }
929ac7ddfbfSEd Maste
CopyStringDataToBufferSP(const StreamString & source,lldb::DataBufferSP & destination)930435933ddSDimitry Andric static bool CopyStringDataToBufferSP(const StreamString &source,
931435933ddSDimitry Andric lldb::DataBufferSP &destination) {
9327aa51b79SEd Maste destination.reset(new DataBufferHeap(source.GetSize() + 1, 0));
933435933ddSDimitry Andric memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize());
9347aa51b79SEd Maste return true;
9357aa51b79SEd Maste }
9367aa51b79SEd Maste
9379f2f44ceSEd Maste std::pair<size_t, bool>
ReadPointedString(lldb::DataBufferSP & buffer_sp,Status & error,uint32_t max_length,bool honor_array,Format item_format)9385517e702SDimitry Andric ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error,
939435933ddSDimitry Andric uint32_t max_length, bool honor_array,
940435933ddSDimitry Andric Format item_format) {
9419f2f44ceSEd Maste bool was_capped = false;
9427aa51b79SEd Maste StreamString s;
943ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
944ac7ddfbfSEd Maste Target *target = exe_ctx.GetTargetPtr();
945ac7ddfbfSEd Maste
946435933ddSDimitry Andric if (!target) {
947ac7ddfbfSEd Maste s << "<no target to read from>";
948ac7ddfbfSEd Maste error.SetErrorString("no target to read from");
9497aa51b79SEd Maste CopyStringDataToBufferSP(s, buffer_sp);
9509f2f44ceSEd Maste return {0, was_capped};
951ac7ddfbfSEd Maste }
952ac7ddfbfSEd Maste
953ac7ddfbfSEd Maste if (max_length == 0)
954ac7ddfbfSEd Maste max_length = target->GetMaximumSizeOfStringSummary();
955ac7ddfbfSEd Maste
956ac7ddfbfSEd Maste size_t bytes_read = 0;
957ac7ddfbfSEd Maste size_t total_bytes_read = 0;
958ac7ddfbfSEd Maste
9599f2f44ceSEd Maste CompilerType compiler_type = GetCompilerType();
9609f2f44ceSEd Maste CompilerType elem_or_pointee_compiler_type;
9619f2f44ceSEd Maste const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
9627aa51b79SEd Maste if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
963435933ddSDimitry Andric elem_or_pointee_compiler_type.IsCharType()) {
964ac7ddfbfSEd Maste addr_t cstr_address = LLDB_INVALID_ADDRESS;
965ac7ddfbfSEd Maste AddressType cstr_address_type = eAddressTypeInvalid;
966ac7ddfbfSEd Maste
967ac7ddfbfSEd Maste size_t cstr_len = 0;
968ac7ddfbfSEd Maste bool capped_data = false;
969435933ddSDimitry Andric const bool is_array = type_flags.Test(eTypeIsArray);
970435933ddSDimitry Andric if (is_array) {
971ac7ddfbfSEd Maste // We have an array
972ac7ddfbfSEd Maste uint64_t array_size = 0;
973435933ddSDimitry Andric if (compiler_type.IsArrayType(NULL, &array_size, NULL)) {
974ac7ddfbfSEd Maste cstr_len = array_size;
975435933ddSDimitry Andric if (cstr_len > max_length) {
976ac7ddfbfSEd Maste capped_data = true;
977ac7ddfbfSEd Maste cstr_len = max_length;
978ac7ddfbfSEd Maste }
979ac7ddfbfSEd Maste }
980ac7ddfbfSEd Maste cstr_address = GetAddressOf(true, &cstr_address_type);
981435933ddSDimitry Andric } else {
982ac7ddfbfSEd Maste // We have a pointer
983ac7ddfbfSEd Maste cstr_address = GetPointerValue(&cstr_address_type);
984ac7ddfbfSEd Maste }
985ac7ddfbfSEd Maste
986435933ddSDimitry Andric if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
987435933ddSDimitry Andric if (cstr_address_type == eAddressTypeHost && is_array) {
988435933ddSDimitry Andric const char *cstr = GetDataExtractor().PeekCStr(0);
989435933ddSDimitry Andric if (cstr == nullptr) {
990ac7ddfbfSEd Maste s << "<invalid address>";
991ac7ddfbfSEd Maste error.SetErrorString("invalid address");
9927aa51b79SEd Maste CopyStringDataToBufferSP(s, buffer_sp);
9939f2f44ceSEd Maste return {0, was_capped};
994ac7ddfbfSEd Maste }
995435933ddSDimitry Andric buffer_sp.reset(new DataBufferHeap(cstr_len, 0));
996435933ddSDimitry Andric memcpy(buffer_sp->GetBytes(), cstr, cstr_len);
997435933ddSDimitry Andric return {cstr_len, was_capped};
998435933ddSDimitry Andric } else {
999435933ddSDimitry Andric s << "<invalid address>";
1000435933ddSDimitry Andric error.SetErrorString("invalid address");
1001435933ddSDimitry Andric CopyStringDataToBufferSP(s, buffer_sp);
1002435933ddSDimitry Andric return {0, was_capped};
1003435933ddSDimitry Andric }
1004435933ddSDimitry Andric }
1005ac7ddfbfSEd Maste
1006ac7ddfbfSEd Maste Address cstr_so_addr(cstr_address);
1007ac7ddfbfSEd Maste DataExtractor data;
1008435933ddSDimitry Andric if (cstr_len > 0 && honor_array) {
1009435933ddSDimitry Andric // I am using GetPointeeData() here to abstract the fact that some
10104ba319b5SDimitry Andric // ValueObjects are actually frozen pointers in the host but the pointed-
10114ba319b5SDimitry Andric // to data lives in the debuggee, and GetPointeeData() automatically
10124ba319b5SDimitry Andric // takes care of this
1013ac7ddfbfSEd Maste GetPointeeData(data, 0, cstr_len);
1014ac7ddfbfSEd Maste
1015435933ddSDimitry Andric if ((bytes_read = data.GetByteSize()) > 0) {
1016ac7ddfbfSEd Maste total_bytes_read = bytes_read;
10177aa51b79SEd Maste for (size_t offset = 0; offset < bytes_read; offset++)
10187aa51b79SEd Maste s.Printf("%c", *data.PeekData(offset, 1));
1019ac7ddfbfSEd Maste if (capped_data)
10209f2f44ceSEd Maste was_capped = true;
1021ac7ddfbfSEd Maste }
1022435933ddSDimitry Andric } else {
1023ac7ddfbfSEd Maste cstr_len = max_length;
1024ac7ddfbfSEd Maste const size_t k_max_buf_size = 64;
1025ac7ddfbfSEd Maste
1026ac7ddfbfSEd Maste size_t offset = 0;
1027ac7ddfbfSEd Maste
1028ac7ddfbfSEd Maste int cstr_len_displayed = -1;
1029ac7ddfbfSEd Maste bool capped_cstr = false;
1030435933ddSDimitry Andric // I am using GetPointeeData() here to abstract the fact that some
10314ba319b5SDimitry Andric // ValueObjects are actually frozen pointers in the host but the pointed-
10324ba319b5SDimitry Andric // to data lives in the debuggee, and GetPointeeData() automatically
10334ba319b5SDimitry Andric // takes care of this
1034435933ddSDimitry Andric while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
1035ac7ddfbfSEd Maste total_bytes_read += bytes_read;
1036ac7ddfbfSEd Maste const char *cstr = data.PeekCStr(0);
10379f2f44ceSEd Maste size_t len = strnlen(cstr, k_max_buf_size);
1038ac7ddfbfSEd Maste if (cstr_len_displayed < 0)
1039ac7ddfbfSEd Maste cstr_len_displayed = len;
1040ac7ddfbfSEd Maste
1041ac7ddfbfSEd Maste if (len == 0)
1042ac7ddfbfSEd Maste break;
1043ac7ddfbfSEd Maste cstr_len_displayed += len;
1044ac7ddfbfSEd Maste if (len > bytes_read)
1045ac7ddfbfSEd Maste len = bytes_read;
1046ac7ddfbfSEd Maste if (len > cstr_len)
1047ac7ddfbfSEd Maste len = cstr_len;
1048ac7ddfbfSEd Maste
10497aa51b79SEd Maste for (size_t offset = 0; offset < bytes_read; offset++)
10507aa51b79SEd Maste s.Printf("%c", *data.PeekData(offset, 1));
1051ac7ddfbfSEd Maste
1052ac7ddfbfSEd Maste if (len < k_max_buf_size)
1053ac7ddfbfSEd Maste break;
1054ac7ddfbfSEd Maste
1055435933ddSDimitry Andric if (len >= cstr_len) {
1056ac7ddfbfSEd Maste capped_cstr = true;
1057ac7ddfbfSEd Maste break;
1058ac7ddfbfSEd Maste }
1059ac7ddfbfSEd Maste
1060ac7ddfbfSEd Maste cstr_len -= len;
1061ac7ddfbfSEd Maste offset += len;
1062ac7ddfbfSEd Maste }
1063ac7ddfbfSEd Maste
1064435933ddSDimitry Andric if (cstr_len_displayed >= 0) {
1065ac7ddfbfSEd Maste if (capped_cstr)
10669f2f44ceSEd Maste was_capped = true;
1067ac7ddfbfSEd Maste }
1068ac7ddfbfSEd Maste }
1069435933ddSDimitry Andric } else {
1070ac7ddfbfSEd Maste error.SetErrorString("not a string object");
1071ac7ddfbfSEd Maste s << "<not a string object>";
1072ac7ddfbfSEd Maste }
10737aa51b79SEd Maste CopyStringDataToBufferSP(s, buffer_sp);
10749f2f44ceSEd Maste return {total_bytes_read, was_capped};
1075ac7ddfbfSEd Maste }
1076ac7ddfbfSEd Maste
GetValidationStatus()1077435933ddSDimitry Andric std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() {
10787aa51b79SEd Maste if (!UpdateValueIfNeeded(true))
1079435933ddSDimitry Andric return {TypeValidatorResult::Success,
1080435933ddSDimitry Andric ""}; // not the validator's job to discuss update problems
10817aa51b79SEd Maste
10827aa51b79SEd Maste if (m_validation_result.hasValue())
10837aa51b79SEd Maste return m_validation_result.getValue();
10847aa51b79SEd Maste
10857aa51b79SEd Maste if (!m_type_validator_sp)
10867aa51b79SEd Maste return {TypeValidatorResult::Success, ""}; // no validator no failure
10877aa51b79SEd Maste
10887aa51b79SEd Maste auto outcome = m_type_validator_sp->FormatObject(this);
10897aa51b79SEd Maste
1090435933ddSDimitry Andric return (m_validation_result = {outcome.m_result, outcome.m_message})
1091435933ddSDimitry Andric .getValue();
10927aa51b79SEd Maste }
10937aa51b79SEd Maste
GetObjectDescription()1094435933ddSDimitry Andric const char *ValueObject::GetObjectDescription() {
1095ac7ddfbfSEd Maste
1096ac7ddfbfSEd Maste if (!UpdateValueIfNeeded(true))
1097ac7ddfbfSEd Maste return NULL;
1098ac7ddfbfSEd Maste
1099ac7ddfbfSEd Maste if (!m_object_desc_str.empty())
1100ac7ddfbfSEd Maste return m_object_desc_str.c_str();
1101ac7ddfbfSEd Maste
1102ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
1103ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
1104ac7ddfbfSEd Maste if (process == NULL)
1105ac7ddfbfSEd Maste return NULL;
1106ac7ddfbfSEd Maste
1107ac7ddfbfSEd Maste StreamString s;
1108ac7ddfbfSEd Maste
1109ac7ddfbfSEd Maste LanguageType language = GetObjectRuntimeLanguage();
1110ac7ddfbfSEd Maste LanguageRuntime *runtime = process->GetLanguageRuntime(language);
1111ac7ddfbfSEd Maste
1112435933ddSDimitry Andric if (runtime == NULL) {
1113435933ddSDimitry Andric // Aw, hell, if the things a pointer, or even just an integer, let's try
1114435933ddSDimitry Andric // ObjC anyway...
11159f2f44ceSEd Maste CompilerType compiler_type = GetCompilerType();
1116435933ddSDimitry Andric if (compiler_type) {
1117ac7ddfbfSEd Maste bool is_signed;
1118435933ddSDimitry Andric if (compiler_type.IsIntegerType(is_signed) ||
1119435933ddSDimitry Andric compiler_type.IsPointerType()) {
1120ac7ddfbfSEd Maste runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
1121ac7ddfbfSEd Maste }
1122ac7ddfbfSEd Maste }
1123ac7ddfbfSEd Maste }
1124ac7ddfbfSEd Maste
1125435933ddSDimitry Andric if (runtime && runtime->GetObjectDescription(s, *this)) {
1126435933ddSDimitry Andric m_object_desc_str.append(s.GetString());
1127ac7ddfbfSEd Maste }
1128ac7ddfbfSEd Maste
1129ac7ddfbfSEd Maste if (m_object_desc_str.empty())
1130ac7ddfbfSEd Maste return NULL;
1131ac7ddfbfSEd Maste else
1132ac7ddfbfSEd Maste return m_object_desc_str.c_str();
1133ac7ddfbfSEd Maste }
1134ac7ddfbfSEd Maste
GetValueAsCString(const lldb_private::TypeFormatImpl & format,std::string & destination)1135435933ddSDimitry Andric bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1136435933ddSDimitry Andric std::string &destination) {
113712b93ac6SEd Maste if (UpdateValueIfNeeded(false))
113812b93ac6SEd Maste return format.FormatObject(this, destination);
113912b93ac6SEd Maste else
114012b93ac6SEd Maste return false;
114112b93ac6SEd Maste }
114212b93ac6SEd Maste
GetValueAsCString(lldb::Format format,std::string & destination)1143435933ddSDimitry Andric bool ValueObject::GetValueAsCString(lldb::Format format,
1144435933ddSDimitry Andric std::string &destination) {
114512b93ac6SEd Maste return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1146ac7ddfbfSEd Maste }
1147ac7ddfbfSEd Maste
GetValueAsCString()1148435933ddSDimitry Andric const char *ValueObject::GetValueAsCString() {
1149435933ddSDimitry Andric if (UpdateValueIfNeeded(true)) {
115012b93ac6SEd Maste lldb::TypeFormatImplSP format_sp;
1151ac7ddfbfSEd Maste lldb::Format my_format = GetFormat();
1152435933ddSDimitry Andric if (my_format == lldb::eFormatDefault) {
1153ac7ddfbfSEd Maste if (m_type_format_sp)
115412b93ac6SEd Maste format_sp = m_type_format_sp;
1155435933ddSDimitry Andric else {
1156ac7ddfbfSEd Maste if (m_is_bitfield_for_scalar)
1157ac7ddfbfSEd Maste my_format = eFormatUnsigned;
1158435933ddSDimitry Andric else {
1159435933ddSDimitry Andric if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) {
1160ac7ddfbfSEd Maste const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1161ac7ddfbfSEd Maste if (reg_info)
1162ac7ddfbfSEd Maste my_format = reg_info->format;
1163435933ddSDimitry Andric } else {
11649f2f44ceSEd Maste my_format = GetValue().GetCompilerType().GetFormat();
1165ac7ddfbfSEd Maste }
1166ac7ddfbfSEd Maste }
1167ac7ddfbfSEd Maste }
1168ac7ddfbfSEd Maste }
1169435933ddSDimitry Andric if (my_format != m_last_format || m_value_str.empty()) {
1170ac7ddfbfSEd Maste m_last_format = my_format;
117112b93ac6SEd Maste if (!format_sp)
117212b93ac6SEd Maste format_sp.reset(new TypeFormatImpl_Format(my_format));
1173435933ddSDimitry Andric if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1174435933ddSDimitry Andric if (!m_value_did_change && m_old_value_valid) {
11754ba319b5SDimitry Andric // The value was gotten successfully, so we consider the value as
11764ba319b5SDimitry Andric // changed if the value string differs
1177ac7ddfbfSEd Maste SetValueDidChange(m_old_value_str != m_value_str);
1178ac7ddfbfSEd Maste }
1179ac7ddfbfSEd Maste }
1180ac7ddfbfSEd Maste }
1181ac7ddfbfSEd Maste }
1182ac7ddfbfSEd Maste if (m_value_str.empty())
1183ac7ddfbfSEd Maste return NULL;
1184ac7ddfbfSEd Maste return m_value_str.c_str();
1185ac7ddfbfSEd Maste }
1186ac7ddfbfSEd Maste
11874ba319b5SDimitry Andric // if > 8bytes, 0 is returned. this method should mostly be used to read
11884ba319b5SDimitry Andric // address values out of pointers
GetValueAsUnsigned(uint64_t fail_value,bool * success)1189435933ddSDimitry Andric uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1190ac7ddfbfSEd Maste // If our byte size is zero this is an aggregate type that has children
1191435933ddSDimitry Andric if (CanProvideValue()) {
1192ac7ddfbfSEd Maste Scalar scalar;
1193435933ddSDimitry Andric if (ResolveValue(scalar)) {
1194ac7ddfbfSEd Maste if (success)
1195ac7ddfbfSEd Maste *success = true;
1196ac7ddfbfSEd Maste return scalar.ULongLong(fail_value);
1197ac7ddfbfSEd Maste }
1198ac7ddfbfSEd Maste // fallthrough, otherwise...
1199ac7ddfbfSEd Maste }
1200ac7ddfbfSEd Maste
1201ac7ddfbfSEd Maste if (success)
1202ac7ddfbfSEd Maste *success = false;
1203ac7ddfbfSEd Maste return fail_value;
1204ac7ddfbfSEd Maste }
1205ac7ddfbfSEd Maste
GetValueAsSigned(int64_t fail_value,bool * success)1206435933ddSDimitry Andric int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
120735617911SEd Maste // If our byte size is zero this is an aggregate type that has children
1208435933ddSDimitry Andric if (CanProvideValue()) {
120935617911SEd Maste Scalar scalar;
1210435933ddSDimitry Andric if (ResolveValue(scalar)) {
121135617911SEd Maste if (success)
121235617911SEd Maste *success = true;
121335617911SEd Maste return scalar.SLongLong(fail_value);
121435617911SEd Maste }
121535617911SEd Maste // fallthrough, otherwise...
121635617911SEd Maste }
121735617911SEd Maste
121835617911SEd Maste if (success)
121935617911SEd Maste *success = false;
122035617911SEd Maste return fail_value;
122135617911SEd Maste }
122235617911SEd Maste
1223435933ddSDimitry Andric // if any more "special cases" are added to
12244ba319b5SDimitry Andric // ValueObject::DumpPrintableRepresentation() please keep this call up to date
12254ba319b5SDimitry Andric // by returning true for your new special cases. We will eventually move to
12264ba319b5SDimitry Andric // checking this call result before trying to display special cases
HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,Format custom_format)1227435933ddSDimitry Andric bool ValueObject::HasSpecialPrintableRepresentation(
1228435933ddSDimitry Andric ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1229ac7ddfbfSEd Maste Flags flags(GetTypeInfo());
1230435933ddSDimitry Andric if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1231435933ddSDimitry Andric val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1232ac7ddfbfSEd Maste if (IsCStringContainer(true) &&
1233435933ddSDimitry Andric (custom_format == eFormatCString || custom_format == eFormatCharArray ||
1234435933ddSDimitry Andric custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1235ac7ddfbfSEd Maste return true;
1236ac7ddfbfSEd Maste
1237435933ddSDimitry Andric if (flags.Test(eTypeIsArray)) {
1238ac7ddfbfSEd Maste if ((custom_format == eFormatBytes) ||
1239ac7ddfbfSEd Maste (custom_format == eFormatBytesWithASCII))
1240ac7ddfbfSEd Maste return true;
1241ac7ddfbfSEd Maste
1242ac7ddfbfSEd Maste if ((custom_format == eFormatVectorOfChar) ||
1243ac7ddfbfSEd Maste (custom_format == eFormatVectorOfFloat32) ||
1244ac7ddfbfSEd Maste (custom_format == eFormatVectorOfFloat64) ||
1245ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt16) ||
1246ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt32) ||
1247ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt64) ||
1248ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt8) ||
1249ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt128) ||
1250ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt16) ||
1251ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt32) ||
1252ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt64) ||
1253ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt8))
1254ac7ddfbfSEd Maste return true;
1255ac7ddfbfSEd Maste }
1256ac7ddfbfSEd Maste }
1257ac7ddfbfSEd Maste return false;
1258ac7ddfbfSEd Maste }
1259ac7ddfbfSEd Maste
DumpPrintableRepresentation(Stream & s,ValueObjectRepresentationStyle val_obj_display,Format custom_format,PrintableRepresentationSpecialCases special,bool do_dump_error)1260435933ddSDimitry Andric bool ValueObject::DumpPrintableRepresentation(
1261435933ddSDimitry Andric Stream &s, ValueObjectRepresentationStyle val_obj_display,
1262435933ddSDimitry Andric Format custom_format, PrintableRepresentationSpecialCases special,
1263435933ddSDimitry Andric bool do_dump_error) {
1264ac7ddfbfSEd Maste
1265ac7ddfbfSEd Maste Flags flags(GetTypeInfo());
1266ac7ddfbfSEd Maste
1267435933ddSDimitry Andric bool allow_special =
1268435933ddSDimitry Andric (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1269435933ddSDimitry Andric const bool only_special = false;
1270ac7ddfbfSEd Maste
1271435933ddSDimitry Andric if (allow_special) {
1272435933ddSDimitry Andric if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1273435933ddSDimitry Andric val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1274435933ddSDimitry Andric // when being asked to get a printable display an array or pointer type
12754ba319b5SDimitry Andric // directly, try to "do the right thing"
1276ac7ddfbfSEd Maste
1277ac7ddfbfSEd Maste if (IsCStringContainer(true) &&
1278ac7ddfbfSEd Maste (custom_format == eFormatCString ||
1279435933ddSDimitry Andric custom_format == eFormatCharArray || custom_format == eFormatChar ||
1280435933ddSDimitry Andric custom_format ==
1281435933ddSDimitry Andric eFormatVectorOfChar)) // print char[] & char* directly
1282ac7ddfbfSEd Maste {
12835517e702SDimitry Andric Status error;
12847aa51b79SEd Maste lldb::DataBufferSP buffer_sp;
1285435933ddSDimitry Andric std::pair<size_t, bool> read_string = ReadPointedString(
1286435933ddSDimitry Andric buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) ||
1287ac7ddfbfSEd Maste (custom_format == eFormatCharArray));
1288435933ddSDimitry Andric lldb_private::formatters::StringPrinter::
1289435933ddSDimitry Andric ReadBufferAndDumpToStreamOptions options(*this);
1290435933ddSDimitry Andric options.SetData(DataExtractor(
1291435933ddSDimitry Andric buffer_sp, lldb::eByteOrderInvalid,
1292435933ddSDimitry Andric 8)); // none of this matters for a string - pass some defaults
12937aa51b79SEd Maste options.SetStream(&s);
12947aa51b79SEd Maste options.SetPrefixToken(0);
12957aa51b79SEd Maste options.SetQuote('"');
12967aa51b79SEd Maste options.SetSourceSize(buffer_sp->GetByteSize());
12979f2f44ceSEd Maste options.SetIsTruncated(read_string.second);
1298435933ddSDimitry Andric formatters::StringPrinter::ReadBufferAndDumpToStream<
1299435933ddSDimitry Andric lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1300435933ddSDimitry Andric options);
1301ac7ddfbfSEd Maste return !error.Fail();
1302ac7ddfbfSEd Maste }
1303ac7ddfbfSEd Maste
1304ac7ddfbfSEd Maste if (custom_format == eFormatEnum)
1305ac7ddfbfSEd Maste return false;
1306ac7ddfbfSEd Maste
13074ba319b5SDimitry Andric // this only works for arrays, because I have no way to know when the
13084ba319b5SDimitry Andric // pointed memory ends, and no special \0 end of data marker
1309435933ddSDimitry Andric if (flags.Test(eTypeIsArray)) {
1310ac7ddfbfSEd Maste if ((custom_format == eFormatBytes) ||
1311435933ddSDimitry Andric (custom_format == eFormatBytesWithASCII)) {
1312ac7ddfbfSEd Maste const size_t count = GetNumChildren();
1313ac7ddfbfSEd Maste
1314ac7ddfbfSEd Maste s << '[';
1315435933ddSDimitry Andric for (size_t low = 0; low < count; low++) {
1316ac7ddfbfSEd Maste
1317ac7ddfbfSEd Maste if (low)
1318ac7ddfbfSEd Maste s << ',';
1319ac7ddfbfSEd Maste
1320ac7ddfbfSEd Maste ValueObjectSP child = GetChildAtIndex(low, true);
1321435933ddSDimitry Andric if (!child.get()) {
1322ac7ddfbfSEd Maste s << "<invalid child>";
1323ac7ddfbfSEd Maste continue;
1324ac7ddfbfSEd Maste }
1325435933ddSDimitry Andric child->DumpPrintableRepresentation(
1326435933ddSDimitry Andric s, ValueObject::eValueObjectRepresentationStyleValue,
1327435933ddSDimitry Andric custom_format);
1328ac7ddfbfSEd Maste }
1329ac7ddfbfSEd Maste
1330ac7ddfbfSEd Maste s << ']';
1331ac7ddfbfSEd Maste
1332ac7ddfbfSEd Maste return true;
1333ac7ddfbfSEd Maste }
1334ac7ddfbfSEd Maste
1335ac7ddfbfSEd Maste if ((custom_format == eFormatVectorOfChar) ||
1336ac7ddfbfSEd Maste (custom_format == eFormatVectorOfFloat32) ||
1337ac7ddfbfSEd Maste (custom_format == eFormatVectorOfFloat64) ||
1338ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt16) ||
1339ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt32) ||
1340ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt64) ||
1341ac7ddfbfSEd Maste (custom_format == eFormatVectorOfSInt8) ||
1342ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt128) ||
1343ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt16) ||
1344ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt32) ||
1345ac7ddfbfSEd Maste (custom_format == eFormatVectorOfUInt64) ||
1346435933ddSDimitry Andric (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1347435933ddSDimitry Andric // with ASCII or any vector
1348435933ddSDimitry Andric // format should be printed
1349435933ddSDimitry Andric // directly
1350ac7ddfbfSEd Maste {
1351ac7ddfbfSEd Maste const size_t count = GetNumChildren();
1352ac7ddfbfSEd Maste
1353ac7ddfbfSEd Maste Format format = FormatManager::GetSingleItemFormat(custom_format);
1354ac7ddfbfSEd Maste
1355ac7ddfbfSEd Maste s << '[';
1356435933ddSDimitry Andric for (size_t low = 0; low < count; low++) {
1357ac7ddfbfSEd Maste
1358ac7ddfbfSEd Maste if (low)
1359ac7ddfbfSEd Maste s << ',';
1360ac7ddfbfSEd Maste
1361ac7ddfbfSEd Maste ValueObjectSP child = GetChildAtIndex(low, true);
1362435933ddSDimitry Andric if (!child.get()) {
1363ac7ddfbfSEd Maste s << "<invalid child>";
1364ac7ddfbfSEd Maste continue;
1365ac7ddfbfSEd Maste }
1366435933ddSDimitry Andric child->DumpPrintableRepresentation(
1367435933ddSDimitry Andric s, ValueObject::eValueObjectRepresentationStyleValue, format);
1368ac7ddfbfSEd Maste }
1369ac7ddfbfSEd Maste
1370ac7ddfbfSEd Maste s << ']';
1371ac7ddfbfSEd Maste
1372ac7ddfbfSEd Maste return true;
1373ac7ddfbfSEd Maste }
1374ac7ddfbfSEd Maste }
1375ac7ddfbfSEd Maste
1376ac7ddfbfSEd Maste if ((custom_format == eFormatBoolean) ||
1377435933ddSDimitry Andric (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1378ac7ddfbfSEd Maste (custom_format == eFormatCharPrintable) ||
1379ac7ddfbfSEd Maste (custom_format == eFormatComplexFloat) ||
1380435933ddSDimitry Andric (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1381ac7ddfbfSEd Maste (custom_format == eFormatHexUppercase) ||
1382435933ddSDimitry Andric (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1383ac7ddfbfSEd Maste (custom_format == eFormatOSType) ||
1384ac7ddfbfSEd Maste (custom_format == eFormatUnicode16) ||
1385ac7ddfbfSEd Maste (custom_format == eFormatUnicode32) ||
1386ac7ddfbfSEd Maste (custom_format == eFormatUnsigned) ||
1387ac7ddfbfSEd Maste (custom_format == eFormatPointer) ||
1388ac7ddfbfSEd Maste (custom_format == eFormatComplexInteger) ||
1389ac7ddfbfSEd Maste (custom_format == eFormatComplex) ||
1390ac7ddfbfSEd Maste (custom_format == eFormatDefault)) // use the [] operator
1391ac7ddfbfSEd Maste return false;
1392ac7ddfbfSEd Maste }
1393ac7ddfbfSEd Maste }
1394ac7ddfbfSEd Maste
1395ac7ddfbfSEd Maste if (only_special)
1396ac7ddfbfSEd Maste return false;
1397ac7ddfbfSEd Maste
1398ac7ddfbfSEd Maste bool var_success = false;
1399ac7ddfbfSEd Maste
1400ac7ddfbfSEd Maste {
1401435933ddSDimitry Andric llvm::StringRef str;
1402ac7ddfbfSEd Maste
1403435933ddSDimitry Andric // this is a local stream that we are using to ensure that the data pointed
14044ba319b5SDimitry Andric // to by cstr survives long enough for us to copy it to its destination -
14054ba319b5SDimitry Andric // it is necessary to have this temporary storage area for cases where our
1406435933ddSDimitry Andric // desired output is not backed by some other longer-term storage
1407ac7ddfbfSEd Maste StreamString strm;
1408ac7ddfbfSEd Maste
1409ac7ddfbfSEd Maste if (custom_format != eFormatInvalid)
1410ac7ddfbfSEd Maste SetFormat(custom_format);
1411ac7ddfbfSEd Maste
1412435933ddSDimitry Andric switch (val_obj_display) {
1413ac7ddfbfSEd Maste case eValueObjectRepresentationStyleValue:
1414435933ddSDimitry Andric str = GetValueAsCString();
1415ac7ddfbfSEd Maste break;
1416ac7ddfbfSEd Maste
1417ac7ddfbfSEd Maste case eValueObjectRepresentationStyleSummary:
1418435933ddSDimitry Andric str = GetSummaryAsCString();
1419ac7ddfbfSEd Maste break;
1420ac7ddfbfSEd Maste
1421ac7ddfbfSEd Maste case eValueObjectRepresentationStyleLanguageSpecific:
1422435933ddSDimitry Andric str = GetObjectDescription();
1423ac7ddfbfSEd Maste break;
1424ac7ddfbfSEd Maste
1425ac7ddfbfSEd Maste case eValueObjectRepresentationStyleLocation:
1426435933ddSDimitry Andric str = GetLocationAsCString();
1427ac7ddfbfSEd Maste break;
1428ac7ddfbfSEd Maste
1429ac7ddfbfSEd Maste case eValueObjectRepresentationStyleChildrenCount:
14300127ef0fSEd Maste strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
1431435933ddSDimitry Andric str = strm.GetString();
1432ac7ddfbfSEd Maste break;
1433ac7ddfbfSEd Maste
1434ac7ddfbfSEd Maste case eValueObjectRepresentationStyleType:
1435435933ddSDimitry Andric str = GetTypeName().GetStringRef();
1436ac7ddfbfSEd Maste break;
1437ac7ddfbfSEd Maste
1438ac7ddfbfSEd Maste case eValueObjectRepresentationStyleName:
1439435933ddSDimitry Andric str = GetName().GetStringRef();
1440ac7ddfbfSEd Maste break;
1441ac7ddfbfSEd Maste
1442ac7ddfbfSEd Maste case eValueObjectRepresentationStyleExpressionPath:
1443ac7ddfbfSEd Maste GetExpressionPath(strm, false);
1444435933ddSDimitry Andric str = strm.GetString();
1445ac7ddfbfSEd Maste break;
1446ac7ddfbfSEd Maste }
1447ac7ddfbfSEd Maste
1448435933ddSDimitry Andric if (str.empty()) {
1449ac7ddfbfSEd Maste if (val_obj_display == eValueObjectRepresentationStyleValue)
1450435933ddSDimitry Andric str = GetSummaryAsCString();
1451435933ddSDimitry Andric else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1452435933ddSDimitry Andric if (!CanProvideValue()) {
1453435933ddSDimitry Andric strm.Printf("%s @ %s", GetTypeName().AsCString(),
1454435933ddSDimitry Andric GetLocationAsCString());
1455435933ddSDimitry Andric str = strm.GetString();
1456435933ddSDimitry Andric } else
1457435933ddSDimitry Andric str = GetValueAsCString();
1458ac7ddfbfSEd Maste }
1459ac7ddfbfSEd Maste }
1460ac7ddfbfSEd Maste
1461435933ddSDimitry Andric if (!str.empty())
1462435933ddSDimitry Andric s << str;
1463435933ddSDimitry Andric else {
1464435933ddSDimitry Andric if (m_error.Fail()) {
146512b93ac6SEd Maste if (do_dump_error)
1466ac7ddfbfSEd Maste s.Printf("<%s>", m_error.AsCString());
146712b93ac6SEd Maste else
146812b93ac6SEd Maste return false;
1469435933ddSDimitry Andric } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1470ac7ddfbfSEd Maste s.PutCString("<no summary available>");
1471ac7ddfbfSEd Maste else if (val_obj_display == eValueObjectRepresentationStyleValue)
1472ac7ddfbfSEd Maste s.PutCString("<no value available>");
1473435933ddSDimitry Andric else if (val_obj_display ==
1474435933ddSDimitry Andric eValueObjectRepresentationStyleLanguageSpecific)
1475435933ddSDimitry Andric s.PutCString("<not a valid Objective-C object>"); // edit this if we
1476435933ddSDimitry Andric // have other runtimes
1477435933ddSDimitry Andric // that support a
1478435933ddSDimitry Andric // description
1479ac7ddfbfSEd Maste else
1480ac7ddfbfSEd Maste s.PutCString("<no printable representation>");
1481ac7ddfbfSEd Maste }
1482ac7ddfbfSEd Maste
14834ba319b5SDimitry Andric // we should only return false here if we could not do *anything* even if
14844ba319b5SDimitry Andric // we have an error message as output, that's a success from our callers'
14854ba319b5SDimitry Andric // perspective, so return true
1486ac7ddfbfSEd Maste var_success = true;
1487ac7ddfbfSEd Maste
1488ac7ddfbfSEd Maste if (custom_format != eFormatInvalid)
1489ac7ddfbfSEd Maste SetFormat(eFormatDefault);
1490ac7ddfbfSEd Maste }
1491ac7ddfbfSEd Maste
1492ac7ddfbfSEd Maste return var_success;
1493ac7ddfbfSEd Maste }
1494ac7ddfbfSEd Maste
GetAddressOf(bool scalar_is_load_address,AddressType * address_type)1495435933ddSDimitry Andric addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1496435933ddSDimitry Andric AddressType *address_type) {
14974bb0738eSEd Maste // Can't take address of a bitfield
14984bb0738eSEd Maste if (IsBitfield())
14994bb0738eSEd Maste return LLDB_INVALID_ADDRESS;
15004bb0738eSEd Maste
1501ac7ddfbfSEd Maste if (!UpdateValueIfNeeded(false))
1502ac7ddfbfSEd Maste return LLDB_INVALID_ADDRESS;
1503ac7ddfbfSEd Maste
1504435933ddSDimitry Andric switch (m_value.GetValueType()) {
1505ac7ddfbfSEd Maste case Value::eValueTypeScalar:
1506ac7ddfbfSEd Maste case Value::eValueTypeVector:
1507435933ddSDimitry Andric if (scalar_is_load_address) {
1508ac7ddfbfSEd Maste if (address_type)
1509ac7ddfbfSEd Maste *address_type = eAddressTypeLoad;
1510ac7ddfbfSEd Maste return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1511ac7ddfbfSEd Maste }
1512ac7ddfbfSEd Maste break;
1513ac7ddfbfSEd Maste
1514ac7ddfbfSEd Maste case Value::eValueTypeLoadAddress:
1515435933ddSDimitry Andric case Value::eValueTypeFileAddress: {
1516ac7ddfbfSEd Maste if (address_type)
1517ac7ddfbfSEd Maste *address_type = m_value.GetValueAddressType();
1518ac7ddfbfSEd Maste return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1519435933ddSDimitry Andric } break;
1520435933ddSDimitry Andric case Value::eValueTypeHostAddress: {
15211c3bbb01SEd Maste if (address_type)
15221c3bbb01SEd Maste *address_type = m_value.GetValueAddressType();
15231c3bbb01SEd Maste return LLDB_INVALID_ADDRESS;
1524435933ddSDimitry Andric } break;
1525ac7ddfbfSEd Maste }
1526ac7ddfbfSEd Maste if (address_type)
1527ac7ddfbfSEd Maste *address_type = eAddressTypeInvalid;
1528ac7ddfbfSEd Maste return LLDB_INVALID_ADDRESS;
1529ac7ddfbfSEd Maste }
1530ac7ddfbfSEd Maste
GetPointerValue(AddressType * address_type)1531435933ddSDimitry Andric addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1532ac7ddfbfSEd Maste addr_t address = LLDB_INVALID_ADDRESS;
1533ac7ddfbfSEd Maste if (address_type)
1534ac7ddfbfSEd Maste *address_type = eAddressTypeInvalid;
1535ac7ddfbfSEd Maste
1536ac7ddfbfSEd Maste if (!UpdateValueIfNeeded(false))
1537ac7ddfbfSEd Maste return address;
1538ac7ddfbfSEd Maste
1539435933ddSDimitry Andric switch (m_value.GetValueType()) {
1540ac7ddfbfSEd Maste case Value::eValueTypeScalar:
1541ac7ddfbfSEd Maste case Value::eValueTypeVector:
1542ac7ddfbfSEd Maste address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1543ac7ddfbfSEd Maste break;
1544ac7ddfbfSEd Maste
1545ac7ddfbfSEd Maste case Value::eValueTypeHostAddress:
1546ac7ddfbfSEd Maste case Value::eValueTypeLoadAddress:
1547435933ddSDimitry Andric case Value::eValueTypeFileAddress: {
1548ac7ddfbfSEd Maste lldb::offset_t data_offset = 0;
1549ac7ddfbfSEd Maste address = m_data.GetPointer(&data_offset);
1550435933ddSDimitry Andric } break;
1551ac7ddfbfSEd Maste }
1552ac7ddfbfSEd Maste
1553ac7ddfbfSEd Maste if (address_type)
1554ac7ddfbfSEd Maste *address_type = GetAddressTypeOfChildren();
1555ac7ddfbfSEd Maste
1556ac7ddfbfSEd Maste return address;
1557ac7ddfbfSEd Maste }
1558ac7ddfbfSEd Maste
SetValueFromCString(const char * value_str,Status & error)15595517e702SDimitry Andric bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
1560ac7ddfbfSEd Maste error.Clear();
1561ac7ddfbfSEd Maste // Make sure our value is up to date first so that our location and location
1562ac7ddfbfSEd Maste // type is valid.
1563435933ddSDimitry Andric if (!UpdateValueIfNeeded(false)) {
1564ac7ddfbfSEd Maste error.SetErrorString("unable to read value");
1565ac7ddfbfSEd Maste return false;
1566ac7ddfbfSEd Maste }
1567ac7ddfbfSEd Maste
1568ac7ddfbfSEd Maste uint64_t count = 0;
15699f2f44ceSEd Maste const Encoding encoding = GetCompilerType().GetEncoding(count);
1570ac7ddfbfSEd Maste
1571ac7ddfbfSEd Maste const size_t byte_size = GetByteSize();
1572ac7ddfbfSEd Maste
1573ac7ddfbfSEd Maste Value::ValueType value_type = m_value.GetValueType();
1574ac7ddfbfSEd Maste
1575435933ddSDimitry Andric if (value_type == Value::eValueTypeScalar) {
1576ac7ddfbfSEd Maste // If the value is already a scalar, then let the scalar change itself:
1577ac7ddfbfSEd Maste m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1578435933ddSDimitry Andric } else if (byte_size <= 16) {
1579ac7ddfbfSEd Maste // If the value fits in a scalar, then make a new scalar and again let the
1580435933ddSDimitry Andric // scalar code do the conversion, then figure out where to put the new
1581435933ddSDimitry Andric // value.
1582ac7ddfbfSEd Maste Scalar new_scalar;
1583ac7ddfbfSEd Maste error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1584435933ddSDimitry Andric if (error.Success()) {
1585435933ddSDimitry Andric switch (value_type) {
1586435933ddSDimitry Andric case Value::eValueTypeLoadAddress: {
1587435933ddSDimitry Andric // If it is a load address, then the scalar value is the storage
15884ba319b5SDimitry Andric // location of the data, and we have to shove this value down to that
15894ba319b5SDimitry Andric // load location.
1590ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
1591ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
1592435933ddSDimitry Andric if (process) {
1593435933ddSDimitry Andric addr_t target_addr =
1594435933ddSDimitry Andric m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1595435933ddSDimitry Andric size_t bytes_written = process->WriteScalarToMemory(
1596435933ddSDimitry Andric target_addr, new_scalar, byte_size, error);
1597ac7ddfbfSEd Maste if (!error.Success())
1598ac7ddfbfSEd Maste return false;
1599435933ddSDimitry Andric if (bytes_written != byte_size) {
1600ac7ddfbfSEd Maste error.SetErrorString("unable to write value to memory");
1601ac7ddfbfSEd Maste return false;
1602ac7ddfbfSEd Maste }
1603ac7ddfbfSEd Maste }
1604435933ddSDimitry Andric } break;
1605435933ddSDimitry Andric case Value::eValueTypeHostAddress: {
1606435933ddSDimitry Andric // If it is a host address, then we stuff the scalar as a DataBuffer
1607435933ddSDimitry Andric // into the Value's data.
1608ac7ddfbfSEd Maste DataExtractor new_data;
1609ac7ddfbfSEd Maste new_data.SetByteOrder(m_data.GetByteOrder());
1610ac7ddfbfSEd Maste
1611ac7ddfbfSEd Maste DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1612ac7ddfbfSEd Maste m_data.SetData(buffer_sp, 0);
1613ac7ddfbfSEd Maste bool success = new_scalar.GetData(new_data);
1614435933ddSDimitry Andric if (success) {
1615435933ddSDimitry Andric new_data.CopyByteOrderedData(
1616435933ddSDimitry Andric 0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1617435933ddSDimitry Andric byte_size, m_data.GetByteOrder());
1618ac7ddfbfSEd Maste }
1619ac7ddfbfSEd Maste m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1620ac7ddfbfSEd Maste
1621435933ddSDimitry Andric } break;
1622ac7ddfbfSEd Maste case Value::eValueTypeFileAddress:
1623ac7ddfbfSEd Maste case Value::eValueTypeScalar:
1624ac7ddfbfSEd Maste case Value::eValueTypeVector:
1625ac7ddfbfSEd Maste break;
1626ac7ddfbfSEd Maste }
1627435933ddSDimitry Andric } else {
1628ac7ddfbfSEd Maste return false;
1629ac7ddfbfSEd Maste }
1630435933ddSDimitry Andric } else {
1631ac7ddfbfSEd Maste // We don't support setting things bigger than a scalar at present.
1632ac7ddfbfSEd Maste error.SetErrorString("unable to write aggregate data type");
1633ac7ddfbfSEd Maste return false;
1634ac7ddfbfSEd Maste }
1635ac7ddfbfSEd Maste
16364ba319b5SDimitry Andric // If we have reached this point, then we have successfully changed the
16374ba319b5SDimitry Andric // value.
1638ac7ddfbfSEd Maste SetNeedsUpdate();
1639ac7ddfbfSEd Maste return true;
1640ac7ddfbfSEd Maste }
1641ac7ddfbfSEd Maste
GetDeclaration(Declaration & decl)1642435933ddSDimitry Andric bool ValueObject::GetDeclaration(Declaration &decl) {
1643ac7ddfbfSEd Maste decl.Clear();
1644ac7ddfbfSEd Maste return false;
1645ac7ddfbfSEd Maste }
1646ac7ddfbfSEd Maste
GetTypeName()1647435933ddSDimitry Andric ConstString ValueObject::GetTypeName() {
16489f2f44ceSEd Maste return GetCompilerType().GetConstTypeName();
1649ac7ddfbfSEd Maste }
1650ac7ddfbfSEd Maste
GetDisplayTypeName()1651435933ddSDimitry Andric ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); }
16520127ef0fSEd Maste
GetQualifiedTypeName()1653435933ddSDimitry Andric ConstString ValueObject::GetQualifiedTypeName() {
16549f2f44ceSEd Maste return GetCompilerType().GetConstQualifiedTypeName();
1655ac7ddfbfSEd Maste }
1656ac7ddfbfSEd Maste
GetObjectRuntimeLanguage()1657435933ddSDimitry Andric LanguageType ValueObject::GetObjectRuntimeLanguage() {
16589f2f44ceSEd Maste return GetCompilerType().GetMinimumLanguage();
1659ac7ddfbfSEd Maste }
1660ac7ddfbfSEd Maste
AddSyntheticChild(const ConstString & key,ValueObject * valobj)1661435933ddSDimitry Andric void ValueObject::AddSyntheticChild(const ConstString &key,
1662435933ddSDimitry Andric ValueObject *valobj) {
1663ac7ddfbfSEd Maste m_synthetic_children[key] = valobj;
1664ac7ddfbfSEd Maste }
1665ac7ddfbfSEd Maste
GetSyntheticChild(const ConstString & key) const1666435933ddSDimitry Andric ValueObjectSP ValueObject::GetSyntheticChild(const ConstString &key) const {
1667ac7ddfbfSEd Maste ValueObjectSP synthetic_child_sp;
1668435933ddSDimitry Andric std::map<ConstString, ValueObject *>::const_iterator pos =
1669435933ddSDimitry Andric m_synthetic_children.find(key);
1670ac7ddfbfSEd Maste if (pos != m_synthetic_children.end())
1671ac7ddfbfSEd Maste synthetic_child_sp = pos->second->GetSP();
1672ac7ddfbfSEd Maste return synthetic_child_sp;
1673ac7ddfbfSEd Maste }
1674ac7ddfbfSEd Maste
1675ac7ddfbfSEd Maste uint32_t
GetTypeInfo(CompilerType * pointee_or_element_compiler_type)1676435933ddSDimitry Andric ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) {
16779f2f44ceSEd Maste return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
1678ac7ddfbfSEd Maste }
1679ac7ddfbfSEd Maste
IsPointerType()1680435933ddSDimitry Andric bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); }
1681ac7ddfbfSEd Maste
IsArrayType()1682435933ddSDimitry Andric bool ValueObject::IsArrayType() {
16839f2f44ceSEd Maste return GetCompilerType().IsArrayType(NULL, NULL, NULL);
1684ac7ddfbfSEd Maste }
1685ac7ddfbfSEd Maste
IsScalarType()1686435933ddSDimitry Andric bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); }
1687ac7ddfbfSEd Maste
IsIntegerType(bool & is_signed)1688435933ddSDimitry Andric bool ValueObject::IsIntegerType(bool &is_signed) {
16899f2f44ceSEd Maste return GetCompilerType().IsIntegerType(is_signed);
1690ac7ddfbfSEd Maste }
1691ac7ddfbfSEd Maste
IsPointerOrReferenceType()1692435933ddSDimitry Andric bool ValueObject::IsPointerOrReferenceType() {
16939f2f44ceSEd Maste return GetCompilerType().IsPointerOrReferenceType();
1694ac7ddfbfSEd Maste }
1695ac7ddfbfSEd Maste
IsPossibleDynamicType()1696435933ddSDimitry Andric bool ValueObject::IsPossibleDynamicType() {
1697ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
1698ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
1699ac7ddfbfSEd Maste if (process)
1700ac7ddfbfSEd Maste return process->IsPossibleDynamicValue(*this);
1701ac7ddfbfSEd Maste else
17029f2f44ceSEd Maste return GetCompilerType().IsPossibleDynamicType(NULL, true, true);
1703ac7ddfbfSEd Maste }
1704ac7ddfbfSEd Maste
IsRuntimeSupportValue()1705435933ddSDimitry Andric bool ValueObject::IsRuntimeSupportValue() {
17061c3bbb01SEd Maste Process *process(GetProcessSP().get());
1707435933ddSDimitry Andric if (process) {
1708435933ddSDimitry Andric LanguageRuntime *runtime =
1709435933ddSDimitry Andric process->GetLanguageRuntime(GetObjectRuntimeLanguage());
17101c3bbb01SEd Maste if (!runtime)
17111c3bbb01SEd Maste runtime = process->GetObjCLanguageRuntime();
17121c3bbb01SEd Maste if (runtime)
17131c3bbb01SEd Maste return runtime->IsRuntimeSupportValue(*this);
17141c3bbb01SEd Maste }
17151c3bbb01SEd Maste return false;
17161c3bbb01SEd Maste }
17171c3bbb01SEd Maste
IsNilReference()1718435933ddSDimitry Andric bool ValueObject::IsNilReference() {
1719435933ddSDimitry Andric if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
17209f2f44ceSEd Maste return language->IsNilReference(*this);
17219f2f44ceSEd Maste }
1722ac7ddfbfSEd Maste return false;
17239f2f44ceSEd Maste }
17249f2f44ceSEd Maste
IsUninitializedReference()1725435933ddSDimitry Andric bool ValueObject::IsUninitializedReference() {
1726435933ddSDimitry Andric if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
17279f2f44ceSEd Maste return language->IsUninitializedReference(*this);
17289f2f44ceSEd Maste }
17299f2f44ceSEd Maste return false;
1730ac7ddfbfSEd Maste }
1731ac7ddfbfSEd Maste
17324ba319b5SDimitry Andric // This allows you to create an array member using and index that doesn't not
17334ba319b5SDimitry Andric // fall in the normal bounds of the array. Many times structure can be defined
17344ba319b5SDimitry Andric // as: struct Collection {
1735ac7ddfbfSEd Maste // uint32_t item_count;
1736ac7ddfbfSEd Maste // Item item_array[0];
1737ac7ddfbfSEd Maste // };
17384ba319b5SDimitry Andric // The size of the "item_array" is 1, but many times in practice there are more
17394ba319b5SDimitry Andric // items in "item_array".
1740ac7ddfbfSEd Maste
GetSyntheticArrayMember(size_t index,bool can_create)1741435933ddSDimitry Andric ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1742435933ddSDimitry Andric bool can_create) {
1743ac7ddfbfSEd Maste ValueObjectSP synthetic_child_sp;
1744435933ddSDimitry Andric if (IsPointerType() || IsArrayType()) {
1745ac7ddfbfSEd Maste char index_str[64];
17460127ef0fSEd Maste snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
1747ac7ddfbfSEd Maste ConstString index_const_str(index_str);
17484ba319b5SDimitry Andric // Check if we have already created a synthetic array member in this valid
17494ba319b5SDimitry Andric // object. If we have we will re-use it.
1750ac7ddfbfSEd Maste synthetic_child_sp = GetSyntheticChild(index_const_str);
1751435933ddSDimitry Andric if (!synthetic_child_sp) {
1752ac7ddfbfSEd Maste ValueObject *synthetic_child;
17534ba319b5SDimitry Andric // We haven't made a synthetic array member for INDEX yet, so lets make
17544ba319b5SDimitry Andric // one and cache it for any future reference.
1755ac7ddfbfSEd Maste synthetic_child = CreateChildAtIndex(0, true, index);
1756ac7ddfbfSEd Maste
1757ac7ddfbfSEd Maste // Cache the value if we got one back...
1758435933ddSDimitry Andric if (synthetic_child) {
1759ac7ddfbfSEd Maste AddSyntheticChild(index_const_str, synthetic_child);
1760ac7ddfbfSEd Maste synthetic_child_sp = synthetic_child->GetSP();
1761ac7ddfbfSEd Maste synthetic_child_sp->SetName(ConstString(index_str));
1762ac7ddfbfSEd Maste synthetic_child_sp->m_is_array_item_for_pointer = true;
1763ac7ddfbfSEd Maste }
1764ac7ddfbfSEd Maste }
1765ac7ddfbfSEd Maste }
1766ac7ddfbfSEd Maste return synthetic_child_sp;
1767ac7ddfbfSEd Maste }
1768ac7ddfbfSEd Maste
GetSyntheticBitFieldChild(uint32_t from,uint32_t to,bool can_create)1769435933ddSDimitry Andric ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1770435933ddSDimitry Andric bool can_create) {
1771ac7ddfbfSEd Maste ValueObjectSP synthetic_child_sp;
1772435933ddSDimitry Andric if (IsScalarType()) {
1773ac7ddfbfSEd Maste char index_str[64];
1774ac7ddfbfSEd Maste snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
1775ac7ddfbfSEd Maste ConstString index_const_str(index_str);
17764ba319b5SDimitry Andric // Check if we have already created a synthetic array member in this valid
17774ba319b5SDimitry Andric // object. If we have we will re-use it.
1778ac7ddfbfSEd Maste synthetic_child_sp = GetSyntheticChild(index_const_str);
1779435933ddSDimitry Andric if (!synthetic_child_sp) {
17804bb0738eSEd Maste uint32_t bit_field_size = to - from + 1;
17814bb0738eSEd Maste uint32_t bit_field_offset = from;
17824bb0738eSEd Maste if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1783435933ddSDimitry Andric bit_field_offset =
1784435933ddSDimitry Andric GetByteSize() * 8 - bit_field_size - bit_field_offset;
17854ba319b5SDimitry Andric // We haven't made a synthetic array member for INDEX yet, so lets make
17864ba319b5SDimitry Andric // one and cache it for any future reference.
1787435933ddSDimitry Andric ValueObjectChild *synthetic_child = new ValueObjectChild(
1788435933ddSDimitry Andric *this, GetCompilerType(), index_const_str, GetByteSize(), 0,
1789435933ddSDimitry Andric bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
17909f2f44ceSEd Maste 0);
1791ac7ddfbfSEd Maste
1792ac7ddfbfSEd Maste // Cache the value if we got one back...
1793435933ddSDimitry Andric if (synthetic_child) {
1794ac7ddfbfSEd Maste AddSyntheticChild(index_const_str, synthetic_child);
1795ac7ddfbfSEd Maste synthetic_child_sp = synthetic_child->GetSP();
1796ac7ddfbfSEd Maste synthetic_child_sp->SetName(ConstString(index_str));
1797ac7ddfbfSEd Maste synthetic_child_sp->m_is_bitfield_for_scalar = true;
1798ac7ddfbfSEd Maste }
1799ac7ddfbfSEd Maste }
1800ac7ddfbfSEd Maste }
1801ac7ddfbfSEd Maste return synthetic_child_sp;
1802ac7ddfbfSEd Maste }
1803ac7ddfbfSEd Maste
GetSyntheticChildAtOffset(uint32_t offset,const CompilerType & type,bool can_create,ConstString name_const_str)1804435933ddSDimitry Andric ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1805435933ddSDimitry Andric uint32_t offset, const CompilerType &type, bool can_create,
1806435933ddSDimitry Andric ConstString name_const_str) {
1807ac7ddfbfSEd Maste
1808ac7ddfbfSEd Maste ValueObjectSP synthetic_child_sp;
1809ac7ddfbfSEd Maste
1810435933ddSDimitry Andric if (name_const_str.IsEmpty()) {
1811ac7ddfbfSEd Maste char name_str[64];
1812ac7ddfbfSEd Maste snprintf(name_str, sizeof(name_str), "@%i", offset);
18134bb0738eSEd Maste name_const_str.SetCString(name_str);
18144bb0738eSEd Maste }
1815ac7ddfbfSEd Maste
18164ba319b5SDimitry Andric // Check if we have already created a synthetic array member in this valid
18174ba319b5SDimitry Andric // object. If we have we will re-use it.
1818ac7ddfbfSEd Maste synthetic_child_sp = GetSyntheticChild(name_const_str);
1819ac7ddfbfSEd Maste
1820ac7ddfbfSEd Maste if (synthetic_child_sp.get())
1821ac7ddfbfSEd Maste return synthetic_child_sp;
1822ac7ddfbfSEd Maste
1823ac7ddfbfSEd Maste if (!can_create)
1824*b5893f02SDimitry Andric return {};
1825ac7ddfbfSEd Maste
18261c3bbb01SEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
1827*b5893f02SDimitry Andric llvm::Optional<uint64_t> size =
1828*b5893f02SDimitry Andric type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1829*b5893f02SDimitry Andric if (!size)
1830*b5893f02SDimitry Andric return {};
1831*b5893f02SDimitry Andric ValueObjectChild *synthetic_child =
1832*b5893f02SDimitry Andric new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1833435933ddSDimitry Andric false, false, eAddressTypeInvalid, 0);
1834435933ddSDimitry Andric if (synthetic_child) {
1835ac7ddfbfSEd Maste AddSyntheticChild(name_const_str, synthetic_child);
1836ac7ddfbfSEd Maste synthetic_child_sp = synthetic_child->GetSP();
1837ac7ddfbfSEd Maste synthetic_child_sp->SetName(name_const_str);
1838ac7ddfbfSEd Maste synthetic_child_sp->m_is_child_at_offset = true;
1839ac7ddfbfSEd Maste }
1840ac7ddfbfSEd Maste return synthetic_child_sp;
1841ac7ddfbfSEd Maste }
1842ac7ddfbfSEd Maste
GetSyntheticBase(uint32_t offset,const CompilerType & type,bool can_create,ConstString name_const_str)1843435933ddSDimitry Andric ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
18444bb0738eSEd Maste const CompilerType &type,
18454bb0738eSEd Maste bool can_create,
1846435933ddSDimitry Andric ConstString name_const_str) {
18470127ef0fSEd Maste ValueObjectSP synthetic_child_sp;
18480127ef0fSEd Maste
1849435933ddSDimitry Andric if (name_const_str.IsEmpty()) {
18504bb0738eSEd Maste char name_str[128];
1851435933ddSDimitry Andric snprintf(name_str, sizeof(name_str), "base%s@%i",
1852435933ddSDimitry Andric type.GetTypeName().AsCString("<unknown>"), offset);
18534bb0738eSEd Maste name_const_str.SetCString(name_str);
18544bb0738eSEd Maste }
18550127ef0fSEd Maste
18564ba319b5SDimitry Andric // Check if we have already created a synthetic array member in this valid
18574ba319b5SDimitry Andric // object. If we have we will re-use it.
18580127ef0fSEd Maste synthetic_child_sp = GetSyntheticChild(name_const_str);
18590127ef0fSEd Maste
18600127ef0fSEd Maste if (synthetic_child_sp.get())
18610127ef0fSEd Maste return synthetic_child_sp;
18620127ef0fSEd Maste
18630127ef0fSEd Maste if (!can_create)
1864*b5893f02SDimitry Andric return {};
18650127ef0fSEd Maste
18660127ef0fSEd Maste const bool is_base_class = true;
18670127ef0fSEd Maste
18681c3bbb01SEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
1869*b5893f02SDimitry Andric llvm::Optional<uint64_t> size =
1870*b5893f02SDimitry Andric type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1871*b5893f02SDimitry Andric if (!size)
1872*b5893f02SDimitry Andric return {};
1873*b5893f02SDimitry Andric ValueObjectChild *synthetic_child =
1874*b5893f02SDimitry Andric new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1875435933ddSDimitry Andric is_base_class, false, eAddressTypeInvalid, 0);
1876435933ddSDimitry Andric if (synthetic_child) {
18770127ef0fSEd Maste AddSyntheticChild(name_const_str, synthetic_child);
18780127ef0fSEd Maste synthetic_child_sp = synthetic_child->GetSP();
18790127ef0fSEd Maste synthetic_child_sp->SetName(name_const_str);
18800127ef0fSEd Maste }
18810127ef0fSEd Maste return synthetic_child_sp;
18820127ef0fSEd Maste }
18830127ef0fSEd Maste
18844ba319b5SDimitry Andric // your expression path needs to have a leading . or -> (unless it somehow
18854ba319b5SDimitry Andric // "looks like" an array, in which case it has a leading [ symbol). while the [
18864ba319b5SDimitry Andric // is meaningful and should be shown to the user, . and -> are just parser
18874ba319b5SDimitry Andric // design, but by no means added information for the user.. strip them off
SkipLeadingExpressionPathSeparators(const char * expression)1888435933ddSDimitry Andric static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
1889ac7ddfbfSEd Maste if (!expression || !expression[0])
1890ac7ddfbfSEd Maste return expression;
1891ac7ddfbfSEd Maste if (expression[0] == '.')
1892ac7ddfbfSEd Maste return expression + 1;
1893ac7ddfbfSEd Maste if (expression[0] == '-' && expression[1] == '>')
1894ac7ddfbfSEd Maste return expression + 2;
1895ac7ddfbfSEd Maste return expression;
1896ac7ddfbfSEd Maste }
1897ac7ddfbfSEd Maste
1898ac7ddfbfSEd Maste ValueObjectSP
GetSyntheticExpressionPathChild(const char * expression,bool can_create)1899435933ddSDimitry Andric ValueObject::GetSyntheticExpressionPathChild(const char *expression,
1900435933ddSDimitry Andric bool can_create) {
1901ac7ddfbfSEd Maste ValueObjectSP synthetic_child_sp;
1902ac7ddfbfSEd Maste ConstString name_const_string(expression);
19034ba319b5SDimitry Andric // Check if we have already created a synthetic array member in this valid
19044ba319b5SDimitry Andric // object. If we have we will re-use it.
1905ac7ddfbfSEd Maste synthetic_child_sp = GetSyntheticChild(name_const_string);
1906435933ddSDimitry Andric if (!synthetic_child_sp) {
19074ba319b5SDimitry Andric // We haven't made a synthetic array member for expression yet, so lets
19084ba319b5SDimitry Andric // make one and cache it for any future reference.
1909435933ddSDimitry Andric synthetic_child_sp = GetValueForExpressionPath(
1910435933ddSDimitry Andric expression, NULL, NULL,
1911435933ddSDimitry Andric GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
1912435933ddSDimitry Andric GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
1913435933ddSDimitry Andric None));
1914ac7ddfbfSEd Maste
1915ac7ddfbfSEd Maste // Cache the value if we got one back...
1916435933ddSDimitry Andric if (synthetic_child_sp.get()) {
1917435933ddSDimitry Andric // FIXME: this causes a "real" child to end up with its name changed to
1918435933ddSDimitry Andric // the contents of expression
1919ac7ddfbfSEd Maste AddSyntheticChild(name_const_string, synthetic_child_sp.get());
1920435933ddSDimitry Andric synthetic_child_sp->SetName(
1921435933ddSDimitry Andric ConstString(SkipLeadingExpressionPathSeparators(expression)));
1922ac7ddfbfSEd Maste }
1923ac7ddfbfSEd Maste }
1924ac7ddfbfSEd Maste return synthetic_child_sp;
1925ac7ddfbfSEd Maste }
1926ac7ddfbfSEd Maste
CalculateSyntheticValue(bool use_synthetic)1927435933ddSDimitry Andric void ValueObject::CalculateSyntheticValue(bool use_synthetic) {
1928*b5893f02SDimitry Andric if (!use_synthetic)
1929ac7ddfbfSEd Maste return;
1930ac7ddfbfSEd Maste
1931ac7ddfbfSEd Maste TargetSP target_sp(GetTargetSP());
1932*b5893f02SDimitry Andric if (target_sp && !target_sp->GetEnableSyntheticValue()) {
1933ac7ddfbfSEd Maste m_synthetic_value = NULL;
1934ac7ddfbfSEd Maste return;
1935ac7ddfbfSEd Maste }
1936ac7ddfbfSEd Maste
1937ac7ddfbfSEd Maste lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
1938ac7ddfbfSEd Maste
1939ac7ddfbfSEd Maste if (!UpdateFormatsIfNeeded() && m_synthetic_value)
1940ac7ddfbfSEd Maste return;
1941ac7ddfbfSEd Maste
1942ac7ddfbfSEd Maste if (m_synthetic_children_sp.get() == NULL)
1943ac7ddfbfSEd Maste return;
1944ac7ddfbfSEd Maste
1945ac7ddfbfSEd Maste if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
1946ac7ddfbfSEd Maste return;
1947ac7ddfbfSEd Maste
1948ac7ddfbfSEd Maste m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
1949ac7ddfbfSEd Maste }
1950ac7ddfbfSEd Maste
CalculateDynamicValue(DynamicValueType use_dynamic)1951435933ddSDimitry Andric void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
1952ac7ddfbfSEd Maste if (use_dynamic == eNoDynamicValues)
1953ac7ddfbfSEd Maste return;
1954ac7ddfbfSEd Maste
1955435933ddSDimitry Andric if (!m_dynamic_value && !IsDynamic()) {
1956ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
1957ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
1958435933ddSDimitry Andric if (process && process->IsPossibleDynamicValue(*this)) {
1959ac7ddfbfSEd Maste ClearDynamicTypeInformation();
1960ac7ddfbfSEd Maste m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
1961ac7ddfbfSEd Maste }
1962ac7ddfbfSEd Maste }
1963ac7ddfbfSEd Maste }
1964ac7ddfbfSEd Maste
GetDynamicValue(DynamicValueType use_dynamic)1965435933ddSDimitry Andric ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
1966ac7ddfbfSEd Maste if (use_dynamic == eNoDynamicValues)
1967ac7ddfbfSEd Maste return ValueObjectSP();
1968ac7ddfbfSEd Maste
1969435933ddSDimitry Andric if (!IsDynamic() && m_dynamic_value == NULL) {
1970ac7ddfbfSEd Maste CalculateDynamicValue(use_dynamic);
1971ac7ddfbfSEd Maste }
1972ac7ddfbfSEd Maste if (m_dynamic_value)
1973ac7ddfbfSEd Maste return m_dynamic_value->GetSP();
1974ac7ddfbfSEd Maste else
1975ac7ddfbfSEd Maste return ValueObjectSP();
1976ac7ddfbfSEd Maste }
1977ac7ddfbfSEd Maste
GetStaticValue()1978435933ddSDimitry Andric ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); }
1979ac7ddfbfSEd Maste
GetNonSyntheticValue()1980435933ddSDimitry Andric lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); }
1981ac7ddfbfSEd Maste
GetSyntheticValue(bool use_synthetic)1982435933ddSDimitry Andric ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) {
1983*b5893f02SDimitry Andric if (!use_synthetic)
1984ac7ddfbfSEd Maste return ValueObjectSP();
1985ac7ddfbfSEd Maste
1986ac7ddfbfSEd Maste CalculateSyntheticValue(use_synthetic);
1987ac7ddfbfSEd Maste
1988ac7ddfbfSEd Maste if (m_synthetic_value)
1989ac7ddfbfSEd Maste return m_synthetic_value->GetSP();
1990ac7ddfbfSEd Maste else
1991ac7ddfbfSEd Maste return ValueObjectSP();
1992ac7ddfbfSEd Maste }
1993ac7ddfbfSEd Maste
HasSyntheticValue()1994435933ddSDimitry Andric bool ValueObject::HasSyntheticValue() {
1995ac7ddfbfSEd Maste UpdateFormatsIfNeeded();
1996ac7ddfbfSEd Maste
1997ac7ddfbfSEd Maste if (m_synthetic_children_sp.get() == NULL)
1998ac7ddfbfSEd Maste return false;
1999ac7ddfbfSEd Maste
2000ac7ddfbfSEd Maste CalculateSyntheticValue(true);
2001ac7ddfbfSEd Maste
2002*b5893f02SDimitry Andric return m_synthetic_value != nullptr;
2003ac7ddfbfSEd Maste }
2004ac7ddfbfSEd Maste
GetBaseClassPath(Stream & s)2005435933ddSDimitry Andric bool ValueObject::GetBaseClassPath(Stream &s) {
2006435933ddSDimitry Andric if (IsBaseClass()) {
2007435933ddSDimitry Andric bool parent_had_base_class =
2008435933ddSDimitry Andric GetParent() && GetParent()->GetBaseClassPath(s);
20099f2f44ceSEd Maste CompilerType compiler_type = GetCompilerType();
2010ac7ddfbfSEd Maste std::string cxx_class_name;
2011435933ddSDimitry Andric bool this_had_base_class =
2012435933ddSDimitry Andric ClangASTContext::GetCXXClassName(compiler_type, cxx_class_name);
2013435933ddSDimitry Andric if (this_had_base_class) {
2014ac7ddfbfSEd Maste if (parent_had_base_class)
2015ac7ddfbfSEd Maste s.PutCString("::");
2016435933ddSDimitry Andric s.PutCString(cxx_class_name);
2017ac7ddfbfSEd Maste }
2018ac7ddfbfSEd Maste return parent_had_base_class || this_had_base_class;
2019ac7ddfbfSEd Maste }
2020ac7ddfbfSEd Maste return false;
2021ac7ddfbfSEd Maste }
2022ac7ddfbfSEd Maste
GetNonBaseClassParent()2023435933ddSDimitry Andric ValueObject *ValueObject::GetNonBaseClassParent() {
2024435933ddSDimitry Andric if (GetParent()) {
2025ac7ddfbfSEd Maste if (GetParent()->IsBaseClass())
2026ac7ddfbfSEd Maste return GetParent()->GetNonBaseClassParent();
2027ac7ddfbfSEd Maste else
2028ac7ddfbfSEd Maste return GetParent();
2029ac7ddfbfSEd Maste }
2030ac7ddfbfSEd Maste return NULL;
2031ac7ddfbfSEd Maste }
2032ac7ddfbfSEd Maste
IsBaseClass(uint32_t & depth)2033435933ddSDimitry Andric bool ValueObject::IsBaseClass(uint32_t &depth) {
2034435933ddSDimitry Andric if (!IsBaseClass()) {
20350127ef0fSEd Maste depth = 0;
20360127ef0fSEd Maste return false;
20370127ef0fSEd Maste }
2038435933ddSDimitry Andric if (GetParent()) {
20390127ef0fSEd Maste GetParent()->IsBaseClass(depth);
20400127ef0fSEd Maste depth = depth + 1;
20410127ef0fSEd Maste return true;
20420127ef0fSEd Maste }
20430127ef0fSEd Maste // TODO: a base of no parent? weird..
20440127ef0fSEd Maste depth = 1;
20450127ef0fSEd Maste return true;
20460127ef0fSEd Maste }
20470127ef0fSEd Maste
GetExpressionPath(Stream & s,bool qualify_cxx_base_classes,GetExpressionPathFormat epformat)2048435933ddSDimitry Andric void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
2049435933ddSDimitry Andric GetExpressionPathFormat epformat) {
2050435933ddSDimitry Andric // synthetic children do not actually "exist" as part of the hierarchy, and
20514ba319b5SDimitry Andric // sometimes they are consed up in ways that don't make sense from an
20524ba319b5SDimitry Andric // underlying language/API standpoint. So, use a special code path here to
20534ba319b5SDimitry Andric // return something that can hopefully be used in expression
2054435933ddSDimitry Andric if (m_is_synthetic_children_generated) {
20557aa51b79SEd Maste UpdateValueIfNeeded();
20567aa51b79SEd Maste
2057435933ddSDimitry Andric if (m_value.GetValueType() == Value::eValueTypeLoadAddress) {
2058435933ddSDimitry Andric if (IsPointerOrReferenceType()) {
2059435933ddSDimitry Andric s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
20607aa51b79SEd Maste GetValueAsUnsigned(0));
20617aa51b79SEd Maste return;
2062435933ddSDimitry Andric } else {
2063435933ddSDimitry Andric uint64_t load_addr =
2064435933ddSDimitry Andric m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
2065435933ddSDimitry Andric if (load_addr != LLDB_INVALID_ADDRESS) {
2066435933ddSDimitry Andric s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
20677aa51b79SEd Maste load_addr);
20687aa51b79SEd Maste return;
20697aa51b79SEd Maste }
20707aa51b79SEd Maste }
20717aa51b79SEd Maste }
20727aa51b79SEd Maste
2073435933ddSDimitry Andric if (CanProvideValue()) {
2074435933ddSDimitry Andric s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
20757aa51b79SEd Maste GetValueAsCString());
20767aa51b79SEd Maste return;
20777aa51b79SEd Maste }
20787aa51b79SEd Maste
20797aa51b79SEd Maste return;
20807aa51b79SEd Maste }
20817aa51b79SEd Maste
2082ac7ddfbfSEd Maste const bool is_deref_of_parent = IsDereferenceOfParent();
2083ac7ddfbfSEd Maste
2084435933ddSDimitry Andric if (is_deref_of_parent &&
2085435933ddSDimitry Andric epformat == eGetExpressionPathFormatDereferencePointers) {
2086435933ddSDimitry Andric // this is the original format of GetExpressionPath() producing code like
20874ba319b5SDimitry Andric // *(a_ptr).memberName, which is entirely fine, until you put this into
2088435933ddSDimitry Andric // StackFrame::GetValueForVariableExpressionPath() which prefers to see
20894ba319b5SDimitry Andric // a_ptr->memberName. the eHonorPointers mode is meant to produce strings
20904ba319b5SDimitry Andric // in this latter format
2091ac7ddfbfSEd Maste s.PutCString("*(");
2092ac7ddfbfSEd Maste }
2093ac7ddfbfSEd Maste
2094ac7ddfbfSEd Maste ValueObject *parent = GetParent();
2095ac7ddfbfSEd Maste
2096ac7ddfbfSEd Maste if (parent)
2097ac7ddfbfSEd Maste parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat);
2098ac7ddfbfSEd Maste
20994ba319b5SDimitry Andric // if we are a deref_of_parent just because we are synthetic array members
21004ba319b5SDimitry Andric // made up to allow ptr[%d] syntax to work in variable printing, then add our
21014ba319b5SDimitry Andric // name ([%d]) to the expression path
2102435933ddSDimitry Andric if (m_is_array_item_for_pointer &&
2103435933ddSDimitry Andric epformat == eGetExpressionPathFormatHonorPointers)
2104ac7ddfbfSEd Maste s.PutCString(m_name.AsCString());
2105ac7ddfbfSEd Maste
2106435933ddSDimitry Andric if (!IsBaseClass()) {
2107435933ddSDimitry Andric if (!is_deref_of_parent) {
2108ac7ddfbfSEd Maste ValueObject *non_base_class_parent = GetNonBaseClassParent();
2109435933ddSDimitry Andric if (non_base_class_parent &&
2110435933ddSDimitry Andric !non_base_class_parent->GetName().IsEmpty()) {
2111435933ddSDimitry Andric CompilerType non_base_class_parent_compiler_type =
2112435933ddSDimitry Andric non_base_class_parent->GetCompilerType();
2113435933ddSDimitry Andric if (non_base_class_parent_compiler_type) {
2114435933ddSDimitry Andric if (parent && parent->IsDereferenceOfParent() &&
2115435933ddSDimitry Andric epformat == eGetExpressionPathFormatHonorPointers) {
2116ac7ddfbfSEd Maste s.PutCString("->");
2117435933ddSDimitry Andric } else {
2118435933ddSDimitry Andric const uint32_t non_base_class_parent_type_info =
2119435933ddSDimitry Andric non_base_class_parent_compiler_type.GetTypeInfo();
2120ac7ddfbfSEd Maste
2121435933ddSDimitry Andric if (non_base_class_parent_type_info & eTypeIsPointer) {
2122ac7ddfbfSEd Maste s.PutCString("->");
2123435933ddSDimitry Andric } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
2124435933ddSDimitry Andric !(non_base_class_parent_type_info & eTypeIsArray)) {
2125ac7ddfbfSEd Maste s.PutChar('.');
2126ac7ddfbfSEd Maste }
2127ac7ddfbfSEd Maste }
2128ac7ddfbfSEd Maste }
2129ac7ddfbfSEd Maste }
2130ac7ddfbfSEd Maste
2131ac7ddfbfSEd Maste const char *name = GetName().GetCString();
2132435933ddSDimitry Andric if (name) {
2133435933ddSDimitry Andric if (qualify_cxx_base_classes) {
2134ac7ddfbfSEd Maste if (GetBaseClassPath(s))
2135ac7ddfbfSEd Maste s.PutCString("::");
2136ac7ddfbfSEd Maste }
2137ac7ddfbfSEd Maste s.PutCString(name);
2138ac7ddfbfSEd Maste }
2139ac7ddfbfSEd Maste }
2140ac7ddfbfSEd Maste }
2141ac7ddfbfSEd Maste
2142435933ddSDimitry Andric if (is_deref_of_parent &&
2143435933ddSDimitry Andric epformat == eGetExpressionPathFormatDereferencePointers) {
2144ac7ddfbfSEd Maste s.PutChar(')');
2145ac7ddfbfSEd Maste }
2146ac7ddfbfSEd Maste }
2147ac7ddfbfSEd Maste
GetValueForExpressionPath(llvm::StringRef expression,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_value_type,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * final_task_on_target)2148435933ddSDimitry Andric ValueObjectSP ValueObject::GetValueForExpressionPath(
2149435933ddSDimitry Andric llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
2150ac7ddfbfSEd Maste ExpressionPathEndResultType *final_value_type,
2151ac7ddfbfSEd Maste const GetValueForExpressionPathOptions &options,
2152435933ddSDimitry Andric ExpressionPathAftermath *final_task_on_target) {
2153ac7ddfbfSEd Maste
2154435933ddSDimitry Andric ExpressionPathScanEndReason dummy_reason_to_stop =
2155435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonUnknown;
2156435933ddSDimitry Andric ExpressionPathEndResultType dummy_final_value_type =
2157435933ddSDimitry Andric ValueObject::eExpressionPathEndResultTypeInvalid;
2158435933ddSDimitry Andric ExpressionPathAftermath dummy_final_task_on_target =
2159435933ddSDimitry Andric ValueObject::eExpressionPathAftermathNothing;
2160ac7ddfbfSEd Maste
2161435933ddSDimitry Andric ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
2162435933ddSDimitry Andric expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2163435933ddSDimitry Andric final_value_type ? final_value_type : &dummy_final_value_type, options,
2164435933ddSDimitry Andric final_task_on_target ? final_task_on_target
2165435933ddSDimitry Andric : &dummy_final_task_on_target);
2166ac7ddfbfSEd Maste
2167435933ddSDimitry Andric if (!final_task_on_target ||
2168435933ddSDimitry Andric *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2169ac7ddfbfSEd Maste return ret_val;
2170ac7ddfbfSEd Maste
2171435933ddSDimitry Andric if (ret_val.get() &&
2172435933ddSDimitry Andric ((final_value_type ? *final_value_type : dummy_final_value_type) ==
2173435933ddSDimitry Andric eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
2174435933ddSDimitry Andric // of plain objects
2175ac7ddfbfSEd Maste {
2176435933ddSDimitry Andric if ((final_task_on_target ? *final_task_on_target
2177435933ddSDimitry Andric : dummy_final_task_on_target) ==
2178435933ddSDimitry Andric ValueObject::eExpressionPathAftermathDereference) {
21795517e702SDimitry Andric Status error;
2180ac7ddfbfSEd Maste ValueObjectSP final_value = ret_val->Dereference(error);
2181435933ddSDimitry Andric if (error.Fail() || !final_value.get()) {
2182ac7ddfbfSEd Maste if (reason_to_stop)
2183435933ddSDimitry Andric *reason_to_stop =
2184435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2185ac7ddfbfSEd Maste if (final_value_type)
2186ac7ddfbfSEd Maste *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2187ac7ddfbfSEd Maste return ValueObjectSP();
2188435933ddSDimitry Andric } else {
2189ac7ddfbfSEd Maste if (final_task_on_target)
2190ac7ddfbfSEd Maste *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2191ac7ddfbfSEd Maste return final_value;
2192ac7ddfbfSEd Maste }
2193ac7ddfbfSEd Maste }
2194435933ddSDimitry Andric if (*final_task_on_target ==
2195435933ddSDimitry Andric ValueObject::eExpressionPathAftermathTakeAddress) {
21965517e702SDimitry Andric Status error;
2197ac7ddfbfSEd Maste ValueObjectSP final_value = ret_val->AddressOf(error);
2198435933ddSDimitry Andric if (error.Fail() || !final_value.get()) {
2199ac7ddfbfSEd Maste if (reason_to_stop)
2200435933ddSDimitry Andric *reason_to_stop =
2201435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2202ac7ddfbfSEd Maste if (final_value_type)
2203ac7ddfbfSEd Maste *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2204ac7ddfbfSEd Maste return ValueObjectSP();
2205435933ddSDimitry Andric } else {
2206ac7ddfbfSEd Maste if (final_task_on_target)
2207ac7ddfbfSEd Maste *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2208ac7ddfbfSEd Maste return final_value;
2209ac7ddfbfSEd Maste }
2210ac7ddfbfSEd Maste }
2211ac7ddfbfSEd Maste }
2212435933ddSDimitry Andric return ret_val; // final_task_on_target will still have its original value, so
2213435933ddSDimitry Andric // you know I did not do it
2214ac7ddfbfSEd Maste }
2215ac7ddfbfSEd Maste
GetValueForExpressionPath_Impl(llvm::StringRef expression,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_result,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * what_next)2216435933ddSDimitry Andric ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
2217435933ddSDimitry Andric llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
2218ac7ddfbfSEd Maste ExpressionPathEndResultType *final_result,
2219ac7ddfbfSEd Maste const GetValueForExpressionPathOptions &options,
2220435933ddSDimitry Andric ExpressionPathAftermath *what_next) {
2221ac7ddfbfSEd Maste ValueObjectSP root = GetSP();
2222ac7ddfbfSEd Maste
2223435933ddSDimitry Andric if (!root)
2224435933ddSDimitry Andric return nullptr;
2225ac7ddfbfSEd Maste
2226435933ddSDimitry Andric llvm::StringRef remainder = expression;
2227ac7ddfbfSEd Maste
2228435933ddSDimitry Andric while (true) {
2229435933ddSDimitry Andric llvm::StringRef temp_expression = remainder;
2230ac7ddfbfSEd Maste
22319f2f44ceSEd Maste CompilerType root_compiler_type = root->GetCompilerType();
22329f2f44ceSEd Maste CompilerType pointee_compiler_type;
22339f2f44ceSEd Maste Flags pointee_compiler_type_info;
2234ac7ddfbfSEd Maste
2235435933ddSDimitry Andric Flags root_compiler_type_info(
2236435933ddSDimitry Andric root_compiler_type.GetTypeInfo(&pointee_compiler_type));
22379f2f44ceSEd Maste if (pointee_compiler_type)
22389f2f44ceSEd Maste pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());
2239ac7ddfbfSEd Maste
2240435933ddSDimitry Andric if (temp_expression.empty()) {
2241ac7ddfbfSEd Maste *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2242ac7ddfbfSEd Maste return root;
2243ac7ddfbfSEd Maste }
2244ac7ddfbfSEd Maste
2245435933ddSDimitry Andric switch (temp_expression.front()) {
2246435933ddSDimitry Andric case '-': {
2247435933ddSDimitry Andric temp_expression = temp_expression.drop_front();
2248ac7ddfbfSEd Maste if (options.m_check_dot_vs_arrow_syntax &&
2249435933ddSDimitry Andric root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2250435933ddSDimitry Andric // use -> on a
2251435933ddSDimitry Andric // non-pointer and I
2252435933ddSDimitry Andric // must catch the error
2253ac7ddfbfSEd Maste {
2254435933ddSDimitry Andric *reason_to_stop =
2255435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2256ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2257ac7ddfbfSEd Maste return ValueObjectSP();
2258ac7ddfbfSEd Maste }
2259435933ddSDimitry Andric if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to
2260435933ddSDimitry Andric // extract an ObjC IVar
2261435933ddSDimitry Andric // when this is forbidden
22629f2f44ceSEd Maste root_compiler_type_info.Test(eTypeIsPointer) &&
2263435933ddSDimitry Andric options.m_no_fragile_ivar) {
2264435933ddSDimitry Andric *reason_to_stop =
2265435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2266ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2267ac7ddfbfSEd Maste return ValueObjectSP();
2268ac7ddfbfSEd Maste }
2269435933ddSDimitry Andric if (!temp_expression.startswith(">")) {
2270435933ddSDimitry Andric *reason_to_stop =
2271435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2272ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2273ac7ddfbfSEd Maste return ValueObjectSP();
2274ac7ddfbfSEd Maste }
2275ac7ddfbfSEd Maste }
22764bb0738eSEd Maste LLVM_FALLTHROUGH;
2277ac7ddfbfSEd Maste case '.': // or fallthrough from ->
2278ac7ddfbfSEd Maste {
2279435933ddSDimitry Andric if (options.m_check_dot_vs_arrow_syntax &&
2280435933ddSDimitry Andric temp_expression.front() == '.' &&
2281435933ddSDimitry Andric root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2282435933ddSDimitry Andric // use . on a pointer
2283435933ddSDimitry Andric // and I must catch the
2284435933ddSDimitry Andric // error
2285ac7ddfbfSEd Maste {
2286435933ddSDimitry Andric *reason_to_stop =
2287435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2288ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2289435933ddSDimitry Andric return nullptr;
2290ac7ddfbfSEd Maste }
2291435933ddSDimitry Andric temp_expression = temp_expression.drop_front(); // skip . or >
2292435933ddSDimitry Andric
2293435933ddSDimitry Andric size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
2294ac7ddfbfSEd Maste ConstString child_name;
2295435933ddSDimitry Andric if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2296435933ddSDimitry Andric // expand this last layer
2297ac7ddfbfSEd Maste {
2298435933ddSDimitry Andric child_name.SetString(temp_expression);
2299435933ddSDimitry Andric ValueObjectSP child_valobj_sp =
2300435933ddSDimitry Andric root->GetChildMemberWithName(child_name, true);
2301ac7ddfbfSEd Maste
2302ac7ddfbfSEd Maste if (child_valobj_sp.get()) // we know we are done, so just return
2303ac7ddfbfSEd Maste {
2304435933ddSDimitry Andric *reason_to_stop =
2305435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonEndOfString;
2306ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2307ac7ddfbfSEd Maste return child_valobj_sp;
2308435933ddSDimitry Andric } else {
2309435933ddSDimitry Andric switch (options.m_synthetic_children_traversal) {
2310435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2311435933ddSDimitry Andric None:
23121c3bbb01SEd Maste break;
2313435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2314435933ddSDimitry Andric FromSynthetic:
2315435933ddSDimitry Andric if (root->IsSynthetic()) {
23161c3bbb01SEd Maste child_valobj_sp = root->GetNonSyntheticValue();
23171c3bbb01SEd Maste if (child_valobj_sp.get())
2318435933ddSDimitry Andric child_valobj_sp =
2319435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
2320ac7ddfbfSEd Maste }
23211c3bbb01SEd Maste break;
2322435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2323435933ddSDimitry Andric ToSynthetic:
2324435933ddSDimitry Andric if (!root->IsSynthetic()) {
2325ac7ddfbfSEd Maste child_valobj_sp = root->GetSyntheticValue();
2326ac7ddfbfSEd Maste if (child_valobj_sp.get())
2327435933ddSDimitry Andric child_valobj_sp =
2328435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
2329ac7ddfbfSEd Maste }
23301c3bbb01SEd Maste break;
2331435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2332435933ddSDimitry Andric Both:
2333435933ddSDimitry Andric if (root->IsSynthetic()) {
23341c3bbb01SEd Maste child_valobj_sp = root->GetNonSyntheticValue();
23351c3bbb01SEd Maste if (child_valobj_sp.get())
2336435933ddSDimitry Andric child_valobj_sp =
2337435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
2338435933ddSDimitry Andric } else {
23391c3bbb01SEd Maste child_valobj_sp = root->GetSyntheticValue();
23401c3bbb01SEd Maste if (child_valobj_sp.get())
2341435933ddSDimitry Andric child_valobj_sp =
2342435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
23431c3bbb01SEd Maste }
23441c3bbb01SEd Maste break;
23451c3bbb01SEd Maste }
23461c3bbb01SEd Maste }
2347ac7ddfbfSEd Maste
2348435933ddSDimitry Andric // if we are here and options.m_no_synthetic_children is true,
23494ba319b5SDimitry Andric // child_valobj_sp is going to be a NULL SP, so we hit the "else"
23504ba319b5SDimitry Andric // branch, and return an error
2351ac7ddfbfSEd Maste if (child_valobj_sp.get()) // if it worked, just return
2352ac7ddfbfSEd Maste {
2353435933ddSDimitry Andric *reason_to_stop =
2354435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonEndOfString;
2355ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2356ac7ddfbfSEd Maste return child_valobj_sp;
2357435933ddSDimitry Andric } else {
2358435933ddSDimitry Andric *reason_to_stop =
2359435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2360ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2361435933ddSDimitry Andric return nullptr;
2362ac7ddfbfSEd Maste }
2363435933ddSDimitry Andric } else // other layers do expand
2364ac7ddfbfSEd Maste {
2365435933ddSDimitry Andric llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
2366435933ddSDimitry Andric
2367435933ddSDimitry Andric child_name.SetString(temp_expression.slice(0, next_sep_pos));
2368435933ddSDimitry Andric
2369435933ddSDimitry Andric ValueObjectSP child_valobj_sp =
2370435933ddSDimitry Andric root->GetChildMemberWithName(child_name, true);
2371ac7ddfbfSEd Maste if (child_valobj_sp.get()) // store the new root and move on
2372ac7ddfbfSEd Maste {
2373ac7ddfbfSEd Maste root = child_valobj_sp;
2374435933ddSDimitry Andric remainder = next_separator;
2375ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2376ac7ddfbfSEd Maste continue;
2377435933ddSDimitry Andric } else {
2378435933ddSDimitry Andric switch (options.m_synthetic_children_traversal) {
2379435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2380435933ddSDimitry Andric None:
23811c3bbb01SEd Maste break;
2382435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2383435933ddSDimitry Andric FromSynthetic:
2384435933ddSDimitry Andric if (root->IsSynthetic()) {
23851c3bbb01SEd Maste child_valobj_sp = root->GetNonSyntheticValue();
23861c3bbb01SEd Maste if (child_valobj_sp.get())
2387435933ddSDimitry Andric child_valobj_sp =
2388435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
2389ac7ddfbfSEd Maste }
23901c3bbb01SEd Maste break;
2391435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2392435933ddSDimitry Andric ToSynthetic:
2393435933ddSDimitry Andric if (!root->IsSynthetic()) {
23941c3bbb01SEd Maste child_valobj_sp = root->GetSyntheticValue();
23951c3bbb01SEd Maste if (child_valobj_sp.get())
2396435933ddSDimitry Andric child_valobj_sp =
2397435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
23981c3bbb01SEd Maste }
23991c3bbb01SEd Maste break;
2400435933ddSDimitry Andric case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2401435933ddSDimitry Andric Both:
2402435933ddSDimitry Andric if (root->IsSynthetic()) {
24031c3bbb01SEd Maste child_valobj_sp = root->GetNonSyntheticValue();
24041c3bbb01SEd Maste if (child_valobj_sp.get())
2405435933ddSDimitry Andric child_valobj_sp =
2406435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
2407435933ddSDimitry Andric } else {
24081c3bbb01SEd Maste child_valobj_sp = root->GetSyntheticValue();
24091c3bbb01SEd Maste if (child_valobj_sp.get())
2410435933ddSDimitry Andric child_valobj_sp =
2411435933ddSDimitry Andric child_valobj_sp->GetChildMemberWithName(child_name, true);
24121c3bbb01SEd Maste }
24131c3bbb01SEd Maste break;
24141c3bbb01SEd Maste }
24151c3bbb01SEd Maste }
2416ac7ddfbfSEd Maste
2417435933ddSDimitry Andric // if we are here and options.m_no_synthetic_children is true,
24184ba319b5SDimitry Andric // child_valobj_sp is going to be a NULL SP, so we hit the "else"
24194ba319b5SDimitry Andric // branch, and return an error
2420ac7ddfbfSEd Maste if (child_valobj_sp.get()) // if it worked, move on
2421ac7ddfbfSEd Maste {
2422ac7ddfbfSEd Maste root = child_valobj_sp;
2423435933ddSDimitry Andric remainder = next_separator;
2424ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2425ac7ddfbfSEd Maste continue;
2426435933ddSDimitry Andric } else {
2427435933ddSDimitry Andric *reason_to_stop =
2428435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2429ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2430435933ddSDimitry Andric return nullptr;
2431ac7ddfbfSEd Maste }
2432ac7ddfbfSEd Maste }
2433ac7ddfbfSEd Maste break;
2434ac7ddfbfSEd Maste }
2435435933ddSDimitry Andric case '[': {
2436435933ddSDimitry Andric if (!root_compiler_type_info.Test(eTypeIsArray) &&
2437435933ddSDimitry Andric !root_compiler_type_info.Test(eTypeIsPointer) &&
2438435933ddSDimitry Andric !root_compiler_type_info.Test(
2439435933ddSDimitry Andric eTypeIsVector)) // if this is not a T[] nor a T*
2440ac7ddfbfSEd Maste {
2441435933ddSDimitry Andric if (!root_compiler_type_info.Test(
2442435933ddSDimitry Andric eTypeIsScalar)) // if this is not even a scalar...
2443ac7ddfbfSEd Maste {
2444435933ddSDimitry Andric if (options.m_synthetic_children_traversal ==
2445435933ddSDimitry Andric GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2446435933ddSDimitry Andric None) // ...only chance left is synthetic
2447ac7ddfbfSEd Maste {
2448435933ddSDimitry Andric *reason_to_stop =
2449435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2450435933ddSDimitry Andric *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2451435933ddSDimitry Andric return ValueObjectSP();
2452435933ddSDimitry Andric }
2453435933ddSDimitry Andric } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
2454435933ddSDimitry Andric // check that we can
2455435933ddSDimitry Andric // expand bitfields
2456ac7ddfbfSEd Maste {
2457435933ddSDimitry Andric *reason_to_stop =
2458435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2459ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2460ac7ddfbfSEd Maste return ValueObjectSP();
2461ac7ddfbfSEd Maste }
2462ac7ddfbfSEd Maste }
2463435933ddSDimitry Andric if (temp_expression[1] ==
2464435933ddSDimitry Andric ']') // if this is an unbounded range it only works for arrays
2465ac7ddfbfSEd Maste {
2466435933ddSDimitry Andric if (!root_compiler_type_info.Test(eTypeIsArray)) {
2467435933ddSDimitry Andric *reason_to_stop =
2468435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2469ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2470435933ddSDimitry Andric return nullptr;
2471435933ddSDimitry Andric } else // even if something follows, we cannot expand unbounded ranges,
2472435933ddSDimitry Andric // just let the caller do it
2473ac7ddfbfSEd Maste {
2474435933ddSDimitry Andric *reason_to_stop =
2475435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2476435933ddSDimitry Andric *final_result =
2477435933ddSDimitry Andric ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2478ac7ddfbfSEd Maste return root;
2479ac7ddfbfSEd Maste }
2480ac7ddfbfSEd Maste }
2481435933ddSDimitry Andric
2482435933ddSDimitry Andric size_t close_bracket_position = temp_expression.find(']', 1);
2483435933ddSDimitry Andric if (close_bracket_position ==
2484435933ddSDimitry Andric llvm::StringRef::npos) // if there is no ], this is a syntax error
2485ac7ddfbfSEd Maste {
2486435933ddSDimitry Andric *reason_to_stop =
2487435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2488ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2489435933ddSDimitry Andric return nullptr;
2490ac7ddfbfSEd Maste }
2491435933ddSDimitry Andric
2492435933ddSDimitry Andric llvm::StringRef bracket_expr =
2493435933ddSDimitry Andric temp_expression.slice(1, close_bracket_position);
2494435933ddSDimitry Andric
2495435933ddSDimitry Andric // If this was an empty expression it would have been caught by the if
2496435933ddSDimitry Andric // above.
2497435933ddSDimitry Andric assert(!bracket_expr.empty());
2498435933ddSDimitry Andric
2499435933ddSDimitry Andric if (!bracket_expr.contains('-')) {
25004ba319b5SDimitry Andric // if no separator, this is of the form [N]. Note that this cannot be
25014ba319b5SDimitry Andric // an unbounded range of the form [], because that case was handled
2502435933ddSDimitry Andric // above with an unconditional return.
2503435933ddSDimitry Andric unsigned long index = 0;
2504435933ddSDimitry Andric if (bracket_expr.getAsInteger(0, index)) {
2505435933ddSDimitry Andric *reason_to_stop =
2506435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2507ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2508435933ddSDimitry Andric return nullptr;
2509ac7ddfbfSEd Maste }
2510435933ddSDimitry Andric
2511ac7ddfbfSEd Maste // from here on we do have a valid index
2512435933ddSDimitry Andric if (root_compiler_type_info.Test(eTypeIsArray)) {
2513ac7ddfbfSEd Maste ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2514ac7ddfbfSEd Maste if (!child_valobj_sp)
25151c3bbb01SEd Maste child_valobj_sp = root->GetSyntheticArrayMember(index, true);
2516ac7ddfbfSEd Maste if (!child_valobj_sp)
2517435933ddSDimitry Andric if (root->HasSyntheticValue() &&
2518435933ddSDimitry Andric root->GetSyntheticValue()->GetNumChildren() > index)
2519435933ddSDimitry Andric child_valobj_sp =
2520435933ddSDimitry Andric root->GetSyntheticValue()->GetChildAtIndex(index, true);
2521435933ddSDimitry Andric if (child_valobj_sp) {
2522ac7ddfbfSEd Maste root = child_valobj_sp;
2523435933ddSDimitry Andric remainder =
2524435933ddSDimitry Andric temp_expression.substr(close_bracket_position + 1); // skip ]
2525ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2526ac7ddfbfSEd Maste continue;
2527435933ddSDimitry Andric } else {
2528435933ddSDimitry Andric *reason_to_stop =
2529435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2530ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2531435933ddSDimitry Andric return nullptr;
2532ac7ddfbfSEd Maste }
2533435933ddSDimitry Andric } else if (root_compiler_type_info.Test(eTypeIsPointer)) {
2534435933ddSDimitry Andric if (*what_next ==
2535435933ddSDimitry Andric ValueObject::
2536435933ddSDimitry Andric eExpressionPathAftermathDereference && // if this is a
2537435933ddSDimitry Andric // ptr-to-scalar, I
2538435933ddSDimitry Andric // am accessing it
2539435933ddSDimitry Andric // by index and I
2540435933ddSDimitry Andric // would have
2541435933ddSDimitry Andric // deref'ed anyway,
2542435933ddSDimitry Andric // then do it now
2543435933ddSDimitry Andric // and use this as
2544435933ddSDimitry Andric // a bitfield
2545435933ddSDimitry Andric pointee_compiler_type_info.Test(eTypeIsScalar)) {
25465517e702SDimitry Andric Status error;
2547ac7ddfbfSEd Maste root = root->Dereference(error);
2548435933ddSDimitry Andric if (error.Fail() || !root) {
2549435933ddSDimitry Andric *reason_to_stop =
2550435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2551ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2552435933ddSDimitry Andric return nullptr;
2553435933ddSDimitry Andric } else {
2554ac7ddfbfSEd Maste *what_next = eExpressionPathAftermathNothing;
2555ac7ddfbfSEd Maste continue;
2556ac7ddfbfSEd Maste }
2557435933ddSDimitry Andric } else {
2558435933ddSDimitry Andric if (root->GetCompilerType().GetMinimumLanguage() ==
2559435933ddSDimitry Andric eLanguageTypeObjC &&
2560435933ddSDimitry Andric pointee_compiler_type_info.AllClear(eTypeIsPointer) &&
2561435933ddSDimitry Andric root->HasSyntheticValue() &&
2562435933ddSDimitry Andric (options.m_synthetic_children_traversal ==
2563435933ddSDimitry Andric GetValueForExpressionPathOptions::
2564435933ddSDimitry Andric SyntheticChildrenTraversal::ToSynthetic ||
2565435933ddSDimitry Andric options.m_synthetic_children_traversal ==
2566435933ddSDimitry Andric GetValueForExpressionPathOptions::
2567435933ddSDimitry Andric SyntheticChildrenTraversal::Both)) {
2568ac7ddfbfSEd Maste root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2569435933ddSDimitry Andric } else
25701c3bbb01SEd Maste root = root->GetSyntheticArrayMember(index, true);
2571435933ddSDimitry Andric if (!root) {
2572435933ddSDimitry Andric *reason_to_stop =
2573435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2574ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2575435933ddSDimitry Andric return nullptr;
2576435933ddSDimitry Andric } else {
2577435933ddSDimitry Andric remainder =
2578435933ddSDimitry Andric temp_expression.substr(close_bracket_position + 1); // skip ]
2579ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2580ac7ddfbfSEd Maste continue;
2581ac7ddfbfSEd Maste }
2582ac7ddfbfSEd Maste }
2583435933ddSDimitry Andric } else if (root_compiler_type_info.Test(eTypeIsScalar)) {
2584ac7ddfbfSEd Maste root = root->GetSyntheticBitFieldChild(index, index, true);
2585435933ddSDimitry Andric if (!root) {
2586435933ddSDimitry Andric *reason_to_stop =
2587435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2588ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2589435933ddSDimitry Andric return nullptr;
2590435933ddSDimitry Andric } else // we do not know how to expand members of bitfields, so we
2591435933ddSDimitry Andric // just return and let the caller do any further processing
2592ac7ddfbfSEd Maste {
2593435933ddSDimitry Andric *reason_to_stop = ValueObject::
2594435933ddSDimitry Andric eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2595ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2596ac7ddfbfSEd Maste return root;
2597ac7ddfbfSEd Maste }
2598435933ddSDimitry Andric } else if (root_compiler_type_info.Test(eTypeIsVector)) {
2599ac7ddfbfSEd Maste root = root->GetChildAtIndex(index, true);
2600435933ddSDimitry Andric if (!root) {
2601435933ddSDimitry Andric *reason_to_stop =
2602435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2603ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2604ac7ddfbfSEd Maste return ValueObjectSP();
2605435933ddSDimitry Andric } else {
2606435933ddSDimitry Andric remainder =
2607435933ddSDimitry Andric temp_expression.substr(close_bracket_position + 1); // skip ]
2608ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2609ac7ddfbfSEd Maste continue;
2610ac7ddfbfSEd Maste }
2611435933ddSDimitry Andric } else if (options.m_synthetic_children_traversal ==
2612435933ddSDimitry Andric GetValueForExpressionPathOptions::
2613435933ddSDimitry Andric SyntheticChildrenTraversal::ToSynthetic ||
2614435933ddSDimitry Andric options.m_synthetic_children_traversal ==
2615435933ddSDimitry Andric GetValueForExpressionPathOptions::
2616435933ddSDimitry Andric SyntheticChildrenTraversal::Both) {
2617ac7ddfbfSEd Maste if (root->HasSyntheticValue())
2618ac7ddfbfSEd Maste root = root->GetSyntheticValue();
2619435933ddSDimitry Andric else if (!root->IsSynthetic()) {
2620435933ddSDimitry Andric *reason_to_stop =
2621435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2622ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2623435933ddSDimitry Andric return nullptr;
2624ac7ddfbfSEd Maste }
26254ba319b5SDimitry Andric // if we are here, then root itself is a synthetic VO.. should be
26264ba319b5SDimitry Andric // good to go
2627ac7ddfbfSEd Maste
2628435933ddSDimitry Andric if (!root) {
2629435933ddSDimitry Andric *reason_to_stop =
2630435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2631ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2632435933ddSDimitry Andric return nullptr;
2633ac7ddfbfSEd Maste }
2634ac7ddfbfSEd Maste root = root->GetChildAtIndex(index, true);
2635435933ddSDimitry Andric if (!root) {
2636435933ddSDimitry Andric *reason_to_stop =
2637435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2638ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2639435933ddSDimitry Andric return nullptr;
2640435933ddSDimitry Andric } else {
2641435933ddSDimitry Andric remainder =
2642435933ddSDimitry Andric temp_expression.substr(close_bracket_position + 1); // skip ]
2643ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2644ac7ddfbfSEd Maste continue;
2645ac7ddfbfSEd Maste }
2646435933ddSDimitry Andric } else {
2647435933ddSDimitry Andric *reason_to_stop =
2648435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2649ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2650435933ddSDimitry Andric return nullptr;
2651ac7ddfbfSEd Maste }
2652435933ddSDimitry Andric } else {
2653435933ddSDimitry Andric // we have a low and a high index
2654435933ddSDimitry Andric llvm::StringRef sleft, sright;
2655435933ddSDimitry Andric unsigned long low_index, high_index;
2656435933ddSDimitry Andric std::tie(sleft, sright) = bracket_expr.split('-');
2657435933ddSDimitry Andric if (sleft.getAsInteger(0, low_index) ||
2658435933ddSDimitry Andric sright.getAsInteger(0, high_index)) {
2659435933ddSDimitry Andric *reason_to_stop =
2660435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2661ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2662435933ddSDimitry Andric return nullptr;
2663ac7ddfbfSEd Maste }
2664435933ddSDimitry Andric
2665435933ddSDimitry Andric if (low_index > high_index) // swap indices if required
2666435933ddSDimitry Andric std::swap(low_index, high_index);
2667435933ddSDimitry Andric
2668435933ddSDimitry Andric if (root_compiler_type_info.Test(
2669435933ddSDimitry Andric eTypeIsScalar)) // expansion only works for scalars
2670ac7ddfbfSEd Maste {
2671435933ddSDimitry Andric root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
2672435933ddSDimitry Andric if (!root) {
2673435933ddSDimitry Andric *reason_to_stop =
2674435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2675ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2676435933ddSDimitry Andric return nullptr;
2677435933ddSDimitry Andric } else {
2678435933ddSDimitry Andric *reason_to_stop = ValueObject::
2679435933ddSDimitry Andric eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2680ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2681ac7ddfbfSEd Maste return root;
2682ac7ddfbfSEd Maste }
2683435933ddSDimitry Andric } else if (root_compiler_type_info.Test(
2684435933ddSDimitry Andric eTypeIsPointer) && // if this is a ptr-to-scalar, I am
2685435933ddSDimitry Andric // accessing it by index and I would
2686435933ddSDimitry Andric // have deref'ed anyway, then do it
2687435933ddSDimitry Andric // now and use this as a bitfield
2688435933ddSDimitry Andric *what_next ==
2689435933ddSDimitry Andric ValueObject::eExpressionPathAftermathDereference &&
2690435933ddSDimitry Andric pointee_compiler_type_info.Test(eTypeIsScalar)) {
26915517e702SDimitry Andric Status error;
2692ac7ddfbfSEd Maste root = root->Dereference(error);
2693435933ddSDimitry Andric if (error.Fail() || !root) {
2694435933ddSDimitry Andric *reason_to_stop =
2695435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2696ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2697435933ddSDimitry Andric return nullptr;
2698435933ddSDimitry Andric } else {
2699ac7ddfbfSEd Maste *what_next = ValueObject::eExpressionPathAftermathNothing;
2700ac7ddfbfSEd Maste continue;
2701ac7ddfbfSEd Maste }
2702435933ddSDimitry Andric } else {
2703435933ddSDimitry Andric *reason_to_stop =
2704435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2705ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
2706ac7ddfbfSEd Maste return root;
2707ac7ddfbfSEd Maste }
2708ac7ddfbfSEd Maste }
2709ac7ddfbfSEd Maste break;
2710ac7ddfbfSEd Maste }
2711ac7ddfbfSEd Maste default: // some non-separator is in the way
2712ac7ddfbfSEd Maste {
2713435933ddSDimitry Andric *reason_to_stop =
2714435933ddSDimitry Andric ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2715ac7ddfbfSEd Maste *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2716435933ddSDimitry Andric return nullptr;
2717ac7ddfbfSEd Maste }
2718ac7ddfbfSEd Maste }
2719ac7ddfbfSEd Maste }
2720ac7ddfbfSEd Maste }
2721ac7ddfbfSEd Maste
LogValueObject(Log * log)2722435933ddSDimitry Andric void ValueObject::LogValueObject(Log *log) {
272335617911SEd Maste if (log)
27241c3bbb01SEd Maste return LogValueObject(log, DumpValueObjectOptions(*this));
2725ac7ddfbfSEd Maste }
2726ac7ddfbfSEd Maste
LogValueObject(Log * log,const DumpValueObjectOptions & options)2727435933ddSDimitry Andric void ValueObject::LogValueObject(Log *log,
2728435933ddSDimitry Andric const DumpValueObjectOptions &options) {
2729435933ddSDimitry Andric if (log) {
2730ac7ddfbfSEd Maste StreamString s;
273135617911SEd Maste Dump(s, options);
2732ac7ddfbfSEd Maste if (s.GetSize())
2733ac7ddfbfSEd Maste log->PutCString(s.GetData());
2734ac7ddfbfSEd Maste }
2735ac7ddfbfSEd Maste }
2736ac7ddfbfSEd Maste
Dump(Stream & s)2737435933ddSDimitry Andric void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
2738ac7ddfbfSEd Maste
Dump(Stream & s,const DumpValueObjectOptions & options)2739435933ddSDimitry Andric void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
274035617911SEd Maste ValueObjectPrinter printer(this, &s, options);
274135617911SEd Maste printer.PrintValueObject();
2742ac7ddfbfSEd Maste }
2743ac7ddfbfSEd Maste
CreateConstantValue(const ConstString & name)2744435933ddSDimitry Andric ValueObjectSP ValueObject::CreateConstantValue(const ConstString &name) {
2745ac7ddfbfSEd Maste ValueObjectSP valobj_sp;
2746ac7ddfbfSEd Maste
2747435933ddSDimitry Andric if (UpdateValueIfNeeded(false) && m_error.Success()) {
2748ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
2749ac7ddfbfSEd Maste
2750ac7ddfbfSEd Maste DataExtractor data;
2751ac7ddfbfSEd Maste data.SetByteOrder(m_data.GetByteOrder());
2752ac7ddfbfSEd Maste data.SetAddressByteSize(m_data.GetAddressByteSize());
2753ac7ddfbfSEd Maste
2754435933ddSDimitry Andric if (IsBitfield()) {
2755ac7ddfbfSEd Maste Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
2756ac7ddfbfSEd Maste m_error = v.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2757435933ddSDimitry Andric } else
2758ac7ddfbfSEd Maste m_error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
2759ac7ddfbfSEd Maste
2760435933ddSDimitry Andric valobj_sp = ValueObjectConstResult::Create(
2761435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
2762ac7ddfbfSEd Maste GetAddressOf());
2763ac7ddfbfSEd Maste }
2764ac7ddfbfSEd Maste
2765435933ddSDimitry Andric if (!valobj_sp) {
276612b93ac6SEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
2767435933ddSDimitry Andric valobj_sp = ValueObjectConstResult::Create(
2768435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(), m_error);
2769ac7ddfbfSEd Maste }
2770ac7ddfbfSEd Maste return valobj_sp;
2771ac7ddfbfSEd Maste }
2772ac7ddfbfSEd Maste
GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue,bool synthValue)2773435933ddSDimitry Andric ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
2774435933ddSDimitry Andric lldb::DynamicValueType dynValue, bool synthValue) {
27757aa51b79SEd Maste ValueObjectSP result_sp(GetSP());
27767aa51b79SEd Maste
2777435933ddSDimitry Andric switch (dynValue) {
27787aa51b79SEd Maste case lldb::eDynamicCanRunTarget:
2779435933ddSDimitry Andric case lldb::eDynamicDontRunTarget: {
2780435933ddSDimitry Andric if (!result_sp->IsDynamic()) {
27817aa51b79SEd Maste if (result_sp->GetDynamicValue(dynValue))
27827aa51b79SEd Maste result_sp = result_sp->GetDynamicValue(dynValue);
27837aa51b79SEd Maste }
2784435933ddSDimitry Andric } break;
2785435933ddSDimitry Andric case lldb::eNoDynamicValues: {
2786435933ddSDimitry Andric if (result_sp->IsDynamic()) {
27877aa51b79SEd Maste if (result_sp->GetStaticValue())
27887aa51b79SEd Maste result_sp = result_sp->GetStaticValue();
27897aa51b79SEd Maste }
2790435933ddSDimitry Andric } break;
27917aa51b79SEd Maste }
27927aa51b79SEd Maste
2793435933ddSDimitry Andric if (synthValue) {
2794435933ddSDimitry Andric if (!result_sp->IsSynthetic()) {
27957aa51b79SEd Maste if (result_sp->GetSyntheticValue())
27967aa51b79SEd Maste result_sp = result_sp->GetSyntheticValue();
27977aa51b79SEd Maste }
2798435933ddSDimitry Andric } else {
2799435933ddSDimitry Andric if (result_sp->IsSynthetic()) {
28007aa51b79SEd Maste if (result_sp->GetNonSyntheticValue())
28017aa51b79SEd Maste result_sp = result_sp->GetNonSyntheticValue();
28027aa51b79SEd Maste }
28037aa51b79SEd Maste }
28047aa51b79SEd Maste
28057aa51b79SEd Maste return result_sp;
28067aa51b79SEd Maste }
28077aa51b79SEd Maste
Dereference(Status & error)28085517e702SDimitry Andric ValueObjectSP ValueObject::Dereference(Status &error) {
2809ac7ddfbfSEd Maste if (m_deref_valobj)
2810ac7ddfbfSEd Maste return m_deref_valobj->GetSP();
2811ac7ddfbfSEd Maste
28129f2f44ceSEd Maste const bool is_pointer_or_reference_type = IsPointerOrReferenceType();
2813435933ddSDimitry Andric if (is_pointer_or_reference_type) {
2814ac7ddfbfSEd Maste bool omit_empty_base_classes = true;
2815ac7ddfbfSEd Maste bool ignore_array_bounds = false;
2816ac7ddfbfSEd Maste
2817ac7ddfbfSEd Maste std::string child_name_str;
2818ac7ddfbfSEd Maste uint32_t child_byte_size = 0;
2819ac7ddfbfSEd Maste int32_t child_byte_offset = 0;
2820ac7ddfbfSEd Maste uint32_t child_bitfield_bit_size = 0;
2821ac7ddfbfSEd Maste uint32_t child_bitfield_bit_offset = 0;
2822ac7ddfbfSEd Maste bool child_is_base_class = false;
2823ac7ddfbfSEd Maste bool child_is_deref_of_parent = false;
2824ac7ddfbfSEd Maste const bool transparent_pointers = false;
28259f2f44ceSEd Maste CompilerType compiler_type = GetCompilerType();
28269f2f44ceSEd Maste CompilerType child_compiler_type;
28279f2f44ceSEd Maste uint64_t language_flags;
2828ac7ddfbfSEd Maste
2829ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
2830ac7ddfbfSEd Maste
2831435933ddSDimitry Andric child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex(
2832435933ddSDimitry Andric &exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
2833435933ddSDimitry Andric ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
2834435933ddSDimitry Andric child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
2835435933ddSDimitry Andric child_is_deref_of_parent, this, language_flags);
2836435933ddSDimitry Andric if (child_compiler_type && child_byte_size) {
2837ac7ddfbfSEd Maste ConstString child_name;
2838ac7ddfbfSEd Maste if (!child_name_str.empty())
2839ac7ddfbfSEd Maste child_name.SetCString(child_name_str.c_str());
2840ac7ddfbfSEd Maste
2841435933ddSDimitry Andric m_deref_valobj = new ValueObjectChild(
2842435933ddSDimitry Andric *this, child_compiler_type, child_name, child_byte_size,
2843435933ddSDimitry Andric child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
2844435933ddSDimitry Andric child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
28459f2f44ceSEd Maste language_flags);
2846ac7ddfbfSEd Maste }
2847f678e45dSDimitry Andric } else if (HasSyntheticValue()) {
2848f678e45dSDimitry Andric m_deref_valobj =
2849f678e45dSDimitry Andric GetSyntheticValue()
2850f678e45dSDimitry Andric ->GetChildMemberWithName(ConstString("$$dereference$$"), true)
2851f678e45dSDimitry Andric .get();
2852ac7ddfbfSEd Maste }
2853ac7ddfbfSEd Maste
2854435933ddSDimitry Andric if (m_deref_valobj) {
2855ac7ddfbfSEd Maste error.Clear();
2856ac7ddfbfSEd Maste return m_deref_valobj->GetSP();
2857435933ddSDimitry Andric } else {
2858ac7ddfbfSEd Maste StreamString strm;
2859ac7ddfbfSEd Maste GetExpressionPath(strm, true);
2860ac7ddfbfSEd Maste
28619f2f44ceSEd Maste if (is_pointer_or_reference_type)
2862435933ddSDimitry Andric error.SetErrorStringWithFormat("dereference failed: (%s) %s",
2863435933ddSDimitry Andric GetTypeName().AsCString("<invalid type>"),
2864435933ddSDimitry Andric strm.GetData());
2865ac7ddfbfSEd Maste else
2866435933ddSDimitry Andric error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
2867435933ddSDimitry Andric GetTypeName().AsCString("<invalid type>"),
2868435933ddSDimitry Andric strm.GetData());
2869ac7ddfbfSEd Maste return ValueObjectSP();
2870ac7ddfbfSEd Maste }
2871ac7ddfbfSEd Maste }
2872ac7ddfbfSEd Maste
AddressOf(Status & error)28735517e702SDimitry Andric ValueObjectSP ValueObject::AddressOf(Status &error) {
2874ac7ddfbfSEd Maste if (m_addr_of_valobj_sp)
2875ac7ddfbfSEd Maste return m_addr_of_valobj_sp;
2876ac7ddfbfSEd Maste
2877ac7ddfbfSEd Maste AddressType address_type = eAddressTypeInvalid;
2878ac7ddfbfSEd Maste const bool scalar_is_load_address = false;
2879ac7ddfbfSEd Maste addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
2880ac7ddfbfSEd Maste error.Clear();
2881435933ddSDimitry Andric if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
2882435933ddSDimitry Andric switch (address_type) {
2883435933ddSDimitry Andric case eAddressTypeInvalid: {
2884ac7ddfbfSEd Maste StreamString expr_path_strm;
2885ac7ddfbfSEd Maste GetExpressionPath(expr_path_strm, true);
2886435933ddSDimitry Andric error.SetErrorStringWithFormat("'%s' is not in memory",
2887435933ddSDimitry Andric expr_path_strm.GetData());
2888435933ddSDimitry Andric } break;
2889ac7ddfbfSEd Maste
2890ac7ddfbfSEd Maste case eAddressTypeFile:
2891435933ddSDimitry Andric case eAddressTypeLoad: {
28929f2f44ceSEd Maste CompilerType compiler_type = GetCompilerType();
2893435933ddSDimitry Andric if (compiler_type) {
2894ac7ddfbfSEd Maste std::string name(1, '&');
2895ac7ddfbfSEd Maste name.append(m_name.AsCString(""));
2896ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
2897435933ddSDimitry Andric m_addr_of_valobj_sp = ValueObjectConstResult::Create(
2898435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(),
2899435933ddSDimitry Andric compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
2900435933ddSDimitry Andric eAddressTypeInvalid, m_data.GetAddressByteSize());
2901ac7ddfbfSEd Maste }
2902435933ddSDimitry Andric } break;
29031c3bbb01SEd Maste default:
29041c3bbb01SEd Maste break;
2905ac7ddfbfSEd Maste }
2906435933ddSDimitry Andric } else {
2907ac7ddfbfSEd Maste StreamString expr_path_strm;
2908ac7ddfbfSEd Maste GetExpressionPath(expr_path_strm, true);
2909435933ddSDimitry Andric error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
2910435933ddSDimitry Andric expr_path_strm.GetData());
2911ac7ddfbfSEd Maste }
2912ac7ddfbfSEd Maste
2913ac7ddfbfSEd Maste return m_addr_of_valobj_sp;
2914ac7ddfbfSEd Maste }
2915ac7ddfbfSEd Maste
Cast(const CompilerType & compiler_type)2916435933ddSDimitry Andric ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
29179f2f44ceSEd Maste return ValueObjectCast::Create(*this, GetName(), compiler_type);
2918ac7ddfbfSEd Maste }
2919ac7ddfbfSEd Maste
Clone(const ConstString & new_name)2920f678e45dSDimitry Andric lldb::ValueObjectSP ValueObject::Clone(const ConstString &new_name) {
2921f678e45dSDimitry Andric return ValueObjectCast::Create(*this, new_name, GetCompilerType());
2922f678e45dSDimitry Andric }
2923f678e45dSDimitry Andric
CastPointerType(const char * name,CompilerType & compiler_type)2924435933ddSDimitry Andric ValueObjectSP ValueObject::CastPointerType(const char *name,
2925435933ddSDimitry Andric CompilerType &compiler_type) {
2926ac7ddfbfSEd Maste ValueObjectSP valobj_sp;
2927ac7ddfbfSEd Maste AddressType address_type;
2928ac7ddfbfSEd Maste addr_t ptr_value = GetPointerValue(&address_type);
2929ac7ddfbfSEd Maste
2930435933ddSDimitry Andric if (ptr_value != LLDB_INVALID_ADDRESS) {
2931ac7ddfbfSEd Maste Address ptr_addr(ptr_value);
2932ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
2933435933ddSDimitry Andric valobj_sp = ValueObjectMemory::Create(
2934435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
2935ac7ddfbfSEd Maste }
2936ac7ddfbfSEd Maste return valobj_sp;
2937ac7ddfbfSEd Maste }
2938ac7ddfbfSEd Maste
CastPointerType(const char * name,TypeSP & type_sp)2939435933ddSDimitry Andric ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
2940ac7ddfbfSEd Maste ValueObjectSP valobj_sp;
2941ac7ddfbfSEd Maste AddressType address_type;
2942ac7ddfbfSEd Maste addr_t ptr_value = GetPointerValue(&address_type);
2943ac7ddfbfSEd Maste
2944435933ddSDimitry Andric if (ptr_value != LLDB_INVALID_ADDRESS) {
2945ac7ddfbfSEd Maste Address ptr_addr(ptr_value);
2946ac7ddfbfSEd Maste ExecutionContext exe_ctx(GetExecutionContextRef());
2947435933ddSDimitry Andric valobj_sp = ValueObjectMemory::Create(
2948435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
2949ac7ddfbfSEd Maste }
2950ac7ddfbfSEd Maste return valobj_sp;
2951ac7ddfbfSEd Maste }
2952ac7ddfbfSEd Maste
EvaluationPoint()2953435933ddSDimitry Andric ValueObject::EvaluationPoint::EvaluationPoint()
2954435933ddSDimitry Andric : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {}
2955ac7ddfbfSEd Maste
EvaluationPoint(ExecutionContextScope * exe_scope,bool use_selected)2956435933ddSDimitry Andric ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
2957435933ddSDimitry Andric bool use_selected)
2958435933ddSDimitry Andric : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {
2959ac7ddfbfSEd Maste ExecutionContext exe_ctx(exe_scope);
2960ac7ddfbfSEd Maste TargetSP target_sp(exe_ctx.GetTargetSP());
2961435933ddSDimitry Andric if (target_sp) {
2962ac7ddfbfSEd Maste m_exe_ctx_ref.SetTargetSP(target_sp);
2963ac7ddfbfSEd Maste ProcessSP process_sp(exe_ctx.GetProcessSP());
2964ac7ddfbfSEd Maste if (!process_sp)
2965ac7ddfbfSEd Maste process_sp = target_sp->GetProcessSP();
2966ac7ddfbfSEd Maste
2967435933ddSDimitry Andric if (process_sp) {
2968ac7ddfbfSEd Maste m_mod_id = process_sp->GetModID();
2969ac7ddfbfSEd Maste m_exe_ctx_ref.SetProcessSP(process_sp);
2970ac7ddfbfSEd Maste
2971ac7ddfbfSEd Maste ThreadSP thread_sp(exe_ctx.GetThreadSP());
2972ac7ddfbfSEd Maste
2973435933ddSDimitry Andric if (!thread_sp) {
2974ac7ddfbfSEd Maste if (use_selected)
2975ac7ddfbfSEd Maste thread_sp = process_sp->GetThreadList().GetSelectedThread();
2976ac7ddfbfSEd Maste }
2977ac7ddfbfSEd Maste
2978435933ddSDimitry Andric if (thread_sp) {
2979ac7ddfbfSEd Maste m_exe_ctx_ref.SetThreadSP(thread_sp);
2980ac7ddfbfSEd Maste
2981ac7ddfbfSEd Maste StackFrameSP frame_sp(exe_ctx.GetFrameSP());
2982435933ddSDimitry Andric if (!frame_sp) {
2983ac7ddfbfSEd Maste if (use_selected)
2984ac7ddfbfSEd Maste frame_sp = thread_sp->GetSelectedFrame();
2985ac7ddfbfSEd Maste }
2986ac7ddfbfSEd Maste if (frame_sp)
2987ac7ddfbfSEd Maste m_exe_ctx_ref.SetFrameSP(frame_sp);
2988ac7ddfbfSEd Maste }
2989ac7ddfbfSEd Maste }
2990ac7ddfbfSEd Maste }
2991ac7ddfbfSEd Maste }
2992ac7ddfbfSEd Maste
EvaluationPoint(const ValueObject::EvaluationPoint & rhs)2993435933ddSDimitry Andric ValueObject::EvaluationPoint::EvaluationPoint(
2994435933ddSDimitry Andric const ValueObject::EvaluationPoint &rhs)
2995435933ddSDimitry Andric : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {}
2996ac7ddfbfSEd Maste
~EvaluationPoint()2997435933ddSDimitry Andric ValueObject::EvaluationPoint::~EvaluationPoint() {}
2998ac7ddfbfSEd Maste
2999435933ddSDimitry Andric // This function checks the EvaluationPoint against the current process state.
30004ba319b5SDimitry Andric // If the current state matches the evaluation point, or the evaluation point
30014ba319b5SDimitry Andric // is already invalid, then we return false, meaning "no change". If the
30024ba319b5SDimitry Andric // current state is different, we update our state, and return true meaning
30034ba319b5SDimitry Andric // "yes, change". If we did see a change, we also set m_needs_update to true,
30044ba319b5SDimitry Andric // so future calls to NeedsUpdate will return true. exe_scope will be set to
30054ba319b5SDimitry Andric // the current execution context scope.
3006ac7ddfbfSEd Maste
SyncWithProcessState(bool accept_invalid_exe_ctx)3007435933ddSDimitry Andric bool ValueObject::EvaluationPoint::SyncWithProcessState(
3008435933ddSDimitry Andric bool accept_invalid_exe_ctx) {
30094ba319b5SDimitry Andric // Start with the target, if it is NULL, then we're obviously not going to
30104ba319b5SDimitry Andric // get any further:
301112b93ac6SEd Maste const bool thread_and_frame_only_if_stopped = true;
3012435933ddSDimitry Andric ExecutionContext exe_ctx(
3013435933ddSDimitry Andric m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
3014ac7ddfbfSEd Maste
3015ac7ddfbfSEd Maste if (exe_ctx.GetTargetPtr() == NULL)
3016ac7ddfbfSEd Maste return false;
3017ac7ddfbfSEd Maste
3018ac7ddfbfSEd Maste // If we don't have a process nothing can change.
3019ac7ddfbfSEd Maste Process *process = exe_ctx.GetProcessPtr();
3020ac7ddfbfSEd Maste if (process == NULL)
3021ac7ddfbfSEd Maste return false;
3022ac7ddfbfSEd Maste
3023ac7ddfbfSEd Maste // If our stop id is the current stop ID, nothing has changed:
3024ac7ddfbfSEd Maste ProcessModID current_mod_id = process->GetModID();
3025ac7ddfbfSEd Maste
3026435933ddSDimitry Andric // If the current stop id is 0, either we haven't run yet, or the process
30274ba319b5SDimitry Andric // state has been cleared. In either case, we aren't going to be able to sync
30284ba319b5SDimitry Andric // with the process state.
3029ac7ddfbfSEd Maste if (current_mod_id.GetStopID() == 0)
3030ac7ddfbfSEd Maste return false;
3031ac7ddfbfSEd Maste
3032ac7ddfbfSEd Maste bool changed = false;
3033ac7ddfbfSEd Maste const bool was_valid = m_mod_id.IsValid();
3034435933ddSDimitry Andric if (was_valid) {
3035435933ddSDimitry Andric if (m_mod_id == current_mod_id) {
30364ba319b5SDimitry Andric // Everything is already up to date in this object, no need to update the
30374ba319b5SDimitry Andric // execution context scope.
3038ac7ddfbfSEd Maste changed = false;
3039435933ddSDimitry Andric } else {
3040ac7ddfbfSEd Maste m_mod_id = current_mod_id;
3041ac7ddfbfSEd Maste m_needs_update = true;
3042ac7ddfbfSEd Maste changed = true;
3043ac7ddfbfSEd Maste }
3044ac7ddfbfSEd Maste }
3045ac7ddfbfSEd Maste
3046435933ddSDimitry Andric // Now re-look up the thread and frame in case the underlying objects have
30474ba319b5SDimitry Andric // gone away & been recreated. That way we'll be sure to return a valid
30484ba319b5SDimitry Andric // exe_scope. If we used to have a thread or a frame but can't find it
30494ba319b5SDimitry Andric // anymore, then mark ourselves as invalid.
3050ac7ddfbfSEd Maste
3051435933ddSDimitry Andric if (!accept_invalid_exe_ctx) {
3052435933ddSDimitry Andric if (m_exe_ctx_ref.HasThreadRef()) {
3053ac7ddfbfSEd Maste ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
3054435933ddSDimitry Andric if (thread_sp) {
3055435933ddSDimitry Andric if (m_exe_ctx_ref.HasFrameRef()) {
3056ac7ddfbfSEd Maste StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
3057435933ddSDimitry Andric if (!frame_sp) {
3058ac7ddfbfSEd Maste // We used to have a frame, but now it is gone
3059ac7ddfbfSEd Maste SetInvalid();
3060ac7ddfbfSEd Maste changed = was_valid;
3061ac7ddfbfSEd Maste }
3062ac7ddfbfSEd Maste }
3063435933ddSDimitry Andric } else {
3064ac7ddfbfSEd Maste // We used to have a thread, but now it is gone
3065ac7ddfbfSEd Maste SetInvalid();
3066ac7ddfbfSEd Maste changed = was_valid;
3067ac7ddfbfSEd Maste }
3068ac7ddfbfSEd Maste }
30691c3bbb01SEd Maste }
30701c3bbb01SEd Maste
3071ac7ddfbfSEd Maste return changed;
3072ac7ddfbfSEd Maste }
3073ac7ddfbfSEd Maste
SetUpdated()3074435933ddSDimitry Andric void ValueObject::EvaluationPoint::SetUpdated() {
3075ac7ddfbfSEd Maste ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
3076ac7ddfbfSEd Maste if (process_sp)
3077ac7ddfbfSEd Maste m_mod_id = process_sp->GetModID();
3078ac7ddfbfSEd Maste m_needs_update = false;
3079ac7ddfbfSEd Maste }
3080ac7ddfbfSEd Maste
ClearUserVisibleData(uint32_t clear_mask)3081435933ddSDimitry Andric void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
3082435933ddSDimitry Andric if ((clear_mask & eClearUserVisibleDataItemsValue) ==
3083435933ddSDimitry Andric eClearUserVisibleDataItemsValue)
3084ac7ddfbfSEd Maste m_value_str.clear();
3085ac7ddfbfSEd Maste
3086435933ddSDimitry Andric if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
3087435933ddSDimitry Andric eClearUserVisibleDataItemsLocation)
3088ac7ddfbfSEd Maste m_location_str.clear();
3089ac7ddfbfSEd Maste
3090435933ddSDimitry Andric if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
3091435933ddSDimitry Andric eClearUserVisibleDataItemsSummary)
3092ac7ddfbfSEd Maste m_summary_str.clear();
3093ac7ddfbfSEd Maste
3094435933ddSDimitry Andric if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
3095435933ddSDimitry Andric eClearUserVisibleDataItemsDescription)
3096ac7ddfbfSEd Maste m_object_desc_str.clear();
3097ac7ddfbfSEd Maste
3098435933ddSDimitry Andric if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
3099435933ddSDimitry Andric eClearUserVisibleDataItemsSyntheticChildren) {
3100ac7ddfbfSEd Maste if (m_synthetic_value)
3101ac7ddfbfSEd Maste m_synthetic_value = NULL;
3102ac7ddfbfSEd Maste }
31037aa51b79SEd Maste
3104435933ddSDimitry Andric if ((clear_mask & eClearUserVisibleDataItemsValidator) ==
3105435933ddSDimitry Andric eClearUserVisibleDataItemsValidator)
31067aa51b79SEd Maste m_validation_result.reset();
3107ac7ddfbfSEd Maste }
3108ac7ddfbfSEd Maste
GetSymbolContextScope()3109435933ddSDimitry Andric SymbolContextScope *ValueObject::GetSymbolContextScope() {
3110435933ddSDimitry Andric if (m_parent) {
3111ac7ddfbfSEd Maste if (!m_parent->IsPointerOrReferenceType())
3112ac7ddfbfSEd Maste return m_parent->GetSymbolContextScope();
3113ac7ddfbfSEd Maste }
3114ac7ddfbfSEd Maste return NULL;
3115ac7ddfbfSEd Maste }
3116ac7ddfbfSEd Maste
3117ac7ddfbfSEd Maste lldb::ValueObjectSP
CreateValueObjectFromExpression(llvm::StringRef name,llvm::StringRef expression,const ExecutionContext & exe_ctx)3118435933ddSDimitry Andric ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
3119435933ddSDimitry Andric llvm::StringRef expression,
3120435933ddSDimitry Andric const ExecutionContext &exe_ctx) {
3121435933ddSDimitry Andric return CreateValueObjectFromExpression(name, expression, exe_ctx,
3122435933ddSDimitry Andric EvaluateExpressionOptions());
31237aa51b79SEd Maste }
31247aa51b79SEd Maste
CreateValueObjectFromExpression(llvm::StringRef name,llvm::StringRef expression,const ExecutionContext & exe_ctx,const EvaluateExpressionOptions & options)3125435933ddSDimitry Andric lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
3126435933ddSDimitry Andric llvm::StringRef name, llvm::StringRef expression,
3127435933ddSDimitry Andric const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
3128ac7ddfbfSEd Maste lldb::ValueObjectSP retval_sp;
3129ac7ddfbfSEd Maste lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
3130ac7ddfbfSEd Maste if (!target_sp)
3131ac7ddfbfSEd Maste return retval_sp;
3132435933ddSDimitry Andric if (expression.empty())
3133ac7ddfbfSEd Maste return retval_sp;
3134435933ddSDimitry Andric target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
3135435933ddSDimitry Andric retval_sp, options);
3136435933ddSDimitry Andric if (retval_sp && !name.empty())
3137ac7ddfbfSEd Maste retval_sp->SetName(ConstString(name));
3138ac7ddfbfSEd Maste return retval_sp;
3139ac7ddfbfSEd Maste }
3140ac7ddfbfSEd Maste
CreateValueObjectFromAddress(llvm::StringRef name,uint64_t address,const ExecutionContext & exe_ctx,CompilerType type)3141435933ddSDimitry Andric lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
3142435933ddSDimitry Andric llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
3143435933ddSDimitry Andric CompilerType type) {
3144435933ddSDimitry Andric if (type) {
31459f2f44ceSEd Maste CompilerType pointer_type(type.GetPointerType());
3146435933ddSDimitry Andric if (pointer_type) {
3147435933ddSDimitry Andric lldb::DataBufferSP buffer(
3148435933ddSDimitry Andric new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
3149435933ddSDimitry Andric lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
3150435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(), pointer_type,
3151435933ddSDimitry Andric ConstString(name), buffer, exe_ctx.GetByteOrder(),
3152ac7ddfbfSEd Maste exe_ctx.GetAddressByteSize()));
3153435933ddSDimitry Andric if (ptr_result_valobj_sp) {
3154435933ddSDimitry Andric ptr_result_valobj_sp->GetValue().SetValueType(
3155435933ddSDimitry Andric Value::eValueTypeLoadAddress);
31565517e702SDimitry Andric Status err;
3157ac7ddfbfSEd Maste ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
3158435933ddSDimitry Andric if (ptr_result_valobj_sp && !name.empty())
3159ac7ddfbfSEd Maste ptr_result_valobj_sp->SetName(ConstString(name));
3160ac7ddfbfSEd Maste }
3161ac7ddfbfSEd Maste return ptr_result_valobj_sp;
3162ac7ddfbfSEd Maste }
3163ac7ddfbfSEd Maste }
3164ac7ddfbfSEd Maste return lldb::ValueObjectSP();
3165ac7ddfbfSEd Maste }
3166ac7ddfbfSEd Maste
CreateValueObjectFromData(llvm::StringRef name,const DataExtractor & data,const ExecutionContext & exe_ctx,CompilerType type)3167435933ddSDimitry Andric lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
3168435933ddSDimitry Andric llvm::StringRef name, const DataExtractor &data,
3169435933ddSDimitry Andric const ExecutionContext &exe_ctx, CompilerType type) {
3170ac7ddfbfSEd Maste lldb::ValueObjectSP new_value_sp;
3171435933ddSDimitry Andric new_value_sp = ValueObjectConstResult::Create(
3172435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
3173ac7ddfbfSEd Maste LLDB_INVALID_ADDRESS);
3174ac7ddfbfSEd Maste new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
3175435933ddSDimitry Andric if (new_value_sp && !name.empty())
3176ac7ddfbfSEd Maste new_value_sp->SetName(ConstString(name));
3177ac7ddfbfSEd Maste return new_value_sp;
3178ac7ddfbfSEd Maste }
3179ac7ddfbfSEd Maste
GetModule()3180435933ddSDimitry Andric ModuleSP ValueObject::GetModule() {
3181ac7ddfbfSEd Maste ValueObject *root(GetRoot());
3182ac7ddfbfSEd Maste if (root != this)
3183ac7ddfbfSEd Maste return root->GetModule();
3184ac7ddfbfSEd Maste return lldb::ModuleSP();
3185ac7ddfbfSEd Maste }
3186ac7ddfbfSEd Maste
GetRoot()3187435933ddSDimitry Andric ValueObject *ValueObject::GetRoot() {
3188ac7ddfbfSEd Maste if (m_root)
3189ac7ddfbfSEd Maste return m_root;
31901c3bbb01SEd Maste return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
31911c3bbb01SEd Maste return (vo->m_parent != nullptr);
31921c3bbb01SEd Maste }));
3193ac7ddfbfSEd Maste }
31941c3bbb01SEd Maste
31951c3bbb01SEd Maste ValueObject *
FollowParentChain(std::function<bool (ValueObject *)> f)3196435933ddSDimitry Andric ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
31971c3bbb01SEd Maste ValueObject *vo = this;
3198435933ddSDimitry Andric while (vo) {
3199*b5893f02SDimitry Andric if (!f(vo))
32001c3bbb01SEd Maste break;
32011c3bbb01SEd Maste vo = vo->m_parent;
32021c3bbb01SEd Maste }
32031c3bbb01SEd Maste return vo;
3204ac7ddfbfSEd Maste }
3205ac7ddfbfSEd Maste
GetAddressTypeOfChildren()3206435933ddSDimitry Andric AddressType ValueObject::GetAddressTypeOfChildren() {
3207435933ddSDimitry Andric if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
3208ac7ddfbfSEd Maste ValueObject *root(GetRoot());
3209ac7ddfbfSEd Maste if (root != this)
3210ac7ddfbfSEd Maste return root->GetAddressTypeOfChildren();
3211ac7ddfbfSEd Maste }
3212ac7ddfbfSEd Maste return m_address_type_of_ptr_or_ref_children;
3213ac7ddfbfSEd Maste }
3214ac7ddfbfSEd Maste
GetDynamicValueType()3215435933ddSDimitry Andric lldb::DynamicValueType ValueObject::GetDynamicValueType() {
3216ac7ddfbfSEd Maste ValueObject *with_dv_info = this;
3217435933ddSDimitry Andric while (with_dv_info) {
3218ac7ddfbfSEd Maste if (with_dv_info->HasDynamicValueTypeInfo())
3219ac7ddfbfSEd Maste return with_dv_info->GetDynamicValueTypeImpl();
3220ac7ddfbfSEd Maste with_dv_info = with_dv_info->m_parent;
3221ac7ddfbfSEd Maste }
3222ac7ddfbfSEd Maste return lldb::eNoDynamicValues;
3223ac7ddfbfSEd Maste }
3224ac7ddfbfSEd Maste
GetFormat() const3225435933ddSDimitry Andric lldb::Format ValueObject::GetFormat() const {
3226ac7ddfbfSEd Maste const ValueObject *with_fmt_info = this;
3227435933ddSDimitry Andric while (with_fmt_info) {
3228ac7ddfbfSEd Maste if (with_fmt_info->m_format != lldb::eFormatDefault)
3229ac7ddfbfSEd Maste return with_fmt_info->m_format;
3230ac7ddfbfSEd Maste with_fmt_info = with_fmt_info->m_parent;
3231ac7ddfbfSEd Maste }
3232ac7ddfbfSEd Maste return m_format;
3233ac7ddfbfSEd Maste }
32347aa51b79SEd Maste
GetPreferredDisplayLanguage()3235435933ddSDimitry Andric lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
32361c3bbb01SEd Maste lldb::LanguageType type = m_preferred_display_language;
3237435933ddSDimitry Andric if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3238435933ddSDimitry Andric if (GetRoot()) {
3239435933ddSDimitry Andric if (GetRoot() == this) {
3240435933ddSDimitry Andric if (StackFrameSP frame_sp = GetFrameSP()) {
3241435933ddSDimitry Andric const SymbolContext &sc(
3242435933ddSDimitry Andric frame_sp->GetSymbolContext(eSymbolContextCompUnit));
32437aa51b79SEd Maste if (CompileUnit *cu = sc.comp_unit)
32447aa51b79SEd Maste type = cu->GetLanguage();
32457aa51b79SEd Maste }
3246435933ddSDimitry Andric } else {
32477aa51b79SEd Maste type = GetRoot()->GetPreferredDisplayLanguage();
32487aa51b79SEd Maste }
32497aa51b79SEd Maste }
32501c3bbb01SEd Maste }
32511c3bbb01SEd Maste return (m_preferred_display_language = type); // only compute it once
32521c3bbb01SEd Maste }
32531c3bbb01SEd Maste
SetPreferredDisplayLanguage(lldb::LanguageType lt)3254435933ddSDimitry Andric void ValueObject::SetPreferredDisplayLanguage(lldb::LanguageType lt) {
32551c3bbb01SEd Maste m_preferred_display_language = lt;
32567aa51b79SEd Maste }
32577aa51b79SEd Maste
SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt)3258435933ddSDimitry Andric void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
32599f2f44ceSEd Maste if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
32609f2f44ceSEd Maste SetPreferredDisplayLanguage(lt);
32619f2f44ceSEd Maste }
32629f2f44ceSEd Maste
CanProvideValue()3263435933ddSDimitry Andric bool ValueObject::CanProvideValue() {
32644ba319b5SDimitry Andric // we need to support invalid types as providers of values because some bare-
32654ba319b5SDimitry Andric // board debugging scenarios have no notion of types, but still manage to
32664ba319b5SDimitry Andric // have raw numeric values for things like registers. sigh.
32679f2f44ceSEd Maste const CompilerType &type(GetCompilerType());
3268*b5893f02SDimitry Andric return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
32697aa51b79SEd Maste }
32707aa51b79SEd Maste
IsChecksumEmpty()3271435933ddSDimitry Andric bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); }
32727aa51b79SEd Maste
Persist()3273435933ddSDimitry Andric ValueObjectSP ValueObject::Persist() {
32747aa51b79SEd Maste if (!UpdateValueIfNeeded())
32757aa51b79SEd Maste return nullptr;
32767aa51b79SEd Maste
32777aa51b79SEd Maste TargetSP target_sp(GetTargetSP());
32787aa51b79SEd Maste if (!target_sp)
32797aa51b79SEd Maste return nullptr;
32807aa51b79SEd Maste
3281435933ddSDimitry Andric PersistentExpressionState *persistent_state =
3282435933ddSDimitry Andric target_sp->GetPersistentExpressionStateForLanguage(
3283435933ddSDimitry Andric GetPreferredDisplayLanguage());
32847aa51b79SEd Maste
32859f2f44ceSEd Maste if (!persistent_state)
32869f2f44ceSEd Maste return nullptr;
32879f2f44ceSEd Maste
32884ba319b5SDimitry Andric auto prefix = persistent_state->GetPersistentVariablePrefix();
32894ba319b5SDimitry Andric ConstString name =
32904ba319b5SDimitry Andric persistent_state->GetNextPersistentVariableName(*target_sp, prefix);
32919f2f44ceSEd Maste
3292435933ddSDimitry Andric ValueObjectSP const_result_sp =
3293435933ddSDimitry Andric ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
32949f2f44ceSEd Maste
3295435933ddSDimitry Andric ExpressionVariableSP clang_var_sp =
3296435933ddSDimitry Andric persistent_state->CreatePersistentVariable(const_result_sp);
32977aa51b79SEd Maste clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp;
32989f2f44ceSEd Maste clang_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;
32997aa51b79SEd Maste
33007aa51b79SEd Maste return clang_var_sp->GetValueObject();
33017aa51b79SEd Maste }
33027aa51b79SEd Maste
IsSyntheticChildrenGenerated()3303435933ddSDimitry Andric bool ValueObject::IsSyntheticChildrenGenerated() {
33047aa51b79SEd Maste return m_is_synthetic_children_generated;
33057aa51b79SEd Maste }
33067aa51b79SEd Maste
SetSyntheticChildrenGenerated(bool b)3307435933ddSDimitry Andric void ValueObject::SetSyntheticChildrenGenerated(bool b) {
33087aa51b79SEd Maste m_is_synthetic_children_generated = b;
33097aa51b79SEd Maste }
33109f2f44ceSEd Maste
GetLanguageFlags()3311435933ddSDimitry Andric uint64_t ValueObject::GetLanguageFlags() { return m_language_flags; }
3312435933ddSDimitry Andric
SetLanguageFlags(uint64_t flags)3313435933ddSDimitry Andric void ValueObject::SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }
3314435933ddSDimitry Andric
ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,lldb::DynamicValueType use_dynamic,bool use_synthetic)3315435933ddSDimitry Andric ValueObjectManager::ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,
3316435933ddSDimitry Andric lldb::DynamicValueType use_dynamic,
3317435933ddSDimitry Andric bool use_synthetic) : m_root_valobj_sp(),
3318435933ddSDimitry Andric m_user_valobj_sp(), m_use_dynamic(use_dynamic), m_stop_id(UINT32_MAX),
3319435933ddSDimitry Andric m_use_synthetic(use_synthetic) {
3320435933ddSDimitry Andric if (!in_valobj_sp)
3321435933ddSDimitry Andric return;
3322435933ddSDimitry Andric // If the user passes in a value object that is dynamic or synthetic, then
3323435933ddSDimitry Andric // water it down to the static type.
3324435933ddSDimitry Andric m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false);
33259f2f44ceSEd Maste }
33269f2f44ceSEd Maste
IsValid() const3327435933ddSDimitry Andric bool ValueObjectManager::IsValid() const {
3328435933ddSDimitry Andric if (!m_root_valobj_sp)
3329435933ddSDimitry Andric return false;
3330435933ddSDimitry Andric lldb::TargetSP target_sp = GetTargetSP();
3331435933ddSDimitry Andric if (target_sp)
3332435933ddSDimitry Andric return target_sp->IsValid();
3333435933ddSDimitry Andric return false;
33349f2f44ceSEd Maste }
3335435933ddSDimitry Andric
GetSP()3336435933ddSDimitry Andric lldb::ValueObjectSP ValueObjectManager::GetSP() {
3337435933ddSDimitry Andric lldb::ProcessSP process_sp = GetProcessSP();
3338435933ddSDimitry Andric if (!process_sp)
3339435933ddSDimitry Andric return lldb::ValueObjectSP();
3340435933ddSDimitry Andric
3341435933ddSDimitry Andric const uint32_t current_stop_id = process_sp->GetLastNaturalStopID();
3342435933ddSDimitry Andric if (current_stop_id == m_stop_id)
3343435933ddSDimitry Andric return m_user_valobj_sp;
3344435933ddSDimitry Andric
3345435933ddSDimitry Andric m_stop_id = current_stop_id;
3346435933ddSDimitry Andric
3347435933ddSDimitry Andric if (!m_root_valobj_sp) {
3348435933ddSDimitry Andric m_user_valobj_sp.reset();
3349435933ddSDimitry Andric return m_root_valobj_sp;
3350435933ddSDimitry Andric }
3351435933ddSDimitry Andric
3352435933ddSDimitry Andric m_user_valobj_sp = m_root_valobj_sp;
3353435933ddSDimitry Andric
3354435933ddSDimitry Andric if (m_use_dynamic != lldb::eNoDynamicValues) {
3355435933ddSDimitry Andric lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic);
3356435933ddSDimitry Andric if (dynamic_sp)
3357435933ddSDimitry Andric m_user_valobj_sp = dynamic_sp;
3358435933ddSDimitry Andric }
3359435933ddSDimitry Andric
3360435933ddSDimitry Andric if (m_use_synthetic) {
3361435933ddSDimitry Andric lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic);
3362435933ddSDimitry Andric if (synthetic_sp)
3363435933ddSDimitry Andric m_user_valobj_sp = synthetic_sp;
3364435933ddSDimitry Andric }
3365435933ddSDimitry Andric
3366435933ddSDimitry Andric return m_user_valobj_sp;
3367435933ddSDimitry Andric }
3368435933ddSDimitry Andric
SetUseDynamic(lldb::DynamicValueType use_dynamic)3369435933ddSDimitry Andric void ValueObjectManager::SetUseDynamic(lldb::DynamicValueType use_dynamic) {
3370435933ddSDimitry Andric if (use_dynamic != m_use_dynamic) {
3371435933ddSDimitry Andric m_use_dynamic = use_dynamic;
3372435933ddSDimitry Andric m_user_valobj_sp.reset();
3373435933ddSDimitry Andric m_stop_id = UINT32_MAX;
3374435933ddSDimitry Andric }
3375435933ddSDimitry Andric }
3376435933ddSDimitry Andric
SetUseSynthetic(bool use_synthetic)3377435933ddSDimitry Andric void ValueObjectManager::SetUseSynthetic(bool use_synthetic) {
3378435933ddSDimitry Andric if (m_use_synthetic != use_synthetic) {
3379435933ddSDimitry Andric m_use_synthetic = use_synthetic;
3380435933ddSDimitry Andric m_user_valobj_sp.reset();
3381435933ddSDimitry Andric m_stop_id = UINT32_MAX;
3382435933ddSDimitry Andric }
3383435933ddSDimitry Andric }
3384435933ddSDimitry Andric
GetTargetSP() const3385435933ddSDimitry Andric lldb::TargetSP ValueObjectManager::GetTargetSP() const {
3386435933ddSDimitry Andric if (!m_root_valobj_sp)
3387435933ddSDimitry Andric return m_root_valobj_sp->GetTargetSP();
3388435933ddSDimitry Andric return lldb::TargetSP();
3389435933ddSDimitry Andric }
3390435933ddSDimitry Andric
GetProcessSP() const3391435933ddSDimitry Andric lldb::ProcessSP ValueObjectManager::GetProcessSP() const {
3392435933ddSDimitry Andric if (m_root_valobj_sp)
3393435933ddSDimitry Andric return m_root_valobj_sp->GetProcessSP();
3394435933ddSDimitry Andric return lldb::ProcessSP();
3395435933ddSDimitry Andric }
3396435933ddSDimitry Andric
GetThreadSP() const3397435933ddSDimitry Andric lldb::ThreadSP ValueObjectManager::GetThreadSP() const {
3398435933ddSDimitry Andric if (m_root_valobj_sp)
3399435933ddSDimitry Andric return m_root_valobj_sp->GetThreadSP();
3400435933ddSDimitry Andric return lldb::ThreadSP();
3401435933ddSDimitry Andric }
3402435933ddSDimitry Andric
GetFrameSP() const3403435933ddSDimitry Andric lldb::StackFrameSP ValueObjectManager::GetFrameSP() const {
3404435933ddSDimitry Andric if (m_root_valobj_sp)
3405435933ddSDimitry Andric return m_root_valobj_sp->GetFrameSP();
3406435933ddSDimitry Andric return lldb::StackFrameSP();
3407435933ddSDimitry Andric }
3408435933ddSDimitry Andric
3409