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