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 
569     if (m_object_desc_str.empty())
570         return NULL;
571     else
572         return m_object_desc_str.c_str();
573 }
574 
575 const char *
576 ValueObject::GetValueAsCString (ExecutionContextScope *exe_scope)
577 {
578     // If our byte size is zero this is an aggregate type that has children
579     if (ClangASTContext::IsAggregateType (GetClangType()) == false)
580     {
581         if (UpdateValueIfNeeded(exe_scope))
582         {
583             if (m_value_str.empty())
584             {
585                 const Value::ContextType context_type = m_value.GetContextType();
586 
587                 switch (context_type)
588                 {
589                 case Value::eContextTypeOpaqueClangQualType:
590                 case Value::eContextTypeDCType:
591                 case Value::eContextTypeDCVariable:
592                     {
593                         void *clang_type = GetClangType ();
594                         if (clang_type)
595                         {
596                             StreamString sstr;
597                             if (m_format == eFormatDefault)
598                                 m_format = ClangASTType::GetFormat(clang_type);
599 
600                             if (ClangASTType::DumpTypeValue (GetClangAST(),            // The clang AST
601                                                              clang_type,               // The clang type to display
602                                                              &sstr,
603                                                              m_format,                 // Format to display this type with
604                                                              m_data,                   // Data to extract from
605                                                              0,                        // Byte offset into "m_data"
606                                                              GetByteSize(),            // Byte size of item in "m_data"
607                                                              GetBitfieldBitSize(),     // Bitfield bit size
608                                                              GetBitfieldBitOffset()))  // Bitfield bit offset
609                                 m_value_str.swap(sstr.GetString());
610                             else
611                                 m_value_str.clear();
612                         }
613                     }
614                     break;
615 
616                 case Value::eContextTypeDCRegisterInfo:
617                     {
618                         const RegisterInfo *reg_info = m_value.GetRegisterInfo();
619                         if (reg_info)
620                         {
621                             StreamString reg_sstr;
622                             m_data.Dump(&reg_sstr, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
623                             m_value_str.swap(reg_sstr.GetString());
624                         }
625                     }
626                     break;
627 
628                 default:
629                     break;
630                 }
631             }
632 
633             if (!m_value_did_change && m_old_value_valid)
634             {
635                 // The value was gotten successfully, so we consider the
636                 // value as changed if the value string differs
637                 SetValueDidChange (m_old_value_str != m_value_str);
638             }
639         }
640     }
641     if (m_value_str.empty())
642         return NULL;
643     return m_value_str.c_str();
644 }
645 
646 addr_t
647 ValueObject::GetPointerValue (lldb::AddressType &address_type, bool scalar_is_load_address)
648 {
649     lldb::addr_t address = LLDB_INVALID_ADDRESS;
650     address_type = eAddressTypeInvalid;
651     switch (GetValue().GetValueType())
652     {
653     case Value::eValueTypeScalar:
654         if (scalar_is_load_address)
655         {
656             address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
657             address_type = eAddressTypeLoad;
658         }
659         break;
660 
661     case Value::eValueTypeLoadAddress:
662     case Value::eValueTypeFileAddress:
663     case Value::eValueTypeHostAddress:
664         {
665             uint32_t data_offset = 0;
666             address = m_data.GetPointer(&data_offset);
667             address_type = m_value.GetValueAddressType();
668             if (address_type == eAddressTypeInvalid)
669                 address_type = eAddressTypeLoad;
670         }
671         break;
672     }
673     return address;
674 }
675 
676 bool
677 ValueObject::SetValueFromCString (ExecutionContextScope *exe_scope, const char *value_str)
678 {
679     // Make sure our value is up to date first so that our location and location
680     // type is valid.
681     if (!UpdateValueIfNeeded(exe_scope))
682         return false;
683 
684     uint32_t count = 0;
685     lldb::Encoding encoding = ClangASTType::GetEncoding (GetClangType(), count);
686 
687     char *end = NULL;
688     const size_t byte_size = GetByteSize();
689     switch (encoding)
690     {
691     case eEncodingInvalid:
692         return false;
693 
694     case eEncodingUint:
695         if (byte_size > sizeof(unsigned long long))
696         {
697             return false;
698         }
699         else
700         {
701             unsigned long long ull_val = strtoull(value_str, &end, 0);
702             if (end && *end != '\0')
703                 return false;
704             m_value = ull_val;
705             // Limit the bytes in our m_data appropriately.
706             m_value.GetScalar().GetData (m_data, byte_size);
707         }
708         break;
709 
710     case eEncodingSint:
711         if (byte_size > sizeof(long long))
712         {
713             return false;
714         }
715         else
716         {
717             long long sll_val = strtoll(value_str, &end, 0);
718             if (end && *end != '\0')
719                 return false;
720             m_value = sll_val;
721             // Limit the bytes in our m_data appropriately.
722             m_value.GetScalar().GetData (m_data, byte_size);
723         }
724         break;
725 
726     case eEncodingIEEE754:
727         {
728             const off_t byte_offset = GetByteOffset();
729             uint8_t *dst = const_cast<uint8_t *>(m_data.PeekData(byte_offset, byte_size));
730             if (dst != NULL)
731             {
732                 // We are decoding a float into host byte order below, so make
733                 // sure m_data knows what it contains.
734                 m_data.SetByteOrder(eByteOrderHost);
735                 const size_t converted_byte_size = ClangASTContext::ConvertStringToFloatValue (
736                                                         GetClangAST(),
737                                                         GetClangType(),
738                                                         value_str,
739                                                         dst,
740                                                         byte_size);
741 
742                 if (converted_byte_size == byte_size)
743                 {
744                 }
745             }
746         }
747         break;
748 
749     case eEncodingVector:
750         return false;
751 
752     default:
753         return false;
754     }
755 
756     // If we have made it here the value is in m_data and we should write it
757     // out to the target
758     return Write ();
759 }
760 
761 bool
762 ValueObject::Write ()
763 {
764     // Clear the update ID so the next time we try and read the value
765     // we try and read it again.
766     m_update_id = 0;
767 
768     // TODO: when Value has a method to write a value back, call it from here.
769     return false;
770 
771 }
772 
773 lldb::LanguageType
774 ValueObject::GetObjectRuntimeLanguage ()
775 {
776     void *opaque_qual_type = GetClangType();
777     if (opaque_qual_type == NULL)
778         return lldb::eLanguageTypeC;
779 
780     // If the type is a reference, then resolve it to what it refers to first:
781     clang::QualType qual_type (clang::QualType::getFromOpaquePtr(opaque_qual_type).getNonReferenceType());
782     if (qual_type->isAnyPointerType())
783     {
784         if (qual_type->isObjCObjectPointerType())
785             return lldb::eLanguageTypeObjC;
786 
787         clang::QualType pointee_type (qual_type->getPointeeType());
788         if (pointee_type->getCXXRecordDeclForPointerType() != NULL)
789             return lldb::eLanguageTypeC_plus_plus;
790         if (pointee_type->isObjCObjectOrInterfaceType())
791             return lldb::eLanguageTypeObjC;
792         if (pointee_type->isObjCClassType())
793             return lldb::eLanguageTypeObjC;
794     }
795     else
796     {
797         if (ClangASTContext::IsObjCClassType (opaque_qual_type))
798             return lldb::eLanguageTypeObjC;
799         if (ClangASTContext::IsCXXClassType (opaque_qual_type))
800             return lldb::eLanguageTypeC_plus_plus;
801     }
802 
803     return lldb::eLanguageTypeC;
804 }
805 
806 void
807 ValueObject::AddSyntheticChild (const ConstString &key, ValueObjectSP& valobj_sp)
808 {
809     m_synthetic_children[key] = valobj_sp;
810 }
811 
812 ValueObjectSP
813 ValueObject::GetSyntheticChild (const ConstString &key) const
814 {
815     ValueObjectSP synthetic_child_sp;
816     std::map<ConstString, ValueObjectSP>::const_iterator pos = m_synthetic_children.find (key);
817     if (pos != m_synthetic_children.end())
818         synthetic_child_sp = pos->second;
819     return synthetic_child_sp;
820 }
821 
822 bool
823 ValueObject::IsPointerType ()
824 {
825     return ClangASTContext::IsPointerType (GetClangType());
826 }
827 
828 bool
829 ValueObject::IsPointerOrReferenceType ()
830 {
831     return ClangASTContext::IsPointerOrReferenceType(GetClangType());
832 }
833 
834 ValueObjectSP
835 ValueObject::GetSyntheticArrayMemberFromPointer (int32_t index, bool can_create)
836 {
837     ValueObjectSP synthetic_child_sp;
838     if (IsPointerType ())
839     {
840         char index_str[64];
841         snprintf(index_str, sizeof(index_str), "[%i]", index);
842         ConstString index_const_str(index_str);
843         // Check if we have already created a synthetic array member in this
844         // valid object. If we have we will re-use it.
845         synthetic_child_sp = GetSyntheticChild (index_const_str);
846         if (!synthetic_child_sp)
847         {
848             // We haven't made a synthetic array member for INDEX yet, so
849             // lets make one and cache it for any future reference.
850             synthetic_child_sp = CreateChildAtIndex(0, true, index);
851 
852             // Cache the value if we got one back...
853             if (synthetic_child_sp)
854                 AddSyntheticChild(index_const_str, synthetic_child_sp);
855         }
856     }
857     return synthetic_child_sp;
858 }
859 
860 bool
861 ValueObject::SetDynamicValue ()
862 {
863     if (!IsPointerOrReferenceType())
864         return false;
865 
866     // Check that the runtime class is correct for determining the most specific class.
867     // If it is a C++ class, see if it is dynamic:
868 
869     return true;
870 }
871 
872 
873 void
874 ValueObject::GetExpressionPath (Stream &s)
875 {
876     if (m_parent)
877     {
878         m_parent->GetExpressionPath (s);
879         clang_type_t parent_clang_type = m_parent->GetClangType();
880         if (parent_clang_type)
881         {
882             if (ClangASTContext::IsPointerType(parent_clang_type))
883             {
884                 s.PutCString("->");
885             }
886             else if (ClangASTContext::IsAggregateType (parent_clang_type))
887             {
888                 if (ClangASTContext::IsArrayType (parent_clang_type) == false &&
889                     m_parent->IsBaseClass() == false)
890                     s.PutChar('.');
891             }
892         }
893     }
894 
895     if (IsBaseClass())
896     {
897         clang_type_t clang_type = GetClangType();
898         std::string cxx_class_name;
899         if (ClangASTContext::GetCXXClassName (clang_type, cxx_class_name))
900         {
901             s << cxx_class_name.c_str() << "::";
902         }
903     }
904     else
905     {
906         const char *name = GetName().AsCString();
907         if (name)
908             s.PutCString(name);
909     }
910 }
911 
912 
913 void
914 ValueObject::DumpValueObject
915 (
916     Stream &s,
917     ExecutionContextScope *exe_scope,
918     ValueObject *valobj,
919     const char *root_valobj_name,
920     uint32_t ptr_depth,
921     uint32_t curr_depth,
922     uint32_t max_depth,
923     bool show_types,
924     bool show_location,
925     bool use_objc,
926     bool scope_already_checked,
927     bool flat_output
928 )
929 {
930     if (valobj)
931     {
932         //const char *loc_cstr = valobj->GetLocationAsCString();
933         clang_type_t clang_type = valobj->GetClangType();
934 
935         const Flags type_info_flags (ClangASTContext::GetTypeInfoMask (clang_type));
936         const char *err_cstr = NULL;
937         const bool has_children = type_info_flags.IsSet (ClangASTContext::eTypeHasChildren);
938         const bool has_value = type_info_flags.IsSet (ClangASTContext::eTypeHasValue);
939 
940         const bool print_valobj = flat_output == false || has_value;
941 
942         if (print_valobj)
943         {
944             if (show_location)
945             {
946                 s.Printf("%s: ", valobj->GetLocationAsCString(exe_scope));
947             }
948 
949             s.Indent();
950 
951             if (show_types)
952                 s.Printf("(%s) ", valobj->GetTypeName().AsCString());
953 
954 
955             if (flat_output)
956             {
957                 valobj->GetExpressionPath(s);
958                 s.PutCString(" =");
959             }
960             else
961             {
962                 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
963                 s.Printf ("%s =", name_cstr);
964             }
965 
966             if (!scope_already_checked && !valobj->IsInScope(exe_scope->CalculateStackFrame()))
967             {
968                 err_cstr = "error: out of scope";
969             }
970         }
971 
972         const char *val_cstr = NULL;
973 
974         if (err_cstr == NULL)
975         {
976             val_cstr = valobj->GetValueAsCString(exe_scope);
977             err_cstr = valobj->GetError().AsCString();
978         }
979 
980         if (err_cstr)
981         {
982             s.Printf (" %s\n", err_cstr);
983         }
984         else
985         {
986             if (print_valobj)
987             {
988                 const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope);
989 
990                 if (val_cstr)
991                     s.Printf(" %s", val_cstr);
992 
993                 if (sum_cstr)
994                     s.Printf(" %s", sum_cstr);
995 
996                 if (use_objc)
997                 {
998                     const char *object_desc = valobj->GetObjectDescription(exe_scope);
999                     if (object_desc)
1000                         s.Printf(" %s\n", object_desc);
1001                     else
1002                         s.Printf (" [no Objective-C description available]\n");
1003                     return;
1004                 }
1005             }
1006 
1007             if (curr_depth < max_depth)
1008             {
1009                 bool is_ptr_or_ref = type_info_flags.IsSet (ClangASTContext::eTypeIsPointer | ClangASTContext::eTypeIsReference);
1010 
1011                 if (!is_ptr_or_ref || ptr_depth > 0)
1012                 {
1013                     const uint32_t num_children = valobj->GetNumChildren();
1014                     if (num_children)
1015                     {
1016                         if (flat_output)
1017                         {
1018                             if (print_valobj)
1019                                 s.EOL();
1020                         }
1021                         else
1022                         {
1023                             if (print_valobj)
1024                                 s.PutCString(" {\n");
1025                             s.IndentMore();
1026                         }
1027 
1028                         for (uint32_t idx=0; idx<num_children; ++idx)
1029                         {
1030                             ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
1031                             if (child_sp.get())
1032                             {
1033                                 DumpValueObject (s,
1034                                                  exe_scope,
1035                                                  child_sp.get(),
1036                                                  NULL,
1037                                                  is_ptr_or_ref ? ptr_depth - 1 : ptr_depth,
1038                                                  curr_depth + 1,
1039                                                  max_depth,
1040                                                  show_types,
1041                                                  show_location,
1042                                                  false,
1043                                                  true,
1044                                                  flat_output);
1045                             }
1046                         }
1047 
1048                         if (!flat_output)
1049                         {
1050                             s.IndentLess();
1051                             s.Indent("}\n");
1052                         }
1053                     }
1054                     else if (has_children)
1055                     {
1056                         // Aggregate, no children...
1057                         if (print_valobj)
1058                             s.PutCString("{}\n");
1059                     }
1060                     else
1061                     {
1062                         if (print_valobj)
1063                             s.EOL();
1064                     }
1065 
1066                 }
1067                 else
1068                 {
1069                     // We printed a pointer, but we are stopping and not printing
1070                     // and children of this pointer...
1071                     s.EOL();
1072                 }
1073             }
1074             else
1075             {
1076                 if (has_children && print_valobj)
1077                 {
1078                     s.PutCString("{...}\n");
1079                 }
1080             }
1081         }
1082     }
1083 }
1084 
1085