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