1 //===-- ValueObject.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/ValueObject.h"
11 
12 // C Includes
13 #include <stdlib.h>
14 
15 // C++ Includes
16 // Other libraries and framework includes
17 #include "llvm/Support/raw_ostream.h"
18 #include "clang/AST/Type.h"
19 
20 // Project includes
21 #include "lldb/Core/DataBufferHeap.h"
22 #include "lldb/Core/StreamString.h"
23 #include "lldb/Core/ValueObjectChild.h"
24 #include "lldb/Core/ValueObjectList.h"
25 
26 #include "lldb/Symbol/ClangASTType.h"
27 #include "lldb/Symbol/ClangASTContext.h"
28 #include "lldb/Symbol/Type.h"
29 
30 #include "lldb/Target/ExecutionContext.h"
31 #include "lldb/Target/LanguageRuntime.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/RegisterContext.h"
34 #include "lldb/Target/Target.h"
35 #include "lldb/Target/Thread.h"
36 
37 using namespace lldb;
38 using namespace lldb_private;
39 
40 static lldb::user_id_t g_value_obj_uid = 0;
41 
42 //----------------------------------------------------------------------
43 // ValueObject constructor
44 //----------------------------------------------------------------------
45 ValueObject::ValueObject (ValueObject *parent) :
46     UserID (++g_value_obj_uid), // Unique identifier for every value object
47     m_parent (parent),
48     m_update_id (0),    // Value object lists always start at 1, value objects start at zero
49     m_name (),
50     m_data (),
51     m_value (),
52     m_error (),
53     m_value_str (),
54     m_old_value_str (),
55     m_location_str (),
56     m_summary_str (),
57     m_object_desc_str (),
58     m_children (),
59     m_synthetic_children (),
60     m_dynamic_value_sp (),
61     m_format (eFormatDefault),
62     m_value_is_valid (false),
63     m_value_did_change (false),
64     m_children_count_valid (false),
65     m_old_value_valid (false)
66 {
67 }
68 
69 //----------------------------------------------------------------------
70 // Destructor
71 //----------------------------------------------------------------------
72 ValueObject::~ValueObject ()
73 {
74 }
75 
76 user_id_t
77 ValueObject::GetUpdateID() const
78 {
79     return m_update_id;
80 }
81 
82 bool
83 ValueObject::UpdateValueIfNeeded (ExecutionContextScope *exe_scope)
84 {
85     // If this is a constant value, then our success is predicated on whether
86     // we have an error or not
87     if (GetIsConstant())
88         return m_error.Success();
89 
90     if (exe_scope)
91     {
92         Process *process = exe_scope->CalculateProcess();
93         if (process)
94         {
95             const user_id_t stop_id = process->GetStopID();
96             if (m_update_id != stop_id)
97             {
98                 bool first_update = m_update_id == 0;
99                 // Save the old value using swap to avoid a string copy which
100                 // also will clear our m_value_str
101                 if (m_value_str.empty())
102                 {
103                     m_old_value_valid = false;
104                 }
105                 else
106                 {
107                     m_old_value_valid = true;
108                     m_old_value_str.swap (m_value_str);
109                     m_value_str.clear();
110                 }
111                 m_location_str.clear();
112                 m_summary_str.clear();
113                 m_object_desc_str.clear();
114 
115                 const bool value_was_valid = GetValueIsValid();
116                 SetValueDidChange (false);
117 
118                 m_error.Clear();
119 
120                 // Call the pure virtual function to update the value
121                 UpdateValue (exe_scope);
122 
123                 // Update the fact that we tried to update the value for this
124                 // value object whether or not we succeed
125                 m_update_id = stop_id;
126                 bool success = m_error.Success();
127                 SetValueIsValid (success);
128 
129                 if (first_update)
130                     SetValueDidChange (false);
131                 else if (!m_value_did_change && success == false)
132                 {
133                     // The value wasn't gotten successfully, so we mark this
134                     // as changed if the value used to be valid and now isn't
135                     SetValueDidChange (value_was_valid);
136                 }
137             }
138         }
139     }
140     return m_error.Success();
141 }
142 
143 const DataExtractor &
144 ValueObject::GetDataExtractor () const
145 {
146     return m_data;
147 }
148 
149 DataExtractor &
150 ValueObject::GetDataExtractor ()
151 {
152     return m_data;
153 }
154 
155 const Error &
156 ValueObject::GetError() const
157 {
158     return m_error;
159 }
160 
161 const ConstString &
162 ValueObject::GetName() const
163 {
164     return m_name;
165 }
166 
167 const char *
168 ValueObject::GetLocationAsCString (ExecutionContextScope *exe_scope)
169 {
170     if (UpdateValueIfNeeded(exe_scope))
171     {
172         if (m_location_str.empty())
173         {
174             StreamString sstr;
175 
176             switch (m_value.GetValueType())
177             {
178             default:
179                 break;
180 
181             case Value::eValueTypeScalar:
182                 if (m_value.GetContextType() == Value::eContextTypeDCRegisterInfo)
183                 {
184                     RegisterInfo *reg_info = m_value.GetRegisterInfo();
185                     if (reg_info)
186                     {
187                         if (reg_info->name)
188                             m_location_str = reg_info->name;
189                         else if (reg_info->alt_name)
190                             m_location_str = reg_info->alt_name;
191                         break;
192                     }
193                 }
194                 m_location_str = "scalar";
195                 break;
196 
197             case Value::eValueTypeLoadAddress:
198             case Value::eValueTypeFileAddress:
199             case Value::eValueTypeHostAddress:
200                 {
201                     uint32_t addr_nibble_size = m_data.GetAddressByteSize() * 2;
202                     sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
203                     m_location_str.swap(sstr.GetString());
204                 }
205                 break;
206             }
207         }
208     }
209     return m_location_str.c_str();
210 }
211 
212 Value &
213 ValueObject::GetValue()
214 {
215     return m_value;
216 }
217 
218 const Value &
219 ValueObject::GetValue() const
220 {
221     return m_value;
222 }
223 
224 bool
225 ValueObject::GetValueIsValid () const
226 {
227     return m_value_is_valid;
228 }
229 
230 
231 void
232 ValueObject::SetValueIsValid (bool b)
233 {
234     m_value_is_valid = b;
235 }
236 
237 bool
238 ValueObject::GetValueDidChange (ExecutionContextScope *exe_scope)
239 {
240     GetValueAsCString (exe_scope);
241     return m_value_did_change;
242 }
243 
244 void
245 ValueObject::SetValueDidChange (bool value_changed)
246 {
247     m_value_did_change = value_changed;
248 }
249 
250 ValueObjectSP
251 ValueObject::GetChildAtIndex (uint32_t idx, bool can_create)
252 {
253     ValueObjectSP child_sp;
254     if (idx < GetNumChildren())
255     {
256         // Check if we have already made the child value object?
257         if (can_create && m_children[idx].get() == NULL)
258         {
259             // No we haven't created the child at this index, so lets have our
260             // subclass do it and cache the result for quick future access.
261             m_children[idx] = CreateChildAtIndex (idx, false, 0);
262         }
263 
264         child_sp = m_children[idx];
265     }
266     return child_sp;
267 }
268 
269 uint32_t
270 ValueObject::GetIndexOfChildWithName (const ConstString &name)
271 {
272     bool omit_empty_base_classes = true;
273     return ClangASTContext::GetIndexOfChildWithName (GetClangAST(),
274                                                      GetClangType(),
275                                                      name.AsCString(),
276                                                      omit_empty_base_classes);
277 }
278 
279 ValueObjectSP
280 ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
281 {
282     // when getting a child by name, it could be burried inside some base
283     // classes (which really aren't part of the expression path), so we
284     // need a vector of indexes that can get us down to the correct child
285     std::vector<uint32_t> child_indexes;
286     clang::ASTContext *clang_ast = GetClangAST();
287     void *clang_type = GetClangType();
288     bool omit_empty_base_classes = true;
289     const size_t num_child_indexes =  ClangASTContext::GetIndexOfChildMemberWithName (clang_ast,
290                                                                                       clang_type,
291                                                                                       name.AsCString(),
292                                                                                       omit_empty_base_classes,
293                                                                                       child_indexes);
294     ValueObjectSP child_sp;
295     if (num_child_indexes > 0)
296     {
297         std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
298         std::vector<uint32_t>::const_iterator end = child_indexes.end ();
299 
300         child_sp = GetChildAtIndex(*pos, can_create);
301         for (++pos; pos != end; ++pos)
302         {
303             if (child_sp)
304             {
305                 ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
306                 child_sp = new_child_sp;
307             }
308             else
309             {
310                 child_sp.reset();
311             }
312 
313         }
314     }
315     return child_sp;
316 }
317 
318 
319 uint32_t
320 ValueObject::GetNumChildren ()
321 {
322     if (!m_children_count_valid)
323     {
324         SetNumChildren (CalculateNumChildren());
325     }
326     return m_children.size();
327 }
328 void
329 ValueObject::SetNumChildren (uint32_t num_children)
330 {
331     m_children_count_valid = true;
332     m_children.resize(num_children);
333 }
334 
335 void
336 ValueObject::SetName (const char *name)
337 {
338     m_name.SetCString(name);
339 }
340 
341 void
342 ValueObject::SetName (const ConstString &name)
343 {
344     m_name = name;
345 }
346 
347 ValueObjectSP
348 ValueObject::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
349 {
350     ValueObjectSP valobj_sp;
351     bool omit_empty_base_classes = true;
352 
353     std::string child_name_str;
354     uint32_t child_byte_size = 0;
355     int32_t child_byte_offset = 0;
356     uint32_t child_bitfield_bit_size = 0;
357     uint32_t child_bitfield_bit_offset = 0;
358     bool child_is_base_class = false;
359     const bool transparent_pointers = synthetic_array_member == false;
360     clang::ASTContext *clang_ast = GetClangAST();
361     void *clang_type = GetClangType();
362     void *child_clang_type;
363     child_clang_type = ClangASTContext::GetChildClangTypeAtIndex (clang_ast,
364                                                                   GetName().AsCString(),
365                                                                   clang_type,
366                                                                   idx,
367                                                                   transparent_pointers,
368                                                                   omit_empty_base_classes,
369                                                                   child_name_str,
370                                                                   child_byte_size,
371                                                                   child_byte_offset,
372                                                                   child_bitfield_bit_size,
373                                                                   child_bitfield_bit_offset,
374                                                                   child_is_base_class);
375     if (child_clang_type)
376     {
377         if (synthetic_index)
378             child_byte_offset += child_byte_size * synthetic_index;
379 
380         ConstString child_name;
381         if (!child_name_str.empty())
382             child_name.SetCString (child_name_str.c_str());
383 
384         valobj_sp.reset (new ValueObjectChild (this,
385                                                clang_ast,
386                                                child_clang_type,
387                                                child_name,
388                                                child_byte_size,
389                                                child_byte_offset,
390                                                child_bitfield_bit_size,
391                                                child_bitfield_bit_offset,
392                                                child_is_base_class));
393     }
394     return valobj_sp;
395 }
396 
397 const char *
398 ValueObject::GetSummaryAsCString (ExecutionContextScope *exe_scope)
399 {
400     if (UpdateValueIfNeeded (exe_scope))
401     {
402         if (m_summary_str.empty())
403         {
404             void *clang_type = GetClangType();
405 
406             // See if this is a pointer to a C string?
407             uint32_t fixed_length = 0;
408             if (clang_type)
409             {
410                 StreamString sstr;
411 
412                 if (ClangASTContext::IsCStringType (clang_type, fixed_length))
413                 {
414                     Process *process = exe_scope->CalculateProcess();
415                     if (process != NULL)
416                     {
417                         lldb::AddressType cstr_address_type = eAddressTypeInvalid;
418                         lldb::addr_t cstr_address = GetPointerValue (cstr_address_type, true);
419 
420                         if (cstr_address != LLDB_INVALID_ADDRESS)
421                         {
422                             DataExtractor data;
423                             size_t bytes_read = 0;
424                             std::vector<char> data_buffer;
425                             std::vector<char> cstr_buffer;
426                             size_t cstr_length;
427                             Error error;
428                             if (fixed_length > 0)
429                             {
430                                 data_buffer.resize(fixed_length);
431                                 // Resize the formatted buffer in case every character
432                                 // uses the "\xXX" format and one extra byte for a NULL
433                                 cstr_buffer.resize(data_buffer.size() * 4 + 1);
434                                 data.SetData (&data_buffer.front(), data_buffer.size(), eByteOrderHost);
435                                 bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), fixed_length, error);
436                                 if (bytes_read > 0)
437                                 {
438                                     sstr << '"';
439                                     cstr_length = data.Dump (&sstr,
440                                                              0,                 // Start offset in "data"
441                                                              eFormatChar,       // Print as characters
442                                                              1,                 // Size of item (1 byte for a char!)
443                                                              bytes_read,        // How many bytes to print?
444                                                              UINT32_MAX,        // num per line
445                                                              LLDB_INVALID_ADDRESS,// base address
446                                                              0,                 // bitfield bit size
447                                                              0);                // bitfield bit offset
448                                     sstr << '"';
449                                 }
450                             }
451                             else
452                             {
453                                 const size_t k_max_buf_size = 256;
454                                 data_buffer.resize (k_max_buf_size + 1);
455                                 // NULL terminate in case we don't get the entire C string
456                                 data_buffer.back() = '\0';
457                                 // Make a formatted buffer that can contain take 4
458                                 // bytes per character in case each byte uses the
459                                 // "\xXX" format and one extra byte for a NULL
460                                 cstr_buffer.resize (k_max_buf_size * 4 + 1);
461 
462                                 data.SetData (&data_buffer.front(), data_buffer.size(), eByteOrderHost);
463                                 size_t total_cstr_len = 0;
464                                 while ((bytes_read = process->ReadMemory (cstr_address, &data_buffer.front(), k_max_buf_size, error)) > 0)
465                                 {
466                                     size_t len = strlen(&data_buffer.front());
467                                     if (len == 0)
468                                         break;
469                                     if (len > bytes_read)
470                                         len = bytes_read;
471                                     if (sstr.GetSize() == 0)
472                                         sstr << '"';
473 
474                                     cstr_length = data.Dump (&sstr,
475                                                              0,                 // Start offset in "data"
476                                                              eFormatChar,       // Print as characters
477                                                              1,                 // Size of item (1 byte for a char!)
478                                                              len,               // How many bytes to print?
479                                                              UINT32_MAX,        // num per line
480                                                              LLDB_INVALID_ADDRESS,// base address
481                                                              0,                 // bitfield bit size
482                                                              0);                // bitfield bit offset
483 
484                                     if (len < k_max_buf_size)
485                                         break;
486                                     cstr_address += total_cstr_len;
487                                 }
488                                 if (sstr.GetSize() > 0)
489                                     sstr << '"';
490                             }
491                         }
492                     }
493 
494                     if (sstr.GetSize() > 0)
495                         m_summary_str.assign (sstr.GetData(), sstr.GetSize());
496                 }
497                 else if (ClangASTContext::IsFunctionPointerType (clang_type))
498                 {
499                     lldb::AddressType func_ptr_address_type = eAddressTypeInvalid;
500                     lldb::addr_t func_ptr_address = GetPointerValue (func_ptr_address_type, true);
501 
502                     if (func_ptr_address != 0 && func_ptr_address != LLDB_INVALID_ADDRESS)
503                     {
504                         switch (func_ptr_address_type)
505                         {
506                         case eAddressTypeInvalid:
507                         case eAddressTypeFile:
508                             break;
509 
510                         case eAddressTypeLoad:
511                             {
512                                 Address so_addr;
513                                 Target *target = exe_scope->CalculateTarget();
514                                 if (target && target->GetSectionLoadList().IsEmpty() == false)
515                                 {
516                                     if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr))
517                                     {
518                                         so_addr.Dump (&sstr,
519                                                       exe_scope,
520                                                       Address::DumpStyleResolvedDescription,
521                                                       Address::DumpStyleSectionNameOffset);
522                                     }
523                                 }
524                             }
525                             break;
526 
527                         case eAddressTypeHost:
528                             break;
529                         }
530                     }
531                     if (sstr.GetSize() > 0)
532                     {
533                         m_summary_str.assign (1, '(');
534                         m_summary_str.append (sstr.GetData(), sstr.GetSize());
535                         m_summary_str.append (1, ')');
536                     }
537                 }
538             }
539         }
540     }
541     if (m_summary_str.empty())
542         return NULL;
543     return m_summary_str.c_str();
544 }
545 
546 const char *
547 ValueObject::GetObjectDescription (ExecutionContextScope *exe_scope)
548 {
549     if (!m_object_desc_str.empty())
550         return m_object_desc_str.c_str();
551 
552     if (!GetValueIsValid())
553         return NULL;
554 
555     Process *process = exe_scope->CalculateProcess();
556     if (process == NULL)
557         return NULL;
558 
559     StreamString s;
560 
561     lldb::LanguageType language = GetObjectRuntimeLanguage();
562     LanguageRuntime *runtime = process->GetLanguageRuntime(language);
563 
564     if (runtime && runtime->GetObjectDescription(s, *this, exe_scope))
565     {
566         m_object_desc_str.append (s.GetData());
567     }
568     return m_object_desc_str.c_str();
569 }
570 
571 const char *
572 ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope)
573 {
574     // If our byte size is zero this is an aggregate type that has children
575     if (ClangASTContext::IsAggregateType (GetClangType()) == false)
576     {
577         if (UpdateValueIfNeeded(exe_scope))
578         {
579             if (m_value_str.empty())
580             {
581                 const Value::ContextType context_type = m_value.GetContextType();
582 
583                 switch (context_type)
584                 {
585                 case Value::eContextTypeOpaqueClangQualType:
586                 case Value::eContextTypeDCType:
587                 case Value::eContextTypeDCVariable:
588                     {
589                         void *clang_type = GetClangType ();
590                         if (clang_type)
591                         {
592                             StreamString sstr;
593                             if (m_format == eFormatDefault)
594                                 m_format = ClangASTType::GetFormat(clang_type);
595 
596                             if (ClangASTType::DumpTypeValue (GetClangAST(),            // The clang AST
597                                                              clang_type,               // The clang type to display
598                                                              &sstr,
599                                                              m_format,                 // Format to display this type with
600                                                              m_data,                   // Data to extract from
601                                                              0,                        // Byte offset into "m_data"
602                                                              GetByteSize(),            // Byte size of item in "m_data"
603                                                              GetBitfieldBitSize(),     // Bitfield bit size
604                                                              GetBitfieldBitOffset()))  // Bitfield bit offset
605                                 m_value_str.swap(sstr.GetString());
606                             else
607                                 m_value_str.clear();
608                         }
609                     }
610                     break;
611 
612                 case Value::eContextTypeDCRegisterInfo:
613                     {
614                         const RegisterInfo *reg_info = m_value.GetRegisterInfo();
615                         if (reg_info)
616                         {
617                             StreamString reg_sstr;
618                             m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
619                             m_value_str.swap(reg_sstr.GetString());
620                         }
621                     }
622                     break;
623 
624                 default:
625                     break;
626                 }
627             }
628 
629             if (!m_value_did_change && m_old_value_valid)
630             {
631                 // The value was gotten successfully, so we consider the
632                 // value as changed if the value string differs
633                 SetValueDidChange (m_old_value_str != m_value_str);
634             }
635         }
636     }
637     if (m_value_str.empty())
638         return NULL;
639     return m_value_str.c_str();
640 }
641 
642 addr_t
643 ValueObject::GetPointerValue (lldb::AddressType &address_type, bool scalar_is_load_address)
644 {
645     lldb::addr_t address = LLDB_INVALID_ADDRESS;
646     address_type = eAddressTypeInvalid;
647     switch (GetValue().GetValueType())
648     {
649     case Value::eValueTypeScalar:
650         if (scalar_is_load_address)
651         {
652             address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
653             address_type = eAddressTypeLoad;
654         }
655         break;
656 
657     case Value::eValueTypeLoadAddress:
658     case Value::eValueTypeFileAddress:
659     case Value::eValueTypeHostAddress:
660         {
661             uint32_t data_offset = 0;
662             address = m_data.GetPointer(&data_offset);
663             address_type = m_value.GetValueAddressType();
664             if (address_type == eAddressTypeInvalid)
665                 address_type = eAddressTypeLoad;
666         }
667         break;
668     }
669     return address;
670 }
671 
672 bool
673 ValueObject::SetValueFromCString (ExecutionContextScope *exe_scope, const char *value_str)
674 {
675     // Make sure our value is up to date first so that our location and location
676     // type is valid.
677     if (!UpdateValueIfNeeded(exe_scope))
678         return false;
679 
680     uint32_t count = 0;
681     lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
682 
683     char *end = NULL;
684     const size_t byte_size = GetByteSize();
685     switch (encoding)
686     {
687     case eEncodingInvalid:
688         return false;
689 
690     case eEncodingUint:
691         if (byte_size > sizeof(unsigned long long))
692         {
693             return false;
694         }
695         else
696         {
697             unsigned long long ull_val = strtoull(value_str, &end, 0);
698             if (end && *end != '\0')
699                 return false;
700             m_value = ull_val;
701             // Limit the bytes in our m_data appropriately.
702             m_value.GetScalar().GetData (m_data, byte_size);
703         }
704         break;
705 
706     case eEncodingSint:
707         if (byte_size > sizeof(long long))
708         {
709             return false;
710         }
711         else
712         {
713             long long sll_val = strtoll(value_str, &end, 0);
714             if (end && *end != '\0')
715                 return false;
716             m_value = sll_val;
717             // Limit the bytes in our m_data appropriately.
718             m_value.GetScalar().GetData (m_data, byte_size);
719         }
720         break;
721 
722     case eEncodingIEEE754:
723         {
724             const off_t byte_offset = GetByteOffset();
725             uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
726             if (dst != NULL)
727             {
728                 // We are decoding a float into host byte order below, so make
729                 // sure m_data knows what it contains.
730                 m_data.SetByteOrder(eByteOrderHost);
731                 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
732                                                         GetClangAST(),
733                                                         GetClangType(),
734                                                         value_str,
735                                                         dst,
736                                                         byte_size);
737 
738                 if (converted_byte_size == byte_size)
739                 {
740                 }
741             }
742         }
743         break;
744 
745     case eEncodingVector:
746         return false;
747 
748     default:
749         return false;
750     }
751 
752     // If we have made it here the value is in m_data and we should write it
753     // out to the target
754     return Write ();
755 }
756 
757 bool
758 ValueObject::Write ()
759 {
760     // Clear the update ID so the next time we try and read the value
761     // we try and read it again.
762     m_update_id = 0;
763 
764     // TODO: when Value has a method to write a value back, call it from here.
765     return false;
766 
767 }
768 
769 lldb::LanguageType
770 ValueObject::GetObjectRuntimeLanguage ()
771 {
772     void *opaque_qual_type = GetClangType();
773     if (opaque_qual_type == NULL)
774         return lldb::eLanguageTypeC;
775 
776     // If the type is a reference, then resolve it to what it refers to first:
777     clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
778     if (qual_type->isAnyPointerType())
779     {
780         if (qual_type->isObjCObjectPointerType())
781             return lldb::eLanguageTypeObjC;
782 
783         clang::QualType pointee_type (qual_type->getPointeeType());
784         if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
785             return lldb::eLanguageTypeC_plus_plus;
786         if (pointee_type->isObjCObjectOrInterfaceType())
787             return lldb::eLanguageTypeObjC;
788         if (pointee_type->isObjCClassType())
789             return lldb::eLanguageTypeObjC;
790     }
791     else
792     {
793         if (ClangASTContext::IsObjCClassType (opaque_qual_type))
794             return lldb::eLanguageTypeObjC;
795         if (ClangASTContext::IsCXXClassType (opaque_qual_type))
796             return lldb::eLanguageTypeC_plus_plus;
797     }
798 
799     return lldb::eLanguageTypeC;
800 }
801 
802 void
803 ValueObject::AddSyntheticChild (const ConstString &key, ValueObjectSP& valobj_sp)
804 {
805     m_synthetic_children[key] = valobj_sp;
806 }
807 
808 ValueObjectSP
809 ValueObject::GetSyntheticChild (const ConstString &key) const
810 {
811     ValueObjectSP synthetic_child_sp;
812     std::map<ConstString, ValueObjectSP>::const_iterator pos = m_synthetic_children.find (key);
813     if (pos != m_synthetic_children.end())
814         synthetic_child_sp = pos->second;
815     return synthetic_child_sp;
816 }
817 
818 bool
819 ValueObject::IsPointerType ()
820 {
821     return ClangASTContext::IsPointerType (GetClangType());
822 }
823 
824 bool
825 ValueObject::IsPointerOrReferenceType ()
826 {
827     return ClangASTContext::IsPointerOrReferenceType(GetClangType());
828 }
829 
830 ValueObjectSP
831 ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
832 {
833     ValueObjectSP synthetic_child_sp;
834     if (IsPointerType ())
835     {
836         char index_str[64];
837         snprintf(index_str, sizeof(index_str), "[%i]", index);
838         ConstString index_const_str(index_str);
839         // Check if we have already created a synthetic array member in this
840         // valid object. If we have we will re-use it.
841         synthetic_child_sp = GetSyntheticChild (index_const_str);
842         if (!synthetic_child_sp)
843         {
844             // We haven't made a synthetic array member for INDEX yet, so
845             // lets make one and cache it for any future reference.
846             synthetic_child_sp = CreateChildAtIndex(0, true, index);
847 
848             // Cache the value if we got one back...
849             if (synthetic_child_sp)
850                 AddSyntheticChild(index_const_str, synthetic_child_sp);
851         }
852     }
853     return synthetic_child_sp;
854 }
855 
856 bool
857 ValueObject::SetDynamicValue ()
858 {
859     if (!IsPointerOrReferenceType())
860         return false;
861 
862     // Check that the runtime class is correct for determining the most specific class.
863     // If it is a C++ class, see if it is dynamic:
864 
865     return true;
866 }
867 
868 
869 void
870 ValueObject::GetExpressionPath (Stream &s)
871 {
872     if (m_parent)
873     {
874         m_parent->GetExpressionPath (s);
875         clang_type_t parent_clang_type = m_parent->GetClangType();
876         if (parent_clang_type)
877         {
878             if (ClangASTContext::IsPointerType(parent_clang_type))
879             {
880                 s.PutCString("->");
881             }
882             else if (ClangASTContext::IsAggregateType (parent_clang_type))
883             {
884                 if (ClangASTContext::IsArrayType (parent_clang_type) == false &&
885                     m_parent->IsBaseClass() == false)
886                     s.PutChar('.');
887             }
888         }
889     }
890 
891     if (IsBaseClass())
892     {
893         clang_type_t clang_type = GetClangType();
894         std::string cxx_class_name;
895         if (ClangASTContext::GetCXXClassName (clang_type, cxx_class_name))
896         {
897             s << cxx_class_name.c_str() << "::";
898         }
899     }
900     else
901     {
902         const char *name = GetName().AsCString();
903         if (name)
904             s.PutCString(name);
905     }
906 }
907 
908 
909 void
910 ValueObject::DumpValueObject
911 (
912     Stream &s,
913     ExecutionContextScope *exe_scope,
914     ValueObject *valobj,
915     const char *root_valobj_name,
916     uint32_t ptr_depth,
917     uint32_t curr_depth,
918     uint32_t max_depth,
919     bool show_types,
920     bool show_location,
921     bool use_objc,
922     bool scope_already_checked,
923     bool flat_output
924 )
925 {
926     if (valobj)
927     {
928         //const char *loc_cstr = valobj->GetLocationAsCString();
929         clang_type_t clang_type = valobj->GetClangType();
930 
931         const Flags type_info_flags (ClangASTContext::GetTypeInfoMask (clang_type));
932         const char *err_cstr = NULL;
933         const bool has_children = type_info_flags.IsSet (ClangASTContext::eTypeHasChildren);
934         const bool has_value = type_info_flags.IsSet (ClangASTContext::eTypeHasValue);
935 
936         const bool print_valobj = flat_output == false || has_value;
937 
938         if (print_valobj)
939         {
940             if (show_location)
941             {
942                 s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope));
943             }
944 
945             s.Indent();
946 
947             if (show_types)
948                 s.Printf("(%s) ", valobj->GetTypeName().AsCString());
949 
950 
951             if (flat_output)
952             {
953                 valobj->GetExpressionPath(s);
954                 s.PutCString(" =");
955             }
956             else
957             {
958                 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
959                 s.Printf ("%s =", name_cstr);
960             }
961 
962             if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame()))
963             {
964                 err_cstr = "error: out of scope";
965             }
966         }
967 
968         const char *val_cstr = NULL;
969 
970         if (err_cstr == NULL)
971         {
972             val_cstr = valobj->GetValueAsCString(exe_scope);
973             err_cstr = valobj->GetError().AsCString();
974         }
975 
976         if (err_cstr)
977         {
978             s.Printf ("error: %s", err_cstr);
979         }
980         else
981         {
982             if (print_valobj)
983             {
984                 const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope);
985 
986                 if (val_cstr)
987                     s.Printf(" %s", val_cstr);
988 
989                 if (sum_cstr)
990                     s.Printf(" %s", sum_cstr);
991 
992                 if (use_objc)
993                 {
994                     const char *object_desc = valobj->GetObjectDescription(exe_scope);
995                     if (object_desc)
996                         s.Printf(" %s\n", object_desc);
997                     else
998                         s.Printf ("No description available.\n");
999                     return;
1000                 }
1001             }
1002 
1003             if (curr_depth < max_depth)
1004             {
1005                 bool is_ptr_or_ref = type_info_flags.IsSet (ClangASTContext::eTypeIsPointer | ClangASTContext::eTypeIsReference);
1006 
1007                 if (!is_ptr_or_ref || ptr_depth > 0)
1008                 {
1009                     const uint32_t num_children = valobj->GetNumChildren();
1010                     if (num_children)
1011                     {
1012                         if (flat_output)
1013                         {
1014                             if (print_valobj)
1015                                 s.EOL();
1016                         }
1017                         else
1018                         {
1019                             if (print_valobj)
1020                                 s.PutCString(" {\n");
1021                             s.IndentMore();
1022                         }
1023 
1024                         for (uint32_t idx=0; idx<num_children; ++idx)
1025                         {
1026                             ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1027                             if (child_sp.get())
1028                             {
1029                                 DumpValueObject (s,
1030                                                  exe_scope,
1031                                                  child_sp.get(),
1032                                                  NULL,
1033                                                  is_ptr_or_ref ? ptr_depth - 1 : ptr_depth,
1034                                                  curr_depth + 1,
1035                                                  max_depth,
1036                                                  show_types,
1037                                                  show_location,
1038                                                  false,
1039                                                  true,
1040                                                  flat_output);
1041                             }
1042                         }
1043 
1044                         if (!flat_output)
1045                         {
1046                             s.IndentLess();
1047                             s.Indent("}\n");
1048                         }
1049                     }
1050                     else if (has_children)
1051                     {
1052                         // Aggregate, no children...
1053                         if (print_valobj)
1054                             s.PutCString("{}\n");
1055                     }
1056                     else
1057                     {
1058                         if (print_valobj)
1059                             s.EOL();
1060                     }
1061 
1062                 }
1063                 else
1064                 {
1065                     // We printed a pointer, but we are stopping and not printing
1066                     // and children of this pointer...
1067                     s.EOL();
1068                 }
1069             }
1070             else
1071             {
1072                 if (has_children && print_valobj)
1073                 {
1074                     s.PutCString("{...}\n");
1075                 }
1076             }
1077         }
1078     }
1079 }
1080 
1081