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