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