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