• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-python.h"
11 
12 #include "lldb/Core/ValueObject.h"
13 
14 // C Includes
15 #include <stdlib.h>
16 
17 // C++ Includes
18 // Other libraries and framework includes
19 #include "llvm/Support/raw_ostream.h"
20 #include "clang/AST/Type.h"
21 
22 // Project includes
23 #include "lldb/Core/DataBufferHeap.h"
24 #include "lldb/Core/Debugger.h"
25 #include "lldb/Core/Log.h"
26 #include "lldb/Core/Module.h"
27 #include "lldb/Core/StreamString.h"
28 #include "lldb/Core/ValueObjectCast.h"
29 #include "lldb/Core/ValueObjectChild.h"
30 #include "lldb/Core/ValueObjectConstResult.h"
31 #include "lldb/Core/ValueObjectDynamicValue.h"
32 #include "lldb/Core/ValueObjectList.h"
33 #include "lldb/Core/ValueObjectMemory.h"
34 #include "lldb/Core/ValueObjectSyntheticFilter.h"
35 
36 #include "lldb/DataFormatters/DataVisualization.h"
37 
38 #include "lldb/Host/Endian.h"
39 
40 #include "lldb/Interpreter/CommandInterpreter.h"
41 #include "lldb/Interpreter/ScriptInterpreterPython.h"
42 
43 #include "lldb/Symbol/ClangASTType.h"
44 #include "lldb/Symbol/ClangASTContext.h"
45 #include "lldb/Symbol/Type.h"
46 
47 #include "lldb/Target/ExecutionContext.h"
48 #include "lldb/Target/LanguageRuntime.h"
49 #include "lldb/Target/ObjCLanguageRuntime.h"
50 #include "lldb/Target/Process.h"
51 #include "lldb/Target/RegisterContext.h"
52 #include "lldb/Target/Target.h"
53 #include "lldb/Target/Thread.h"
54 
55 using namespace lldb;
56 using namespace lldb_private;
57 using namespace lldb_utility;
58 
59 static user_id_t g_value_obj_uid = 0;
60 
61 //----------------------------------------------------------------------
62 // ValueObject constructor
63 //----------------------------------------------------------------------
ValueObject(ValueObject & parent)64 ValueObject::ValueObject (ValueObject &parent) :
65     UserID (++g_value_obj_uid), // Unique identifier for every value object
66     m_parent (&parent),
67     m_root (NULL),
68     m_update_point (parent.GetUpdatePoint ()),
69     m_name (),
70     m_data (),
71     m_value (),
72     m_error (),
73     m_value_str (),
74     m_old_value_str (),
75     m_location_str (),
76     m_summary_str (),
77     m_object_desc_str (),
78     m_manager(parent.GetManager()),
79     m_children (),
80     m_synthetic_children (),
81     m_dynamic_value (NULL),
82     m_synthetic_value(NULL),
83     m_deref_valobj(NULL),
84     m_format (eFormatDefault),
85     m_last_format (eFormatDefault),
86     m_last_format_mgr_revision(0),
87     m_type_summary_sp(),
88     m_type_format_sp(),
89     m_synthetic_children_sp(),
90     m_user_id_of_forced_summary(),
91     m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid),
92     m_value_is_valid (false),
93     m_value_did_change (false),
94     m_children_count_valid (false),
95     m_old_value_valid (false),
96     m_is_deref_of_parent (false),
97     m_is_array_item_for_pointer(false),
98     m_is_bitfield_for_scalar(false),
99     m_is_child_at_offset(false),
100     m_is_getting_summary(false),
101     m_did_calculate_complete_objc_class_type(false)
102 {
103     m_manager->ManageObject(this);
104 }
105 
106 //----------------------------------------------------------------------
107 // ValueObject constructor
108 //----------------------------------------------------------------------
ValueObject(ExecutionContextScope * exe_scope,AddressType child_ptr_or_ref_addr_type)109 ValueObject::ValueObject (ExecutionContextScope *exe_scope,
110                           AddressType child_ptr_or_ref_addr_type) :
111     UserID (++g_value_obj_uid), // Unique identifier for every value object
112     m_parent (NULL),
113     m_root (NULL),
114     m_update_point (exe_scope),
115     m_name (),
116     m_data (),
117     m_value (),
118     m_error (),
119     m_value_str (),
120     m_old_value_str (),
121     m_location_str (),
122     m_summary_str (),
123     m_object_desc_str (),
124     m_manager(),
125     m_children (),
126     m_synthetic_children (),
127     m_dynamic_value (NULL),
128     m_synthetic_value(NULL),
129     m_deref_valobj(NULL),
130     m_format (eFormatDefault),
131     m_last_format (eFormatDefault),
132     m_last_format_mgr_revision(0),
133     m_type_summary_sp(),
134     m_type_format_sp(),
135     m_synthetic_children_sp(),
136     m_user_id_of_forced_summary(),
137     m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type),
138     m_value_is_valid (false),
139     m_value_did_change (false),
140     m_children_count_valid (false),
141     m_old_value_valid (false),
142     m_is_deref_of_parent (false),
143     m_is_array_item_for_pointer(false),
144     m_is_bitfield_for_scalar(false),
145     m_is_child_at_offset(false),
146     m_is_getting_summary(false),
147     m_did_calculate_complete_objc_class_type(false)
148 {
149     m_manager = new ValueObjectManager();
150     m_manager->ManageObject (this);
151 }
152 
153 //----------------------------------------------------------------------
154 // Destructor
155 //----------------------------------------------------------------------
~ValueObject()156 ValueObject::~ValueObject ()
157 {
158 }
159 
160 bool
UpdateValueIfNeeded(bool update_format)161 ValueObject::UpdateValueIfNeeded (bool update_format)
162 {
163 
164     bool did_change_formats = false;
165 
166     if (update_format)
167         did_change_formats = UpdateFormatsIfNeeded();
168 
169     // If this is a constant value, then our success is predicated on whether
170     // we have an error or not
171     if (GetIsConstant())
172     {
173         // if you were asked to update your formatters, but did not get a chance to do it
174         // clear your own values (this serves the purpose of faking a stop-id for frozen
175         // objects (which are regarded as constant, but could have changes behind their backs
176         // because of the frozen-pointer depth limit)
177 		// TODO: decouple summary from value and then remove this code and only force-clear the summary
178         if (update_format && !did_change_formats)
179             ClearUserVisibleData(eClearUserVisibleDataItemsSummary);
180         return m_error.Success();
181     }
182 
183     bool first_update = m_update_point.IsFirstEvaluation();
184 
185     if (m_update_point.NeedsUpdating())
186     {
187         m_update_point.SetUpdated();
188 
189         // Save the old value using swap to avoid a string copy which
190         // also will clear our m_value_str
191         if (m_value_str.empty())
192         {
193             m_old_value_valid = false;
194         }
195         else
196         {
197             m_old_value_valid = true;
198             m_old_value_str.swap (m_value_str);
199             ClearUserVisibleData(eClearUserVisibleDataItemsValue);
200         }
201 
202         ClearUserVisibleData();
203 
204         if (IsInScope())
205         {
206             const bool value_was_valid = GetValueIsValid();
207             SetValueDidChange (false);
208 
209             m_error.Clear();
210 
211             // Call the pure virtual function to update the value
212             bool success = UpdateValue ();
213 
214             SetValueIsValid (success);
215 
216             if (first_update)
217                 SetValueDidChange (false);
218             else if (!m_value_did_change && success == false)
219             {
220                 // The value wasn't gotten successfully, so we mark this
221                 // as changed if the value used to be valid and now isn't
222                 SetValueDidChange (value_was_valid);
223             }
224         }
225         else
226         {
227             m_error.SetErrorString("out of scope");
228         }
229     }
230     return m_error.Success();
231 }
232 
233 bool
UpdateFormatsIfNeeded()234 ValueObject::UpdateFormatsIfNeeded()
235 {
236     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
237     if (log)
238         log->Printf("[%s %p] checking for FormatManager revisions. ValueObject rev: %d - Global rev: %d",
239            GetName().GetCString(),
240            this,
241            m_last_format_mgr_revision,
242            DataVisualization::GetCurrentRevision());
243 
244     bool any_change = false;
245 
246     if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()))
247     {
248         SetValueFormat(DataVisualization::ValueFormats::GetFormat (*this, eNoDynamicValues));
249         SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, GetDynamicValueType()));
250 #ifndef LLDB_DISABLE_PYTHON
251         SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, GetDynamicValueType()));
252 #endif
253 
254         m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
255 
256         any_change = true;
257     }
258 
259     return any_change;
260 
261 }
262 
263 void
SetNeedsUpdate()264 ValueObject::SetNeedsUpdate ()
265 {
266     m_update_point.SetNeedsUpdate();
267     // We have to clear the value string here so ConstResult children will notice if their values are
268     // changed by hand (i.e. with SetValueAsCString).
269     ClearUserVisibleData(eClearUserVisibleDataItemsValue);
270 }
271 
272 void
ClearDynamicTypeInformation()273 ValueObject::ClearDynamicTypeInformation ()
274 {
275     m_did_calculate_complete_objc_class_type = false;
276     m_last_format_mgr_revision = 0;
277     m_override_type = ClangASTType();
278     SetValueFormat(lldb::TypeFormatImplSP());
279     SetSummaryFormat(lldb::TypeSummaryImplSP());
280     SetSyntheticChildren(lldb::SyntheticChildrenSP());
281 }
282 
283 ClangASTType
MaybeCalculateCompleteType()284 ValueObject::MaybeCalculateCompleteType ()
285 {
286     ClangASTType clang_type(GetClangTypeImpl());
287 
288     if (m_did_calculate_complete_objc_class_type)
289     {
290         if (m_override_type.IsValid())
291             return m_override_type;
292         else
293             return clang_type;
294     }
295 
296     ClangASTType class_type;
297     bool is_pointer_type = false;
298 
299     if (clang_type.IsObjCObjectPointerType(&class_type))
300     {
301         is_pointer_type = true;
302     }
303     else if (clang_type.IsObjCObjectOrInterfaceType())
304     {
305         class_type = clang_type;
306     }
307     else
308     {
309         return clang_type;
310     }
311 
312     m_did_calculate_complete_objc_class_type = true;
313 
314     if (class_type)
315     {
316         ConstString class_name (class_type.GetConstTypeName());
317 
318         if (class_name)
319         {
320             ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
321 
322             if (process_sp)
323             {
324                 ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime());
325 
326                 if (objc_language_runtime)
327                 {
328                     TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name);
329 
330                     if (complete_objc_class_type_sp)
331                     {
332                         ClangASTType complete_class(complete_objc_class_type_sp->GetClangFullType());
333 
334                         if (complete_class.GetCompleteType())
335                         {
336                             if (is_pointer_type)
337                             {
338                                 m_override_type = complete_class.GetPointerType();
339                             }
340                             else
341                             {
342                                 m_override_type = complete_class;
343                             }
344 
345                             if (m_override_type.IsValid())
346                                 return m_override_type;
347                         }
348                     }
349                 }
350             }
351         }
352     }
353     return clang_type;
354 }
355 
356 ClangASTType
GetClangType()357 ValueObject::GetClangType ()
358 {
359     return MaybeCalculateCompleteType();
360 }
361 
362 DataExtractor &
GetDataExtractor()363 ValueObject::GetDataExtractor ()
364 {
365     UpdateValueIfNeeded(false);
366     return m_data;
367 }
368 
369 const Error &
GetError()370 ValueObject::GetError()
371 {
372     UpdateValueIfNeeded(false);
373     return m_error;
374 }
375 
376 const ConstString &
GetName() const377 ValueObject::GetName() const
378 {
379     return m_name;
380 }
381 
382 const char *
GetLocationAsCString()383 ValueObject::GetLocationAsCString ()
384 {
385     return GetLocationAsCStringImpl(m_value,
386                                     m_data);
387 }
388 
389 const char *
GetLocationAsCStringImpl(const Value & value,const DataExtractor & data)390 ValueObject::GetLocationAsCStringImpl (const Value& value,
391                                        const DataExtractor& data)
392 {
393     if (UpdateValueIfNeeded(false))
394     {
395         if (m_location_str.empty())
396         {
397             StreamString sstr;
398 
399             Value::ValueType value_type = value.GetValueType();
400 
401             switch (value_type)
402             {
403             case Value::eValueTypeScalar:
404             case Value::eValueTypeVector:
405                 if (value.GetContextType() == Value::eContextTypeRegisterInfo)
406                 {
407                     RegisterInfo *reg_info = value.GetRegisterInfo();
408                     if (reg_info)
409                     {
410                         if (reg_info->name)
411                             m_location_str = reg_info->name;
412                         else if (reg_info->alt_name)
413                             m_location_str = reg_info->alt_name;
414                         if (m_location_str.empty())
415                             m_location_str = (reg_info->encoding == lldb::eEncodingVector) ? "vector" : "scalar";
416                     }
417                 }
418                 if (m_location_str.empty())
419                     m_location_str = (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
420                 break;
421 
422             case Value::eValueTypeLoadAddress:
423             case Value::eValueTypeFileAddress:
424             case Value::eValueTypeHostAddress:
425                 {
426                     uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
427                     sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
428                     m_location_str.swap(sstr.GetString());
429                 }
430                 break;
431             }
432         }
433     }
434     return m_location_str.c_str();
435 }
436 
437 Value &
GetValue()438 ValueObject::GetValue()
439 {
440     return m_value;
441 }
442 
443 const Value &
GetValue() const444 ValueObject::GetValue() const
445 {
446     return m_value;
447 }
448 
449 bool
ResolveValue(Scalar & scalar)450 ValueObject::ResolveValue (Scalar &scalar)
451 {
452     if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
453     {
454         ExecutionContext exe_ctx (GetExecutionContextRef());
455         Value tmp_value(m_value);
456         scalar = tmp_value.ResolveValue(&exe_ctx);
457         if (scalar.IsValid())
458         {
459             const uint32_t bitfield_bit_size = GetBitfieldBitSize();
460             if (bitfield_bit_size)
461                 return scalar.ExtractBitfield (bitfield_bit_size, GetBitfieldBitOffset());
462             return true;
463         }
464     }
465     return false;
466 }
467 
468 bool
GetValueIsValid() const469 ValueObject::GetValueIsValid () const
470 {
471     return m_value_is_valid;
472 }
473 
474 
475 void
SetValueIsValid(bool b)476 ValueObject::SetValueIsValid (bool b)
477 {
478     m_value_is_valid = b;
479 }
480 
481 bool
GetValueDidChange()482 ValueObject::GetValueDidChange ()
483 {
484     GetValueAsCString ();
485     return m_value_did_change;
486 }
487 
488 void
SetValueDidChange(bool value_changed)489 ValueObject::SetValueDidChange (bool value_changed)
490 {
491     m_value_did_change = value_changed;
492 }
493 
494 ValueObjectSP
GetChildAtIndex(size_t idx,bool can_create)495 ValueObject::GetChildAtIndex (size_t idx, bool can_create)
496 {
497     ValueObjectSP child_sp;
498     // We may need to update our value if we are dynamic
499     if (IsPossibleDynamicType ())
500         UpdateValueIfNeeded(false);
501     if (idx < GetNumChildren())
502     {
503         // Check if we have already made the child value object?
504         if (can_create && !m_children.HasChildAtIndex(idx))
505         {
506             // No we haven't created the child at this index, so lets have our
507             // subclass do it and cache the result for quick future access.
508             m_children.SetChildAtIndex(idx,CreateChildAtIndex (idx, false, 0));
509         }
510 
511         ValueObject* child = m_children.GetChildAtIndex(idx);
512         if (child != NULL)
513             return child->GetSP();
514     }
515     return child_sp;
516 }
517 
518 ValueObjectSP
GetChildAtIndexPath(const std::initializer_list<size_t> & idxs,size_t * index_of_error)519 ValueObject::GetChildAtIndexPath (const std::initializer_list<size_t>& idxs,
520                                   size_t* index_of_error)
521 {
522     if (idxs.size() == 0)
523         return GetSP();
524     ValueObjectSP root(GetSP());
525     for (size_t idx : idxs)
526     {
527         root = root->GetChildAtIndex(idx, true);
528         if (!root)
529         {
530             if (index_of_error)
531                 *index_of_error = idx;
532             return root;
533         }
534     }
535     return root;
536 }
537 
538 ValueObjectSP
GetChildAtIndexPath(const std::initializer_list<std::pair<size_t,bool>> & idxs,size_t * index_of_error)539 ValueObject::GetChildAtIndexPath (const std::initializer_list< std::pair<size_t, bool> >& idxs,
540                                   size_t* index_of_error)
541 {
542     if (idxs.size() == 0)
543         return GetSP();
544     ValueObjectSP root(GetSP());
545     for (std::pair<size_t, bool> idx : idxs)
546     {
547         root = root->GetChildAtIndex(idx.first, idx.second);
548         if (!root)
549         {
550             if (index_of_error)
551                 *index_of_error = idx.first;
552             return root;
553         }
554     }
555     return root;
556 }
557 
558 lldb::ValueObjectSP
GetChildAtIndexPath(const std::vector<size_t> & idxs,size_t * index_of_error)559 ValueObject::GetChildAtIndexPath (const std::vector<size_t> &idxs,
560                                   size_t* index_of_error)
561 {
562     if (idxs.size() == 0)
563         return GetSP();
564     ValueObjectSP root(GetSP());
565     for (size_t idx : idxs)
566     {
567         root = root->GetChildAtIndex(idx, true);
568         if (!root)
569         {
570             if (index_of_error)
571                 *index_of_error = idx;
572             return root;
573         }
574     }
575     return root;
576 }
577 
578 lldb::ValueObjectSP
GetChildAtIndexPath(const std::vector<std::pair<size_t,bool>> & idxs,size_t * index_of_error)579 ValueObject::GetChildAtIndexPath (const std::vector< std::pair<size_t, bool> > &idxs,
580                                   size_t* index_of_error)
581 {
582     if (idxs.size() == 0)
583         return GetSP();
584     ValueObjectSP root(GetSP());
585     for (std::pair<size_t, bool> idx : idxs)
586     {
587         root = root->GetChildAtIndex(idx.first, idx.second);
588         if (!root)
589         {
590             if (index_of_error)
591                 *index_of_error = idx.first;
592             return root;
593         }
594     }
595     return root;
596 }
597 
598 size_t
GetIndexOfChildWithName(const ConstString & name)599 ValueObject::GetIndexOfChildWithName (const ConstString &name)
600 {
601     bool omit_empty_base_classes = true;
602     return GetClangType().GetIndexOfChildWithName (name.GetCString(), omit_empty_base_classes);
603 }
604 
605 ValueObjectSP
GetChildMemberWithName(const ConstString & name,bool can_create)606 ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
607 {
608     // when getting a child by name, it could be buried inside some base
609     // classes (which really aren't part of the expression path), so we
610     // need a vector of indexes that can get us down to the correct child
611     ValueObjectSP child_sp;
612 
613     // We may need to update our value if we are dynamic
614     if (IsPossibleDynamicType ())
615         UpdateValueIfNeeded(false);
616 
617     std::vector<uint32_t> child_indexes;
618     bool omit_empty_base_classes = true;
619     const size_t num_child_indexes =  GetClangType().GetIndexOfChildMemberWithName (name.GetCString(),
620                                                                                     omit_empty_base_classes,
621                                                                                     child_indexes);
622     if (num_child_indexes > 0)
623     {
624         std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
625         std::vector<uint32_t>::const_iterator end = child_indexes.end ();
626 
627         child_sp = GetChildAtIndex(*pos, can_create);
628         for (++pos; pos != end; ++pos)
629         {
630             if (child_sp)
631             {
632                 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
633                 child_sp = new_child_sp;
634             }
635             else
636             {
637                 child_sp.reset();
638             }
639 
640         }
641     }
642     return child_sp;
643 }
644 
645 
646 size_t
GetNumChildren()647 ValueObject::GetNumChildren ()
648 {
649     UpdateValueIfNeeded();
650     if (!m_children_count_valid)
651     {
652         SetNumChildren (CalculateNumChildren());
653     }
654     return m_children.GetChildrenCount();
655 }
656 
657 bool
MightHaveChildren()658 ValueObject::MightHaveChildren()
659 {
660     bool has_children = false;
661     const uint32_t type_info = GetTypeInfo();
662     if (type_info)
663     {
664         if (type_info & (ClangASTType::eTypeHasChildren |
665                          ClangASTType::eTypeIsPointer |
666                          ClangASTType::eTypeIsReference))
667             has_children = true;
668     }
669     else
670     {
671         has_children = GetNumChildren () > 0;
672     }
673     return has_children;
674 }
675 
676 // Should only be called by ValueObject::GetNumChildren()
677 void
SetNumChildren(size_t num_children)678 ValueObject::SetNumChildren (size_t num_children)
679 {
680     m_children_count_valid = true;
681     m_children.SetChildrenCount(num_children);
682 }
683 
684 void
SetName(const ConstString & name)685 ValueObject::SetName (const ConstString &name)
686 {
687     m_name = name;
688 }
689 
690 ValueObject *
CreateChildAtIndex(size_t idx,bool synthetic_array_member,int32_t synthetic_index)691 ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
692 {
693     ValueObject *valobj = NULL;
694 
695     bool omit_empty_base_classes = true;
696     bool ignore_array_bounds = synthetic_array_member;
697     std::string child_name_str;
698     uint32_t child_byte_size = 0;
699     int32_t child_byte_offset = 0;
700     uint32_t child_bitfield_bit_size = 0;
701     uint32_t child_bitfield_bit_offset = 0;
702     bool child_is_base_class = false;
703     bool child_is_deref_of_parent = false;
704 
705     const bool transparent_pointers = synthetic_array_member == false;
706     ClangASTType child_clang_type;
707 
708     ExecutionContext exe_ctx (GetExecutionContextRef());
709 
710     child_clang_type = GetClangType().GetChildClangTypeAtIndex (&exe_ctx,
711                                                                 GetName().GetCString(),
712                                                                 idx,
713                                                                 transparent_pointers,
714                                                                 omit_empty_base_classes,
715                                                                 ignore_array_bounds,
716                                                                 child_name_str,
717                                                                 child_byte_size,
718                                                                 child_byte_offset,
719                                                                 child_bitfield_bit_size,
720                                                                 child_bitfield_bit_offset,
721                                                                 child_is_base_class,
722                                                                 child_is_deref_of_parent);
723     if (child_clang_type)
724     {
725         if (synthetic_index)
726             child_byte_offset += child_byte_size * synthetic_index;
727 
728         ConstString child_name;
729         if (!child_name_str.empty())
730             child_name.SetCString (child_name_str.c_str());
731 
732         valobj = new ValueObjectChild (*this,
733                                        child_clang_type,
734                                        child_name,
735                                        child_byte_size,
736                                        child_byte_offset,
737                                        child_bitfield_bit_size,
738                                        child_bitfield_bit_offset,
739                                        child_is_base_class,
740                                        child_is_deref_of_parent,
741                                        eAddressTypeInvalid);
742         //if (valobj)
743         //    valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
744    }
745 
746     return valobj;
747 }
748 
749 bool
GetSummaryAsCString(TypeSummaryImpl * summary_ptr,std::string & destination)750 ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
751                                   std::string& destination)
752 {
753     destination.clear();
754 
755     // ideally we would like to bail out if passing NULL, but if we do so
756     // we end up not providing the summary for function pointers anymore
757     if (/*summary_ptr == NULL ||*/ m_is_getting_summary)
758         return false;
759 
760     m_is_getting_summary = true;
761 
762     // this is a hot path in code and we prefer to avoid setting this string all too often also clearing out other
763     // information that we might care to see in a crash log. might be useful in very specific situations though.
764     /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s. Summary provider's description is %s",
765                                         GetTypeName().GetCString(),
766                                         GetName().GetCString(),
767                                         summary_ptr->GetDescription().c_str());*/
768 
769     if (UpdateValueIfNeeded (false))
770     {
771         if (summary_ptr)
772         {
773             if (HasSyntheticValue())
774                 m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#})
775             summary_ptr->FormatObject(this, destination);
776         }
777         else
778         {
779             ClangASTType clang_type = GetClangType();
780 
781             // Do some default printout for function pointers
782             if (clang_type)
783             {
784                 if (clang_type.IsFunctionPointerType ())
785                 {
786                     StreamString sstr;
787                     AddressType func_ptr_address_type = eAddressTypeInvalid;
788                     addr_t func_ptr_address = GetPointerValue (&func_ptr_address_type);
789                     if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
790                     {
791                         switch (func_ptr_address_type)
792                         {
793                             case eAddressTypeInvalid:
794                             case eAddressTypeFile:
795                                 break;
796 
797                             case eAddressTypeLoad:
798                             {
799                                 ExecutionContext exe_ctx (GetExecutionContextRef());
800 
801                                 Address so_addr;
802                                 Target *target = exe_ctx.GetTargetPtr();
803                                 if (target && target->GetSectionLoadList().IsEmpty() == false)
804                                 {
805                                     if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
806                                     {
807                                         so_addr.Dump (&sstr,
808                                                       exe_ctx.GetBestExecutionContextScope(),
809                                                       Address::DumpStyleResolvedDescription,
810                                                       Address::DumpStyleSectionNameOffset);
811                                     }
812                                 }
813                             }
814                                 break;
815 
816                             case eAddressTypeHost:
817                                 break;
818                         }
819                     }
820                     if (sstr.GetSize() > 0)
821                     {
822                         destination.assign (1, '(');
823                         destination.append (sstr.GetData(), sstr.GetSize());
824                         destination.append (1, ')');
825                     }
826                 }
827             }
828         }
829     }
830     m_is_getting_summary = false;
831     return !destination.empty();
832 }
833 
834 const char *
GetSummaryAsCString()835 ValueObject::GetSummaryAsCString ()
836 {
837     if (UpdateValueIfNeeded(true) && m_summary_str.empty())
838     {
839         GetSummaryAsCString(GetSummaryFormat().get(),
840                             m_summary_str);
841     }
842     if (m_summary_str.empty())
843         return NULL;
844     return m_summary_str.c_str();
845 }
846 
847 bool
IsCStringContainer(bool check_pointer)848 ValueObject::IsCStringContainer(bool check_pointer)
849 {
850     ClangASTType pointee_or_element_clang_type;
851     const Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type));
852     bool is_char_arr_ptr (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) &&
853                           pointee_or_element_clang_type.IsCharType ());
854     if (!is_char_arr_ptr)
855         return false;
856     if (!check_pointer)
857         return true;
858     if (type_flags.Test(ClangASTType::eTypeIsArray))
859         return true;
860     addr_t cstr_address = LLDB_INVALID_ADDRESS;
861     AddressType cstr_address_type = eAddressTypeInvalid;
862     cstr_address = GetAddressOf (true, &cstr_address_type);
863     return (cstr_address != LLDB_INVALID_ADDRESS);
864 }
865 
866 size_t
GetPointeeData(DataExtractor & data,uint32_t item_idx,uint32_t item_count)867 ValueObject::GetPointeeData (DataExtractor& data,
868                              uint32_t item_idx,
869                              uint32_t item_count)
870 {
871     ClangASTType pointee_or_element_clang_type;
872     const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type);
873     const bool is_pointer_type = type_info & ClangASTType::eTypeIsPointer;
874     const bool is_array_type = type_info & ClangASTType::eTypeIsArray;
875     if (!(is_pointer_type || is_array_type))
876         return 0;
877 
878     if (item_count == 0)
879         return 0;
880 
881     const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize();
882     const uint64_t bytes = item_count * item_type_size;
883     const uint64_t offset = item_idx * item_type_size;
884 
885     if (item_idx == 0 && item_count == 1) // simply a deref
886     {
887         if (is_pointer_type)
888         {
889             Error error;
890             ValueObjectSP pointee_sp = Dereference(error);
891             if (error.Fail() || pointee_sp.get() == NULL)
892                 return 0;
893             return pointee_sp->GetDataExtractor().Copy(data);
894         }
895         else
896         {
897             ValueObjectSP child_sp = GetChildAtIndex(0, true);
898             if (child_sp.get() == NULL)
899                 return 0;
900             return child_sp->GetDataExtractor().Copy(data);
901         }
902         return true;
903     }
904     else /* (items > 1) */
905     {
906         Error error;
907         lldb_private::DataBufferHeap* heap_buf_ptr = NULL;
908         lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap());
909 
910         AddressType addr_type;
911         lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
912 
913         switch (addr_type)
914         {
915             case eAddressTypeFile:
916                 {
917                     ModuleSP module_sp (GetModule());
918                     if (module_sp)
919                     {
920                         addr = addr + offset;
921                         Address so_addr;
922                         module_sp->ResolveFileAddress(addr, so_addr);
923                         ExecutionContext exe_ctx (GetExecutionContextRef());
924                         Target* target = exe_ctx.GetTargetPtr();
925                         if (target)
926                         {
927                             heap_buf_ptr->SetByteSize(bytes);
928                             size_t bytes_read = target->ReadMemory(so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
929                             if (error.Success())
930                             {
931                                 data.SetData(data_sp);
932                                 return bytes_read;
933                             }
934                         }
935                     }
936                 }
937                 break;
938             case eAddressTypeLoad:
939                 {
940                     ExecutionContext exe_ctx (GetExecutionContextRef());
941                     Process *process = exe_ctx.GetProcessPtr();
942                     if (process)
943                     {
944                         heap_buf_ptr->SetByteSize(bytes);
945                         size_t bytes_read = process->ReadMemory(addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
946                         if (error.Success())
947                         {
948                             data.SetData(data_sp);
949                             return bytes_read;
950                         }
951                     }
952                 }
953                 break;
954             case eAddressTypeHost:
955                 {
956                     const uint64_t max_bytes = GetClangType().GetByteSize();
957                     if (max_bytes > offset)
958                     {
959                         size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes);
960                         heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read);
961                         data.SetData(data_sp);
962                         return bytes_read;
963                     }
964                 }
965                 break;
966             case eAddressTypeInvalid:
967                 break;
968         }
969     }
970     return 0;
971 }
972 
973 uint64_t
GetData(DataExtractor & data)974 ValueObject::GetData (DataExtractor& data)
975 {
976     UpdateValueIfNeeded(false);
977     ExecutionContext exe_ctx (GetExecutionContextRef());
978     Error error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
979     if (error.Fail())
980     {
981         if (m_data.GetByteSize())
982         {
983             data = m_data;
984             return data.GetByteSize();
985         }
986         else
987         {
988             return 0;
989         }
990     }
991     data.SetAddressByteSize(m_data.GetAddressByteSize());
992     data.SetByteOrder(m_data.GetByteOrder());
993     return data.GetByteSize();
994 }
995 
996 bool
SetData(DataExtractor & data,Error & error)997 ValueObject::SetData (DataExtractor &data, Error &error)
998 {
999     error.Clear();
1000     // Make sure our value is up to date first so that our location and location
1001     // type is valid.
1002     if (!UpdateValueIfNeeded(false))
1003     {
1004         error.SetErrorString("unable to read value");
1005         return false;
1006     }
1007 
1008     uint64_t count = 0;
1009     const Encoding encoding = GetClangType().GetEncoding(count);
1010 
1011     const size_t byte_size = GetByteSize();
1012 
1013     Value::ValueType value_type = m_value.GetValueType();
1014 
1015     switch (value_type)
1016     {
1017     case Value::eValueTypeScalar:
1018         {
1019             Error set_error = m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
1020 
1021             if (!set_error.Success())
1022             {
1023                 error.SetErrorStringWithFormat("unable to set scalar value: %s", set_error.AsCString());
1024                 return false;
1025             }
1026         }
1027         break;
1028     case Value::eValueTypeLoadAddress:
1029         {
1030             // If it is a load address, then the scalar value is the storage location
1031             // of the data, and we have to shove this value down to that load location.
1032             ExecutionContext exe_ctx (GetExecutionContextRef());
1033             Process *process = exe_ctx.GetProcessPtr();
1034             if (process)
1035             {
1036                 addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1037                 size_t bytes_written = process->WriteMemory(target_addr,
1038                                                             data.GetDataStart(),
1039                                                             byte_size,
1040                                                             error);
1041                 if (!error.Success())
1042                     return false;
1043                 if (bytes_written != byte_size)
1044                 {
1045                     error.SetErrorString("unable to write value to memory");
1046                     return false;
1047                 }
1048             }
1049         }
1050         break;
1051     case Value::eValueTypeHostAddress:
1052         {
1053             // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
1054             DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
1055             m_data.SetData(buffer_sp, 0);
1056             data.CopyByteOrderedData (0,
1057                                       byte_size,
1058                                       const_cast<uint8_t *>(m_data.GetDataStart()),
1059                                       byte_size,
1060                                       m_data.GetByteOrder());
1061             m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1062         }
1063         break;
1064     case Value::eValueTypeFileAddress:
1065     case Value::eValueTypeVector:
1066         break;
1067     }
1068 
1069     // If we have reached this point, then we have successfully changed the value.
1070     SetNeedsUpdate();
1071     return true;
1072 }
1073 
1074 // will compute strlen(str), but without consuming more than
1075 // maxlen bytes out of str (this serves the purpose of reading
1076 // chunks of a string without having to worry about
1077 // missing NULL terminators in the chunk)
1078 // of course, if strlen(str) > maxlen, the function will return
1079 // maxlen_value (which should be != maxlen, because that allows you
1080 // to know whether strlen(str) == maxlen or strlen(str) > maxlen)
1081 static uint32_t
strlen_or_inf(const char * str,uint32_t maxlen,uint32_t maxlen_value)1082 strlen_or_inf (const char* str,
1083                uint32_t maxlen,
1084                uint32_t maxlen_value)
1085 {
1086     uint32_t len = 0;
1087     if (str)
1088     {
1089         while(*str)
1090         {
1091             len++;str++;
1092             if (len >= maxlen)
1093                 return maxlen_value;
1094         }
1095     }
1096     return len;
1097 }
1098 
1099 size_t
ReadPointedString(Stream & s,Error & error,uint32_t max_length,bool honor_array,Format item_format)1100 ValueObject::ReadPointedString (Stream& s,
1101                                 Error& error,
1102                                 uint32_t max_length,
1103                                 bool honor_array,
1104                                 Format item_format)
1105 {
1106     ExecutionContext exe_ctx (GetExecutionContextRef());
1107     Target* target = exe_ctx.GetTargetPtr();
1108 
1109     if (!target)
1110     {
1111         s << "<no target to read from>";
1112         error.SetErrorString("no target to read from");
1113         return 0;
1114     }
1115 
1116     if (max_length == 0)
1117         max_length = target->GetMaximumSizeOfStringSummary();
1118 
1119     size_t bytes_read = 0;
1120     size_t total_bytes_read = 0;
1121 
1122     ClangASTType clang_type = GetClangType();
1123     ClangASTType elem_or_pointee_clang_type;
1124     const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type));
1125     if (type_flags.AnySet (ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer) &&
1126         elem_or_pointee_clang_type.IsCharType ())
1127     {
1128         addr_t cstr_address = LLDB_INVALID_ADDRESS;
1129         AddressType cstr_address_type = eAddressTypeInvalid;
1130 
1131         size_t cstr_len = 0;
1132         bool capped_data = false;
1133         if (type_flags.Test (ClangASTType::eTypeIsArray))
1134         {
1135             // We have an array
1136             uint64_t array_size = 0;
1137             if (clang_type.IsArrayType(NULL, &array_size, NULL))
1138             {
1139                 cstr_len = array_size;
1140                 if (cstr_len > max_length)
1141                 {
1142                     capped_data = true;
1143                     cstr_len = max_length;
1144                 }
1145             }
1146             cstr_address = GetAddressOf (true, &cstr_address_type);
1147         }
1148         else
1149         {
1150             // We have a pointer
1151             cstr_address = GetPointerValue (&cstr_address_type);
1152         }
1153 
1154         if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS)
1155         {
1156             s << "<invalid address>";
1157             error.SetErrorString("invalid address");
1158             return 0;
1159         }
1160 
1161         Address cstr_so_addr (cstr_address);
1162         DataExtractor data;
1163         if (cstr_len > 0 && honor_array)
1164         {
1165             // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
1166             // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
1167             GetPointeeData(data, 0, cstr_len);
1168 
1169             if ((bytes_read = data.GetByteSize()) > 0)
1170             {
1171                 total_bytes_read = bytes_read;
1172                 s << '"';
1173                 data.Dump (&s,
1174                            0,                 // Start offset in "data"
1175                            item_format,
1176                            1,                 // Size of item (1 byte for a char!)
1177                            bytes_read,        // How many bytes to print?
1178                            UINT32_MAX,        // num per line
1179                            LLDB_INVALID_ADDRESS,// base address
1180                            0,                 // bitfield bit size
1181                            0);                // bitfield bit offset
1182                 if (capped_data)
1183                     s << "...";
1184                 s << '"';
1185             }
1186         }
1187         else
1188         {
1189             cstr_len = max_length;
1190             const size_t k_max_buf_size = 64;
1191 
1192             size_t offset = 0;
1193 
1194             int cstr_len_displayed = -1;
1195             bool capped_cstr = false;
1196             // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
1197             // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
1198             while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0)
1199             {
1200                 total_bytes_read += bytes_read;
1201                 const char *cstr = data.PeekCStr(0);
1202                 size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1);
1203                 if (len > k_max_buf_size)
1204                     len = k_max_buf_size;
1205                 if (cstr && cstr_len_displayed < 0)
1206                     s << '"';
1207 
1208                 if (cstr_len_displayed < 0)
1209                     cstr_len_displayed = len;
1210 
1211                 if (len == 0)
1212                     break;
1213                 cstr_len_displayed += len;
1214                 if (len > bytes_read)
1215                     len = bytes_read;
1216                 if (len > cstr_len)
1217                     len = cstr_len;
1218 
1219                 data.Dump (&s,
1220                            0,                 // Start offset in "data"
1221                            item_format,
1222                            1,                 // Size of item (1 byte for a char!)
1223                            len,               // How many bytes to print?
1224                            UINT32_MAX,        // num per line
1225                            LLDB_INVALID_ADDRESS,// base address
1226                            0,                 // bitfield bit size
1227                            0);                // bitfield bit offset
1228 
1229                 if (len < k_max_buf_size)
1230                     break;
1231 
1232                 if (len >= cstr_len)
1233                 {
1234                     capped_cstr = true;
1235                     break;
1236                 }
1237 
1238                 cstr_len -= len;
1239                 offset += len;
1240             }
1241 
1242             if (cstr_len_displayed >= 0)
1243             {
1244                 s << '"';
1245                 if (capped_cstr)
1246                     s << "...";
1247             }
1248         }
1249     }
1250     else
1251     {
1252         error.SetErrorString("not a string object");
1253         s << "<not a string object>";
1254     }
1255     return total_bytes_read;
1256 }
1257 
1258 const char *
GetObjectDescription()1259 ValueObject::GetObjectDescription ()
1260 {
1261 
1262     if (!UpdateValueIfNeeded (true))
1263         return NULL;
1264 
1265     if (!m_object_desc_str.empty())
1266         return m_object_desc_str.c_str();
1267 
1268     ExecutionContext exe_ctx (GetExecutionContextRef());
1269     Process *process = exe_ctx.GetProcessPtr();
1270     if (process == NULL)
1271         return NULL;
1272 
1273     StreamString s;
1274 
1275     LanguageType language = GetObjectRuntimeLanguage();
1276     LanguageRuntime *runtime = process->GetLanguageRuntime(language);
1277 
1278     if (runtime == NULL)
1279     {
1280         // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
1281         ClangASTType clang_type = GetClangType();
1282         if (clang_type)
1283         {
1284             bool is_signed;
1285             if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType ())
1286             {
1287                 runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
1288             }
1289         }
1290     }
1291 
1292     if (runtime && runtime->GetObjectDescription(s, *this))
1293     {
1294         m_object_desc_str.append (s.GetData());
1295     }
1296 
1297     if (m_object_desc_str.empty())
1298         return NULL;
1299     else
1300         return m_object_desc_str.c_str();
1301 }
1302 
1303 bool
GetValueAsCString(lldb::Format format,std::string & destination)1304 ValueObject::GetValueAsCString (lldb::Format format,
1305                                 std::string& destination)
1306 {
1307     if (GetClangType().IsAggregateType () == false && UpdateValueIfNeeded(false))
1308     {
1309         const Value::ContextType context_type = m_value.GetContextType();
1310 
1311         if (context_type == Value::eContextTypeRegisterInfo)
1312         {
1313             const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1314             if (reg_info)
1315             {
1316                 ExecutionContext exe_ctx (GetExecutionContextRef());
1317 
1318                 StreamString reg_sstr;
1319                 m_data.Dump (&reg_sstr,
1320                              0,
1321                              format,
1322                              reg_info->byte_size,
1323                              1,
1324                              UINT32_MAX,
1325                              LLDB_INVALID_ADDRESS,
1326                              0,
1327                              0,
1328                              exe_ctx.GetBestExecutionContextScope());
1329                 destination.swap(reg_sstr.GetString());
1330             }
1331         }
1332         else
1333         {
1334             ClangASTType clang_type = GetClangType ();
1335             if (clang_type)
1336             {
1337                  // put custom bytes to display in this DataExtractor to override the default value logic
1338                 lldb_private::DataExtractor special_format_data;
1339                 if (format == eFormatCString)
1340                 {
1341                     Flags type_flags(clang_type.GetTypeInfo(NULL));
1342                     if (type_flags.Test(ClangASTType::eTypeIsPointer) && !type_flags.Test(ClangASTType::eTypeIsObjC))
1343                     {
1344                         // if we are dumping a pointer as a c-string, get the pointee data as a string
1345                         TargetSP target_sp(GetTargetSP());
1346                         if (target_sp)
1347                         {
1348                             size_t max_len = target_sp->GetMaximumSizeOfStringSummary();
1349                             Error error;
1350                             DataBufferSP buffer_sp(new DataBufferHeap(max_len+1,0));
1351                             Address address(GetPointerValue());
1352                             if (target_sp->ReadCStringFromMemory(address, (char*)buffer_sp->GetBytes(), max_len, error) && error.Success())
1353                                 special_format_data.SetData(buffer_sp);
1354                         }
1355                     }
1356                 }
1357 
1358                 StreamString sstr;
1359                 ExecutionContext exe_ctx (GetExecutionContextRef());
1360                 clang_type.DumpTypeValue (&sstr,                         // The stream to use for display
1361                                           format,                        // Format to display this type with
1362                                           special_format_data.GetByteSize() ?
1363                                           special_format_data: m_data,   // Data to extract from
1364                                           0,                             // Byte offset into "m_data"
1365                                           GetByteSize(),                 // Byte size of item in "m_data"
1366                                           GetBitfieldBitSize(),          // Bitfield bit size
1367                                           GetBitfieldBitOffset(),        // Bitfield bit offset
1368                                           exe_ctx.GetBestExecutionContextScope());
1369                 // Don't set the m_error to anything here otherwise
1370                 // we won't be able to re-format as anything else. The
1371                 // code for ClangASTType::DumpTypeValue() should always
1372                 // return something, even if that something contains
1373                 // an error messsage. "m_error" is used to detect errors
1374                 // when reading the valid object, not for formatting errors.
1375                 if (sstr.GetString().empty())
1376                     destination.clear();
1377                 else
1378                     destination.swap(sstr.GetString());
1379             }
1380         }
1381         return !destination.empty();
1382     }
1383     else
1384         return false;
1385 }
1386 
1387 const char *
GetValueAsCString()1388 ValueObject::GetValueAsCString ()
1389 {
1390     if (UpdateValueIfNeeded(true))
1391     {
1392         lldb::Format my_format = GetFormat();
1393         if (my_format == lldb::eFormatDefault)
1394         {
1395             if (m_type_format_sp)
1396                 my_format = m_type_format_sp->GetFormat();
1397             else
1398             {
1399                 if (m_is_bitfield_for_scalar)
1400                     my_format = eFormatUnsigned;
1401                 else
1402                 {
1403                     if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
1404                     {
1405                         const RegisterInfo *reg_info = m_value.GetRegisterInfo();
1406                         if (reg_info)
1407                             my_format = reg_info->format;
1408                     }
1409                     else
1410                     {
1411                         my_format = GetClangType().GetFormat();
1412                     }
1413                 }
1414             }
1415         }
1416         if (my_format != m_last_format || m_value_str.empty())
1417         {
1418             m_last_format = my_format;
1419             if (GetValueAsCString(my_format, m_value_str))
1420             {
1421                 if (!m_value_did_change && m_old_value_valid)
1422                 {
1423                     // The value was gotten successfully, so we consider the
1424                     // value as changed if the value string differs
1425                     SetValueDidChange (m_old_value_str != m_value_str);
1426                 }
1427             }
1428         }
1429     }
1430     if (m_value_str.empty())
1431         return NULL;
1432     return m_value_str.c_str();
1433 }
1434 
1435 // if > 8bytes, 0 is returned. this method should mostly be used
1436 // to read address values out of pointers
1437 uint64_t
GetValueAsUnsigned(uint64_t fail_value,bool * success)1438 ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
1439 {
1440     // If our byte size is zero this is an aggregate type that has children
1441     if (!GetClangType().IsAggregateType())
1442     {
1443         Scalar scalar;
1444         if (ResolveValue (scalar))
1445         {
1446             if (success)
1447                 *success = true;
1448             return scalar.ULongLong(fail_value);
1449         }
1450         // fallthrough, otherwise...
1451     }
1452 
1453     if (success)
1454         *success = false;
1455     return fail_value;
1456 }
1457 
1458 // if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep
1459 // this call up to date by returning true for your new special cases. We will eventually move
1460 // to checking this call result before trying to display special cases
1461 bool
HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,Format custom_format)1462 ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
1463                                                Format custom_format)
1464 {
1465     Flags flags(GetTypeInfo());
1466     if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer)
1467         && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
1468     {
1469         if (IsCStringContainer(true) &&
1470             (custom_format == eFormatCString ||
1471              custom_format == eFormatCharArray ||
1472              custom_format == eFormatChar ||
1473              custom_format == eFormatVectorOfChar))
1474             return true;
1475 
1476         if (flags.Test(ClangASTType::eTypeIsArray))
1477         {
1478             if ((custom_format == eFormatBytes) ||
1479                 (custom_format == eFormatBytesWithASCII))
1480                 return true;
1481 
1482             if ((custom_format == eFormatVectorOfChar) ||
1483                 (custom_format == eFormatVectorOfFloat32) ||
1484                 (custom_format == eFormatVectorOfFloat64) ||
1485                 (custom_format == eFormatVectorOfSInt16) ||
1486                 (custom_format == eFormatVectorOfSInt32) ||
1487                 (custom_format == eFormatVectorOfSInt64) ||
1488                 (custom_format == eFormatVectorOfSInt8) ||
1489                 (custom_format == eFormatVectorOfUInt128) ||
1490                 (custom_format == eFormatVectorOfUInt16) ||
1491                 (custom_format == eFormatVectorOfUInt32) ||
1492                 (custom_format == eFormatVectorOfUInt64) ||
1493                 (custom_format == eFormatVectorOfUInt8))
1494                 return true;
1495         }
1496     }
1497     return false;
1498 }
1499 
1500 bool
DumpPrintableRepresentation(Stream & s,ValueObjectRepresentationStyle val_obj_display,Format custom_format,PrintableRepresentationSpecialCases special)1501 ValueObject::DumpPrintableRepresentation(Stream& s,
1502                                          ValueObjectRepresentationStyle val_obj_display,
1503                                          Format custom_format,
1504                                          PrintableRepresentationSpecialCases special)
1505 {
1506 
1507     Flags flags(GetTypeInfo());
1508 
1509     bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
1510     bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
1511 
1512     if (allow_special)
1513     {
1514         if (flags.AnySet(ClangASTType::eTypeIsArray | ClangASTType::eTypeIsPointer)
1515              && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
1516         {
1517             // when being asked to get a printable display an array or pointer type directly,
1518             // try to "do the right thing"
1519 
1520             if (IsCStringContainer(true) &&
1521                 (custom_format == eFormatCString ||
1522                  custom_format == eFormatCharArray ||
1523                  custom_format == eFormatChar ||
1524                  custom_format == eFormatVectorOfChar)) // print char[] & char* directly
1525             {
1526                 Error error;
1527                 ReadPointedString(s,
1528                                   error,
1529                                   0,
1530                                   (custom_format == eFormatVectorOfChar) ||
1531                                   (custom_format == eFormatCharArray));
1532                 return !error.Fail();
1533             }
1534 
1535             if (custom_format == eFormatEnum)
1536                 return false;
1537 
1538             // this only works for arrays, because I have no way to know when
1539             // the pointed memory ends, and no special \0 end of data marker
1540             if (flags.Test(ClangASTType::eTypeIsArray))
1541             {
1542                 if ((custom_format == eFormatBytes) ||
1543                     (custom_format == eFormatBytesWithASCII))
1544                 {
1545                     const size_t count = GetNumChildren();
1546 
1547                     s << '[';
1548                     for (size_t low = 0; low < count; low++)
1549                     {
1550 
1551                         if (low)
1552                             s << ',';
1553 
1554                         ValueObjectSP child = GetChildAtIndex(low,true);
1555                         if (!child.get())
1556                         {
1557                             s << "<invalid child>";
1558                             continue;
1559                         }
1560                         child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, custom_format);
1561                     }
1562 
1563                     s << ']';
1564 
1565                     return true;
1566                 }
1567 
1568                 if ((custom_format == eFormatVectorOfChar) ||
1569                     (custom_format == eFormatVectorOfFloat32) ||
1570                     (custom_format == eFormatVectorOfFloat64) ||
1571                     (custom_format == eFormatVectorOfSInt16) ||
1572                     (custom_format == eFormatVectorOfSInt32) ||
1573                     (custom_format == eFormatVectorOfSInt64) ||
1574                     (custom_format == eFormatVectorOfSInt8) ||
1575                     (custom_format == eFormatVectorOfUInt128) ||
1576                     (custom_format == eFormatVectorOfUInt16) ||
1577                     (custom_format == eFormatVectorOfUInt32) ||
1578                     (custom_format == eFormatVectorOfUInt64) ||
1579                     (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
1580                 {
1581                     const size_t count = GetNumChildren();
1582 
1583                     Format format = FormatManager::GetSingleItemFormat(custom_format);
1584 
1585                     s << '[';
1586                     for (size_t low = 0; low < count; low++)
1587                     {
1588 
1589                         if (low)
1590                             s << ',';
1591 
1592                         ValueObjectSP child = GetChildAtIndex(low,true);
1593                         if (!child.get())
1594                         {
1595                             s << "<invalid child>";
1596                             continue;
1597                         }
1598                         child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, format);
1599                     }
1600 
1601                     s << ']';
1602 
1603                     return true;
1604                 }
1605             }
1606 
1607             if ((custom_format == eFormatBoolean) ||
1608                 (custom_format == eFormatBinary) ||
1609                 (custom_format == eFormatChar) ||
1610                 (custom_format == eFormatCharPrintable) ||
1611                 (custom_format == eFormatComplexFloat) ||
1612                 (custom_format == eFormatDecimal) ||
1613                 (custom_format == eFormatHex) ||
1614                 (custom_format == eFormatHexUppercase) ||
1615                 (custom_format == eFormatFloat) ||
1616                 (custom_format == eFormatOctal) ||
1617                 (custom_format == eFormatOSType) ||
1618                 (custom_format == eFormatUnicode16) ||
1619                 (custom_format == eFormatUnicode32) ||
1620                 (custom_format == eFormatUnsigned) ||
1621                 (custom_format == eFormatPointer) ||
1622                 (custom_format == eFormatComplexInteger) ||
1623                 (custom_format == eFormatComplex) ||
1624                 (custom_format == eFormatDefault)) // use the [] operator
1625                 return false;
1626         }
1627     }
1628 
1629     if (only_special)
1630         return false;
1631 
1632     bool var_success = false;
1633 
1634     {
1635         const char *cstr = NULL;
1636 
1637          // this is a local stream that we are using to ensure that the data pointed to by cstr survives
1638         // long enough for us to copy it to its destination - it is necessary to have this temporary storage
1639         // area for cases where our desired output is not backed by some other longer-term storage
1640         StreamString strm;
1641 
1642         if (custom_format != eFormatInvalid)
1643             SetFormat(custom_format);
1644 
1645         switch(val_obj_display)
1646         {
1647             case eValueObjectRepresentationStyleValue:
1648                 cstr = GetValueAsCString();
1649                 break;
1650 
1651             case eValueObjectRepresentationStyleSummary:
1652                 cstr = GetSummaryAsCString();
1653                 break;
1654 
1655             case eValueObjectRepresentationStyleLanguageSpecific:
1656                 cstr = GetObjectDescription();
1657                 break;
1658 
1659             case eValueObjectRepresentationStyleLocation:
1660                 cstr = GetLocationAsCString();
1661                 break;
1662 
1663             case eValueObjectRepresentationStyleChildrenCount:
1664                 strm.Printf("%zu", GetNumChildren());
1665                 cstr = strm.GetString().c_str();
1666                 break;
1667 
1668             case eValueObjectRepresentationStyleType:
1669                 cstr = GetTypeName().AsCString();
1670                 break;
1671 
1672             case eValueObjectRepresentationStyleName:
1673                 cstr = GetName().AsCString();
1674                 break;
1675 
1676             case eValueObjectRepresentationStyleExpressionPath:
1677                 GetExpressionPath(strm, false);
1678                 cstr = strm.GetString().c_str();
1679                 break;
1680         }
1681 
1682         if (!cstr)
1683         {
1684             if (val_obj_display == eValueObjectRepresentationStyleValue)
1685                 cstr = GetSummaryAsCString();
1686             else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1687             {
1688                 if (GetClangType().IsAggregateType())
1689                 {
1690                     strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
1691                     cstr = strm.GetString().c_str();
1692                 }
1693                 else
1694                     cstr = GetValueAsCString();
1695             }
1696         }
1697 
1698         if (cstr)
1699             s.PutCString(cstr);
1700         else
1701         {
1702             if (m_error.Fail())
1703                 s.Printf("<%s>", m_error.AsCString());
1704             else if (val_obj_display == eValueObjectRepresentationStyleSummary)
1705                 s.PutCString("<no summary available>");
1706             else if (val_obj_display == eValueObjectRepresentationStyleValue)
1707                 s.PutCString("<no value available>");
1708             else if (val_obj_display == eValueObjectRepresentationStyleLanguageSpecific)
1709                 s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description
1710             else
1711                 s.PutCString("<no printable representation>");
1712         }
1713 
1714         // we should only return false here if we could not do *anything*
1715         // even if we have an error message as output, that's a success
1716         // from our callers' perspective, so return true
1717         var_success = true;
1718 
1719         if (custom_format != eFormatInvalid)
1720             SetFormat(eFormatDefault);
1721     }
1722 
1723     return var_success;
1724 }
1725 
1726 addr_t
GetAddressOf(bool scalar_is_load_address,AddressType * address_type)1727 ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type)
1728 {
1729     if (!UpdateValueIfNeeded(false))
1730         return LLDB_INVALID_ADDRESS;
1731 
1732     switch (m_value.GetValueType())
1733     {
1734     case Value::eValueTypeScalar:
1735     case Value::eValueTypeVector:
1736         if (scalar_is_load_address)
1737         {
1738             if(address_type)
1739                 *address_type = eAddressTypeLoad;
1740             return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1741         }
1742         break;
1743 
1744     case Value::eValueTypeLoadAddress:
1745     case Value::eValueTypeFileAddress:
1746     case Value::eValueTypeHostAddress:
1747         {
1748             if(address_type)
1749                 *address_type = m_value.GetValueAddressType ();
1750             return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1751         }
1752         break;
1753     }
1754     if (address_type)
1755         *address_type = eAddressTypeInvalid;
1756     return LLDB_INVALID_ADDRESS;
1757 }
1758 
1759 addr_t
GetPointerValue(AddressType * address_type)1760 ValueObject::GetPointerValue (AddressType *address_type)
1761 {
1762     addr_t address = LLDB_INVALID_ADDRESS;
1763     if(address_type)
1764         *address_type = eAddressTypeInvalid;
1765 
1766     if (!UpdateValueIfNeeded(false))
1767         return address;
1768 
1769     switch (m_value.GetValueType())
1770     {
1771     case Value::eValueTypeScalar:
1772     case Value::eValueTypeVector:
1773         address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1774         break;
1775 
1776     case Value::eValueTypeHostAddress:
1777     case Value::eValueTypeLoadAddress:
1778     case Value::eValueTypeFileAddress:
1779         {
1780             lldb::offset_t data_offset = 0;
1781             address = m_data.GetPointer(&data_offset);
1782         }
1783         break;
1784     }
1785 
1786     if (address_type)
1787         *address_type = GetAddressTypeOfChildren();
1788 
1789     return address;
1790 }
1791 
1792 bool
SetValueFromCString(const char * value_str,Error & error)1793 ValueObject::SetValueFromCString (const char *value_str, Error& error)
1794 {
1795     error.Clear();
1796     // Make sure our value is up to date first so that our location and location
1797     // type is valid.
1798     if (!UpdateValueIfNeeded(false))
1799     {
1800         error.SetErrorString("unable to read value");
1801         return false;
1802     }
1803 
1804     uint64_t count = 0;
1805     const Encoding encoding = GetClangType().GetEncoding (count);
1806 
1807     const size_t byte_size = GetByteSize();
1808 
1809     Value::ValueType value_type = m_value.GetValueType();
1810 
1811     if (value_type == Value::eValueTypeScalar)
1812     {
1813         // If the value is already a scalar, then let the scalar change itself:
1814         m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size);
1815     }
1816     else if (byte_size <= Scalar::GetMaxByteSize())
1817     {
1818         // If the value fits in a scalar, then make a new scalar and again let the
1819         // scalar code do the conversion, then figure out where to put the new value.
1820         Scalar new_scalar;
1821         error = new_scalar.SetValueFromCString (value_str, encoding, byte_size);
1822         if (error.Success())
1823         {
1824             switch (value_type)
1825             {
1826             case Value::eValueTypeLoadAddress:
1827                 {
1828                     // If it is a load address, then the scalar value is the storage location
1829                     // of the data, and we have to shove this value down to that load location.
1830                     ExecutionContext exe_ctx (GetExecutionContextRef());
1831                     Process *process = exe_ctx.GetProcessPtr();
1832                     if (process)
1833                     {
1834                         addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
1835                         size_t bytes_written = process->WriteScalarToMemory (target_addr,
1836                                                                              new_scalar,
1837                                                                              byte_size,
1838                                                                              error);
1839                         if (!error.Success())
1840                             return false;
1841                         if (bytes_written != byte_size)
1842                         {
1843                             error.SetErrorString("unable to write value to memory");
1844                             return false;
1845                         }
1846                     }
1847                 }
1848                 break;
1849             case Value::eValueTypeHostAddress:
1850                 {
1851                     // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
1852                     DataExtractor new_data;
1853                     new_data.SetByteOrder (m_data.GetByteOrder());
1854 
1855                     DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
1856                     m_data.SetData(buffer_sp, 0);
1857                     bool success = new_scalar.GetData(new_data);
1858                     if (success)
1859                     {
1860                         new_data.CopyByteOrderedData (0,
1861                                                       byte_size,
1862                                                       const_cast<uint8_t *>(m_data.GetDataStart()),
1863                                                       byte_size,
1864                                                       m_data.GetByteOrder());
1865                     }
1866                     m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
1867 
1868                 }
1869                 break;
1870             case Value::eValueTypeFileAddress:
1871             case Value::eValueTypeScalar:
1872             case Value::eValueTypeVector:
1873                 break;
1874             }
1875         }
1876         else
1877         {
1878             return false;
1879         }
1880     }
1881     else
1882     {
1883         // We don't support setting things bigger than a scalar at present.
1884         error.SetErrorString("unable to write aggregate data type");
1885         return false;
1886     }
1887 
1888     // If we have reached this point, then we have successfully changed the value.
1889     SetNeedsUpdate();
1890     return true;
1891 }
1892 
1893 bool
GetDeclaration(Declaration & decl)1894 ValueObject::GetDeclaration (Declaration &decl)
1895 {
1896     decl.Clear();
1897     return false;
1898 }
1899 
1900 ConstString
GetTypeName()1901 ValueObject::GetTypeName()
1902 {
1903     return GetClangType().GetConstTypeName();
1904 }
1905 
1906 ConstString
GetQualifiedTypeName()1907 ValueObject::GetQualifiedTypeName()
1908 {
1909     return GetClangType().GetConstQualifiedTypeName();
1910 }
1911 
1912 
1913 LanguageType
GetObjectRuntimeLanguage()1914 ValueObject::GetObjectRuntimeLanguage ()
1915 {
1916     return GetClangType().GetMinimumLanguage ();
1917 }
1918 
1919 void
AddSyntheticChild(const ConstString & key,ValueObject * valobj)1920 ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
1921 {
1922     m_synthetic_children[key] = valobj;
1923 }
1924 
1925 ValueObjectSP
GetSyntheticChild(const ConstString & key) const1926 ValueObject::GetSyntheticChild (const ConstString &key) const
1927 {
1928     ValueObjectSP synthetic_child_sp;
1929     std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
1930     if (pos != m_synthetic_children.end())
1931         synthetic_child_sp = pos->second->GetSP();
1932     return synthetic_child_sp;
1933 }
1934 
1935 uint32_t
GetTypeInfo(ClangASTType * pointee_or_element_clang_type)1936 ValueObject::GetTypeInfo (ClangASTType *pointee_or_element_clang_type)
1937 {
1938     return GetClangType().GetTypeInfo (pointee_or_element_clang_type);
1939 }
1940 
1941 bool
IsPointerType()1942 ValueObject::IsPointerType ()
1943 {
1944     return GetClangType().IsPointerType();
1945 }
1946 
1947 bool
IsArrayType()1948 ValueObject::IsArrayType ()
1949 {
1950     return GetClangType().IsArrayType (NULL, NULL, NULL);
1951 }
1952 
1953 bool
IsScalarType()1954 ValueObject::IsScalarType ()
1955 {
1956     return GetClangType().IsScalarType ();
1957 }
1958 
1959 bool
IsIntegerType(bool & is_signed)1960 ValueObject::IsIntegerType (bool &is_signed)
1961 {
1962     return GetClangType().IsIntegerType (is_signed);
1963 }
1964 
1965 bool
IsPointerOrReferenceType()1966 ValueObject::IsPointerOrReferenceType ()
1967 {
1968     return GetClangType().IsPointerOrReferenceType ();
1969 }
1970 
1971 bool
IsPossibleDynamicType()1972 ValueObject::IsPossibleDynamicType ()
1973 {
1974     ExecutionContext exe_ctx (GetExecutionContextRef());
1975     Process *process = exe_ctx.GetProcessPtr();
1976     if (process)
1977         return process->IsPossibleDynamicValue(*this);
1978     else
1979         return GetClangType().IsPossibleDynamicType (NULL, true, true);
1980 }
1981 
1982 bool
IsObjCNil()1983 ValueObject::IsObjCNil ()
1984 {
1985     const uint32_t mask = ClangASTType::eTypeIsObjC | ClangASTType::eTypeIsPointer;
1986     bool isObjCpointer = (((GetClangType().GetTypeInfo(NULL)) & mask) == mask);
1987     if (!isObjCpointer)
1988         return false;
1989     bool canReadValue = true;
1990     bool isZero = GetValueAsUnsigned(0,&canReadValue) == 0;
1991     return canReadValue && isZero;
1992 }
1993 
1994 ValueObjectSP
GetSyntheticArrayMember(size_t index,bool can_create)1995 ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
1996 {
1997     const uint32_t type_info = GetTypeInfo ();
1998     if (type_info & ClangASTType::eTypeIsArray)
1999         return GetSyntheticArrayMemberFromArray(index, can_create);
2000 
2001     if (type_info & ClangASTType::eTypeIsPointer)
2002         return GetSyntheticArrayMemberFromPointer(index, can_create);
2003 
2004     return ValueObjectSP();
2005 
2006 }
2007 
2008 ValueObjectSP
GetSyntheticArrayMemberFromPointer(size_t index,bool can_create)2009 ValueObject::GetSyntheticArrayMemberFromPointer (size_t index, bool can_create)
2010 {
2011     ValueObjectSP synthetic_child_sp;
2012     if (IsPointerType ())
2013     {
2014         char index_str[64];
2015         snprintf(index_str, sizeof(index_str), "[%zu]", index);
2016         ConstString index_const_str(index_str);
2017         // Check if we have already created a synthetic array member in this
2018         // valid object. If we have we will re-use it.
2019         synthetic_child_sp = GetSyntheticChild (index_const_str);
2020         if (!synthetic_child_sp)
2021         {
2022             ValueObject *synthetic_child;
2023             // We haven't made a synthetic array member for INDEX yet, so
2024             // lets make one and cache it for any future reference.
2025             synthetic_child = CreateChildAtIndex(0, true, index);
2026 
2027             // Cache the value if we got one back...
2028             if (synthetic_child)
2029             {
2030                 AddSyntheticChild(index_const_str, synthetic_child);
2031                 synthetic_child_sp = synthetic_child->GetSP();
2032                 synthetic_child_sp->SetName(ConstString(index_str));
2033                 synthetic_child_sp->m_is_array_item_for_pointer = true;
2034             }
2035         }
2036     }
2037     return synthetic_child_sp;
2038 }
2039 
2040 // This allows you to create an array member using and index
2041 // that doesn't not fall in the normal bounds of the array.
2042 // Many times structure can be defined as:
2043 // struct Collection
2044 // {
2045 //     uint32_t item_count;
2046 //     Item item_array[0];
2047 // };
2048 // The size of the "item_array" is 1, but many times in practice
2049 // there are more items in "item_array".
2050 
2051 ValueObjectSP
GetSyntheticArrayMemberFromArray(size_t index,bool can_create)2052 ValueObject::GetSyntheticArrayMemberFromArray (size_t index, bool can_create)
2053 {
2054     ValueObjectSP synthetic_child_sp;
2055     if (IsArrayType ())
2056     {
2057         char index_str[64];
2058         snprintf(index_str, sizeof(index_str), "[%zu]", index);
2059         ConstString index_const_str(index_str);
2060         // Check if we have already created a synthetic array member in this
2061         // valid object. If we have we will re-use it.
2062         synthetic_child_sp = GetSyntheticChild (index_const_str);
2063         if (!synthetic_child_sp)
2064         {
2065             ValueObject *synthetic_child;
2066             // We haven't made a synthetic array member for INDEX yet, so
2067             // lets make one and cache it for any future reference.
2068             synthetic_child = CreateChildAtIndex(0, true, index);
2069 
2070             // Cache the value if we got one back...
2071             if (synthetic_child)
2072             {
2073                 AddSyntheticChild(index_const_str, synthetic_child);
2074                 synthetic_child_sp = synthetic_child->GetSP();
2075                 synthetic_child_sp->SetName(ConstString(index_str));
2076                 synthetic_child_sp->m_is_array_item_for_pointer = true;
2077             }
2078         }
2079     }
2080     return synthetic_child_sp;
2081 }
2082 
2083 ValueObjectSP
GetSyntheticBitFieldChild(uint32_t from,uint32_t to,bool can_create)2084 ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
2085 {
2086     ValueObjectSP synthetic_child_sp;
2087     if (IsScalarType ())
2088     {
2089         char index_str[64];
2090         snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
2091         ConstString index_const_str(index_str);
2092         // Check if we have already created a synthetic array member in this
2093         // valid object. If we have we will re-use it.
2094         synthetic_child_sp = GetSyntheticChild (index_const_str);
2095         if (!synthetic_child_sp)
2096         {
2097             // We haven't made a synthetic array member for INDEX yet, so
2098             // lets make one and cache it for any future reference.
2099             ValueObjectChild *synthetic_child = new ValueObjectChild (*this,
2100                                                                       GetClangType(),
2101                                                                       index_const_str,
2102                                                                       GetByteSize(),
2103                                                                       0,
2104                                                                       to-from+1,
2105                                                                       from,
2106                                                                       false,
2107                                                                       false,
2108                                                                       eAddressTypeInvalid);
2109 
2110             // Cache the value if we got one back...
2111             if (synthetic_child)
2112             {
2113                 AddSyntheticChild(index_const_str, synthetic_child);
2114                 synthetic_child_sp = synthetic_child->GetSP();
2115                 synthetic_child_sp->SetName(ConstString(index_str));
2116                 synthetic_child_sp->m_is_bitfield_for_scalar = true;
2117             }
2118         }
2119     }
2120     return synthetic_child_sp;
2121 }
2122 
2123 ValueObjectSP
GetSyntheticChildAtOffset(uint32_t offset,const ClangASTType & type,bool can_create)2124 ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create)
2125 {
2126 
2127     ValueObjectSP synthetic_child_sp;
2128 
2129     char name_str[64];
2130     snprintf(name_str, sizeof(name_str), "@%i", offset);
2131     ConstString name_const_str(name_str);
2132 
2133     // Check if we have already created a synthetic array member in this
2134     // valid object. If we have we will re-use it.
2135     synthetic_child_sp = GetSyntheticChild (name_const_str);
2136 
2137     if (synthetic_child_sp.get())
2138         return synthetic_child_sp;
2139 
2140     if (!can_create)
2141         return ValueObjectSP();
2142 
2143     ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
2144                                                              type,
2145                                                              name_const_str,
2146                                                              type.GetByteSize(),
2147                                                              offset,
2148                                                              0,
2149                                                              0,
2150                                                              false,
2151                                                              false,
2152                                                              eAddressTypeInvalid);
2153     if (synthetic_child)
2154     {
2155         AddSyntheticChild(name_const_str, synthetic_child);
2156         synthetic_child_sp = synthetic_child->GetSP();
2157         synthetic_child_sp->SetName(name_const_str);
2158         synthetic_child_sp->m_is_child_at_offset = true;
2159     }
2160     return synthetic_child_sp;
2161 }
2162 
2163 // your expression path needs to have a leading . or ->
2164 // (unless it somehow "looks like" an array, in which case it has
2165 // a leading [ symbol). while the [ is meaningful and should be shown
2166 // to the user, . and -> are just parser design, but by no means
2167 // added information for the user.. strip them off
2168 static const char*
SkipLeadingExpressionPathSeparators(const char * expression)2169 SkipLeadingExpressionPathSeparators(const char* expression)
2170 {
2171     if (!expression || !expression[0])
2172         return expression;
2173     if (expression[0] == '.')
2174         return expression+1;
2175     if (expression[0] == '-' && expression[1] == '>')
2176         return expression+2;
2177     return expression;
2178 }
2179 
2180 ValueObjectSP
GetSyntheticExpressionPathChild(const char * expression,bool can_create)2181 ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
2182 {
2183     ValueObjectSP synthetic_child_sp;
2184     ConstString name_const_string(expression);
2185     // Check if we have already created a synthetic array member in this
2186     // valid object. If we have we will re-use it.
2187     synthetic_child_sp = GetSyntheticChild (name_const_string);
2188     if (!synthetic_child_sp)
2189     {
2190         // We haven't made a synthetic array member for expression yet, so
2191         // lets make one and cache it for any future reference.
2192         synthetic_child_sp = GetValueForExpressionPath(expression,
2193                                                        NULL, NULL, NULL,
2194                                                        GetValueForExpressionPathOptions().DontAllowSyntheticChildren());
2195 
2196         // Cache the value if we got one back...
2197         if (synthetic_child_sp.get())
2198         {
2199             // FIXME: this causes a "real" child to end up with its name changed to the contents of expression
2200             AddSyntheticChild(name_const_string, synthetic_child_sp.get());
2201             synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
2202         }
2203     }
2204     return synthetic_child_sp;
2205 }
2206 
2207 void
CalculateSyntheticValue(bool use_synthetic)2208 ValueObject::CalculateSyntheticValue (bool use_synthetic)
2209 {
2210     if (use_synthetic == false)
2211         return;
2212 
2213     TargetSP target_sp(GetTargetSP());
2214     if (target_sp && (target_sp->GetEnableSyntheticValue() == false || target_sp->GetSuppressSyntheticValue() == true))
2215     {
2216         m_synthetic_value = NULL;
2217         return;
2218     }
2219 
2220     lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
2221 
2222     if (!UpdateFormatsIfNeeded() && m_synthetic_value)
2223         return;
2224 
2225     if (m_synthetic_children_sp.get() == NULL)
2226         return;
2227 
2228     if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
2229         return;
2230 
2231     m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
2232 }
2233 
2234 void
CalculateDynamicValue(DynamicValueType use_dynamic)2235 ValueObject::CalculateDynamicValue (DynamicValueType use_dynamic)
2236 {
2237     if (use_dynamic == eNoDynamicValues)
2238         return;
2239 
2240     if (!m_dynamic_value && !IsDynamic())
2241     {
2242         ExecutionContext exe_ctx (GetExecutionContextRef());
2243         Process *process = exe_ctx.GetProcessPtr();
2244         if (process && process->IsPossibleDynamicValue(*this))
2245         {
2246             ClearDynamicTypeInformation ();
2247             m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
2248         }
2249     }
2250 }
2251 
2252 ValueObjectSP
GetDynamicValue(DynamicValueType use_dynamic)2253 ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
2254 {
2255     if (use_dynamic == eNoDynamicValues)
2256         return ValueObjectSP();
2257 
2258     if (!IsDynamic() && m_dynamic_value == NULL)
2259     {
2260         CalculateDynamicValue(use_dynamic);
2261     }
2262     if (m_dynamic_value)
2263         return m_dynamic_value->GetSP();
2264     else
2265         return ValueObjectSP();
2266 }
2267 
2268 ValueObjectSP
GetStaticValue()2269 ValueObject::GetStaticValue()
2270 {
2271     return GetSP();
2272 }
2273 
2274 lldb::ValueObjectSP
GetNonSyntheticValue()2275 ValueObject::GetNonSyntheticValue ()
2276 {
2277     return GetSP();
2278 }
2279 
2280 ValueObjectSP
GetSyntheticValue(bool use_synthetic)2281 ValueObject::GetSyntheticValue (bool use_synthetic)
2282 {
2283     if (use_synthetic == false)
2284         return ValueObjectSP();
2285 
2286     CalculateSyntheticValue(use_synthetic);
2287 
2288     if (m_synthetic_value)
2289         return m_synthetic_value->GetSP();
2290     else
2291         return ValueObjectSP();
2292 }
2293 
2294 bool
HasSyntheticValue()2295 ValueObject::HasSyntheticValue()
2296 {
2297     UpdateFormatsIfNeeded();
2298 
2299     if (m_synthetic_children_sp.get() == NULL)
2300         return false;
2301 
2302     CalculateSyntheticValue(true);
2303 
2304     if (m_synthetic_value)
2305         return true;
2306     else
2307         return false;
2308 }
2309 
2310 bool
GetBaseClassPath(Stream & s)2311 ValueObject::GetBaseClassPath (Stream &s)
2312 {
2313     if (IsBaseClass())
2314     {
2315         bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
2316         ClangASTType clang_type = GetClangType();
2317         std::string cxx_class_name;
2318         bool this_had_base_class = clang_type.GetCXXClassName (cxx_class_name);
2319         if (this_had_base_class)
2320         {
2321             if (parent_had_base_class)
2322                 s.PutCString("::");
2323             s.PutCString(cxx_class_name.c_str());
2324         }
2325         return parent_had_base_class || this_had_base_class;
2326     }
2327     return false;
2328 }
2329 
2330 
2331 ValueObject *
GetNonBaseClassParent()2332 ValueObject::GetNonBaseClassParent()
2333 {
2334     if (GetParent())
2335     {
2336         if (GetParent()->IsBaseClass())
2337             return GetParent()->GetNonBaseClassParent();
2338         else
2339             return GetParent();
2340     }
2341     return NULL;
2342 }
2343 
2344 void
GetExpressionPath(Stream & s,bool qualify_cxx_base_classes,GetExpressionPathFormat epformat)2345 ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
2346 {
2347     const bool is_deref_of_parent = IsDereferenceOfParent ();
2348 
2349     if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
2350     {
2351         // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
2352         // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
2353         // the eHonorPointers mode is meant to produce strings in this latter format
2354         s.PutCString("*(");
2355     }
2356 
2357     ValueObject* parent = GetParent();
2358 
2359     if (parent)
2360         parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
2361 
2362     // if we are a deref_of_parent just because we are synthetic array
2363     // members made up to allow ptr[%d] syntax to work in variable
2364     // printing, then add our name ([%d]) to the expression path
2365     if (m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers)
2366         s.PutCString(m_name.AsCString());
2367 
2368     if (!IsBaseClass())
2369     {
2370         if (!is_deref_of_parent)
2371         {
2372             ValueObject *non_base_class_parent = GetNonBaseClassParent();
2373             if (non_base_class_parent)
2374             {
2375                 ClangASTType non_base_class_parent_clang_type = non_base_class_parent->GetClangType();
2376                 if (non_base_class_parent_clang_type)
2377                 {
2378                     if (parent && parent->IsDereferenceOfParent() && epformat == eGetExpressionPathFormatHonorPointers)
2379                     {
2380                         s.PutCString("->");
2381                     }
2382                     else
2383                     {
2384                         const uint32_t non_base_class_parent_type_info = non_base_class_parent_clang_type.GetTypeInfo();
2385 
2386                         if (non_base_class_parent_type_info & ClangASTType::eTypeIsPointer)
2387                         {
2388                             s.PutCString("->");
2389                         }
2390                         else if ((non_base_class_parent_type_info & ClangASTType::eTypeHasChildren) &&
2391                                  !(non_base_class_parent_type_info & ClangASTType::eTypeIsArray))
2392                         {
2393                             s.PutChar('.');
2394                         }
2395                     }
2396                 }
2397             }
2398 
2399             const char *name = GetName().GetCString();
2400             if (name)
2401             {
2402                 if (qualify_cxx_base_classes)
2403                 {
2404                     if (GetBaseClassPath (s))
2405                         s.PutCString("::");
2406                 }
2407                 s.PutCString(name);
2408             }
2409         }
2410     }
2411 
2412     if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
2413     {
2414         s.PutChar(')');
2415     }
2416 }
2417 
2418 ValueObjectSP
GetValueForExpressionPath(const char * expression,const char ** first_unparsed,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_value_type,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * final_task_on_target)2419 ValueObject::GetValueForExpressionPath(const char* expression,
2420                                        const char** first_unparsed,
2421                                        ExpressionPathScanEndReason* reason_to_stop,
2422                                        ExpressionPathEndResultType* final_value_type,
2423                                        const GetValueForExpressionPathOptions& options,
2424                                        ExpressionPathAftermath* final_task_on_target)
2425 {
2426 
2427     const char* dummy_first_unparsed;
2428     ExpressionPathScanEndReason dummy_reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnknown;
2429     ExpressionPathEndResultType dummy_final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2430     ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2431 
2432     ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
2433                                                            first_unparsed ? first_unparsed : &dummy_first_unparsed,
2434                                                            reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2435                                                            final_value_type ? final_value_type : &dummy_final_value_type,
2436                                                            options,
2437                                                            final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
2438 
2439     if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2440         return ret_val;
2441 
2442     if (ret_val.get() && ((final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress of plain objects
2443     {
2444         if ( (final_task_on_target ? *final_task_on_target : dummy_final_task_on_target) == ValueObject::eExpressionPathAftermathDereference)
2445         {
2446             Error error;
2447             ValueObjectSP final_value = ret_val->Dereference(error);
2448             if (error.Fail() || !final_value.get())
2449             {
2450                 if (reason_to_stop)
2451                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2452                 if (final_value_type)
2453                     *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2454                 return ValueObjectSP();
2455             }
2456             else
2457             {
2458                 if (final_task_on_target)
2459                     *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2460                 return final_value;
2461             }
2462         }
2463         if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
2464         {
2465             Error error;
2466             ValueObjectSP final_value = ret_val->AddressOf(error);
2467             if (error.Fail() || !final_value.get())
2468             {
2469                 if (reason_to_stop)
2470                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2471                 if (final_value_type)
2472                     *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2473                 return ValueObjectSP();
2474             }
2475             else
2476             {
2477                 if (final_task_on_target)
2478                     *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2479                 return final_value;
2480             }
2481         }
2482     }
2483     return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
2484 }
2485 
2486 int
GetValuesForExpressionPath(const char * expression,ValueObjectListSP & list,const char ** first_unparsed,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_value_type,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * final_task_on_target)2487 ValueObject::GetValuesForExpressionPath(const char* expression,
2488                                         ValueObjectListSP& list,
2489                                         const char** first_unparsed,
2490                                         ExpressionPathScanEndReason* reason_to_stop,
2491                                         ExpressionPathEndResultType* final_value_type,
2492                                         const GetValueForExpressionPathOptions& options,
2493                                         ExpressionPathAftermath* final_task_on_target)
2494 {
2495     const char* dummy_first_unparsed;
2496     ExpressionPathScanEndReason dummy_reason_to_stop;
2497     ExpressionPathEndResultType dummy_final_value_type;
2498     ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2499 
2500     ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
2501                                                            first_unparsed ? first_unparsed : &dummy_first_unparsed,
2502                                                            reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2503                                                            final_value_type ? final_value_type : &dummy_final_value_type,
2504                                                            options,
2505                                                            final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
2506 
2507     if (!ret_val.get()) // if there are errors, I add nothing to the list
2508         return 0;
2509 
2510     if ( (reason_to_stop ? *reason_to_stop : dummy_reason_to_stop) != eExpressionPathScanEndReasonArrayRangeOperatorMet)
2511     {
2512         // I need not expand a range, just post-process the final value and return
2513         if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
2514         {
2515             list->Append(ret_val);
2516             return 1;
2517         }
2518         if (ret_val.get() && (final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain) // I can only deref and takeaddress of plain objects
2519         {
2520             if (*final_task_on_target == ValueObject::eExpressionPathAftermathDereference)
2521             {
2522                 Error error;
2523                 ValueObjectSP final_value = ret_val->Dereference(error);
2524                 if (error.Fail() || !final_value.get())
2525                 {
2526                     if (reason_to_stop)
2527                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2528                     if (final_value_type)
2529                         *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2530                     return 0;
2531                 }
2532                 else
2533                 {
2534                     *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2535                     list->Append(final_value);
2536                     return 1;
2537                 }
2538             }
2539             if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
2540             {
2541                 Error error;
2542                 ValueObjectSP final_value = ret_val->AddressOf(error);
2543                 if (error.Fail() || !final_value.get())
2544                 {
2545                     if (reason_to_stop)
2546                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
2547                     if (final_value_type)
2548                         *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
2549                     return 0;
2550                 }
2551                 else
2552                 {
2553                     *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
2554                     list->Append(final_value);
2555                     return 1;
2556                 }
2557             }
2558         }
2559     }
2560     else
2561     {
2562         return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
2563                                           first_unparsed ? first_unparsed : &dummy_first_unparsed,
2564                                           ret_val,
2565                                           list,
2566                                           reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
2567                                           final_value_type ? final_value_type : &dummy_final_value_type,
2568                                           options,
2569                                           final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
2570     }
2571     // in any non-covered case, just do the obviously right thing
2572     list->Append(ret_val);
2573     return 1;
2574 }
2575 
2576 ValueObjectSP
GetValueForExpressionPath_Impl(const char * expression_cstr,const char ** first_unparsed,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_result,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * what_next)2577 ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
2578                                             const char** first_unparsed,
2579                                             ExpressionPathScanEndReason* reason_to_stop,
2580                                             ExpressionPathEndResultType* final_result,
2581                                             const GetValueForExpressionPathOptions& options,
2582                                             ExpressionPathAftermath* what_next)
2583 {
2584     ValueObjectSP root = GetSP();
2585 
2586     if (!root.get())
2587         return ValueObjectSP();
2588 
2589     *first_unparsed = expression_cstr;
2590 
2591     while (true)
2592     {
2593 
2594         const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
2595 
2596         ClangASTType root_clang_type = root->GetClangType();
2597         ClangASTType pointee_clang_type;
2598         Flags pointee_clang_type_info;
2599 
2600         Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type));
2601         if (pointee_clang_type)
2602             pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo());
2603 
2604         if (!expression_cstr || *expression_cstr == '\0')
2605         {
2606             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2607             return root;
2608         }
2609 
2610         switch (*expression_cstr)
2611         {
2612             case '-':
2613             {
2614                 if (options.m_check_dot_vs_arrow_syntax &&
2615                     root_clang_type_info.Test(ClangASTType::eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error
2616                 {
2617                     *first_unparsed = expression_cstr;
2618                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
2619                     *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2620                     return ValueObjectSP();
2621                 }
2622                 if (root_clang_type_info.Test(ClangASTType::eTypeIsObjC) &&  // if yo are trying to extract an ObjC IVar when this is forbidden
2623                     root_clang_type_info.Test(ClangASTType::eTypeIsPointer) &&
2624                     options.m_no_fragile_ivar)
2625                 {
2626                     *first_unparsed = expression_cstr;
2627                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
2628                     *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2629                     return ValueObjectSP();
2630                 }
2631                 if (expression_cstr[1] != '>')
2632                 {
2633                     *first_unparsed = expression_cstr;
2634                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2635                     *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2636                     return ValueObjectSP();
2637                 }
2638                 expression_cstr++; // skip the -
2639             }
2640             case '.': // or fallthrough from ->
2641             {
2642                 if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
2643                     root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error
2644                 {
2645                     *first_unparsed = expression_cstr;
2646                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
2647                     *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2648                     return ValueObjectSP();
2649                 }
2650                 expression_cstr++; // skip .
2651                 const char *next_separator = strpbrk(expression_cstr+1,"-.[");
2652                 ConstString child_name;
2653                 if (!next_separator) // if no other separator just expand this last layer
2654                 {
2655                     child_name.SetCString (expression_cstr);
2656                     ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2657 
2658                     if (child_valobj_sp.get()) // we know we are done, so just return
2659                     {
2660                         *first_unparsed = "";
2661                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2662                         *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2663                         return child_valobj_sp;
2664                     }
2665                     else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2666                     {
2667                         if (root->IsSynthetic())
2668                         {
2669                             *first_unparsed = expression_cstr;
2670                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2671                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2672                             return ValueObjectSP();
2673                         }
2674 
2675                         child_valobj_sp = root->GetSyntheticValue();
2676                         if (child_valobj_sp.get())
2677                             child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
2678                     }
2679 
2680                     // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2681                     // so we hit the "else" branch, and return an error
2682                     if(child_valobj_sp.get()) // if it worked, just return
2683                     {
2684                         *first_unparsed = "";
2685                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
2686                         *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2687                         return child_valobj_sp;
2688                     }
2689                     else
2690                     {
2691                         *first_unparsed = expression_cstr;
2692                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2693                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2694                         return ValueObjectSP();
2695                     }
2696                 }
2697                 else // other layers do expand
2698                 {
2699                     child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
2700                     ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
2701                     if (child_valobj_sp.get()) // store the new root and move on
2702                     {
2703                         root = child_valobj_sp;
2704                         *first_unparsed = next_separator;
2705                         *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2706                         continue;
2707                     }
2708                     else if (options.m_no_synthetic_children == false) // let's try with synthetic children
2709                     {
2710                         if (root->IsSynthetic())
2711                         {
2712                             *first_unparsed = expression_cstr;
2713                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2714                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2715                             return ValueObjectSP();
2716                         }
2717 
2718                         child_valobj_sp = root->GetSyntheticValue(true);
2719                         if (child_valobj_sp)
2720                             child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
2721                     }
2722 
2723                     // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
2724                     // so we hit the "else" branch, and return an error
2725                     if(child_valobj_sp.get()) // if it worked, move on
2726                     {
2727                         root = child_valobj_sp;
2728                         *first_unparsed = next_separator;
2729                         *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2730                         continue;
2731                     }
2732                     else
2733                     {
2734                         *first_unparsed = expression_cstr;
2735                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2736                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2737                         return ValueObjectSP();
2738                     }
2739                 }
2740                 break;
2741             }
2742             case '[':
2743             {
2744                 if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && !root_clang_type_info.Test(ClangASTType::eTypeIsVector)) // if this is not a T[] nor a T*
2745                 {
2746                     if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar...
2747                     {
2748                         if (options.m_no_synthetic_children) // ...only chance left is synthetic
2749                         {
2750                             *first_unparsed = expression_cstr;
2751                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
2752                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2753                             return ValueObjectSP();
2754                         }
2755                     }
2756                     else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
2757                     {
2758                         *first_unparsed = expression_cstr;
2759                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
2760                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2761                         return ValueObjectSP();
2762                     }
2763                 }
2764                 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
2765                 {
2766                     if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray))
2767                     {
2768                         *first_unparsed = expression_cstr;
2769                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2770                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2771                         return ValueObjectSP();
2772                     }
2773                     else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
2774                     {
2775                         *first_unparsed = expression_cstr+2;
2776                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2777                         *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2778                         return root;
2779                     }
2780                 }
2781                 const char *separator_position = ::strchr(expression_cstr+1,'-');
2782                 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
2783                 if (!close_bracket_position) // if there is no ], this is a syntax error
2784                 {
2785                     *first_unparsed = expression_cstr;
2786                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2787                     *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2788                     return ValueObjectSP();
2789                 }
2790                 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
2791                 {
2792                     char *end = NULL;
2793                     unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
2794                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
2795                     {
2796                         *first_unparsed = expression_cstr;
2797                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2798                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2799                         return ValueObjectSP();
2800                     }
2801                     if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
2802                     {
2803                         if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
2804                         {
2805                             *first_unparsed = expression_cstr+2;
2806                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
2807                             *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
2808                             return root;
2809                         }
2810                         else
2811                         {
2812                             *first_unparsed = expression_cstr;
2813                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
2814                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2815                             return ValueObjectSP();
2816                         }
2817                     }
2818                     // from here on we do have a valid index
2819                     if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
2820                     {
2821                         ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
2822                         if (!child_valobj_sp)
2823                             child_valobj_sp = root->GetSyntheticArrayMemberFromArray(index, true);
2824                         if (!child_valobj_sp)
2825                             if (root->HasSyntheticValue() && root->GetSyntheticValue()->GetNumChildren() > index)
2826                                 child_valobj_sp = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2827                         if (child_valobj_sp)
2828                         {
2829                             root = child_valobj_sp;
2830                             *first_unparsed = end+1; // skip ]
2831                             *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2832                             continue;
2833                         }
2834                         else
2835                         {
2836                             *first_unparsed = expression_cstr;
2837                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2838                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2839                             return ValueObjectSP();
2840                         }
2841                     }
2842                     else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer))
2843                     {
2844                         if (*what_next == ValueObject::eExpressionPathAftermathDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
2845                             pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
2846                         {
2847                             Error error;
2848                             root = root->Dereference(error);
2849                             if (error.Fail() || !root.get())
2850                             {
2851                                 *first_unparsed = expression_cstr;
2852                                 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
2853                                 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2854                                 return ValueObjectSP();
2855                             }
2856                             else
2857                             {
2858                                 *what_next = eExpressionPathAftermathNothing;
2859                                 continue;
2860                             }
2861                         }
2862                         else
2863                         {
2864                             if (root->GetClangType().GetMinimumLanguage() == eLanguageTypeObjC
2865                                 && pointee_clang_type_info.AllClear(ClangASTType::eTypeIsPointer)
2866                                 && root->HasSyntheticValue()
2867                                 && options.m_no_synthetic_children == false)
2868                             {
2869                                 root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
2870                             }
2871                             else
2872                                 root = root->GetSyntheticArrayMemberFromPointer(index, true);
2873                             if (!root.get())
2874                             {
2875                                 *first_unparsed = expression_cstr;
2876                                 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2877                                 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2878                                 return ValueObjectSP();
2879                             }
2880                             else
2881                             {
2882                                 *first_unparsed = end+1; // skip ]
2883                                 *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2884                                 continue;
2885                             }
2886                         }
2887                     }
2888                     else if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar))
2889                     {
2890                         root = root->GetSyntheticBitFieldChild(index, index, true);
2891                         if (!root.get())
2892                         {
2893                             *first_unparsed = expression_cstr;
2894                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2895                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2896                             return ValueObjectSP();
2897                         }
2898                         else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
2899                         {
2900                             *first_unparsed = end+1; // skip ]
2901                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
2902                             *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
2903                             return root;
2904                         }
2905                     }
2906                     else if (root_clang_type_info.Test(ClangASTType::eTypeIsVector))
2907                     {
2908                         root = root->GetChildAtIndex(index, true);
2909                         if (!root.get())
2910                         {
2911                             *first_unparsed = expression_cstr;
2912                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2913                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2914                             return ValueObjectSP();
2915                         }
2916                         else
2917                         {
2918                             *first_unparsed = end+1; // skip ]
2919                             *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2920                             continue;
2921                         }
2922                     }
2923                     else if (options.m_no_synthetic_children == false)
2924                     {
2925                         if (root->HasSyntheticValue())
2926                             root = root->GetSyntheticValue();
2927                         else if (!root->IsSynthetic())
2928                         {
2929                             *first_unparsed = expression_cstr;
2930                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2931                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2932                             return ValueObjectSP();
2933                         }
2934                         // if we are here, then root itself is a synthetic VO.. should be good to go
2935 
2936                         if (!root.get())
2937                         {
2938                             *first_unparsed = expression_cstr;
2939                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
2940                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2941                             return ValueObjectSP();
2942                         }
2943                         root = root->GetChildAtIndex(index, true);
2944                         if (!root.get())
2945                         {
2946                             *first_unparsed = expression_cstr;
2947                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2948                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2949                             return ValueObjectSP();
2950                         }
2951                         else
2952                         {
2953                             *first_unparsed = end+1; // skip ]
2954                             *final_result = ValueObject::eExpressionPathEndResultTypePlain;
2955                             continue;
2956                         }
2957                     }
2958                     else
2959                     {
2960                         *first_unparsed = expression_cstr;
2961                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2962                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2963                         return ValueObjectSP();
2964                     }
2965                 }
2966                 else // we have a low and a high index
2967                 {
2968                     char *end = NULL;
2969                     unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
2970                     if (!end || end != separator_position) // if something weird is in our way return an error
2971                     {
2972                         *first_unparsed = expression_cstr;
2973                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2974                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2975                         return ValueObjectSP();
2976                     }
2977                     unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
2978                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
2979                     {
2980                         *first_unparsed = expression_cstr;
2981                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
2982                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2983                         return ValueObjectSP();
2984                     }
2985                     if (index_lower > index_higher) // swap indices if required
2986                     {
2987                         unsigned long temp = index_lower;
2988                         index_lower = index_higher;
2989                         index_higher = temp;
2990                     }
2991                     if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars
2992                     {
2993                         root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
2994                         if (!root.get())
2995                         {
2996                             *first_unparsed = expression_cstr;
2997                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
2998                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
2999                             return ValueObjectSP();
3000                         }
3001                         else
3002                         {
3003                             *first_unparsed = end+1; // skip ]
3004                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
3005                             *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
3006                             return root;
3007                         }
3008                     }
3009                     else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
3010                              *what_next == ValueObject::eExpressionPathAftermathDereference &&
3011                              pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
3012                     {
3013                         Error error;
3014                         root = root->Dereference(error);
3015                         if (error.Fail() || !root.get())
3016                         {
3017                             *first_unparsed = expression_cstr;
3018                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
3019                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3020                             return ValueObjectSP();
3021                         }
3022                         else
3023                         {
3024                             *what_next = ValueObject::eExpressionPathAftermathNothing;
3025                             continue;
3026                         }
3027                     }
3028                     else
3029                     {
3030                         *first_unparsed = expression_cstr;
3031                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
3032                         *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
3033                         return root;
3034                     }
3035                 }
3036                 break;
3037             }
3038             default: // some non-separator is in the way
3039             {
3040                 *first_unparsed = expression_cstr;
3041                 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3042                 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3043                 return ValueObjectSP();
3044                 break;
3045             }
3046         }
3047     }
3048 }
3049 
3050 int
ExpandArraySliceExpression(const char * expression_cstr,const char ** first_unparsed,ValueObjectSP root,ValueObjectListSP & list,ExpressionPathScanEndReason * reason_to_stop,ExpressionPathEndResultType * final_result,const GetValueForExpressionPathOptions & options,ExpressionPathAftermath * what_next)3051 ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
3052                                         const char** first_unparsed,
3053                                         ValueObjectSP root,
3054                                         ValueObjectListSP& list,
3055                                         ExpressionPathScanEndReason* reason_to_stop,
3056                                         ExpressionPathEndResultType* final_result,
3057                                         const GetValueForExpressionPathOptions& options,
3058                                         ExpressionPathAftermath* what_next)
3059 {
3060     if (!root.get())
3061         return 0;
3062 
3063     *first_unparsed = expression_cstr;
3064 
3065     while (true)
3066     {
3067 
3068         const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
3069 
3070         ClangASTType root_clang_type = root->GetClangType();
3071         ClangASTType pointee_clang_type;
3072         Flags pointee_clang_type_info;
3073         Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type));
3074         if (pointee_clang_type)
3075             pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo());
3076 
3077         if (!expression_cstr || *expression_cstr == '\0')
3078         {
3079             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
3080             list->Append(root);
3081             return 1;
3082         }
3083 
3084         switch (*expression_cstr)
3085         {
3086             case '[':
3087             {
3088                 if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray) && !root_clang_type_info.Test(ClangASTType::eTypeIsPointer)) // if this is not a T[] nor a T*
3089                 {
3090                     if (!root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong!
3091                     {
3092                         *first_unparsed = expression_cstr;
3093                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
3094                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3095                         return 0;
3096                     }
3097                     else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
3098                     {
3099                         *first_unparsed = expression_cstr;
3100                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
3101                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3102                         return 0;
3103                     }
3104                 }
3105                 if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
3106                 {
3107                     if (!root_clang_type_info.Test(ClangASTType::eTypeIsArray))
3108                     {
3109                         *first_unparsed = expression_cstr;
3110                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
3111                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3112                         return 0;
3113                     }
3114                     else // expand this into list
3115                     {
3116                         const size_t max_index = root->GetNumChildren() - 1;
3117                         for (size_t index = 0; index < max_index; index++)
3118                         {
3119                             ValueObjectSP child =
3120                                 root->GetChildAtIndex(index, true);
3121                             list->Append(child);
3122                         }
3123                         *first_unparsed = expression_cstr+2;
3124                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3125                         *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
3126                         return max_index; // tell me number of items I added to the VOList
3127                     }
3128                 }
3129                 const char *separator_position = ::strchr(expression_cstr+1,'-');
3130                 const char *close_bracket_position = ::strchr(expression_cstr+1,']');
3131                 if (!close_bracket_position) // if there is no ], this is a syntax error
3132                 {
3133                     *first_unparsed = expression_cstr;
3134                     *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3135                     *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3136                     return 0;
3137                 }
3138                 if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
3139                 {
3140                     char *end = NULL;
3141                     unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
3142                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
3143                     {
3144                         *first_unparsed = expression_cstr;
3145                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3146                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3147                         return 0;
3148                     }
3149                     if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
3150                     {
3151                         if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
3152                         {
3153                             const size_t max_index = root->GetNumChildren() - 1;
3154                             for (size_t index = 0; index < max_index; index++)
3155                             {
3156                                 ValueObjectSP child =
3157                                 root->GetChildAtIndex(index, true);
3158                                 list->Append(child);
3159                             }
3160                             *first_unparsed = expression_cstr+2;
3161                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3162                             *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
3163                             return max_index; // tell me number of items I added to the VOList
3164                         }
3165                         else
3166                         {
3167                             *first_unparsed = expression_cstr;
3168                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
3169                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3170                             return 0;
3171                         }
3172                     }
3173                     // from here on we do have a valid index
3174                     if (root_clang_type_info.Test(ClangASTType::eTypeIsArray))
3175                     {
3176                         root = root->GetChildAtIndex(index, true);
3177                         if (!root.get())
3178                         {
3179                             *first_unparsed = expression_cstr;
3180                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3181                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3182                             return 0;
3183                         }
3184                         else
3185                         {
3186                             list->Append(root);
3187                             *first_unparsed = end+1; // skip ]
3188                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3189                             *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
3190                             return 1;
3191                         }
3192                     }
3193                     else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer))
3194                     {
3195                         if (*what_next == ValueObject::eExpressionPathAftermathDereference &&  // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
3196                             pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
3197                         {
3198                             Error error;
3199                             root = root->Dereference(error);
3200                             if (error.Fail() || !root.get())
3201                             {
3202                                 *first_unparsed = expression_cstr;
3203                                 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
3204                                 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3205                                 return 0;
3206                             }
3207                             else
3208                             {
3209                                 *what_next = eExpressionPathAftermathNothing;
3210                                 continue;
3211                             }
3212                         }
3213                         else
3214                         {
3215                             root = root->GetSyntheticArrayMemberFromPointer(index, true);
3216                             if (!root.get())
3217                             {
3218                                 *first_unparsed = expression_cstr;
3219                                 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3220                                 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3221                                 return 0;
3222                             }
3223                             else
3224                             {
3225                                 list->Append(root);
3226                                 *first_unparsed = end+1; // skip ]
3227                                 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3228                                 *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
3229                                 return 1;
3230                             }
3231                         }
3232                     }
3233                     else /*if (ClangASTContext::IsScalarType(root_clang_type))*/
3234                     {
3235                         root = root->GetSyntheticBitFieldChild(index, index, true);
3236                         if (!root.get())
3237                         {
3238                             *first_unparsed = expression_cstr;
3239                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3240                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3241                             return 0;
3242                         }
3243                         else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
3244                         {
3245                             list->Append(root);
3246                             *first_unparsed = end+1; // skip ]
3247                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3248                             *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
3249                             return 1;
3250                         }
3251                     }
3252                 }
3253                 else // we have a low and a high index
3254                 {
3255                     char *end = NULL;
3256                     unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
3257                     if (!end || end != separator_position) // if something weird is in our way return an error
3258                     {
3259                         *first_unparsed = expression_cstr;
3260                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3261                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3262                         return 0;
3263                     }
3264                     unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
3265                     if (!end || end != close_bracket_position) // if something weird is in our way return an error
3266                     {
3267                         *first_unparsed = expression_cstr;
3268                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3269                         *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3270                         return 0;
3271                     }
3272                     if (index_lower > index_higher) // swap indices if required
3273                     {
3274                         unsigned long temp = index_lower;
3275                         index_lower = index_higher;
3276                         index_higher = temp;
3277                     }
3278                     if (root_clang_type_info.Test(ClangASTType::eTypeIsScalar)) // expansion only works for scalars
3279                     {
3280                         root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
3281                         if (!root.get())
3282                         {
3283                             *first_unparsed = expression_cstr;
3284                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
3285                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3286                             return 0;
3287                         }
3288                         else
3289                         {
3290                             list->Append(root);
3291                             *first_unparsed = end+1; // skip ]
3292                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3293                             *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
3294                             return 1;
3295                         }
3296                     }
3297                     else if (root_clang_type_info.Test(ClangASTType::eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield
3298                              *what_next == ValueObject::eExpressionPathAftermathDereference &&
3299                              pointee_clang_type_info.Test(ClangASTType::eTypeIsScalar))
3300                     {
3301                         Error error;
3302                         root = root->Dereference(error);
3303                         if (error.Fail() || !root.get())
3304                         {
3305                             *first_unparsed = expression_cstr;
3306                             *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
3307                             *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3308                             return 0;
3309                         }
3310                         else
3311                         {
3312                             *what_next = ValueObject::eExpressionPathAftermathNothing;
3313                             continue;
3314                         }
3315                     }
3316                     else
3317                     {
3318                         for (unsigned long index = index_lower;
3319                              index <= index_higher; index++)
3320                         {
3321                             ValueObjectSP child =
3322                                 root->GetChildAtIndex(index, true);
3323                             list->Append(child);
3324                         }
3325                         *first_unparsed = end+1;
3326                         *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
3327                         *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
3328                         return index_higher-index_lower+1; // tell me number of items I added to the VOList
3329                     }
3330                 }
3331                 break;
3332             }
3333             default: // some non-[ separator, or something entirely wrong, is in the way
3334             {
3335                 *first_unparsed = expression_cstr;
3336                 *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
3337                 *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
3338                 return 0;
3339                 break;
3340             }
3341         }
3342     }
3343 }
3344 
3345 static void
DumpValueObject_Impl(Stream & s,ValueObject * valobj,const ValueObject::DumpValueObjectOptions & options,uint32_t ptr_depth,uint32_t curr_depth)3346 DumpValueObject_Impl (Stream &s,
3347                       ValueObject *valobj,
3348                       const ValueObject::DumpValueObjectOptions& options,
3349                       uint32_t ptr_depth,
3350                       uint32_t curr_depth)
3351 {
3352     if (valobj)
3353     {
3354         bool update_success = valobj->UpdateValueIfNeeded (true);
3355 
3356         const char *root_valobj_name =
3357             options.m_root_valobj_name.empty() ?
3358                 valobj->GetName().AsCString() :
3359                 options.m_root_valobj_name.c_str();
3360 
3361         if (update_success && options.m_use_dynamic != eNoDynamicValues)
3362         {
3363             ValueObject *dynamic_value = valobj->GetDynamicValue(options.m_use_dynamic).get();
3364             if (dynamic_value)
3365                 valobj = dynamic_value;
3366         }
3367 
3368         ClangASTType clang_type = valobj->GetClangType();
3369         const Flags type_flags (clang_type.GetTypeInfo ());
3370         const char *err_cstr = NULL;
3371         const bool has_children = type_flags.Test (ClangASTType::eTypeHasChildren);
3372         const bool has_value = type_flags.Test (ClangASTType::eTypeHasValue);
3373 
3374         const bool print_valobj = options.m_flat_output == false || has_value;
3375 
3376         if (print_valobj)
3377         {
3378             if (options.m_show_location)
3379             {
3380                 s.Printf("%s: ", valobj->GetLocationAsCString());
3381             }
3382 
3383             s.Indent();
3384 
3385             bool show_type = true;
3386             // if we are at the root-level and been asked to hide the root's type, then hide it
3387             if (curr_depth == 0 && options.m_hide_root_type)
3388                 show_type = false;
3389             else
3390             // otherwise decide according to the usual rules (asked to show types - always at the root level)
3391                 show_type = options.m_show_types || (curr_depth == 0 && !options.m_flat_output);
3392 
3393             if (show_type)
3394             {
3395                 // Some ValueObjects don't have types (like registers sets). Only print
3396                 // the type if there is one to print
3397                 ConstString qualified_type_name(valobj->GetQualifiedTypeName());
3398                 if (qualified_type_name)
3399                     s.Printf("(%s) ", qualified_type_name.GetCString());
3400             }
3401 
3402             if (options.m_flat_output)
3403             {
3404                 // If we are showing types, also qualify the C++ base classes
3405                 const bool qualify_cxx_base_classes = options.m_show_types;
3406                 if (!options.m_hide_name)
3407                 {
3408                     valobj->GetExpressionPath(s, qualify_cxx_base_classes);
3409                     s.PutCString(" =");
3410                 }
3411             }
3412             else if (!options.m_hide_name)
3413             {
3414                 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
3415                 s.Printf ("%s =", name_cstr);
3416             }
3417 
3418             if (!options.m_scope_already_checked && !valobj->IsInScope())
3419             {
3420                 err_cstr = "out of scope";
3421             }
3422         }
3423 
3424         std::string summary_str;
3425         std::string value_str;
3426         const char *val_cstr = NULL;
3427         const char *sum_cstr = NULL;
3428         TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : valobj->GetSummaryFormat().get();
3429 
3430         if (options.m_omit_summary_depth > 0)
3431             entry = NULL;
3432 
3433         bool is_nil = valobj->IsObjCNil();
3434 
3435         if (err_cstr == NULL)
3436         {
3437             if (options.m_format != eFormatDefault && options.m_format != valobj->GetFormat())
3438             {
3439                 valobj->GetValueAsCString(options.m_format,
3440                                           value_str);
3441             }
3442             else
3443             {
3444                 val_cstr = valobj->GetValueAsCString();
3445                 if (val_cstr)
3446                     value_str = val_cstr;
3447             }
3448             err_cstr = valobj->GetError().AsCString();
3449         }
3450 
3451         if (err_cstr)
3452         {
3453             s.Printf (" <%s>\n", err_cstr);
3454         }
3455         else
3456         {
3457             const bool is_ref = type_flags.Test (ClangASTType::eTypeIsReference);
3458             if (print_valobj)
3459             {
3460                 if (is_nil)
3461                     sum_cstr = "nil";
3462                 else if (options.m_omit_summary_depth == 0)
3463                 {
3464                     if (options.m_summary_sp)
3465                     {
3466                         valobj->GetSummaryAsCString(entry, summary_str);
3467                         sum_cstr = summary_str.c_str();
3468                     }
3469                     else
3470                         sum_cstr = valobj->GetSummaryAsCString();
3471                 }
3472 
3473                 // Make sure we have a value and make sure the summary didn't
3474                 // specify that the value should not be printed - and do not print
3475                 // the value if this thing is nil
3476                 // (but show the value if the user passes a format explicitly)
3477                 if (!is_nil && !value_str.empty() && (entry == NULL || (entry->DoesPrintValue() || options.m_format != eFormatDefault) || sum_cstr == NULL) && !options.m_hide_value)
3478                     s.Printf(" %s", value_str.c_str());
3479 
3480                 if (sum_cstr)
3481                     s.Printf(" %s", sum_cstr);
3482 
3483                 // let's avoid the overly verbose no description error for a nil thing
3484                 if (options.m_use_objc && !is_nil)
3485                 {
3486                     if (!options.m_hide_value || !options.m_hide_name)
3487                         s.Printf(" ");
3488                     const char *object_desc = valobj->GetObjectDescription();
3489                     if (object_desc)
3490                         s.Printf("%s\n", object_desc);
3491                     else
3492                         s.Printf ("[no Objective-C description available]\n");
3493                     return;
3494                 }
3495             }
3496 
3497             if (curr_depth < options.m_max_depth)
3498             {
3499                 // We will show children for all concrete types. We won't show
3500                 // pointer contents unless a pointer depth has been specified.
3501                 // We won't reference contents unless the reference is the
3502                 // root object (depth of zero).
3503                 bool print_children = true;
3504 
3505                 // Use a new temporary pointer depth in case we override the
3506                 // current pointer depth below...
3507                 uint32_t curr_ptr_depth = ptr_depth;
3508 
3509                 const bool is_ptr = type_flags.Test (ClangASTType::eTypeIsPointer);
3510                 if (is_ptr || is_ref)
3511                 {
3512                     // We have a pointer or reference whose value is an address.
3513                     // Make sure that address is not NULL
3514                     AddressType ptr_address_type;
3515                     if (valobj->GetPointerValue (&ptr_address_type) == 0)
3516                         print_children = false;
3517 
3518                     else if (is_ref && curr_depth == 0)
3519                     {
3520                         // If this is the root object (depth is zero) that we are showing
3521                         // and it is a reference, and no pointer depth has been supplied
3522                         // print out what it references. Don't do this at deeper depths
3523                         // otherwise we can end up with infinite recursion...
3524                         curr_ptr_depth = 1;
3525                     }
3526 
3527                     if (curr_ptr_depth == 0)
3528                         print_children = false;
3529                 }
3530 
3531                 if (print_children && (!entry || entry->DoesPrintChildren() || !sum_cstr))
3532                 {
3533                     ValueObjectSP synth_valobj_sp = valobj->GetSyntheticValue (options.m_use_synthetic);
3534                     ValueObject* synth_valobj = (synth_valobj_sp ? synth_valobj_sp.get() : valobj);
3535 
3536                     size_t num_children = synth_valobj->GetNumChildren();
3537                     bool print_dotdotdot = false;
3538                     if (num_children)
3539                     {
3540                         if (options.m_flat_output)
3541                         {
3542                             if (print_valobj)
3543                                 s.EOL();
3544                         }
3545                         else
3546                         {
3547                             if (print_valobj)
3548                                 s.PutCString(is_ref ? ": {\n" : " {\n");
3549                             s.IndentMore();
3550                         }
3551 
3552                         const size_t max_num_children = valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
3553 
3554                         if (num_children > max_num_children && !options.m_ignore_cap)
3555                         {
3556                             num_children = max_num_children;
3557                             print_dotdotdot = true;
3558                         }
3559 
3560                         ValueObject::DumpValueObjectOptions child_options(options);
3561                         child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
3562                         child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
3563                         .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
3564                         for (size_t idx=0; idx<num_children; ++idx)
3565                         {
3566                             ValueObjectSP child_sp(synth_valobj->GetChildAtIndex(idx, true));
3567                             if (child_sp.get())
3568                             {
3569                                 DumpValueObject_Impl (s,
3570                                                       child_sp.get(),
3571                                                       child_options,
3572                                                       (is_ptr || is_ref) ? curr_ptr_depth - 1 : curr_ptr_depth,
3573                                                       curr_depth + 1);
3574                             }
3575                         }
3576 
3577                         if (!options.m_flat_output)
3578                         {
3579                             if (print_dotdotdot)
3580                             {
3581                                 ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
3582                                 Target *target = exe_ctx.GetTargetPtr();
3583                                 if (target)
3584                                     target->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
3585                                 s.Indent("...\n");
3586                             }
3587                             s.IndentLess();
3588                             s.Indent("}\n");
3589                         }
3590                     }
3591                     else if (has_children)
3592                     {
3593                         // Aggregate, no children...
3594                         if (print_valobj)
3595                             s.PutCString(" {}\n");
3596                     }
3597                     else
3598                     {
3599                         if (print_valobj)
3600                             s.EOL();
3601                     }
3602 
3603                 }
3604                 else
3605                 {
3606                     s.EOL();
3607                 }
3608             }
3609             else
3610             {
3611                 if (has_children && print_valobj)
3612                 {
3613                     s.PutCString("{...}\n");
3614                 }
3615             }
3616         }
3617     }
3618 }
3619 
3620 void
LogValueObject(Log * log,ValueObject * valobj)3621 ValueObject::LogValueObject (Log *log,
3622                              ValueObject *valobj)
3623 {
3624     if (log && valobj)
3625         return LogValueObject (log, valobj, DumpValueObjectOptions::DefaultOptions());
3626 }
3627 
3628 void
LogValueObject(Log * log,ValueObject * valobj,const DumpValueObjectOptions & options)3629 ValueObject::LogValueObject (Log *log,
3630                              ValueObject *valobj,
3631                              const DumpValueObjectOptions& options)
3632 {
3633     if (log && valobj)
3634     {
3635         StreamString s;
3636         ValueObject::DumpValueObject (s, valobj, options);
3637         if (s.GetSize())
3638             log->PutCString(s.GetData());
3639     }
3640 }
3641 
3642 void
DumpValueObject(Stream & s,ValueObject * valobj)3643 ValueObject::DumpValueObject (Stream &s,
3644                               ValueObject *valobj)
3645 {
3646 
3647     if (!valobj)
3648         return;
3649 
3650     DumpValueObject_Impl(s,
3651                          valobj,
3652                          DumpValueObjectOptions::DefaultOptions(),
3653                          0,
3654                          0);
3655 }
3656 
3657 void
DumpValueObject(Stream & s,ValueObject * valobj,const DumpValueObjectOptions & options)3658 ValueObject::DumpValueObject (Stream &s,
3659                               ValueObject *valobj,
3660                               const DumpValueObjectOptions& options)
3661 {
3662     DumpValueObject_Impl(s,
3663                          valobj,
3664                          options,
3665                          options.m_max_ptr_depth, // max pointer depth allowed, we will go down from here
3666                          0 // current object depth is 0 since we are just starting
3667                          );
3668 }
3669 
3670 ValueObjectSP
CreateConstantValue(const ConstString & name)3671 ValueObject::CreateConstantValue (const ConstString &name)
3672 {
3673     ValueObjectSP valobj_sp;
3674 
3675     if (UpdateValueIfNeeded(false) && m_error.Success())
3676     {
3677         ExecutionContext exe_ctx (GetExecutionContextRef());
3678 
3679         DataExtractor data;
3680         data.SetByteOrder (m_data.GetByteOrder());
3681         data.SetAddressByteSize(m_data.GetAddressByteSize());
3682 
3683         if (IsBitfield())
3684         {
3685             Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
3686             m_error = v.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
3687         }
3688         else
3689             m_error = m_value.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
3690 
3691         valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
3692                                                     GetClangType(),
3693                                                     name,
3694                                                     data,
3695                                                     GetAddressOf());
3696     }
3697 
3698     if (!valobj_sp)
3699     {
3700         valobj_sp = ValueObjectConstResult::Create (NULL, m_error);
3701     }
3702     return valobj_sp;
3703 }
3704 
3705 ValueObjectSP
Dereference(Error & error)3706 ValueObject::Dereference (Error &error)
3707 {
3708     if (m_deref_valobj)
3709         return m_deref_valobj->GetSP();
3710 
3711     const bool is_pointer_type = IsPointerType();
3712     if (is_pointer_type)
3713     {
3714         bool omit_empty_base_classes = true;
3715         bool ignore_array_bounds = false;
3716 
3717         std::string child_name_str;
3718         uint32_t child_byte_size = 0;
3719         int32_t child_byte_offset = 0;
3720         uint32_t child_bitfield_bit_size = 0;
3721         uint32_t child_bitfield_bit_offset = 0;
3722         bool child_is_base_class = false;
3723         bool child_is_deref_of_parent = false;
3724         const bool transparent_pointers = false;
3725         ClangASTType clang_type = GetClangType();
3726         ClangASTType child_clang_type;
3727 
3728         ExecutionContext exe_ctx (GetExecutionContextRef());
3729 
3730         child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx,
3731                                                                 GetName().GetCString(),
3732                                                                 0,
3733                                                                 transparent_pointers,
3734                                                                 omit_empty_base_classes,
3735                                                                 ignore_array_bounds,
3736                                                                 child_name_str,
3737                                                                 child_byte_size,
3738                                                                 child_byte_offset,
3739                                                                 child_bitfield_bit_size,
3740                                                                 child_bitfield_bit_offset,
3741                                                                 child_is_base_class,
3742                                                                 child_is_deref_of_parent);
3743         if (child_clang_type && child_byte_size)
3744         {
3745             ConstString child_name;
3746             if (!child_name_str.empty())
3747                 child_name.SetCString (child_name_str.c_str());
3748 
3749             m_deref_valobj = new ValueObjectChild (*this,
3750                                                    child_clang_type,
3751                                                    child_name,
3752                                                    child_byte_size,
3753                                                    child_byte_offset,
3754                                                    child_bitfield_bit_size,
3755                                                    child_bitfield_bit_offset,
3756                                                    child_is_base_class,
3757                                                    child_is_deref_of_parent,
3758                                                    eAddressTypeInvalid);
3759         }
3760     }
3761 
3762     if (m_deref_valobj)
3763     {
3764         error.Clear();
3765         return m_deref_valobj->GetSP();
3766     }
3767     else
3768     {
3769         StreamString strm;
3770         GetExpressionPath(strm, true);
3771 
3772         if (is_pointer_type)
3773             error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
3774         else
3775             error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
3776         return ValueObjectSP();
3777     }
3778 }
3779 
3780 ValueObjectSP
AddressOf(Error & error)3781 ValueObject::AddressOf (Error &error)
3782 {
3783     if (m_addr_of_valobj_sp)
3784         return m_addr_of_valobj_sp;
3785 
3786     AddressType address_type = eAddressTypeInvalid;
3787     const bool scalar_is_load_address = false;
3788     addr_t addr = GetAddressOf (scalar_is_load_address, &address_type);
3789     error.Clear();
3790     if (addr != LLDB_INVALID_ADDRESS)
3791     {
3792         switch (address_type)
3793         {
3794         case eAddressTypeInvalid:
3795             {
3796                 StreamString expr_path_strm;
3797                 GetExpressionPath(expr_path_strm, true);
3798                 error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
3799             }
3800             break;
3801 
3802         case eAddressTypeFile:
3803         case eAddressTypeLoad:
3804         case eAddressTypeHost:
3805             {
3806                 ClangASTType clang_type = GetClangType();
3807                 if (clang_type)
3808                 {
3809                     std::string name (1, '&');
3810                     name.append (m_name.AsCString(""));
3811                     ExecutionContext exe_ctx (GetExecutionContextRef());
3812                     m_addr_of_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
3813                                                                           clang_type.GetPointerType(),
3814                                                                           ConstString (name.c_str()),
3815                                                                           addr,
3816                                                                           eAddressTypeInvalid,
3817                                                                           m_data.GetAddressByteSize());
3818                 }
3819             }
3820             break;
3821         }
3822     }
3823     else
3824     {
3825         StreamString expr_path_strm;
3826         GetExpressionPath(expr_path_strm, true);
3827         error.SetErrorStringWithFormat("'%s' doesn't have a valid address", expr_path_strm.GetString().c_str());
3828     }
3829 
3830     return m_addr_of_valobj_sp;
3831 }
3832 
3833 ValueObjectSP
Cast(const ClangASTType & clang_ast_type)3834 ValueObject::Cast (const ClangASTType &clang_ast_type)
3835 {
3836     return ValueObjectCast::Create (*this, GetName(), clang_ast_type);
3837 }
3838 
3839 ValueObjectSP
CastPointerType(const char * name,ClangASTType & clang_ast_type)3840 ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type)
3841 {
3842     ValueObjectSP valobj_sp;
3843     AddressType address_type;
3844     addr_t ptr_value = GetPointerValue (&address_type);
3845 
3846     if (ptr_value != LLDB_INVALID_ADDRESS)
3847     {
3848         Address ptr_addr (ptr_value);
3849         ExecutionContext exe_ctx (GetExecutionContextRef());
3850         valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(),
3851                                                name,
3852                                                ptr_addr,
3853                                                clang_ast_type);
3854     }
3855     return valobj_sp;
3856 }
3857 
3858 ValueObjectSP
CastPointerType(const char * name,TypeSP & type_sp)3859 ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
3860 {
3861     ValueObjectSP valobj_sp;
3862     AddressType address_type;
3863     addr_t ptr_value = GetPointerValue (&address_type);
3864 
3865     if (ptr_value != LLDB_INVALID_ADDRESS)
3866     {
3867         Address ptr_addr (ptr_value);
3868         ExecutionContext exe_ctx (GetExecutionContextRef());
3869         valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(),
3870                                                name,
3871                                                ptr_addr,
3872                                                type_sp);
3873     }
3874     return valobj_sp;
3875 }
3876 
EvaluationPoint()3877 ValueObject::EvaluationPoint::EvaluationPoint () :
3878     m_mod_id(),
3879     m_exe_ctx_ref(),
3880     m_needs_update (true),
3881     m_first_update (true)
3882 {
3883 }
3884 
EvaluationPoint(ExecutionContextScope * exe_scope,bool use_selected)3885 ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
3886     m_mod_id(),
3887     m_exe_ctx_ref(),
3888     m_needs_update (true),
3889     m_first_update (true)
3890 {
3891     ExecutionContext exe_ctx(exe_scope);
3892     TargetSP target_sp (exe_ctx.GetTargetSP());
3893     if (target_sp)
3894     {
3895         m_exe_ctx_ref.SetTargetSP (target_sp);
3896         ProcessSP process_sp (exe_ctx.GetProcessSP());
3897         if (!process_sp)
3898             process_sp = target_sp->GetProcessSP();
3899 
3900         if (process_sp)
3901         {
3902             m_mod_id = process_sp->GetModID();
3903             m_exe_ctx_ref.SetProcessSP (process_sp);
3904 
3905             ThreadSP thread_sp (exe_ctx.GetThreadSP());
3906 
3907             if (!thread_sp)
3908             {
3909                 if (use_selected)
3910                     thread_sp = process_sp->GetThreadList().GetSelectedThread();
3911             }
3912 
3913             if (thread_sp)
3914             {
3915                 m_exe_ctx_ref.SetThreadSP(thread_sp);
3916 
3917                 StackFrameSP frame_sp (exe_ctx.GetFrameSP());
3918                 if (!frame_sp)
3919                 {
3920                     if (use_selected)
3921                         frame_sp = thread_sp->GetSelectedFrame();
3922                 }
3923                 if (frame_sp)
3924                     m_exe_ctx_ref.SetFrameSP(frame_sp);
3925             }
3926         }
3927     }
3928 }
3929 
EvaluationPoint(const ValueObject::EvaluationPoint & rhs)3930 ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
3931     m_mod_id(),
3932     m_exe_ctx_ref(rhs.m_exe_ctx_ref),
3933     m_needs_update (true),
3934     m_first_update (true)
3935 {
3936 }
3937 
~EvaluationPoint()3938 ValueObject::EvaluationPoint::~EvaluationPoint ()
3939 {
3940 }
3941 
3942 // This function checks the EvaluationPoint against the current process state.  If the current
3943 // state matches the evaluation point, or the evaluation point is already invalid, then we return
3944 // false, meaning "no change".  If the current state is different, we update our state, and return
3945 // true meaning "yes, change".  If we did see a change, we also set m_needs_update to true, so
3946 // future calls to NeedsUpdate will return true.
3947 // exe_scope will be set to the current execution context scope.
3948 
3949 bool
SyncWithProcessState()3950 ValueObject::EvaluationPoint::SyncWithProcessState()
3951 {
3952 
3953     // Start with the target, if it is NULL, then we're obviously not going to get any further:
3954     ExecutionContext exe_ctx(m_exe_ctx_ref.Lock());
3955 
3956     if (exe_ctx.GetTargetPtr() == NULL)
3957         return false;
3958 
3959     // If we don't have a process nothing can change.
3960     Process *process = exe_ctx.GetProcessPtr();
3961     if (process == NULL)
3962         return false;
3963 
3964     // If our stop id is the current stop ID, nothing has changed:
3965     ProcessModID current_mod_id = process->GetModID();
3966 
3967     // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
3968     // In either case, we aren't going to be able to sync with the process state.
3969     if (current_mod_id.GetStopID() == 0)
3970         return false;
3971 
3972     bool changed = false;
3973     const bool was_valid = m_mod_id.IsValid();
3974     if (was_valid)
3975     {
3976         if (m_mod_id == current_mod_id)
3977         {
3978             // Everything is already up to date in this object, no need to
3979             // update the execution context scope.
3980             changed = false;
3981         }
3982         else
3983         {
3984             m_mod_id = current_mod_id;
3985             m_needs_update = true;
3986             changed = true;
3987         }
3988     }
3989 
3990     // Now re-look up the thread and frame in case the underlying objects have gone away & been recreated.
3991     // That way we'll be sure to return a valid exe_scope.
3992     // If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid.
3993 
3994     if (m_exe_ctx_ref.HasThreadRef())
3995     {
3996         ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP());
3997         if (thread_sp)
3998         {
3999             if (m_exe_ctx_ref.HasFrameRef())
4000             {
4001                 StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP());
4002                 if (!frame_sp)
4003                 {
4004                     // We used to have a frame, but now it is gone
4005                     SetInvalid();
4006                     changed = was_valid;
4007                 }
4008             }
4009         }
4010         else
4011         {
4012             // We used to have a thread, but now it is gone
4013             SetInvalid();
4014             changed = was_valid;
4015         }
4016 
4017     }
4018     return changed;
4019 }
4020 
4021 void
SetUpdated()4022 ValueObject::EvaluationPoint::SetUpdated ()
4023 {
4024     ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
4025     if (process_sp)
4026         m_mod_id = process_sp->GetModID();
4027     m_first_update = false;
4028     m_needs_update = false;
4029 }
4030 
4031 
4032 
4033 void
ClearUserVisibleData(uint32_t clear_mask)4034 ValueObject::ClearUserVisibleData(uint32_t clear_mask)
4035 {
4036     if ((clear_mask & eClearUserVisibleDataItemsValue) == eClearUserVisibleDataItemsValue)
4037         m_value_str.clear();
4038 
4039     if ((clear_mask & eClearUserVisibleDataItemsLocation) == eClearUserVisibleDataItemsLocation)
4040         m_location_str.clear();
4041 
4042     if ((clear_mask & eClearUserVisibleDataItemsSummary) == eClearUserVisibleDataItemsSummary)
4043     {
4044         m_summary_str.clear();
4045     }
4046 
4047     if ((clear_mask & eClearUserVisibleDataItemsDescription) == eClearUserVisibleDataItemsDescription)
4048         m_object_desc_str.clear();
4049 
4050     if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) == eClearUserVisibleDataItemsSyntheticChildren)
4051     {
4052             if (m_synthetic_value)
4053                 m_synthetic_value = NULL;
4054     }
4055 }
4056 
4057 SymbolContextScope *
GetSymbolContextScope()4058 ValueObject::GetSymbolContextScope()
4059 {
4060     if (m_parent)
4061     {
4062         if (!m_parent->IsPointerOrReferenceType())
4063             return m_parent->GetSymbolContextScope();
4064     }
4065     return NULL;
4066 }
4067 
4068 lldb::ValueObjectSP
CreateValueObjectFromExpression(const char * name,const char * expression,const ExecutionContext & exe_ctx)4069 ValueObject::CreateValueObjectFromExpression (const char* name,
4070                                               const char* expression,
4071                                               const ExecutionContext& exe_ctx)
4072 {
4073     lldb::ValueObjectSP retval_sp;
4074     lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
4075     if (!target_sp)
4076         return retval_sp;
4077     if (!expression || !*expression)
4078         return retval_sp;
4079     target_sp->EvaluateExpression (expression,
4080                                    exe_ctx.GetFrameSP().get(),
4081                                    retval_sp);
4082     if (retval_sp && name && *name)
4083         retval_sp->SetName(ConstString(name));
4084     return retval_sp;
4085 }
4086 
4087 lldb::ValueObjectSP
CreateValueObjectFromAddress(const char * name,uint64_t address,const ExecutionContext & exe_ctx,ClangASTType type)4088 ValueObject::CreateValueObjectFromAddress (const char* name,
4089                                            uint64_t address,
4090                                            const ExecutionContext& exe_ctx,
4091                                            ClangASTType type)
4092 {
4093     if (type)
4094     {
4095         ClangASTType pointer_type(type.GetPointerType());
4096         if (pointer_type)
4097         {
4098             lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
4099             lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
4100                                                                                      pointer_type,
4101                                                                                      ConstString(name),
4102                                                                                      buffer,
4103                                                                                      lldb::endian::InlHostByteOrder(),
4104                                                                                      exe_ctx.GetAddressByteSize()));
4105             if (ptr_result_valobj_sp)
4106             {
4107                 ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
4108                 Error err;
4109                 ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
4110                 if (ptr_result_valobj_sp && name && *name)
4111                     ptr_result_valobj_sp->SetName(ConstString(name));
4112             }
4113             return ptr_result_valobj_sp;
4114         }
4115     }
4116     return lldb::ValueObjectSP();
4117 }
4118 
4119 lldb::ValueObjectSP
CreateValueObjectFromData(const char * name,DataExtractor & data,const ExecutionContext & exe_ctx,ClangASTType type)4120 ValueObject::CreateValueObjectFromData (const char* name,
4121                                         DataExtractor& data,
4122                                         const ExecutionContext& exe_ctx,
4123                                         ClangASTType type)
4124 {
4125     lldb::ValueObjectSP new_value_sp;
4126     new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
4127                                                    type,
4128                                                    ConstString(name),
4129                                                    data,
4130                                                    LLDB_INVALID_ADDRESS);
4131     new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
4132     if (new_value_sp && name && *name)
4133         new_value_sp->SetName(ConstString(name));
4134     return new_value_sp;
4135 }
4136 
4137 ModuleSP
GetModule()4138 ValueObject::GetModule ()
4139 {
4140     ValueObject* root(GetRoot());
4141     if (root != this)
4142         return root->GetModule();
4143     return lldb::ModuleSP();
4144 }
4145 
4146 ValueObject*
GetRoot()4147 ValueObject::GetRoot ()
4148 {
4149     if (m_root)
4150         return m_root;
4151     ValueObject* parent = m_parent;
4152     if (!parent)
4153         return (m_root = this);
4154     while (parent->m_parent)
4155     {
4156         if (parent->m_root)
4157             return (m_root = parent->m_root);
4158         parent = parent->m_parent;
4159     }
4160     return (m_root = parent);
4161 }
4162 
4163 AddressType
GetAddressTypeOfChildren()4164 ValueObject::GetAddressTypeOfChildren()
4165 {
4166     if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid)
4167     {
4168         ValueObject* root(GetRoot());
4169         if (root != this)
4170             return root->GetAddressTypeOfChildren();
4171     }
4172     return m_address_type_of_ptr_or_ref_children;
4173 }
4174 
4175 lldb::DynamicValueType
GetDynamicValueType()4176 ValueObject::GetDynamicValueType ()
4177 {
4178     ValueObject* with_dv_info = this;
4179     while (with_dv_info)
4180     {
4181         if (with_dv_info->HasDynamicValueTypeInfo())
4182             return with_dv_info->GetDynamicValueTypeImpl();
4183         with_dv_info = with_dv_info->m_parent;
4184     }
4185     return lldb::eNoDynamicValues;
4186 }
4187 
4188 lldb::Format
GetFormat() const4189 ValueObject::GetFormat () const
4190 {
4191     const ValueObject* with_fmt_info = this;
4192     while (with_fmt_info)
4193     {
4194         if (with_fmt_info->m_format != lldb::eFormatDefault)
4195             return with_fmt_info->m_format;
4196         with_fmt_info = with_fmt_info->m_parent;
4197     }
4198     return m_format;
4199 }
4200