1 //===-- ValueObject.cpp ---------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Core/ValueObject.h"
10 
11 #include "lldb/Core/Address.h"
12 #include "lldb/Core/Declaration.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ValueObjectCast.h"
15 #include "lldb/Core/ValueObjectChild.h"
16 #include "lldb/Core/ValueObjectConstResult.h"
17 #include "lldb/Core/ValueObjectDynamicValue.h"
18 #include "lldb/Core/ValueObjectMemory.h"
19 #include "lldb/Core/ValueObjectSyntheticFilter.h"
20 #include "lldb/DataFormatters/DataVisualization.h"
21 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
22 #include "lldb/DataFormatters/FormatManager.h"
23 #include "lldb/DataFormatters/StringPrinter.h"
24 #include "lldb/DataFormatters/TypeFormat.h"
25 #include "lldb/DataFormatters/TypeSummary.h"
26 #include "lldb/DataFormatters/ValueObjectPrinter.h"
27 #include "lldb/Expression/ExpressionVariable.h"
28 #include "lldb/Host/Config.h"
29 #include "lldb/Symbol/CompileUnit.h"
30 #include "lldb/Symbol/CompilerType.h"
31 #include "lldb/Symbol/SymbolContext.h"
32 #include "lldb/Symbol/Type.h"
33 #include "lldb/Symbol/Variable.h"
34 #include "lldb/Target/ExecutionContext.h"
35 #include "lldb/Target/Language.h"
36 #include "lldb/Target/LanguageRuntime.h"
37 #include "lldb/Target/Process.h"
38 #include "lldb/Target/StackFrame.h"
39 #include "lldb/Target/Target.h"
40 #include "lldb/Target/Thread.h"
41 #include "lldb/Target/ThreadList.h"
42 #include "lldb/Utility/DataBuffer.h"
43 #include "lldb/Utility/DataBufferHeap.h"
44 #include "lldb/Utility/Flags.h"
45 #include "lldb/Utility/LLDBLog.h"
46 #include "lldb/Utility/Log.h"
47 #include "lldb/Utility/Scalar.h"
48 #include "lldb/Utility/Stream.h"
49 #include "lldb/Utility/StreamString.h"
50 #include "lldb/lldb-private-types.h"
51 
52 #include "llvm/Support/Compiler.h"
53 
54 #include <algorithm>
55 #include <cstdint>
56 #include <cstdlib>
57 #include <memory>
58 #include <optional>
59 #include <tuple>
60 
61 #include <cassert>
62 #include <cinttypes>
63 #include <cstdio>
64 #include <cstring>
65 
66 #include <lldb/Core/ValueObject.h>
67 
68 namespace lldb_private {
69 class ExecutionContextScope;
70 }
71 namespace lldb_private {
72 class SymbolContextScope;
73 }
74 
75 using namespace lldb;
76 using namespace lldb_private;
77 
78 static user_id_t g_value_obj_uid = 0;
79 
80 // ValueObject constructor
ValueObject(ValueObject & parent)81 ValueObject::ValueObject(ValueObject &parent)
82     : m_parent(&parent), m_update_point(parent.GetUpdatePoint()),
83       m_manager(parent.GetManager()), m_id(++g_value_obj_uid) {
84   m_flags.m_is_synthetic_children_generated =
85       parent.m_flags.m_is_synthetic_children_generated;
86   m_data.SetByteOrder(parent.GetDataExtractor().GetByteOrder());
87   m_data.SetAddressByteSize(parent.GetDataExtractor().GetAddressByteSize());
88   m_manager->ManageObject(this);
89 }
90 
91 // ValueObject constructor
ValueObject(ExecutionContextScope * exe_scope,ValueObjectManager & manager,AddressType child_ptr_or_ref_addr_type)92 ValueObject::ValueObject(ExecutionContextScope *exe_scope,
93                          ValueObjectManager &manager,
94                          AddressType child_ptr_or_ref_addr_type)
95     : m_update_point(exe_scope), m_manager(&manager),
96       m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
97       m_id(++g_value_obj_uid) {
98   if (exe_scope) {
99     TargetSP target_sp(exe_scope->CalculateTarget());
100     if (target_sp) {
101       const ArchSpec &arch = target_sp->GetArchitecture();
102       m_data.SetByteOrder(arch.GetByteOrder());
103       m_data.SetAddressByteSize(arch.GetAddressByteSize());
104     }
105   }
106   m_manager->ManageObject(this);
107 }
108 
109 // Destructor
110 ValueObject::~ValueObject() = default;
111 
UpdateValueIfNeeded(bool update_format)112 bool ValueObject::UpdateValueIfNeeded(bool update_format) {
113 
114   bool did_change_formats = false;
115 
116   if (update_format)
117     did_change_formats = UpdateFormatsIfNeeded();
118 
119   // If this is a constant value, then our success is predicated on whether we
120   // have an error or not
121   if (GetIsConstant()) {
122     // if you are constant, things might still have changed behind your back
123     // (e.g. you are a frozen object and things have changed deeper than you
124     // cared to freeze-dry yourself) in this case, your value has not changed,
125     // but "computed" entries might have, so you might now have a different
126     // summary, or a different object description. clear these so we will
127     // recompute them
128     if (update_format && !did_change_formats)
129       ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
130                            eClearUserVisibleDataItemsDescription);
131     return m_error.Success();
132   }
133 
134   bool first_update = IsChecksumEmpty();
135 
136   if (NeedsUpdating()) {
137     m_update_point.SetUpdated();
138 
139     // Save the old value using swap to avoid a string copy which also will
140     // clear our m_value_str
141     if (m_value_str.empty()) {
142       m_flags.m_old_value_valid = false;
143     } else {
144       m_flags.m_old_value_valid = true;
145       m_old_value_str.swap(m_value_str);
146       ClearUserVisibleData(eClearUserVisibleDataItemsValue);
147     }
148 
149     ClearUserVisibleData();
150 
151     if (IsInScope()) {
152       const bool value_was_valid = GetValueIsValid();
153       SetValueDidChange(false);
154 
155       m_error.Clear();
156 
157       // Call the pure virtual function to update the value
158 
159       bool need_compare_checksums = false;
160       llvm::SmallVector<uint8_t, 16> old_checksum;
161 
162       if (!first_update && CanProvideValue()) {
163         need_compare_checksums = true;
164         old_checksum.resize(m_value_checksum.size());
165         std::copy(m_value_checksum.begin(), m_value_checksum.end(),
166                   old_checksum.begin());
167       }
168 
169       bool success = UpdateValue();
170 
171       SetValueIsValid(success);
172 
173       if (success) {
174         UpdateChildrenAddressType();
175         const uint64_t max_checksum_size = 128;
176         m_data.Checksum(m_value_checksum, max_checksum_size);
177       } else {
178         need_compare_checksums = false;
179         m_value_checksum.clear();
180       }
181 
182       assert(!need_compare_checksums ||
183              (!old_checksum.empty() && !m_value_checksum.empty()));
184 
185       if (first_update)
186         SetValueDidChange(false);
187       else if (!m_flags.m_value_did_change && !success) {
188         // The value wasn't gotten successfully, so we mark this as changed if
189         // the value used to be valid and now isn't
190         SetValueDidChange(value_was_valid);
191       } else if (need_compare_checksums) {
192         SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
193                                  m_value_checksum.size()));
194       }
195 
196     } else {
197       m_error.SetErrorString("out of scope");
198     }
199   }
200   return m_error.Success();
201 }
202 
UpdateFormatsIfNeeded()203 bool ValueObject::UpdateFormatsIfNeeded() {
204   Log *log = GetLog(LLDBLog::DataFormatters);
205   LLDB_LOGF(log,
206             "[%s %p] checking for FormatManager revisions. ValueObject "
207             "rev: %d - Global rev: %d",
208             GetName().GetCString(), static_cast<void *>(this),
209             m_last_format_mgr_revision,
210             DataVisualization::GetCurrentRevision());
211 
212   bool any_change = false;
213 
214   if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
215     m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
216     any_change = true;
217 
218     SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
219     SetSummaryFormat(
220         DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
221 #if LLDB_ENABLE_PYTHON
222     SetSyntheticChildren(
223         DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
224 #endif
225   }
226 
227   return any_change;
228 }
229 
SetNeedsUpdate()230 void ValueObject::SetNeedsUpdate() {
231   m_update_point.SetNeedsUpdate();
232   // We have to clear the value string here so ConstResult children will notice
233   // if their values are changed by hand (i.e. with SetValueAsCString).
234   ClearUserVisibleData(eClearUserVisibleDataItemsValue);
235 }
236 
ClearDynamicTypeInformation()237 void ValueObject::ClearDynamicTypeInformation() {
238   m_flags.m_children_count_valid = false;
239   m_flags.m_did_calculate_complete_objc_class_type = false;
240   m_last_format_mgr_revision = 0;
241   m_override_type = CompilerType();
242   SetValueFormat(lldb::TypeFormatImplSP());
243   SetSummaryFormat(lldb::TypeSummaryImplSP());
244   SetSyntheticChildren(lldb::SyntheticChildrenSP());
245 }
246 
MaybeCalculateCompleteType()247 CompilerType ValueObject::MaybeCalculateCompleteType() {
248   CompilerType compiler_type(GetCompilerTypeImpl());
249 
250   if (m_flags.m_did_calculate_complete_objc_class_type) {
251     if (m_override_type.IsValid())
252       return m_override_type;
253     else
254       return compiler_type;
255   }
256 
257   m_flags.m_did_calculate_complete_objc_class_type = true;
258 
259   ProcessSP process_sp(
260       GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
261 
262   if (!process_sp)
263     return compiler_type;
264 
265   if (auto *runtime =
266           process_sp->GetLanguageRuntime(GetObjectRuntimeLanguage())) {
267     if (std::optional<CompilerType> complete_type =
268             runtime->GetRuntimeType(compiler_type)) {
269       m_override_type = *complete_type;
270       if (m_override_type.IsValid())
271         return m_override_type;
272     }
273   }
274   return compiler_type;
275 }
276 
277 
278 
GetDataExtractor()279 DataExtractor &ValueObject::GetDataExtractor() {
280   UpdateValueIfNeeded(false);
281   return m_data;
282 }
283 
GetError()284 const Status &ValueObject::GetError() {
285   UpdateValueIfNeeded(false);
286   return m_error;
287 }
288 
GetLocationAsCStringImpl(const Value & value,const DataExtractor & data)289 const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
290                                                   const DataExtractor &data) {
291   if (UpdateValueIfNeeded(false)) {
292     if (m_location_str.empty()) {
293       StreamString sstr;
294 
295       Value::ValueType value_type = value.GetValueType();
296 
297       switch (value_type) {
298       case Value::ValueType::Invalid:
299         m_location_str = "invalid";
300         break;
301       case Value::ValueType::Scalar:
302         if (value.GetContextType() == Value::ContextType::RegisterInfo) {
303           RegisterInfo *reg_info = value.GetRegisterInfo();
304           if (reg_info) {
305             if (reg_info->name)
306               m_location_str = reg_info->name;
307             else if (reg_info->alt_name)
308               m_location_str = reg_info->alt_name;
309             if (m_location_str.empty())
310               m_location_str = (reg_info->encoding == lldb::eEncodingVector)
311                                    ? "vector"
312                                    : "scalar";
313           }
314         }
315         if (m_location_str.empty())
316           m_location_str = "scalar";
317         break;
318 
319       case Value::ValueType::LoadAddress:
320       case Value::ValueType::FileAddress:
321       case Value::ValueType::HostAddress: {
322         uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
323         sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
324                     value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
325         m_location_str = std::string(sstr.GetString());
326       } break;
327       }
328     }
329   }
330   return m_location_str.c_str();
331 }
332 
ResolveValue(Scalar & scalar)333 bool ValueObject::ResolveValue(Scalar &scalar) {
334   if (UpdateValueIfNeeded(
335           false)) // make sure that you are up to date before returning anything
336   {
337     ExecutionContext exe_ctx(GetExecutionContextRef());
338     Value tmp_value(m_value);
339     scalar = tmp_value.ResolveValue(&exe_ctx);
340     if (scalar.IsValid()) {
341       const uint32_t bitfield_bit_size = GetBitfieldBitSize();
342       if (bitfield_bit_size)
343         return scalar.ExtractBitfield(bitfield_bit_size,
344                                       GetBitfieldBitOffset());
345       return true;
346     }
347   }
348   return false;
349 }
350 
IsLogicalTrue(Status & error)351 bool ValueObject::IsLogicalTrue(Status &error) {
352   if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
353     LazyBool is_logical_true = language->IsLogicalTrue(*this, error);
354     switch (is_logical_true) {
355     case eLazyBoolYes:
356     case eLazyBoolNo:
357       return (is_logical_true == true);
358     case eLazyBoolCalculate:
359       break;
360     }
361   }
362 
363   Scalar scalar_value;
364 
365   if (!ResolveValue(scalar_value)) {
366     error.SetErrorString("failed to get a scalar result");
367     return false;
368   }
369 
370   bool ret;
371   ret = scalar_value.ULongLong(1) != 0;
372   error.Clear();
373   return ret;
374 }
375 
GetChildAtIndex(size_t idx,bool can_create)376 ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
377   ValueObjectSP child_sp;
378   // We may need to update our value if we are dynamic
379   if (IsPossibleDynamicType())
380     UpdateValueIfNeeded(false);
381   if (idx < GetNumChildren()) {
382     // Check if we have already made the child value object?
383     if (can_create && !m_children.HasChildAtIndex(idx)) {
384       // No we haven't created the child at this index, so lets have our
385       // subclass do it and cache the result for quick future access.
386       m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
387     }
388 
389     ValueObject *child = m_children.GetChildAtIndex(idx);
390     if (child != nullptr)
391       return child->GetSP();
392   }
393   return child_sp;
394 }
395 
396 lldb::ValueObjectSP
GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,size_t * index_of_error)397 ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
398                                  size_t *index_of_error) {
399   if (idxs.size() == 0)
400     return GetSP();
401   ValueObjectSP root(GetSP());
402   for (size_t idx : idxs) {
403     root = root->GetChildAtIndex(idx, true);
404     if (!root) {
405       if (index_of_error)
406         *index_of_error = idx;
407       return root;
408     }
409   }
410   return root;
411 }
412 
GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t,bool>> idxs,size_t * index_of_error)413 lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
414   llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) {
415   if (idxs.size() == 0)
416     return GetSP();
417   ValueObjectSP root(GetSP());
418   for (std::pair<size_t, bool> idx : idxs) {
419     root = root->GetChildAtIndex(idx.first, idx.second);
420     if (!root) {
421       if (index_of_error)
422         *index_of_error = idx.first;
423       return root;
424     }
425   }
426   return root;
427 }
428 
429 lldb::ValueObjectSP
GetChildAtNamePath(llvm::ArrayRef<ConstString> names,ConstString * name_of_error)430 ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
431                                 ConstString *name_of_error) {
432   if (names.size() == 0)
433     return GetSP();
434   ValueObjectSP root(GetSP());
435   for (ConstString name : names) {
436     root = root->GetChildMemberWithName(name, true);
437     if (!root) {
438       if (name_of_error)
439         *name_of_error = name;
440       return root;
441     }
442   }
443   return root;
444 }
445 
GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString,bool>> names,ConstString * name_of_error)446 lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
447     llvm::ArrayRef<std::pair<ConstString, bool>> names,
448     ConstString *name_of_error) {
449   if (names.size() == 0)
450     return GetSP();
451   ValueObjectSP root(GetSP());
452   for (std::pair<ConstString, bool> name : names) {
453     root = root->GetChildMemberWithName(name.first, name.second);
454     if (!root) {
455       if (name_of_error)
456         *name_of_error = name.first;
457       return root;
458     }
459   }
460   return root;
461 }
462 
GetIndexOfChildWithName(ConstString name)463 size_t ValueObject::GetIndexOfChildWithName(ConstString name) {
464   bool omit_empty_base_classes = true;
465   return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
466                                                    omit_empty_base_classes);
467 }
468 
GetChildMemberWithName(ConstString name,bool can_create)469 ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name,
470                                                   bool can_create) {
471   // We may need to update our value if we are dynamic.
472   if (IsPossibleDynamicType())
473     UpdateValueIfNeeded(false);
474 
475   // When getting a child by name, it could be buried inside some base classes
476   // (which really aren't part of the expression path), so we need a vector of
477   // indexes that can get us down to the correct child.
478   std::vector<uint32_t> child_indexes;
479   bool omit_empty_base_classes = true;
480 
481   if (!GetCompilerType().IsValid())
482     return ValueObjectSP();
483 
484   const size_t num_child_indexes =
485       GetCompilerType().GetIndexOfChildMemberWithName(
486           name.GetCString(), omit_empty_base_classes, child_indexes);
487   if (num_child_indexes == 0)
488     return nullptr;
489 
490   ValueObjectSP child_sp = GetSP();
491   for (uint32_t idx : child_indexes)
492     if (child_sp)
493       child_sp = child_sp->GetChildAtIndex(idx, can_create);
494   return child_sp;
495 }
496 
GetNumChildren(uint32_t max)497 size_t ValueObject::GetNumChildren(uint32_t max) {
498   UpdateValueIfNeeded();
499 
500   if (max < UINT32_MAX) {
501     if (m_flags.m_children_count_valid) {
502       size_t children_count = m_children.GetChildrenCount();
503       return children_count <= max ? children_count : max;
504     } else
505       return CalculateNumChildren(max);
506   }
507 
508   if (!m_flags.m_children_count_valid) {
509     SetNumChildren(CalculateNumChildren());
510   }
511   return m_children.GetChildrenCount();
512 }
513 
MightHaveChildren()514 bool ValueObject::MightHaveChildren() {
515   bool has_children = false;
516   const uint32_t type_info = GetTypeInfo();
517   if (type_info) {
518     if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
519       has_children = true;
520   } else {
521     has_children = GetNumChildren() > 0;
522   }
523   return has_children;
524 }
525 
526 // Should only be called by ValueObject::GetNumChildren()
SetNumChildren(size_t num_children)527 void ValueObject::SetNumChildren(size_t num_children) {
528   m_flags.m_children_count_valid = true;
529   m_children.SetChildrenCount(num_children);
530 }
531 
CreateChildAtIndex(size_t idx,bool synthetic_array_member,int32_t synthetic_index)532 ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
533                                              bool synthetic_array_member,
534                                              int32_t synthetic_index) {
535   ValueObject *valobj = nullptr;
536 
537   bool omit_empty_base_classes = true;
538   bool ignore_array_bounds = synthetic_array_member;
539   std::string child_name_str;
540   uint32_t child_byte_size = 0;
541   int32_t child_byte_offset = 0;
542   uint32_t child_bitfield_bit_size = 0;
543   uint32_t child_bitfield_bit_offset = 0;
544   bool child_is_base_class = false;
545   bool child_is_deref_of_parent = false;
546   uint64_t language_flags = 0;
547 
548   const bool transparent_pointers = !synthetic_array_member;
549   CompilerType child_compiler_type;
550 
551   ExecutionContext exe_ctx(GetExecutionContextRef());
552 
553   child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex(
554       &exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
555       ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
556       child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
557       child_is_deref_of_parent, this, language_flags);
558   if (child_compiler_type) {
559     if (synthetic_index)
560       child_byte_offset += child_byte_size * synthetic_index;
561 
562     ConstString child_name;
563     if (!child_name_str.empty())
564       child_name.SetCString(child_name_str.c_str());
565 
566     valobj = new ValueObjectChild(
567         *this, child_compiler_type, child_name, child_byte_size,
568         child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
569         child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
570         language_flags);
571   }
572 
573   // In case of an incomplete type, try to use the ValueObject's
574   // synthetic value to create the child ValueObject.
575   if (!valobj && synthetic_array_member) {
576     if (ValueObjectSP synth_valobj_sp = GetSyntheticValue()) {
577       valobj = synth_valobj_sp
578                    ->GetChildAtIndex(synthetic_index, synthetic_array_member)
579                    .get();
580     }
581   }
582 
583   return valobj;
584 }
585 
GetSummaryAsCString(TypeSummaryImpl * summary_ptr,std::string & destination,lldb::LanguageType lang)586 bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
587                                       std::string &destination,
588                                       lldb::LanguageType lang) {
589   return GetSummaryAsCString(summary_ptr, destination,
590                              TypeSummaryOptions().SetLanguage(lang));
591 }
592 
GetSummaryAsCString(TypeSummaryImpl * summary_ptr,std::string & destination,const TypeSummaryOptions & options)593 bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
594                                       std::string &destination,
595                                       const TypeSummaryOptions &options) {
596   destination.clear();
597 
598   // If we have a forcefully completed type, don't try and show a summary from
599   // a valid summary string or function because the type is not complete and
600   // no member variables or member functions will be available.
601   if (GetCompilerType().IsForcefullyCompleted()) {
602       destination = "<incomplete type>";
603       return true;
604   }
605 
606   // ideally we would like to bail out if passing NULL, but if we do so we end
607   // up not providing the summary for function pointers anymore
608   if (/*summary_ptr == NULL ||*/ m_flags.m_is_getting_summary)
609     return false;
610 
611   m_flags.m_is_getting_summary = true;
612 
613   TypeSummaryOptions actual_options(options);
614 
615   if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown)
616     actual_options.SetLanguage(GetPreferredDisplayLanguage());
617 
618   // this is a hot path in code and we prefer to avoid setting this string all
619   // too often also clearing out other information that we might care to see in
620   // a crash log. might be useful in very specific situations though.
621   /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s.
622    Summary provider's description is %s",
623    GetTypeName().GetCString(),
624    GetName().GetCString(),
625    summary_ptr->GetDescription().c_str());*/
626 
627   if (UpdateValueIfNeeded(false) && summary_ptr) {
628     if (HasSyntheticValue())
629       m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on
630                                                 // the synthetic children being
631                                                 // up-to-date (e.g. ${svar%#})
632     summary_ptr->FormatObject(this, destination, actual_options);
633   }
634   m_flags.m_is_getting_summary = false;
635   return !destination.empty();
636 }
637 
GetSummaryAsCString(lldb::LanguageType lang)638 const char *ValueObject::GetSummaryAsCString(lldb::LanguageType lang) {
639   if (UpdateValueIfNeeded(true) && m_summary_str.empty()) {
640     TypeSummaryOptions summary_options;
641     summary_options.SetLanguage(lang);
642     GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str,
643                         summary_options);
644   }
645   if (m_summary_str.empty())
646     return nullptr;
647   return m_summary_str.c_str();
648 }
649 
GetSummaryAsCString(std::string & destination,const TypeSummaryOptions & options)650 bool ValueObject::GetSummaryAsCString(std::string &destination,
651                                       const TypeSummaryOptions &options) {
652   return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
653 }
654 
IsCStringContainer(bool check_pointer)655 bool ValueObject::IsCStringContainer(bool check_pointer) {
656   CompilerType pointee_or_element_compiler_type;
657   const Flags type_flags(GetTypeInfo(&pointee_or_element_compiler_type));
658   bool is_char_arr_ptr(type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
659                        pointee_or_element_compiler_type.IsCharType());
660   if (!is_char_arr_ptr)
661     return false;
662   if (!check_pointer)
663     return true;
664   if (type_flags.Test(eTypeIsArray))
665     return true;
666   addr_t cstr_address = LLDB_INVALID_ADDRESS;
667   AddressType cstr_address_type = eAddressTypeInvalid;
668   cstr_address = GetPointerValue(&cstr_address_type);
669   return (cstr_address != LLDB_INVALID_ADDRESS);
670 }
671 
GetPointeeData(DataExtractor & data,uint32_t item_idx,uint32_t item_count)672 size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
673                                    uint32_t item_count) {
674   CompilerType pointee_or_element_compiler_type;
675   const uint32_t type_info = GetTypeInfo(&pointee_or_element_compiler_type);
676   const bool is_pointer_type = type_info & eTypeIsPointer;
677   const bool is_array_type = type_info & eTypeIsArray;
678   if (!(is_pointer_type || is_array_type))
679     return 0;
680 
681   if (item_count == 0)
682     return 0;
683 
684   ExecutionContext exe_ctx(GetExecutionContextRef());
685 
686   std::optional<uint64_t> item_type_size =
687       pointee_or_element_compiler_type.GetByteSize(
688           exe_ctx.GetBestExecutionContextScope());
689   if (!item_type_size)
690     return 0;
691   const uint64_t bytes = item_count * *item_type_size;
692   const uint64_t offset = item_idx * *item_type_size;
693 
694   if (item_idx == 0 && item_count == 1) // simply a deref
695   {
696     if (is_pointer_type) {
697       Status error;
698       ValueObjectSP pointee_sp = Dereference(error);
699       if (error.Fail() || pointee_sp.get() == nullptr)
700         return 0;
701       return pointee_sp->GetData(data, error);
702     } else {
703       ValueObjectSP child_sp = GetChildAtIndex(0, true);
704       if (child_sp.get() == nullptr)
705         return 0;
706       Status error;
707       return child_sp->GetData(data, error);
708     }
709     return true;
710   } else /* (items > 1) */
711   {
712     Status error;
713     lldb_private::DataBufferHeap *heap_buf_ptr = nullptr;
714     lldb::DataBufferSP data_sp(heap_buf_ptr =
715                                    new lldb_private::DataBufferHeap());
716 
717     AddressType addr_type;
718     lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
719                                         : GetAddressOf(true, &addr_type);
720 
721     switch (addr_type) {
722     case eAddressTypeFile: {
723       ModuleSP module_sp(GetModule());
724       if (module_sp) {
725         addr = addr + offset;
726         Address so_addr;
727         module_sp->ResolveFileAddress(addr, so_addr);
728         ExecutionContext exe_ctx(GetExecutionContextRef());
729         Target *target = exe_ctx.GetTargetPtr();
730         if (target) {
731           heap_buf_ptr->SetByteSize(bytes);
732           size_t bytes_read = target->ReadMemory(
733               so_addr, heap_buf_ptr->GetBytes(), bytes, error, true);
734           if (error.Success()) {
735             data.SetData(data_sp);
736             return bytes_read;
737           }
738         }
739       }
740     } break;
741     case eAddressTypeLoad: {
742       ExecutionContext exe_ctx(GetExecutionContextRef());
743       Process *process = exe_ctx.GetProcessPtr();
744       if (process) {
745         heap_buf_ptr->SetByteSize(bytes);
746         size_t bytes_read = process->ReadMemory(
747             addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
748         if (error.Success() || bytes_read > 0) {
749           data.SetData(data_sp);
750           return bytes_read;
751         }
752       }
753     } break;
754     case eAddressTypeHost: {
755       auto max_bytes =
756           GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope());
757       if (max_bytes && *max_bytes > offset) {
758         size_t bytes_read = std::min<uint64_t>(*max_bytes - offset, bytes);
759         addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
760         if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
761           break;
762         heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
763         data.SetData(data_sp);
764         return bytes_read;
765       }
766     } break;
767     case eAddressTypeInvalid:
768       break;
769     }
770   }
771   return 0;
772 }
773 
GetData(DataExtractor & data,Status & error)774 uint64_t ValueObject::GetData(DataExtractor &data, Status &error) {
775   UpdateValueIfNeeded(false);
776   ExecutionContext exe_ctx(GetExecutionContextRef());
777   error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
778   if (error.Fail()) {
779     if (m_data.GetByteSize()) {
780       data = m_data;
781       error.Clear();
782       return data.GetByteSize();
783     } else {
784       return 0;
785     }
786   }
787   data.SetAddressByteSize(m_data.GetAddressByteSize());
788   data.SetByteOrder(m_data.GetByteOrder());
789   return data.GetByteSize();
790 }
791 
SetData(DataExtractor & data,Status & error)792 bool ValueObject::SetData(DataExtractor &data, Status &error) {
793   error.Clear();
794   // Make sure our value is up to date first so that our location and location
795   // type is valid.
796   if (!UpdateValueIfNeeded(false)) {
797     error.SetErrorString("unable to read value");
798     return false;
799   }
800 
801   uint64_t count = 0;
802   const Encoding encoding = GetCompilerType().GetEncoding(count);
803 
804   const size_t byte_size = GetByteSize().value_or(0);
805 
806   Value::ValueType value_type = m_value.GetValueType();
807 
808   switch (value_type) {
809   case Value::ValueType::Invalid:
810     error.SetErrorString("invalid location");
811     return false;
812   case Value::ValueType::Scalar: {
813     Status set_error =
814         m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
815 
816     if (!set_error.Success()) {
817       error.SetErrorStringWithFormat("unable to set scalar value: %s",
818                                      set_error.AsCString());
819       return false;
820     }
821   } break;
822   case Value::ValueType::LoadAddress: {
823     // If it is a load address, then the scalar value is the storage location
824     // of the data, and we have to shove this value down to that load location.
825     ExecutionContext exe_ctx(GetExecutionContextRef());
826     Process *process = exe_ctx.GetProcessPtr();
827     if (process) {
828       addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
829       size_t bytes_written = process->WriteMemory(
830           target_addr, data.GetDataStart(), byte_size, error);
831       if (!error.Success())
832         return false;
833       if (bytes_written != byte_size) {
834         error.SetErrorString("unable to write value to memory");
835         return false;
836       }
837     }
838   } break;
839   case Value::ValueType::HostAddress: {
840     // If it is a host address, then we stuff the scalar as a DataBuffer into
841     // the Value's data.
842     DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
843     m_data.SetData(buffer_sp, 0);
844     data.CopyByteOrderedData(0, byte_size,
845                              const_cast<uint8_t *>(m_data.GetDataStart()),
846                              byte_size, m_data.GetByteOrder());
847     m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
848   } break;
849   case Value::ValueType::FileAddress:
850     break;
851   }
852 
853   // If we have reached this point, then we have successfully changed the
854   // value.
855   SetNeedsUpdate();
856   return true;
857 }
858 
CopyStringDataToBufferSP(const StreamString & source,lldb::WritableDataBufferSP & destination)859 static bool CopyStringDataToBufferSP(const StreamString &source,
860                                      lldb::WritableDataBufferSP &destination) {
861   llvm::StringRef src = source.GetString();
862   src = src.rtrim('\0');
863   destination = std::make_shared<DataBufferHeap>(src.size(), 0);
864   memcpy(destination->GetBytes(), src.data(), src.size());
865   return true;
866 }
867 
868 std::pair<size_t, bool>
ReadPointedString(lldb::WritableDataBufferSP & buffer_sp,Status & error,uint32_t max_length,bool honor_array,Format item_format)869 ValueObject::ReadPointedString(lldb::WritableDataBufferSP &buffer_sp,
870                                Status &error, uint32_t max_length,
871                                bool honor_array, Format item_format) {
872   bool was_capped = false;
873   StreamString s;
874   ExecutionContext exe_ctx(GetExecutionContextRef());
875   Target *target = exe_ctx.GetTargetPtr();
876 
877   if (!target) {
878     s << "<no target to read from>";
879     error.SetErrorString("no target to read from");
880     CopyStringDataToBufferSP(s, buffer_sp);
881     return {0, was_capped};
882   }
883 
884   if (max_length == 0)
885     max_length = target->GetMaximumSizeOfStringSummary();
886 
887   size_t bytes_read = 0;
888   size_t total_bytes_read = 0;
889 
890   CompilerType compiler_type = GetCompilerType();
891   CompilerType elem_or_pointee_compiler_type;
892   const Flags type_flags(GetTypeInfo(&elem_or_pointee_compiler_type));
893   if (type_flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
894       elem_or_pointee_compiler_type.IsCharType()) {
895     addr_t cstr_address = LLDB_INVALID_ADDRESS;
896     AddressType cstr_address_type = eAddressTypeInvalid;
897 
898     size_t cstr_len = 0;
899     bool capped_data = false;
900     const bool is_array = type_flags.Test(eTypeIsArray);
901     if (is_array) {
902       // We have an array
903       uint64_t array_size = 0;
904       if (compiler_type.IsArrayType(nullptr, &array_size)) {
905         cstr_len = array_size;
906         if (cstr_len > max_length) {
907           capped_data = true;
908           cstr_len = max_length;
909         }
910       }
911       cstr_address = GetAddressOf(true, &cstr_address_type);
912     } else {
913       // We have a pointer
914       cstr_address = GetPointerValue(&cstr_address_type);
915     }
916 
917     if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
918       if (cstr_address_type == eAddressTypeHost && is_array) {
919         const char *cstr = GetDataExtractor().PeekCStr(0);
920         if (cstr == nullptr) {
921           s << "<invalid address>";
922           error.SetErrorString("invalid address");
923           CopyStringDataToBufferSP(s, buffer_sp);
924           return {0, was_capped};
925         }
926         s << llvm::StringRef(cstr, cstr_len);
927         CopyStringDataToBufferSP(s, buffer_sp);
928         return {cstr_len, was_capped};
929       } else {
930         s << "<invalid address>";
931         error.SetErrorString("invalid address");
932         CopyStringDataToBufferSP(s, buffer_sp);
933         return {0, was_capped};
934       }
935     }
936 
937     Address cstr_so_addr(cstr_address);
938     DataExtractor data;
939     if (cstr_len > 0 && honor_array) {
940       // I am using GetPointeeData() here to abstract the fact that some
941       // ValueObjects are actually frozen pointers in the host but the pointed-
942       // to data lives in the debuggee, and GetPointeeData() automatically
943       // takes care of this
944       GetPointeeData(data, 0, cstr_len);
945 
946       if ((bytes_read = data.GetByteSize()) > 0) {
947         total_bytes_read = bytes_read;
948         for (size_t offset = 0; offset < bytes_read; offset++)
949           s.Printf("%c", *data.PeekData(offset, 1));
950         if (capped_data)
951           was_capped = true;
952       }
953     } else {
954       cstr_len = max_length;
955       const size_t k_max_buf_size = 64;
956 
957       size_t offset = 0;
958 
959       int cstr_len_displayed = -1;
960       bool capped_cstr = false;
961       // I am using GetPointeeData() here to abstract the fact that some
962       // ValueObjects are actually frozen pointers in the host but the pointed-
963       // to data lives in the debuggee, and GetPointeeData() automatically
964       // takes care of this
965       while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
966         total_bytes_read += bytes_read;
967         const char *cstr = data.PeekCStr(0);
968         size_t len = strnlen(cstr, k_max_buf_size);
969         if (cstr_len_displayed < 0)
970           cstr_len_displayed = len;
971 
972         if (len == 0)
973           break;
974         cstr_len_displayed += len;
975         if (len > bytes_read)
976           len = bytes_read;
977         if (len > cstr_len)
978           len = cstr_len;
979 
980         for (size_t offset = 0; offset < bytes_read; offset++)
981           s.Printf("%c", *data.PeekData(offset, 1));
982 
983         if (len < k_max_buf_size)
984           break;
985 
986         if (len >= cstr_len) {
987           capped_cstr = true;
988           break;
989         }
990 
991         cstr_len -= len;
992         offset += len;
993       }
994 
995       if (cstr_len_displayed >= 0) {
996         if (capped_cstr)
997           was_capped = true;
998       }
999     }
1000   } else {
1001     error.SetErrorString("not a string object");
1002     s << "<not a string object>";
1003   }
1004   CopyStringDataToBufferSP(s, buffer_sp);
1005   return {total_bytes_read, was_capped};
1006 }
1007 
GetObjectDescription()1008 const char *ValueObject::GetObjectDescription() {
1009   if (!UpdateValueIfNeeded(true))
1010     return nullptr;
1011 
1012   // Return cached value.
1013   if (!m_object_desc_str.empty())
1014     return m_object_desc_str.c_str();
1015 
1016   ExecutionContext exe_ctx(GetExecutionContextRef());
1017   Process *process = exe_ctx.GetProcessPtr();
1018   if (!process)
1019     return nullptr;
1020 
1021   // Returns the object description produced by one language runtime.
1022   auto get_object_description = [&](LanguageType language) -> const char * {
1023     if (LanguageRuntime *runtime = process->GetLanguageRuntime(language)) {
1024       StreamString s;
1025       if (runtime->GetObjectDescription(s, *this)) {
1026         m_object_desc_str.append(std::string(s.GetString()));
1027         return m_object_desc_str.c_str();
1028       }
1029     }
1030     return nullptr;
1031   };
1032 
1033   // Try the native language runtime first.
1034   LanguageType native_language = GetObjectRuntimeLanguage();
1035   if (const char *desc = get_object_description(native_language))
1036     return desc;
1037 
1038   // Try the Objective-C language runtime. This fallback is necessary
1039   // for Objective-C++ and mixed Objective-C / C++ programs.
1040   if (Language::LanguageIsCFamily(native_language))
1041     return get_object_description(eLanguageTypeObjC);
1042   return nullptr;
1043 }
1044 
GetValueAsCString(const lldb_private::TypeFormatImpl & format,std::string & destination)1045 bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
1046                                     std::string &destination) {
1047   if (UpdateValueIfNeeded(false))
1048     return format.FormatObject(this, destination);
1049   else
1050     return false;
1051 }
1052 
GetValueAsCString(lldb::Format format,std::string & destination)1053 bool ValueObject::GetValueAsCString(lldb::Format format,
1054                                     std::string &destination) {
1055   return GetValueAsCString(TypeFormatImpl_Format(format), destination);
1056 }
1057 
GetValueAsCString()1058 const char *ValueObject::GetValueAsCString() {
1059   if (UpdateValueIfNeeded(true)) {
1060     lldb::TypeFormatImplSP format_sp;
1061     lldb::Format my_format = GetFormat();
1062     if (my_format == lldb::eFormatDefault) {
1063       if (m_type_format_sp)
1064         format_sp = m_type_format_sp;
1065       else {
1066         if (m_flags.m_is_bitfield_for_scalar)
1067           my_format = eFormatUnsigned;
1068         else {
1069           if (m_value.GetContextType() == Value::ContextType::RegisterInfo) {
1070             const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1071             if (reg_info)
1072               my_format = reg_info->format;
1073           } else {
1074             my_format = GetValue().GetCompilerType().GetFormat();
1075           }
1076         }
1077       }
1078     }
1079     if (my_format != m_last_format || m_value_str.empty()) {
1080       m_last_format = my_format;
1081       if (!format_sp)
1082         format_sp = std::make_shared<TypeFormatImpl_Format>(my_format);
1083       if (GetValueAsCString(*format_sp.get(), m_value_str)) {
1084         if (!m_flags.m_value_did_change && m_flags.m_old_value_valid) {
1085           // The value was gotten successfully, so we consider the value as
1086           // changed if the value string differs
1087           SetValueDidChange(m_old_value_str != m_value_str);
1088         }
1089       }
1090     }
1091   }
1092   if (m_value_str.empty())
1093     return nullptr;
1094   return m_value_str.c_str();
1095 }
1096 
1097 // if > 8bytes, 0 is returned. this method should mostly be used to read
1098 // address values out of pointers
GetValueAsUnsigned(uint64_t fail_value,bool * success)1099 uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
1100   // If our byte size is zero this is an aggregate type that has children
1101   if (CanProvideValue()) {
1102     Scalar scalar;
1103     if (ResolveValue(scalar)) {
1104       if (success)
1105         *success = true;
1106       scalar.MakeUnsigned();
1107       return scalar.ULongLong(fail_value);
1108     }
1109     // fallthrough, otherwise...
1110   }
1111 
1112   if (success)
1113     *success = false;
1114   return fail_value;
1115 }
1116 
GetValueAsSigned(int64_t fail_value,bool * success)1117 int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
1118   // If our byte size is zero this is an aggregate type that has children
1119   if (CanProvideValue()) {
1120     Scalar scalar;
1121     if (ResolveValue(scalar)) {
1122       if (success)
1123         *success = true;
1124       scalar.MakeSigned();
1125       return scalar.SLongLong(fail_value);
1126     }
1127     // fallthrough, otherwise...
1128   }
1129 
1130   if (success)
1131     *success = false;
1132   return fail_value;
1133 }
1134 
1135 // if any more "special cases" are added to
1136 // ValueObject::DumpPrintableRepresentation() please keep this call up to date
1137 // by returning true for your new special cases. We will eventually move to
1138 // checking this call result before trying to display special cases
HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,Format custom_format)1139 bool ValueObject::HasSpecialPrintableRepresentation(
1140     ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
1141   Flags flags(GetTypeInfo());
1142   if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1143       val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1144     if (IsCStringContainer(true) &&
1145         (custom_format == eFormatCString || custom_format == eFormatCharArray ||
1146          custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
1147       return true;
1148 
1149     if (flags.Test(eTypeIsArray)) {
1150       if ((custom_format == eFormatBytes) ||
1151           (custom_format == eFormatBytesWithASCII))
1152         return true;
1153 
1154       if ((custom_format == eFormatVectorOfChar) ||
1155           (custom_format == eFormatVectorOfFloat32) ||
1156           (custom_format == eFormatVectorOfFloat64) ||
1157           (custom_format == eFormatVectorOfSInt16) ||
1158           (custom_format == eFormatVectorOfSInt32) ||
1159           (custom_format == eFormatVectorOfSInt64) ||
1160           (custom_format == eFormatVectorOfSInt8) ||
1161           (custom_format == eFormatVectorOfUInt128) ||
1162           (custom_format == eFormatVectorOfUInt16) ||
1163           (custom_format == eFormatVectorOfUInt32) ||
1164           (custom_format == eFormatVectorOfUInt64) ||
1165           (custom_format == eFormatVectorOfUInt8))
1166         return true;
1167     }
1168   }
1169   return false;
1170 }
1171 
DumpPrintableRepresentation(Stream & s,ValueObjectRepresentationStyle val_obj_display,Format custom_format,PrintableRepresentationSpecialCases special,bool do_dump_error)1172 bool ValueObject::DumpPrintableRepresentation(
1173     Stream &s, ValueObjectRepresentationStyle val_obj_display,
1174     Format custom_format, PrintableRepresentationSpecialCases special,
1175     bool do_dump_error) {
1176 
1177   Flags flags(GetTypeInfo());
1178 
1179   bool allow_special =
1180       (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
1181   const bool only_special = false;
1182 
1183   if (allow_special) {
1184     if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
1185         val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
1186       // when being asked to get a printable display an array or pointer type
1187       // directly, try to "do the right thing"
1188 
1189       if (IsCStringContainer(true) &&
1190           (custom_format == eFormatCString ||
1191            custom_format == eFormatCharArray || custom_format == eFormatChar ||
1192            custom_format ==
1193                eFormatVectorOfChar)) // print char[] & char* directly
1194       {
1195         Status error;
1196         lldb::WritableDataBufferSP buffer_sp;
1197         std::pair<size_t, bool> read_string = ReadPointedString(
1198             buffer_sp, error, 0, (custom_format == eFormatVectorOfChar) ||
1199                                      (custom_format == eFormatCharArray));
1200         lldb_private::formatters::StringPrinter::
1201             ReadBufferAndDumpToStreamOptions options(*this);
1202         options.SetData(DataExtractor(
1203             buffer_sp, lldb::eByteOrderInvalid,
1204             8)); // none of this matters for a string - pass some defaults
1205         options.SetStream(&s);
1206         options.SetPrefixToken(nullptr);
1207         options.SetQuote('"');
1208         options.SetSourceSize(buffer_sp->GetByteSize());
1209         options.SetIsTruncated(read_string.second);
1210         options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar);
1211         formatters::StringPrinter::ReadBufferAndDumpToStream<
1212             lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
1213             options);
1214         return !error.Fail();
1215       }
1216 
1217       if (custom_format == eFormatEnum)
1218         return false;
1219 
1220       // this only works for arrays, because I have no way to know when the
1221       // pointed memory ends, and no special \0 end of data marker
1222       if (flags.Test(eTypeIsArray)) {
1223         if ((custom_format == eFormatBytes) ||
1224             (custom_format == eFormatBytesWithASCII)) {
1225           const size_t count = GetNumChildren();
1226 
1227           s << '[';
1228           for (size_t low = 0; low < count; low++) {
1229 
1230             if (low)
1231               s << ',';
1232 
1233             ValueObjectSP child = GetChildAtIndex(low, true);
1234             if (!child.get()) {
1235               s << "<invalid child>";
1236               continue;
1237             }
1238             child->DumpPrintableRepresentation(
1239                 s, ValueObject::eValueObjectRepresentationStyleValue,
1240                 custom_format);
1241           }
1242 
1243           s << ']';
1244 
1245           return true;
1246         }
1247 
1248         if ((custom_format == eFormatVectorOfChar) ||
1249             (custom_format == eFormatVectorOfFloat32) ||
1250             (custom_format == eFormatVectorOfFloat64) ||
1251             (custom_format == eFormatVectorOfSInt16) ||
1252             (custom_format == eFormatVectorOfSInt32) ||
1253             (custom_format == eFormatVectorOfSInt64) ||
1254             (custom_format == eFormatVectorOfSInt8) ||
1255             (custom_format == eFormatVectorOfUInt128) ||
1256             (custom_format == eFormatVectorOfUInt16) ||
1257             (custom_format == eFormatVectorOfUInt32) ||
1258             (custom_format == eFormatVectorOfUInt64) ||
1259             (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
1260                                                      // with ASCII or any vector
1261                                                      // format should be printed
1262                                                      // directly
1263         {
1264           const size_t count = GetNumChildren();
1265 
1266           Format format = FormatManager::GetSingleItemFormat(custom_format);
1267 
1268           s << '[';
1269           for (size_t low = 0; low < count; low++) {
1270 
1271             if (low)
1272               s << ',';
1273 
1274             ValueObjectSP child = GetChildAtIndex(low, true);
1275             if (!child.get()) {
1276               s << "<invalid child>";
1277               continue;
1278             }
1279             child->DumpPrintableRepresentation(
1280                 s, ValueObject::eValueObjectRepresentationStyleValue, format);
1281           }
1282 
1283           s << ']';
1284 
1285           return true;
1286         }
1287       }
1288 
1289       if ((custom_format == eFormatBoolean) ||
1290           (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
1291           (custom_format == eFormatCharPrintable) ||
1292           (custom_format == eFormatComplexFloat) ||
1293           (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
1294           (custom_format == eFormatHexUppercase) ||
1295           (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
1296           (custom_format == eFormatOSType) ||
1297           (custom_format == eFormatUnicode16) ||
1298           (custom_format == eFormatUnicode32) ||
1299           (custom_format == eFormatUnsigned) ||
1300           (custom_format == eFormatPointer) ||
1301           (custom_format == eFormatComplexInteger) ||
1302           (custom_format == eFormatComplex) ||
1303           (custom_format == eFormatDefault)) // use the [] operator
1304         return false;
1305     }
1306   }
1307 
1308   if (only_special)
1309     return false;
1310 
1311   bool var_success = false;
1312 
1313   {
1314     llvm::StringRef str;
1315 
1316     // this is a local stream that we are using to ensure that the data pointed
1317     // to by cstr survives long enough for us to copy it to its destination -
1318     // it is necessary to have this temporary storage area for cases where our
1319     // desired output is not backed by some other longer-term storage
1320     StreamString strm;
1321 
1322     if (custom_format != eFormatInvalid)
1323       SetFormat(custom_format);
1324 
1325     switch (val_obj_display) {
1326     case eValueObjectRepresentationStyleValue:
1327       str = GetValueAsCString();
1328       break;
1329 
1330     case eValueObjectRepresentationStyleSummary:
1331       str = GetSummaryAsCString();
1332       break;
1333 
1334     case eValueObjectRepresentationStyleLanguageSpecific:
1335       str = GetObjectDescription();
1336       break;
1337 
1338     case eValueObjectRepresentationStyleLocation:
1339       str = GetLocationAsCString();
1340       break;
1341 
1342     case eValueObjectRepresentationStyleChildrenCount:
1343       strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
1344       str = strm.GetString();
1345       break;
1346 
1347     case eValueObjectRepresentationStyleType:
1348       str = GetTypeName().GetStringRef();
1349       break;
1350 
1351     case eValueObjectRepresentationStyleName:
1352       str = GetName().GetStringRef();
1353       break;
1354 
1355     case eValueObjectRepresentationStyleExpressionPath:
1356       GetExpressionPath(strm);
1357       str = strm.GetString();
1358       break;
1359     }
1360 
1361     if (str.empty()) {
1362       if (val_obj_display == eValueObjectRepresentationStyleValue)
1363         str = GetSummaryAsCString();
1364       else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
1365         if (!CanProvideValue()) {
1366           strm.Printf("%s @ %s", GetTypeName().AsCString(),
1367                       GetLocationAsCString());
1368           str = strm.GetString();
1369         } else
1370           str = GetValueAsCString();
1371       }
1372     }
1373 
1374     if (!str.empty())
1375       s << str;
1376     else {
1377       if (m_error.Fail()) {
1378         if (do_dump_error)
1379           s.Printf("<%s>", m_error.AsCString());
1380         else
1381           return false;
1382       } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1383         s.PutCString("<no summary available>");
1384       else if (val_obj_display == eValueObjectRepresentationStyleValue)
1385         s.PutCString("<no value available>");
1386       else if (val_obj_display ==
1387                eValueObjectRepresentationStyleLanguageSpecific)
1388         s.PutCString("<not a valid Objective-C object>"); // edit this if we
1389                                                           // have other runtimes
1390                                                           // that support a
1391                                                           // description
1392       else
1393         s.PutCString("<no printable representation>");
1394     }
1395 
1396     // we should only return false here if we could not do *anything* even if
1397     // we have an error message as output, that's a success from our callers'
1398     // perspective, so return true
1399     var_success = true;
1400 
1401     if (custom_format != eFormatInvalid)
1402       SetFormat(eFormatDefault);
1403   }
1404 
1405   return var_success;
1406 }
1407 
GetAddressOf(bool scalar_is_load_address,AddressType * address_type)1408 addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
1409                                  AddressType *address_type) {
1410   // Can't take address of a bitfield
1411   if (IsBitfield())
1412     return LLDB_INVALID_ADDRESS;
1413 
1414   if (!UpdateValueIfNeeded(false))
1415     return LLDB_INVALID_ADDRESS;
1416 
1417   switch (m_value.GetValueType()) {
1418   case Value::ValueType::Invalid:
1419     return LLDB_INVALID_ADDRESS;
1420   case Value::ValueType::Scalar:
1421     if (scalar_is_load_address) {
1422       if (address_type)
1423         *address_type = eAddressTypeLoad;
1424       return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1425     }
1426     break;
1427 
1428   case Value::ValueType::LoadAddress:
1429   case Value::ValueType::FileAddress: {
1430     if (address_type)
1431       *address_type = m_value.GetValueAddressType();
1432     return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1433   } break;
1434   case Value::ValueType::HostAddress: {
1435     if (address_type)
1436       *address_type = m_value.GetValueAddressType();
1437     return LLDB_INVALID_ADDRESS;
1438   } break;
1439   }
1440   if (address_type)
1441     *address_type = eAddressTypeInvalid;
1442   return LLDB_INVALID_ADDRESS;
1443 }
1444 
GetPointerValue(AddressType * address_type)1445 addr_t ValueObject::GetPointerValue(AddressType *address_type) {
1446   addr_t address = LLDB_INVALID_ADDRESS;
1447   if (address_type)
1448     *address_type = eAddressTypeInvalid;
1449 
1450   if (!UpdateValueIfNeeded(false))
1451     return address;
1452 
1453   switch (m_value.GetValueType()) {
1454   case Value::ValueType::Invalid:
1455     return LLDB_INVALID_ADDRESS;
1456   case Value::ValueType::Scalar:
1457     address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1458     break;
1459 
1460   case Value::ValueType::HostAddress:
1461   case Value::ValueType::LoadAddress:
1462   case Value::ValueType::FileAddress: {
1463     lldb::offset_t data_offset = 0;
1464     address = m_data.GetAddress(&data_offset);
1465   } break;
1466   }
1467 
1468   if (address_type)
1469     *address_type = GetAddressTypeOfChildren();
1470 
1471   return address;
1472 }
1473 
SetValueFromCString(const char * value_str,Status & error)1474 bool ValueObject::SetValueFromCString(const char *value_str, Status &error) {
1475   error.Clear();
1476   // Make sure our value is up to date first so that our location and location
1477   // type is valid.
1478   if (!UpdateValueIfNeeded(false)) {
1479     error.SetErrorString("unable to read value");
1480     return false;
1481   }
1482 
1483   uint64_t count = 0;
1484   const Encoding encoding = GetCompilerType().GetEncoding(count);
1485 
1486   const size_t byte_size = GetByteSize().value_or(0);
1487 
1488   Value::ValueType value_type = m_value.GetValueType();
1489 
1490   if (value_type == Value::ValueType::Scalar) {
1491     // If the value is already a scalar, then let the scalar change itself:
1492     m_value.GetScalar().SetValueFromCString(value_str, encoding, byte_size);
1493   } else if (byte_size <= 16) {
1494     // If the value fits in a scalar, then make a new scalar and again let the
1495     // scalar code do the conversion, then figure out where to put the new
1496     // value.
1497     Scalar new_scalar;
1498     error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
1499     if (error.Success()) {
1500       switch (value_type) {
1501       case Value::ValueType::LoadAddress: {
1502         // If it is a load address, then the scalar value is the storage
1503         // location of the data, and we have to shove this value down to that
1504         // load location.
1505         ExecutionContext exe_ctx(GetExecutionContextRef());
1506         Process *process = exe_ctx.GetProcessPtr();
1507         if (process) {
1508           addr_t target_addr =
1509               m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1510           size_t bytes_written = process->WriteScalarToMemory(
1511               target_addr, new_scalar, byte_size, error);
1512           if (!error.Success())
1513             return false;
1514           if (bytes_written != byte_size) {
1515             error.SetErrorString("unable to write value to memory");
1516             return false;
1517           }
1518         }
1519       } break;
1520       case Value::ValueType::HostAddress: {
1521         // If it is a host address, then we stuff the scalar as a DataBuffer
1522         // into the Value's data.
1523         DataExtractor new_data;
1524         new_data.SetByteOrder(m_data.GetByteOrder());
1525 
1526         DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
1527         m_data.SetData(buffer_sp, 0);
1528         bool success = new_scalar.GetData(new_data);
1529         if (success) {
1530           new_data.CopyByteOrderedData(
1531               0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
1532               byte_size, m_data.GetByteOrder());
1533         }
1534         m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1535 
1536       } break;
1537       case Value::ValueType::Invalid:
1538         error.SetErrorString("invalid location");
1539         return false;
1540       case Value::ValueType::FileAddress:
1541       case Value::ValueType::Scalar:
1542         break;
1543       }
1544     } else {
1545       return false;
1546     }
1547   } else {
1548     // We don't support setting things bigger than a scalar at present.
1549     error.SetErrorString("unable to write aggregate data type");
1550     return false;
1551   }
1552 
1553   // If we have reached this point, then we have successfully changed the
1554   // value.
1555   SetNeedsUpdate();
1556   return true;
1557 }
1558 
GetDeclaration(Declaration & decl)1559 bool ValueObject::GetDeclaration(Declaration &decl) {
1560   decl.Clear();
1561   return false;
1562 }
1563 
AddSyntheticChild(ConstString key,ValueObject * valobj)1564 void ValueObject::AddSyntheticChild(ConstString key,
1565                                     ValueObject *valobj) {
1566   m_synthetic_children[key] = valobj;
1567 }
1568 
GetSyntheticChild(ConstString key) const1569 ValueObjectSP ValueObject::GetSyntheticChild(ConstString key) const {
1570   ValueObjectSP synthetic_child_sp;
1571   std::map<ConstString, ValueObject *>::const_iterator pos =
1572       m_synthetic_children.find(key);
1573   if (pos != m_synthetic_children.end())
1574     synthetic_child_sp = pos->second->GetSP();
1575   return synthetic_child_sp;
1576 }
1577 
IsPossibleDynamicType()1578 bool ValueObject::IsPossibleDynamicType() {
1579   ExecutionContext exe_ctx(GetExecutionContextRef());
1580   Process *process = exe_ctx.GetProcessPtr();
1581   if (process)
1582     return process->IsPossibleDynamicValue(*this);
1583   else
1584     return GetCompilerType().IsPossibleDynamicType(nullptr, true, true);
1585 }
1586 
IsRuntimeSupportValue()1587 bool ValueObject::IsRuntimeSupportValue() {
1588   Process *process(GetProcessSP().get());
1589   if (!process)
1590     return false;
1591 
1592   // We trust that the compiler did the right thing and marked runtime support
1593   // values as artificial.
1594   if (!GetVariable() || !GetVariable()->IsArtificial())
1595     return false;
1596 
1597   if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage()))
1598     if (runtime->IsAllowedRuntimeValue(GetName()))
1599       return false;
1600 
1601   return true;
1602 }
1603 
IsNilReference()1604 bool ValueObject::IsNilReference() {
1605   if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1606     return language->IsNilReference(*this);
1607   }
1608   return false;
1609 }
1610 
IsUninitializedReference()1611 bool ValueObject::IsUninitializedReference() {
1612   if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
1613     return language->IsUninitializedReference(*this);
1614   }
1615   return false;
1616 }
1617 
1618 // This allows you to create an array member using and index that doesn't not
1619 // fall in the normal bounds of the array. Many times structure can be defined
1620 // as: struct Collection {
1621 //     uint32_t item_count;
1622 //     Item item_array[0];
1623 // };
1624 // The size of the "item_array" is 1, but many times in practice there are more
1625 // items in "item_array".
1626 
GetSyntheticArrayMember(size_t index,bool can_create)1627 ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
1628                                                    bool can_create) {
1629   ValueObjectSP synthetic_child_sp;
1630   if (IsPointerType() || IsArrayType()) {
1631     std::string index_str = llvm::formatv("[{0}]", index);
1632     ConstString index_const_str(index_str);
1633     // Check if we have already created a synthetic array member in this valid
1634     // object. If we have we will re-use it.
1635     synthetic_child_sp = GetSyntheticChild(index_const_str);
1636     if (!synthetic_child_sp) {
1637       ValueObject *synthetic_child;
1638       // We haven't made a synthetic array member for INDEX yet, so lets make
1639       // one and cache it for any future reference.
1640       synthetic_child = CreateChildAtIndex(0, true, index);
1641 
1642       // Cache the value if we got one back...
1643       if (synthetic_child) {
1644         AddSyntheticChild(index_const_str, synthetic_child);
1645         synthetic_child_sp = synthetic_child->GetSP();
1646         synthetic_child_sp->SetName(ConstString(index_str));
1647         synthetic_child_sp->m_flags.m_is_array_item_for_pointer = true;
1648       }
1649     }
1650   }
1651   return synthetic_child_sp;
1652 }
1653 
GetSyntheticBitFieldChild(uint32_t from,uint32_t to,bool can_create)1654 ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
1655                                                      bool can_create) {
1656   ValueObjectSP synthetic_child_sp;
1657   if (IsScalarType()) {
1658     std::string index_str = llvm::formatv("[{0}-{1}]", from, to);
1659     ConstString index_const_str(index_str);
1660     // Check if we have already created a synthetic array member in this valid
1661     // object. If we have we will re-use it.
1662     synthetic_child_sp = GetSyntheticChild(index_const_str);
1663     if (!synthetic_child_sp) {
1664       uint32_t bit_field_size = to - from + 1;
1665       uint32_t bit_field_offset = from;
1666       if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
1667         bit_field_offset =
1668             GetByteSize().value_or(0) * 8 - bit_field_size - bit_field_offset;
1669       // We haven't made a synthetic array member for INDEX yet, so lets make
1670       // one and cache it for any future reference.
1671       ValueObjectChild *synthetic_child = new ValueObjectChild(
1672           *this, GetCompilerType(), index_const_str, GetByteSize().value_or(0),
1673           0, bit_field_size, bit_field_offset, false, false,
1674           eAddressTypeInvalid, 0);
1675 
1676       // Cache the value if we got one back...
1677       if (synthetic_child) {
1678         AddSyntheticChild(index_const_str, synthetic_child);
1679         synthetic_child_sp = synthetic_child->GetSP();
1680         synthetic_child_sp->SetName(ConstString(index_str));
1681         synthetic_child_sp->m_flags.m_is_bitfield_for_scalar = true;
1682       }
1683     }
1684   }
1685   return synthetic_child_sp;
1686 }
1687 
GetSyntheticChildAtOffset(uint32_t offset,const CompilerType & type,bool can_create,ConstString name_const_str)1688 ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
1689     uint32_t offset, const CompilerType &type, bool can_create,
1690     ConstString name_const_str) {
1691 
1692   ValueObjectSP synthetic_child_sp;
1693 
1694   if (name_const_str.IsEmpty()) {
1695     name_const_str.SetString("@" + std::to_string(offset));
1696   }
1697 
1698   // Check if we have already created a synthetic array member in this valid
1699   // object. If we have we will re-use it.
1700   synthetic_child_sp = GetSyntheticChild(name_const_str);
1701 
1702   if (synthetic_child_sp.get())
1703     return synthetic_child_sp;
1704 
1705   if (!can_create)
1706     return {};
1707 
1708   ExecutionContext exe_ctx(GetExecutionContextRef());
1709   std::optional<uint64_t> size =
1710       type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1711   if (!size)
1712     return {};
1713   ValueObjectChild *synthetic_child =
1714       new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1715                            false, false, eAddressTypeInvalid, 0);
1716   if (synthetic_child) {
1717     AddSyntheticChild(name_const_str, synthetic_child);
1718     synthetic_child_sp = synthetic_child->GetSP();
1719     synthetic_child_sp->SetName(name_const_str);
1720     synthetic_child_sp->m_flags.m_is_child_at_offset = true;
1721   }
1722   return synthetic_child_sp;
1723 }
1724 
GetSyntheticBase(uint32_t offset,const CompilerType & type,bool can_create,ConstString name_const_str)1725 ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
1726                                             const CompilerType &type,
1727                                             bool can_create,
1728                                             ConstString name_const_str) {
1729   ValueObjectSP synthetic_child_sp;
1730 
1731   if (name_const_str.IsEmpty()) {
1732     char name_str[128];
1733     snprintf(name_str, sizeof(name_str), "base%s@%i",
1734              type.GetTypeName().AsCString("<unknown>"), offset);
1735     name_const_str.SetCString(name_str);
1736   }
1737 
1738   // Check if we have already created a synthetic array member in this valid
1739   // object. If we have we will re-use it.
1740   synthetic_child_sp = GetSyntheticChild(name_const_str);
1741 
1742   if (synthetic_child_sp.get())
1743     return synthetic_child_sp;
1744 
1745   if (!can_create)
1746     return {};
1747 
1748   const bool is_base_class = true;
1749 
1750   ExecutionContext exe_ctx(GetExecutionContextRef());
1751   std::optional<uint64_t> size =
1752       type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
1753   if (!size)
1754     return {};
1755   ValueObjectChild *synthetic_child =
1756       new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0,
1757                            is_base_class, false, eAddressTypeInvalid, 0);
1758   if (synthetic_child) {
1759     AddSyntheticChild(name_const_str, synthetic_child);
1760     synthetic_child_sp = synthetic_child->GetSP();
1761     synthetic_child_sp->SetName(name_const_str);
1762   }
1763   return synthetic_child_sp;
1764 }
1765 
1766 // your expression path needs to have a leading . or -> (unless it somehow
1767 // "looks like" an array, in which case it has a leading [ symbol). while the [
1768 // is meaningful and should be shown to the user, . and -> are just parser
1769 // design, but by no means added information for the user.. strip them off
SkipLeadingExpressionPathSeparators(const char * expression)1770 static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
1771   if (!expression || !expression[0])
1772     return expression;
1773   if (expression[0] == '.')
1774     return expression + 1;
1775   if (expression[0] == '-' && expression[1] == '>')
1776     return expression + 2;
1777   return expression;
1778 }
1779 
1780 ValueObjectSP
GetSyntheticExpressionPathChild(const char * expression,bool can_create)1781 ValueObject::GetSyntheticExpressionPathChild(const char *expression,
1782                                              bool can_create) {
1783   ValueObjectSP synthetic_child_sp;
1784   ConstString name_const_string(expression);
1785   // Check if we have already created a synthetic array member in this valid
1786   // object. If we have we will re-use it.
1787   synthetic_child_sp = GetSyntheticChild(name_const_string);
1788   if (!synthetic_child_sp) {
1789     // We haven't made a synthetic array member for expression yet, so lets
1790     // make one and cache it for any future reference.
1791     synthetic_child_sp = GetValueForExpressionPath(
1792         expression, nullptr, nullptr,
1793         GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
1794             GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
1795                 None));
1796 
1797     // Cache the value if we got one back...
1798     if (synthetic_child_sp.get()) {
1799       // FIXME: this causes a "real" child to end up with its name changed to
1800       // the contents of expression
1801       AddSyntheticChild(name_const_string, synthetic_child_sp.get());
1802       synthetic_child_sp->SetName(
1803           ConstString(SkipLeadingExpressionPathSeparators(expression)));
1804     }
1805   }
1806   return synthetic_child_sp;
1807 }
1808 
CalculateSyntheticValue()1809 void ValueObject::CalculateSyntheticValue() {
1810   TargetSP target_sp(GetTargetSP());
1811   if (target_sp && !target_sp->GetEnableSyntheticValue()) {
1812     m_synthetic_value = nullptr;
1813     return;
1814   }
1815 
1816   lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
1817 
1818   if (!UpdateFormatsIfNeeded() && m_synthetic_value)
1819     return;
1820 
1821   if (m_synthetic_children_sp.get() == nullptr)
1822     return;
1823 
1824   if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
1825     return;
1826 
1827   m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
1828 }
1829 
CalculateDynamicValue(DynamicValueType use_dynamic)1830 void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
1831   if (use_dynamic == eNoDynamicValues)
1832     return;
1833 
1834   if (!m_dynamic_value && !IsDynamic()) {
1835     ExecutionContext exe_ctx(GetExecutionContextRef());
1836     Process *process = exe_ctx.GetProcessPtr();
1837     if (process && process->IsPossibleDynamicValue(*this)) {
1838       ClearDynamicTypeInformation();
1839       m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
1840     }
1841   }
1842 }
1843 
GetDynamicValue(DynamicValueType use_dynamic)1844 ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
1845   if (use_dynamic == eNoDynamicValues)
1846     return ValueObjectSP();
1847 
1848   if (!IsDynamic() && m_dynamic_value == nullptr) {
1849     CalculateDynamicValue(use_dynamic);
1850   }
1851   if (m_dynamic_value)
1852     return m_dynamic_value->GetSP();
1853   else
1854     return ValueObjectSP();
1855 }
1856 
GetSyntheticValue()1857 ValueObjectSP ValueObject::GetSyntheticValue() {
1858   CalculateSyntheticValue();
1859 
1860   if (m_synthetic_value)
1861     return m_synthetic_value->GetSP();
1862   else
1863     return ValueObjectSP();
1864 }
1865 
HasSyntheticValue()1866 bool ValueObject::HasSyntheticValue() {
1867   UpdateFormatsIfNeeded();
1868 
1869   if (m_synthetic_children_sp.get() == nullptr)
1870     return false;
1871 
1872   CalculateSyntheticValue();
1873 
1874   return m_synthetic_value != nullptr;
1875 }
1876 
GetNonBaseClassParent()1877 ValueObject *ValueObject::GetNonBaseClassParent() {
1878   if (GetParent()) {
1879     if (GetParent()->IsBaseClass())
1880       return GetParent()->GetNonBaseClassParent();
1881     else
1882       return GetParent();
1883   }
1884   return nullptr;
1885 }
1886 
IsBaseClass(uint32_t & depth)1887 bool ValueObject::IsBaseClass(uint32_t &depth) {
1888   if (!IsBaseClass()) {
1889     depth = 0;
1890     return false;
1891   }
1892   if (GetParent()) {
1893     GetParent()->IsBaseClass(depth);
1894     depth = depth + 1;
1895     return true;
1896   }
1897   // TODO: a base of no parent? weird..
1898   depth = 1;
1899   return true;
1900 }
1901 
GetExpressionPath(Stream & s,GetExpressionPathFormat epformat)1902 void ValueObject::GetExpressionPath(Stream &s,
1903                                     GetExpressionPathFormat epformat) {
1904   // synthetic children do not actually "exist" as part of the hierarchy, and
1905   // sometimes they are consed up in ways that don't make sense from an
1906   // underlying language/API standpoint. So, use a special code path here to
1907   // return something that can hopefully be used in expression
1908   if (m_flags.m_is_synthetic_children_generated) {
1909     UpdateValueIfNeeded();
1910 
1911     if (m_value.GetValueType() == Value::ValueType::LoadAddress) {
1912       if (IsPointerOrReferenceType()) {
1913         s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
1914                  GetValueAsUnsigned(0));
1915         return;
1916       } else {
1917         uint64_t load_addr =
1918             m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1919         if (load_addr != LLDB_INVALID_ADDRESS) {
1920           s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
1921                    load_addr);
1922           return;
1923         }
1924       }
1925     }
1926 
1927     if (CanProvideValue()) {
1928       s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
1929                GetValueAsCString());
1930       return;
1931     }
1932 
1933     return;
1934   }
1935 
1936   const bool is_deref_of_parent = IsDereferenceOfParent();
1937 
1938   if (is_deref_of_parent &&
1939       epformat == eGetExpressionPathFormatDereferencePointers) {
1940     // this is the original format of GetExpressionPath() producing code like
1941     // *(a_ptr).memberName, which is entirely fine, until you put this into
1942     // StackFrame::GetValueForVariableExpressionPath() which prefers to see
1943     // a_ptr->memberName. the eHonorPointers mode is meant to produce strings
1944     // in this latter format
1945     s.PutCString("*(");
1946   }
1947 
1948   ValueObject *parent = GetParent();
1949 
1950   if (parent)
1951     parent->GetExpressionPath(s, epformat);
1952 
1953   // if we are a deref_of_parent just because we are synthetic array members
1954   // made up to allow ptr[%d] syntax to work in variable printing, then add our
1955   // name ([%d]) to the expression path
1956   if (m_flags.m_is_array_item_for_pointer &&
1957       epformat == eGetExpressionPathFormatHonorPointers)
1958     s.PutCString(m_name.GetStringRef());
1959 
1960   if (!IsBaseClass()) {
1961     if (!is_deref_of_parent) {
1962       ValueObject *non_base_class_parent = GetNonBaseClassParent();
1963       if (non_base_class_parent &&
1964           !non_base_class_parent->GetName().IsEmpty()) {
1965         CompilerType non_base_class_parent_compiler_type =
1966             non_base_class_parent->GetCompilerType();
1967         if (non_base_class_parent_compiler_type) {
1968           if (parent && parent->IsDereferenceOfParent() &&
1969               epformat == eGetExpressionPathFormatHonorPointers) {
1970             s.PutCString("->");
1971           } else {
1972             const uint32_t non_base_class_parent_type_info =
1973                 non_base_class_parent_compiler_type.GetTypeInfo();
1974 
1975             if (non_base_class_parent_type_info & eTypeIsPointer) {
1976               s.PutCString("->");
1977             } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
1978                        !(non_base_class_parent_type_info & eTypeIsArray)) {
1979               s.PutChar('.');
1980             }
1981           }
1982         }
1983       }
1984 
1985       const char *name = GetName().GetCString();
1986       if (name)
1987         s.PutCString(name);
1988     }
1989   }
1990 
1991   if (is_deref_of_parent &&
1992       epformat == eGetExpressionPathFormatDereferencePointers) {
1993     s.PutChar(')');
1994   }
1995 }
1996 
GetValueForExpressionPath(llvm::StringRef expression,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_value_type,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * final_task_on_target)1997 ValueObjectSP ValueObject::GetValueForExpressionPath(
1998     llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
1999     ExpressionPathEndResultType *final_value_type,
2000     const GetValueForExpressionPathOptions &options,
2001     ExpressionPathAftermath *final_task_on_target) {
2002 
2003   ExpressionPathScanEndReason dummy_reason_to_stop =
2004       ValueObject::eExpressionPathScanEndReasonUnknown;
2005   ExpressionPathEndResultType dummy_final_value_type =
2006       ValueObject::eExpressionPathEndResultTypeInvalid;
2007   ExpressionPathAftermath dummy_final_task_on_target =
2008       ValueObject::eExpressionPathAftermathNothing;
2009 
2010   ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
2011       expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2012       final_value_type ? final_value_type : &dummy_final_value_type, options,
2013       final_task_on_target ? final_task_on_target
2014                            : &dummy_final_task_on_target);
2015 
2016   if (!final_task_on_target ||
2017       *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2018     return ret_val;
2019 
2020   if (ret_val.get() &&
2021       ((final_value_type ? *final_value_type : dummy_final_value_type) ==
2022        eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
2023                                            // of plain objects
2024   {
2025     if ((final_task_on_target ? *final_task_on_target
2026                               : dummy_final_task_on_target) ==
2027         ValueObject::eExpressionPathAftermathDereference) {
2028       Status error;
2029       ValueObjectSP final_value = ret_val->Dereference(error);
2030       if (error.Fail() || !final_value.get()) {
2031         if (reason_to_stop)
2032           *reason_to_stop =
2033               ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2034         if (final_value_type)
2035           *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2036         return ValueObjectSP();
2037       } else {
2038         if (final_task_on_target)
2039           *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2040         return final_value;
2041       }
2042     }
2043     if (*final_task_on_target ==
2044         ValueObject::eExpressionPathAftermathTakeAddress) {
2045       Status error;
2046       ValueObjectSP final_value = ret_val->AddressOf(error);
2047       if (error.Fail() || !final_value.get()) {
2048         if (reason_to_stop)
2049           *reason_to_stop =
2050               ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2051         if (final_value_type)
2052           *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2053         return ValueObjectSP();
2054       } else {
2055         if (final_task_on_target)
2056           *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2057         return final_value;
2058       }
2059     }
2060   }
2061   return ret_val; // final_task_on_target will still have its original value, so
2062                   // you know I did not do it
2063 }
2064 
GetValueForExpressionPath_Impl(llvm::StringRef expression,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_result,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * what_next)2065 ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
2066     llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
2067     ExpressionPathEndResultType *final_result,
2068     const GetValueForExpressionPathOptions &options,
2069     ExpressionPathAftermath *what_next) {
2070   ValueObjectSP root = GetSP();
2071 
2072   if (!root)
2073     return nullptr;
2074 
2075   llvm::StringRef remainder = expression;
2076 
2077   while (true) {
2078     llvm::StringRef temp_expression = remainder;
2079 
2080     CompilerType root_compiler_type = root->GetCompilerType();
2081     CompilerType pointee_compiler_type;
2082     Flags pointee_compiler_type_info;
2083 
2084     Flags root_compiler_type_info(
2085         root_compiler_type.GetTypeInfo(&pointee_compiler_type));
2086     if (pointee_compiler_type)
2087       pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo());
2088 
2089     if (temp_expression.empty()) {
2090       *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2091       return root;
2092     }
2093 
2094     switch (temp_expression.front()) {
2095     case '-': {
2096       temp_expression = temp_expression.drop_front();
2097       if (options.m_check_dot_vs_arrow_syntax &&
2098           root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2099                                                         // use -> on a
2100                                                         // non-pointer and I
2101                                                         // must catch the error
2102       {
2103         *reason_to_stop =
2104             ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2105         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2106         return ValueObjectSP();
2107       }
2108       if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to
2109                                                        // extract an ObjC IVar
2110                                                        // when this is forbidden
2111           root_compiler_type_info.Test(eTypeIsPointer) &&
2112           options.m_no_fragile_ivar) {
2113         *reason_to_stop =
2114             ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2115         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2116         return ValueObjectSP();
2117       }
2118       if (!temp_expression.startswith(">")) {
2119         *reason_to_stop =
2120             ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2121         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2122         return ValueObjectSP();
2123       }
2124     }
2125       [[fallthrough]];
2126     case '.': // or fallthrough from ->
2127     {
2128       if (options.m_check_dot_vs_arrow_syntax &&
2129           temp_expression.front() == '.' &&
2130           root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
2131                                                         // use . on a pointer
2132                                                         // and I must catch the
2133                                                         // error
2134       {
2135         *reason_to_stop =
2136             ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2137         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2138         return nullptr;
2139       }
2140       temp_expression = temp_expression.drop_front(); // skip . or >
2141 
2142       size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
2143       ConstString child_name;
2144       if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
2145                                                  // expand this last layer
2146       {
2147         child_name.SetString(temp_expression);
2148         ValueObjectSP child_valobj_sp =
2149             root->GetChildMemberWithName(child_name, true);
2150 
2151         if (child_valobj_sp.get()) // we know we are done, so just return
2152         {
2153           *reason_to_stop =
2154               ValueObject::eExpressionPathScanEndReasonEndOfString;
2155           *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2156           return child_valobj_sp;
2157         } else {
2158           switch (options.m_synthetic_children_traversal) {
2159           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2160               None:
2161             break;
2162           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2163               FromSynthetic:
2164             if (root->IsSynthetic()) {
2165               child_valobj_sp = root->GetNonSyntheticValue();
2166               if (child_valobj_sp.get())
2167                 child_valobj_sp =
2168                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2169             }
2170             break;
2171           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2172               ToSynthetic:
2173             if (!root->IsSynthetic()) {
2174               child_valobj_sp = root->GetSyntheticValue();
2175               if (child_valobj_sp.get())
2176                 child_valobj_sp =
2177                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2178             }
2179             break;
2180           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2181               Both:
2182             if (root->IsSynthetic()) {
2183               child_valobj_sp = root->GetNonSyntheticValue();
2184               if (child_valobj_sp.get())
2185                 child_valobj_sp =
2186                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2187             } else {
2188               child_valobj_sp = root->GetSyntheticValue();
2189               if (child_valobj_sp.get())
2190                 child_valobj_sp =
2191                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2192             }
2193             break;
2194           }
2195         }
2196 
2197         // if we are here and options.m_no_synthetic_children is true,
2198         // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2199         // branch, and return an error
2200         if (child_valobj_sp.get()) // if it worked, just return
2201         {
2202           *reason_to_stop =
2203               ValueObject::eExpressionPathScanEndReasonEndOfString;
2204           *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2205           return child_valobj_sp;
2206         } else {
2207           *reason_to_stop =
2208               ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2209           *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2210           return nullptr;
2211         }
2212       } else // other layers do expand
2213       {
2214         llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
2215 
2216         child_name.SetString(temp_expression.slice(0, next_sep_pos));
2217 
2218         ValueObjectSP child_valobj_sp =
2219             root->GetChildMemberWithName(child_name, true);
2220         if (child_valobj_sp.get()) // store the new root and move on
2221         {
2222           root = child_valobj_sp;
2223           remainder = next_separator;
2224           *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2225           continue;
2226         } else {
2227           switch (options.m_synthetic_children_traversal) {
2228           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2229               None:
2230             break;
2231           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2232               FromSynthetic:
2233             if (root->IsSynthetic()) {
2234               child_valobj_sp = root->GetNonSyntheticValue();
2235               if (child_valobj_sp.get())
2236                 child_valobj_sp =
2237                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2238             }
2239             break;
2240           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2241               ToSynthetic:
2242             if (!root->IsSynthetic()) {
2243               child_valobj_sp = root->GetSyntheticValue();
2244               if (child_valobj_sp.get())
2245                 child_valobj_sp =
2246                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2247             }
2248             break;
2249           case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2250               Both:
2251             if (root->IsSynthetic()) {
2252               child_valobj_sp = root->GetNonSyntheticValue();
2253               if (child_valobj_sp.get())
2254                 child_valobj_sp =
2255                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2256             } else {
2257               child_valobj_sp = root->GetSyntheticValue();
2258               if (child_valobj_sp.get())
2259                 child_valobj_sp =
2260                     child_valobj_sp->GetChildMemberWithName(child_name, true);
2261             }
2262             break;
2263           }
2264         }
2265 
2266         // if we are here and options.m_no_synthetic_children is true,
2267         // child_valobj_sp is going to be a NULL SP, so we hit the "else"
2268         // branch, and return an error
2269         if (child_valobj_sp.get()) // if it worked, move on
2270         {
2271           root = child_valobj_sp;
2272           remainder = next_separator;
2273           *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2274           continue;
2275         } else {
2276           *reason_to_stop =
2277               ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2278           *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2279           return nullptr;
2280         }
2281       }
2282       break;
2283     }
2284     case '[': {
2285       if (!root_compiler_type_info.Test(eTypeIsArray) &&
2286           !root_compiler_type_info.Test(eTypeIsPointer) &&
2287           !root_compiler_type_info.Test(
2288               eTypeIsVector)) // if this is not a T[] nor a T*
2289       {
2290         if (!root_compiler_type_info.Test(
2291                 eTypeIsScalar)) // if this is not even a scalar...
2292         {
2293           if (options.m_synthetic_children_traversal ==
2294               GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
2295                   None) // ...only chance left is synthetic
2296           {
2297             *reason_to_stop =
2298                 ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2299             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2300             return ValueObjectSP();
2301           }
2302         } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
2303                                                       // check that we can
2304                                                       // expand bitfields
2305         {
2306           *reason_to_stop =
2307               ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2308           *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2309           return ValueObjectSP();
2310         }
2311       }
2312       if (temp_expression[1] ==
2313           ']') // if this is an unbounded range it only works for arrays
2314       {
2315         if (!root_compiler_type_info.Test(eTypeIsArray)) {
2316           *reason_to_stop =
2317               ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2318           *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2319           return nullptr;
2320         } else // even if something follows, we cannot expand unbounded ranges,
2321                // just let the caller do it
2322         {
2323           *reason_to_stop =
2324               ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2325           *final_result =
2326               ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2327           return root;
2328         }
2329       }
2330 
2331       size_t close_bracket_position = temp_expression.find(']', 1);
2332       if (close_bracket_position ==
2333           llvm::StringRef::npos) // if there is no ], this is a syntax error
2334       {
2335         *reason_to_stop =
2336             ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2337         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2338         return nullptr;
2339       }
2340 
2341       llvm::StringRef bracket_expr =
2342           temp_expression.slice(1, close_bracket_position);
2343 
2344       // If this was an empty expression it would have been caught by the if
2345       // above.
2346       assert(!bracket_expr.empty());
2347 
2348       if (!bracket_expr.contains('-')) {
2349         // if no separator, this is of the form [N].  Note that this cannot be
2350         // an unbounded range of the form [], because that case was handled
2351         // above with an unconditional return.
2352         unsigned long index = 0;
2353         if (bracket_expr.getAsInteger(0, index)) {
2354           *reason_to_stop =
2355               ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2356           *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2357           return nullptr;
2358         }
2359 
2360         // from here on we do have a valid index
2361         if (root_compiler_type_info.Test(eTypeIsArray)) {
2362           ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2363           if (!child_valobj_sp)
2364             child_valobj_sp = root->GetSyntheticArrayMember(index, true);
2365           if (!child_valobj_sp)
2366             if (root->HasSyntheticValue() &&
2367                 root->GetSyntheticValue()->GetNumChildren() > index)
2368               child_valobj_sp =
2369                   root->GetSyntheticValue()->GetChildAtIndex(index, true);
2370           if (child_valobj_sp) {
2371             root = child_valobj_sp;
2372             remainder =
2373                 temp_expression.substr(close_bracket_position + 1); // skip ]
2374             *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2375             continue;
2376           } else {
2377             *reason_to_stop =
2378                 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2379             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2380             return nullptr;
2381           }
2382         } else if (root_compiler_type_info.Test(eTypeIsPointer)) {
2383           if (*what_next ==
2384                   ValueObject::
2385                       eExpressionPathAftermathDereference && // if this is a
2386                                                              // ptr-to-scalar, I
2387                                                              // am accessing it
2388                                                              // by index and I
2389                                                              // would have
2390                                                              // deref'ed anyway,
2391                                                              // then do it now
2392                                                              // and use this as
2393                                                              // a bitfield
2394               pointee_compiler_type_info.Test(eTypeIsScalar)) {
2395             Status error;
2396             root = root->Dereference(error);
2397             if (error.Fail() || !root) {
2398               *reason_to_stop =
2399                   ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2400               *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2401               return nullptr;
2402             } else {
2403               *what_next = eExpressionPathAftermathNothing;
2404               continue;
2405             }
2406           } else {
2407             if (root->GetCompilerType().GetMinimumLanguage() ==
2408                     eLanguageTypeObjC &&
2409                 pointee_compiler_type_info.AllClear(eTypeIsPointer) &&
2410                 root->HasSyntheticValue() &&
2411                 (options.m_synthetic_children_traversal ==
2412                      GetValueForExpressionPathOptions::
2413                          SyntheticChildrenTraversal::ToSynthetic ||
2414                  options.m_synthetic_children_traversal ==
2415                      GetValueForExpressionPathOptions::
2416                          SyntheticChildrenTraversal::Both)) {
2417               root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2418             } else
2419               root = root->GetSyntheticArrayMember(index, true);
2420             if (!root) {
2421               *reason_to_stop =
2422                   ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2423               *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2424               return nullptr;
2425             } else {
2426               remainder =
2427                   temp_expression.substr(close_bracket_position + 1); // skip ]
2428               *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2429               continue;
2430             }
2431           }
2432         } else if (root_compiler_type_info.Test(eTypeIsScalar)) {
2433           root = root->GetSyntheticBitFieldChild(index, index, true);
2434           if (!root) {
2435             *reason_to_stop =
2436                 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2437             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2438             return nullptr;
2439           } else // we do not know how to expand members of bitfields, so we
2440                  // just return and let the caller do any further processing
2441           {
2442             *reason_to_stop = ValueObject::
2443                 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2444             *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2445             return root;
2446           }
2447         } else if (root_compiler_type_info.Test(eTypeIsVector)) {
2448           root = root->GetChildAtIndex(index, true);
2449           if (!root) {
2450             *reason_to_stop =
2451                 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2452             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2453             return ValueObjectSP();
2454           } else {
2455             remainder =
2456                 temp_expression.substr(close_bracket_position + 1); // skip ]
2457             *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2458             continue;
2459           }
2460         } else if (options.m_synthetic_children_traversal ==
2461                        GetValueForExpressionPathOptions::
2462                            SyntheticChildrenTraversal::ToSynthetic ||
2463                    options.m_synthetic_children_traversal ==
2464                        GetValueForExpressionPathOptions::
2465                            SyntheticChildrenTraversal::Both) {
2466           if (root->HasSyntheticValue())
2467             root = root->GetSyntheticValue();
2468           else if (!root->IsSynthetic()) {
2469             *reason_to_stop =
2470                 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2471             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2472             return nullptr;
2473           }
2474           // if we are here, then root itself is a synthetic VO.. should be
2475           // good to go
2476 
2477           if (!root) {
2478             *reason_to_stop =
2479                 ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2480             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2481             return nullptr;
2482           }
2483           root = root->GetChildAtIndex(index, true);
2484           if (!root) {
2485             *reason_to_stop =
2486                 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2487             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2488             return nullptr;
2489           } else {
2490             remainder =
2491                 temp_expression.substr(close_bracket_position + 1); // skip ]
2492             *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2493             continue;
2494           }
2495         } else {
2496           *reason_to_stop =
2497               ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2498           *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2499           return nullptr;
2500         }
2501       } else {
2502         // we have a low and a high index
2503         llvm::StringRef sleft, sright;
2504         unsigned long low_index, high_index;
2505         std::tie(sleft, sright) = bracket_expr.split('-');
2506         if (sleft.getAsInteger(0, low_index) ||
2507             sright.getAsInteger(0, high_index)) {
2508           *reason_to_stop =
2509               ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2510           *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2511           return nullptr;
2512         }
2513 
2514         if (low_index > high_index) // swap indices if required
2515           std::swap(low_index, high_index);
2516 
2517         if (root_compiler_type_info.Test(
2518                 eTypeIsScalar)) // expansion only works for scalars
2519         {
2520           root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
2521           if (!root) {
2522             *reason_to_stop =
2523                 ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2524             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2525             return nullptr;
2526           } else {
2527             *reason_to_stop = ValueObject::
2528                 eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2529             *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2530             return root;
2531           }
2532         } else if (root_compiler_type_info.Test(
2533                        eTypeIsPointer) && // if this is a ptr-to-scalar, I am
2534                                           // accessing it by index and I would
2535                                           // have deref'ed anyway, then do it
2536                                           // now and use this as a bitfield
2537                    *what_next ==
2538                        ValueObject::eExpressionPathAftermathDereference &&
2539                    pointee_compiler_type_info.Test(eTypeIsScalar)) {
2540           Status error;
2541           root = root->Dereference(error);
2542           if (error.Fail() || !root) {
2543             *reason_to_stop =
2544                 ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2545             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2546             return nullptr;
2547           } else {
2548             *what_next = ValueObject::eExpressionPathAftermathNothing;
2549             continue;
2550           }
2551         } else {
2552           *reason_to_stop =
2553               ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2554           *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
2555           return root;
2556         }
2557       }
2558       break;
2559     }
2560     default: // some non-separator is in the way
2561     {
2562       *reason_to_stop =
2563           ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2564       *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2565       return nullptr;
2566     }
2567     }
2568   }
2569 }
2570 
Dump(Stream & s)2571 void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
2572 
Dump(Stream & s,const DumpValueObjectOptions & options)2573 void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
2574   ValueObjectPrinter printer(this, &s, options);
2575   printer.PrintValueObject();
2576 }
2577 
CreateConstantValue(ConstString name)2578 ValueObjectSP ValueObject::CreateConstantValue(ConstString name) {
2579   ValueObjectSP valobj_sp;
2580 
2581   if (UpdateValueIfNeeded(false) && m_error.Success()) {
2582     ExecutionContext exe_ctx(GetExecutionContextRef());
2583 
2584     DataExtractor data;
2585     data.SetByteOrder(m_data.GetByteOrder());
2586     data.SetAddressByteSize(m_data.GetAddressByteSize());
2587 
2588     if (IsBitfield()) {
2589       Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
2590       m_error = v.GetValueAsData(&exe_ctx, data, GetModule().get());
2591     } else
2592       m_error = m_value.GetValueAsData(&exe_ctx, data, GetModule().get());
2593 
2594     valobj_sp = ValueObjectConstResult::Create(
2595         exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
2596         GetAddressOf());
2597   }
2598 
2599   if (!valobj_sp) {
2600     ExecutionContext exe_ctx(GetExecutionContextRef());
2601     valobj_sp = ValueObjectConstResult::Create(
2602         exe_ctx.GetBestExecutionContextScope(), m_error);
2603   }
2604   return valobj_sp;
2605 }
2606 
GetQualifiedRepresentationIfAvailable(lldb::DynamicValueType dynValue,bool synthValue)2607 ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
2608     lldb::DynamicValueType dynValue, bool synthValue) {
2609   ValueObjectSP result_sp(GetSP());
2610 
2611   switch (dynValue) {
2612   case lldb::eDynamicCanRunTarget:
2613   case lldb::eDynamicDontRunTarget: {
2614     if (!result_sp->IsDynamic()) {
2615       if (result_sp->GetDynamicValue(dynValue))
2616         result_sp = result_sp->GetDynamicValue(dynValue);
2617     }
2618   } break;
2619   case lldb::eNoDynamicValues: {
2620     if (result_sp->IsDynamic()) {
2621       if (result_sp->GetStaticValue())
2622         result_sp = result_sp->GetStaticValue();
2623     }
2624   } break;
2625   }
2626 
2627   if (synthValue) {
2628     if (!result_sp->IsSynthetic()) {
2629       if (result_sp->GetSyntheticValue())
2630         result_sp = result_sp->GetSyntheticValue();
2631     }
2632   } else {
2633     if (result_sp->IsSynthetic()) {
2634       if (result_sp->GetNonSyntheticValue())
2635         result_sp = result_sp->GetNonSyntheticValue();
2636     }
2637   }
2638 
2639   return result_sp;
2640 }
2641 
Dereference(Status & error)2642 ValueObjectSP ValueObject::Dereference(Status &error) {
2643   if (m_deref_valobj)
2644     return m_deref_valobj->GetSP();
2645 
2646   const bool is_pointer_or_reference_type = IsPointerOrReferenceType();
2647   if (is_pointer_or_reference_type) {
2648     bool omit_empty_base_classes = true;
2649     bool ignore_array_bounds = false;
2650 
2651     std::string child_name_str;
2652     uint32_t child_byte_size = 0;
2653     int32_t child_byte_offset = 0;
2654     uint32_t child_bitfield_bit_size = 0;
2655     uint32_t child_bitfield_bit_offset = 0;
2656     bool child_is_base_class = false;
2657     bool child_is_deref_of_parent = false;
2658     const bool transparent_pointers = false;
2659     CompilerType compiler_type = GetCompilerType();
2660     CompilerType child_compiler_type;
2661     uint64_t language_flags = 0;
2662 
2663     ExecutionContext exe_ctx(GetExecutionContextRef());
2664 
2665     child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex(
2666         &exe_ctx, 0, transparent_pointers, omit_empty_base_classes,
2667         ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset,
2668         child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
2669         child_is_deref_of_parent, this, language_flags);
2670     if (child_compiler_type && child_byte_size) {
2671       ConstString child_name;
2672       if (!child_name_str.empty())
2673         child_name.SetCString(child_name_str.c_str());
2674 
2675       m_deref_valobj = new ValueObjectChild(
2676           *this, child_compiler_type, child_name, child_byte_size,
2677           child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset,
2678           child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid,
2679           language_flags);
2680     }
2681 
2682     // In case of incomplete child compiler type, use the pointee type and try
2683     // to recreate a new ValueObjectChild using it.
2684     if (!m_deref_valobj) {
2685       // FIXME(#59012): C++ stdlib formatters break with incomplete types (e.g.
2686       // `std::vector<int> &`). Remove ObjC restriction once that's resolved.
2687       if (Language::LanguageIsObjC(GetPreferredDisplayLanguage()) &&
2688           HasSyntheticValue()) {
2689         child_compiler_type = compiler_type.GetPointeeType();
2690 
2691         if (child_compiler_type) {
2692           ConstString child_name;
2693           if (!child_name_str.empty())
2694             child_name.SetCString(child_name_str.c_str());
2695 
2696           m_deref_valobj = new ValueObjectChild(
2697               *this, child_compiler_type, child_name, child_byte_size,
2698               child_byte_offset, child_bitfield_bit_size,
2699               child_bitfield_bit_offset, child_is_base_class,
2700               child_is_deref_of_parent, eAddressTypeInvalid, language_flags);
2701         }
2702       }
2703     }
2704 
2705   } else if (HasSyntheticValue()) {
2706     m_deref_valobj =
2707         GetSyntheticValue()
2708             ->GetChildMemberWithName(ConstString("$$dereference$$"), true)
2709             .get();
2710   } else if (IsSynthetic()) {
2711     m_deref_valobj =
2712         GetChildMemberWithName(ConstString("$$dereference$$"), true).get();
2713   }
2714 
2715   if (m_deref_valobj) {
2716     error.Clear();
2717     return m_deref_valobj->GetSP();
2718   } else {
2719     StreamString strm;
2720     GetExpressionPath(strm);
2721 
2722     if (is_pointer_or_reference_type)
2723       error.SetErrorStringWithFormat("dereference failed: (%s) %s",
2724                                      GetTypeName().AsCString("<invalid type>"),
2725                                      strm.GetData());
2726     else
2727       error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
2728                                      GetTypeName().AsCString("<invalid type>"),
2729                                      strm.GetData());
2730     return ValueObjectSP();
2731   }
2732 }
2733 
AddressOf(Status & error)2734 ValueObjectSP ValueObject::AddressOf(Status &error) {
2735   if (m_addr_of_valobj_sp)
2736     return m_addr_of_valobj_sp;
2737 
2738   AddressType address_type = eAddressTypeInvalid;
2739   const bool scalar_is_load_address = false;
2740   addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
2741   error.Clear();
2742   if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
2743     switch (address_type) {
2744     case eAddressTypeInvalid: {
2745       StreamString expr_path_strm;
2746       GetExpressionPath(expr_path_strm);
2747       error.SetErrorStringWithFormat("'%s' is not in memory",
2748                                      expr_path_strm.GetData());
2749     } break;
2750 
2751     case eAddressTypeFile:
2752     case eAddressTypeLoad: {
2753       CompilerType compiler_type = GetCompilerType();
2754       if (compiler_type) {
2755         std::string name(1, '&');
2756         name.append(m_name.AsCString(""));
2757         ExecutionContext exe_ctx(GetExecutionContextRef());
2758         m_addr_of_valobj_sp = ValueObjectConstResult::Create(
2759             exe_ctx.GetBestExecutionContextScope(),
2760             compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
2761             eAddressTypeInvalid, m_data.GetAddressByteSize());
2762       }
2763     } break;
2764     default:
2765       break;
2766     }
2767   } else {
2768     StreamString expr_path_strm;
2769     GetExpressionPath(expr_path_strm);
2770     error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
2771                                    expr_path_strm.GetData());
2772   }
2773 
2774   return m_addr_of_valobj_sp;
2775 }
2776 
Cast(const CompilerType & compiler_type)2777 ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
2778   return ValueObjectCast::Create(*this, GetName(), compiler_type);
2779 }
2780 
Clone(ConstString new_name)2781 lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) {
2782   return ValueObjectCast::Create(*this, new_name, GetCompilerType());
2783 }
2784 
CastPointerType(const char * name,CompilerType & compiler_type)2785 ValueObjectSP ValueObject::CastPointerType(const char *name,
2786                                            CompilerType &compiler_type) {
2787   ValueObjectSP valobj_sp;
2788   AddressType address_type;
2789   addr_t ptr_value = GetPointerValue(&address_type);
2790 
2791   if (ptr_value != LLDB_INVALID_ADDRESS) {
2792     Address ptr_addr(ptr_value);
2793     ExecutionContext exe_ctx(GetExecutionContextRef());
2794     valobj_sp = ValueObjectMemory::Create(
2795         exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
2796   }
2797   return valobj_sp;
2798 }
2799 
CastPointerType(const char * name,TypeSP & type_sp)2800 ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
2801   ValueObjectSP valobj_sp;
2802   AddressType address_type;
2803   addr_t ptr_value = GetPointerValue(&address_type);
2804 
2805   if (ptr_value != LLDB_INVALID_ADDRESS) {
2806     Address ptr_addr(ptr_value);
2807     ExecutionContext exe_ctx(GetExecutionContextRef());
2808     valobj_sp = ValueObjectMemory::Create(
2809         exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
2810   }
2811   return valobj_sp;
2812 }
2813 
EvaluationPoint()2814 ValueObject::EvaluationPoint::EvaluationPoint() : m_mod_id(), m_exe_ctx_ref() {}
2815 
EvaluationPoint(ExecutionContextScope * exe_scope,bool use_selected)2816 ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
2817                                               bool use_selected)
2818     : m_mod_id(), m_exe_ctx_ref() {
2819   ExecutionContext exe_ctx(exe_scope);
2820   TargetSP target_sp(exe_ctx.GetTargetSP());
2821   if (target_sp) {
2822     m_exe_ctx_ref.SetTargetSP(target_sp);
2823     ProcessSP process_sp(exe_ctx.GetProcessSP());
2824     if (!process_sp)
2825       process_sp = target_sp->GetProcessSP();
2826 
2827     if (process_sp) {
2828       m_mod_id = process_sp->GetModID();
2829       m_exe_ctx_ref.SetProcessSP(process_sp);
2830 
2831       ThreadSP thread_sp(exe_ctx.GetThreadSP());
2832 
2833       if (!thread_sp) {
2834         if (use_selected)
2835           thread_sp = process_sp->GetThreadList().GetSelectedThread();
2836       }
2837 
2838       if (thread_sp) {
2839         m_exe_ctx_ref.SetThreadSP(thread_sp);
2840 
2841         StackFrameSP frame_sp(exe_ctx.GetFrameSP());
2842         if (!frame_sp) {
2843           if (use_selected)
2844             frame_sp = thread_sp->GetSelectedFrame();
2845         }
2846         if (frame_sp)
2847           m_exe_ctx_ref.SetFrameSP(frame_sp);
2848       }
2849     }
2850   }
2851 }
2852 
EvaluationPoint(const ValueObject::EvaluationPoint & rhs)2853 ValueObject::EvaluationPoint::EvaluationPoint(
2854     const ValueObject::EvaluationPoint &rhs)
2855     : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref) {}
2856 
2857 ValueObject::EvaluationPoint::~EvaluationPoint() = default;
2858 
2859 // This function checks the EvaluationPoint against the current process state.
2860 // If the current state matches the evaluation point, or the evaluation point
2861 // is already invalid, then we return false, meaning "no change".  If the
2862 // current state is different, we update our state, and return true meaning
2863 // "yes, change".  If we did see a change, we also set m_needs_update to true,
2864 // so future calls to NeedsUpdate will return true. exe_scope will be set to
2865 // the current execution context scope.
2866 
SyncWithProcessState(bool accept_invalid_exe_ctx)2867 bool ValueObject::EvaluationPoint::SyncWithProcessState(
2868     bool accept_invalid_exe_ctx) {
2869   // Start with the target, if it is NULL, then we're obviously not going to
2870   // get any further:
2871   const bool thread_and_frame_only_if_stopped = true;
2872   ExecutionContext exe_ctx(
2873       m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
2874 
2875   if (exe_ctx.GetTargetPtr() == nullptr)
2876     return false;
2877 
2878   // If we don't have a process nothing can change.
2879   Process *process = exe_ctx.GetProcessPtr();
2880   if (process == nullptr)
2881     return false;
2882 
2883   // If our stop id is the current stop ID, nothing has changed:
2884   ProcessModID current_mod_id = process->GetModID();
2885 
2886   // If the current stop id is 0, either we haven't run yet, or the process
2887   // state has been cleared. In either case, we aren't going to be able to sync
2888   // with the process state.
2889   if (current_mod_id.GetStopID() == 0)
2890     return false;
2891 
2892   bool changed = false;
2893   const bool was_valid = m_mod_id.IsValid();
2894   if (was_valid) {
2895     if (m_mod_id == current_mod_id) {
2896       // Everything is already up to date in this object, no need to update the
2897       // execution context scope.
2898       changed = false;
2899     } else {
2900       m_mod_id = current_mod_id;
2901       m_needs_update = true;
2902       changed = true;
2903     }
2904   }
2905 
2906   // Now re-look up the thread and frame in case the underlying objects have
2907   // gone away & been recreated. That way we'll be sure to return a valid
2908   // exe_scope. If we used to have a thread or a frame but can't find it
2909   // anymore, then mark ourselves as invalid.
2910 
2911   if (!accept_invalid_exe_ctx) {
2912     if (m_exe_ctx_ref.HasThreadRef()) {
2913       ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
2914       if (thread_sp) {
2915         if (m_exe_ctx_ref.HasFrameRef()) {
2916           StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
2917           if (!frame_sp) {
2918             // We used to have a frame, but now it is gone
2919             SetInvalid();
2920             changed = was_valid;
2921           }
2922         }
2923       } else {
2924         // We used to have a thread, but now it is gone
2925         SetInvalid();
2926         changed = was_valid;
2927       }
2928     }
2929   }
2930 
2931   return changed;
2932 }
2933 
SetUpdated()2934 void ValueObject::EvaluationPoint::SetUpdated() {
2935   ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
2936   if (process_sp)
2937     m_mod_id = process_sp->GetModID();
2938   m_needs_update = false;
2939 }
2940 
ClearUserVisibleData(uint32_t clear_mask)2941 void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
2942   if ((clear_mask & eClearUserVisibleDataItemsValue) ==
2943       eClearUserVisibleDataItemsValue)
2944     m_value_str.clear();
2945 
2946   if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
2947       eClearUserVisibleDataItemsLocation)
2948     m_location_str.clear();
2949 
2950   if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
2951       eClearUserVisibleDataItemsSummary)
2952     m_summary_str.clear();
2953 
2954   if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
2955       eClearUserVisibleDataItemsDescription)
2956     m_object_desc_str.clear();
2957 
2958   if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
2959       eClearUserVisibleDataItemsSyntheticChildren) {
2960     if (m_synthetic_value)
2961       m_synthetic_value = nullptr;
2962   }
2963 }
2964 
GetSymbolContextScope()2965 SymbolContextScope *ValueObject::GetSymbolContextScope() {
2966   if (m_parent) {
2967     if (!m_parent->IsPointerOrReferenceType())
2968       return m_parent->GetSymbolContextScope();
2969   }
2970   return nullptr;
2971 }
2972 
2973 lldb::ValueObjectSP
CreateValueObjectFromExpression(llvm::StringRef name,llvm::StringRef expression,const ExecutionContext & exe_ctx)2974 ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
2975                                              llvm::StringRef expression,
2976                                              const ExecutionContext &exe_ctx) {
2977   return CreateValueObjectFromExpression(name, expression, exe_ctx,
2978                                          EvaluateExpressionOptions());
2979 }
2980 
CreateValueObjectFromExpression(llvm::StringRef name,llvm::StringRef expression,const ExecutionContext & exe_ctx,const EvaluateExpressionOptions & options)2981 lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
2982     llvm::StringRef name, llvm::StringRef expression,
2983     const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
2984   lldb::ValueObjectSP retval_sp;
2985   lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
2986   if (!target_sp)
2987     return retval_sp;
2988   if (expression.empty())
2989     return retval_sp;
2990   target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
2991                                 retval_sp, options);
2992   if (retval_sp && !name.empty())
2993     retval_sp->SetName(ConstString(name));
2994   return retval_sp;
2995 }
2996 
CreateValueObjectFromAddress(llvm::StringRef name,uint64_t address,const ExecutionContext & exe_ctx,CompilerType type)2997 lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
2998     llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
2999     CompilerType type) {
3000   if (type) {
3001     CompilerType pointer_type(type.GetPointerType());
3002     if (pointer_type) {
3003       lldb::DataBufferSP buffer(
3004           new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
3005       lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
3006           exe_ctx.GetBestExecutionContextScope(), pointer_type,
3007           ConstString(name), buffer, exe_ctx.GetByteOrder(),
3008           exe_ctx.GetAddressByteSize()));
3009       if (ptr_result_valobj_sp) {
3010         ptr_result_valobj_sp->GetValue().SetValueType(
3011             Value::ValueType::LoadAddress);
3012         Status err;
3013         ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
3014         if (ptr_result_valobj_sp && !name.empty())
3015           ptr_result_valobj_sp->SetName(ConstString(name));
3016       }
3017       return ptr_result_valobj_sp;
3018     }
3019   }
3020   return lldb::ValueObjectSP();
3021 }
3022 
CreateValueObjectFromData(llvm::StringRef name,const DataExtractor & data,const ExecutionContext & exe_ctx,CompilerType type)3023 lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
3024     llvm::StringRef name, const DataExtractor &data,
3025     const ExecutionContext &exe_ctx, CompilerType type) {
3026   lldb::ValueObjectSP new_value_sp;
3027   new_value_sp = ValueObjectConstResult::Create(
3028       exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
3029       LLDB_INVALID_ADDRESS);
3030   new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
3031   if (new_value_sp && !name.empty())
3032     new_value_sp->SetName(ConstString(name));
3033   return new_value_sp;
3034 }
3035 
GetModule()3036 ModuleSP ValueObject::GetModule() {
3037   ValueObject *root(GetRoot());
3038   if (root != this)
3039     return root->GetModule();
3040   return lldb::ModuleSP();
3041 }
3042 
GetRoot()3043 ValueObject *ValueObject::GetRoot() {
3044   if (m_root)
3045     return m_root;
3046   return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
3047             return (vo->m_parent != nullptr);
3048           }));
3049 }
3050 
3051 ValueObject *
FollowParentChain(std::function<bool (ValueObject *)> f)3052 ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
3053   ValueObject *vo = this;
3054   while (vo) {
3055     if (!f(vo))
3056       break;
3057     vo = vo->m_parent;
3058   }
3059   return vo;
3060 }
3061 
GetAddressTypeOfChildren()3062 AddressType ValueObject::GetAddressTypeOfChildren() {
3063   if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
3064     ValueObject *root(GetRoot());
3065     if (root != this)
3066       return root->GetAddressTypeOfChildren();
3067   }
3068   return m_address_type_of_ptr_or_ref_children;
3069 }
3070 
GetDynamicValueType()3071 lldb::DynamicValueType ValueObject::GetDynamicValueType() {
3072   ValueObject *with_dv_info = this;
3073   while (with_dv_info) {
3074     if (with_dv_info->HasDynamicValueTypeInfo())
3075       return with_dv_info->GetDynamicValueTypeImpl();
3076     with_dv_info = with_dv_info->m_parent;
3077   }
3078   return lldb::eNoDynamicValues;
3079 }
3080 
GetFormat() const3081 lldb::Format ValueObject::GetFormat() const {
3082   const ValueObject *with_fmt_info = this;
3083   while (with_fmt_info) {
3084     if (with_fmt_info->m_format != lldb::eFormatDefault)
3085       return with_fmt_info->m_format;
3086     with_fmt_info = with_fmt_info->m_parent;
3087   }
3088   return m_format;
3089 }
3090 
GetPreferredDisplayLanguage()3091 lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
3092   lldb::LanguageType type = m_preferred_display_language;
3093   if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
3094     if (GetRoot()) {
3095       if (GetRoot() == this) {
3096         if (StackFrameSP frame_sp = GetFrameSP()) {
3097           const SymbolContext &sc(
3098               frame_sp->GetSymbolContext(eSymbolContextCompUnit));
3099           if (CompileUnit *cu = sc.comp_unit)
3100             type = cu->GetLanguage();
3101         }
3102       } else {
3103         type = GetRoot()->GetPreferredDisplayLanguage();
3104       }
3105     }
3106   }
3107   return (m_preferred_display_language = type); // only compute it once
3108 }
3109 
SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt)3110 void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
3111   if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
3112     SetPreferredDisplayLanguage(lt);
3113 }
3114 
CanProvideValue()3115 bool ValueObject::CanProvideValue() {
3116   // we need to support invalid types as providers of values because some bare-
3117   // board debugging scenarios have no notion of types, but still manage to
3118   // have raw numeric values for things like registers. sigh.
3119   CompilerType type = GetCompilerType();
3120   return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
3121 }
3122 
3123 
3124 
Persist()3125 ValueObjectSP ValueObject::Persist() {
3126   if (!UpdateValueIfNeeded())
3127     return nullptr;
3128 
3129   TargetSP target_sp(GetTargetSP());
3130   if (!target_sp)
3131     return nullptr;
3132 
3133   PersistentExpressionState *persistent_state =
3134       target_sp->GetPersistentExpressionStateForLanguage(
3135           GetPreferredDisplayLanguage());
3136 
3137   if (!persistent_state)
3138     return nullptr;
3139 
3140   ConstString name = persistent_state->GetNextPersistentVariableName();
3141 
3142   ValueObjectSP const_result_sp =
3143       ValueObjectConstResult::Create(target_sp.get(), GetValue(), name);
3144 
3145   ExpressionVariableSP persistent_var_sp =
3146       persistent_state->CreatePersistentVariable(const_result_sp);
3147   persistent_var_sp->m_live_sp = persistent_var_sp->m_frozen_sp;
3148   persistent_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference;
3149 
3150   return persistent_var_sp->GetValueObject();
3151 }
3152