]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/ValueObjectPrinter.cpp
Import sqlite3 3.12.1
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / DataFormatters / ValueObjectPrinter.cpp
1 //===-- ValueObjectPrinter.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/DataFormatters/ValueObjectPrinter.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Stream.h"
17 #include "lldb/Core/ValueObject.h"
18 #include "lldb/DataFormatters/DataVisualization.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Target/Language.h"
21 #include "lldb/Target/Target.h"
22
23 using namespace lldb;
24 using namespace lldb_private;
25
26 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
27                                         Stream* s)
28 {
29     if (valobj)
30     {
31         DumpValueObjectOptions options(*valobj);
32         Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
33     }
34     else
35     {
36         DumpValueObjectOptions options;
37         Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
38     }
39 }
40
41 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
42                                         Stream* s,
43                                         const DumpValueObjectOptions& options)
44 {
45     Init(valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
46 }
47
48 ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
49                                         Stream* s,
50                                         const DumpValueObjectOptions& options,
51                                         const DumpValueObjectOptions::PointerDepth& ptr_depth,
52                                         uint32_t curr_depth,
53                                         InstancePointersSetSP printed_instance_pointers)
54 {
55     Init(valobj,s,options,ptr_depth,curr_depth, printed_instance_pointers);
56 }
57
58 void
59 ValueObjectPrinter::Init (ValueObject* valobj,
60                           Stream* s,
61                           const DumpValueObjectOptions& options,
62                           const DumpValueObjectOptions::PointerDepth& ptr_depth,
63                           uint32_t curr_depth,
64                           InstancePointersSetSP printed_instance_pointers)
65 {
66     m_orig_valobj = valobj;
67     m_valobj = nullptr;
68     m_stream = s;
69     m_options = options;
70     m_ptr_depth = ptr_depth;
71     m_curr_depth = curr_depth;
72     assert (m_orig_valobj && "cannot print a NULL ValueObject");
73     assert (m_stream && "cannot print to a NULL Stream");
74     m_should_print = eLazyBoolCalculate;
75     m_is_nil = eLazyBoolCalculate;
76     m_is_uninit = eLazyBoolCalculate;
77     m_is_ptr = eLazyBoolCalculate;
78     m_is_ref = eLazyBoolCalculate;
79     m_is_aggregate = eLazyBoolCalculate;
80     m_is_instance_ptr = eLazyBoolCalculate;
81     m_summary_formatter = {nullptr,false};
82     m_value.assign("");
83     m_summary.assign("");
84     m_error.assign("");
85     m_val_summary_ok = false;
86     m_printed_instance_pointers = printed_instance_pointers ? printed_instance_pointers : InstancePointersSetSP(new InstancePointersSet());
87 }
88
89 bool
90 ValueObjectPrinter::PrintValueObject ()
91 {
92     if (!GetMostSpecializedValue () || m_valobj == nullptr)
93         return false;
94     
95     if (ShouldPrintValueObject())
96     {
97         PrintValidationMarkerIfNeeded();
98         
99         PrintLocationIfNeeded();
100         m_stream->Indent();
101         
102         PrintDecl();
103     }
104
105     bool value_printed = false;
106     bool summary_printed = false;
107     
108     m_val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
109
110     if (m_val_summary_ok)
111         PrintChildrenIfNeeded (value_printed, summary_printed);
112     else
113         m_stream->EOL();
114     
115     PrintValidationErrorIfNeeded();
116     
117     return true;
118 }
119
120 bool
121 ValueObjectPrinter::GetMostSpecializedValue ()
122 {
123     if (m_valobj)
124         return true;
125     bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
126     if (!update_success)
127     {
128         m_valobj = m_orig_valobj;
129     }
130     else
131     {
132         if (m_orig_valobj->IsDynamic())
133         {
134             if (m_options.m_use_dynamic == eNoDynamicValues)
135             {
136                 ValueObject *static_value = m_orig_valobj->GetStaticValue().get();
137                 if (static_value)
138                     m_valobj = static_value;
139                 else
140                     m_valobj = m_orig_valobj;
141             }
142             else
143                 m_valobj = m_orig_valobj;
144         }
145         else
146         {
147             if (m_options.m_use_dynamic != eNoDynamicValues)
148             {
149                 ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get();
150                 if (dynamic_value)
151                     m_valobj = dynamic_value;
152                 else
153                     m_valobj = m_orig_valobj;
154             }
155             else
156                 m_valobj = m_orig_valobj;
157         }
158         
159         if (m_valobj->IsSynthetic())
160         {
161             if (m_options.m_use_synthetic == false)
162             {
163                 ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
164                 if (non_synthetic)
165                     m_valobj = non_synthetic;
166             }
167         }
168         else
169         {
170             if (m_options.m_use_synthetic == true)
171             {
172                 ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
173                 if (synthetic)
174                     m_valobj = synthetic;
175             }
176         }
177     }
178     m_compiler_type = m_valobj->GetCompilerType();
179     m_type_flags = m_compiler_type.GetTypeInfo ();
180     return true;
181 }
182
183 const char*
184 ValueObjectPrinter::GetDescriptionForDisplay ()
185 {
186     const char* str = m_valobj->GetObjectDescription();
187     if (!str)
188         str = m_valobj->GetSummaryAsCString();
189     if (!str)
190         str = m_valobj->GetValueAsCString();
191     return str;
192 }
193
194 const char*
195 ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
196 {
197     const char *root_valobj_name = m_options.m_root_valobj_name.empty() ?
198         m_valobj->GetName().AsCString() :
199         m_options.m_root_valobj_name.c_str();
200     return root_valobj_name ? root_valobj_name : if_fail;
201 }
202
203 bool
204 ValueObjectPrinter::ShouldPrintValueObject ()
205 {
206     if (m_should_print == eLazyBoolCalculate)
207         m_should_print = (m_options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
208     return m_should_print == eLazyBoolYes;
209 }
210
211 bool
212 ValueObjectPrinter::IsNil ()
213 {
214     if (m_is_nil == eLazyBoolCalculate)
215         m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo;
216     return m_is_nil == eLazyBoolYes;
217 }
218
219 bool
220 ValueObjectPrinter::IsUninitialized ()
221 {
222     if (m_is_uninit == eLazyBoolCalculate)
223         m_is_uninit = m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo;
224     return m_is_uninit == eLazyBoolYes;
225 }
226
227 bool
228 ValueObjectPrinter::IsPtr ()
229 {
230     if (m_is_ptr == eLazyBoolCalculate)
231         m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
232     return m_is_ptr == eLazyBoolYes;
233 }
234
235 bool
236 ValueObjectPrinter::IsRef ()
237 {
238     if (m_is_ref == eLazyBoolCalculate)
239         m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
240     return m_is_ref == eLazyBoolYes;
241 }
242
243 bool
244 ValueObjectPrinter::IsAggregate ()
245 {
246     if (m_is_aggregate == eLazyBoolCalculate)
247         m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
248     return m_is_aggregate == eLazyBoolYes;
249 }
250
251 bool
252 ValueObjectPrinter::IsInstancePointer ()
253 {
254     // you need to do this check on the value's clang type
255     if (m_is_instance_ptr == eLazyBoolCalculate)
256         m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & eTypeInstanceIsPointer) != 0 ? eLazyBoolYes : eLazyBoolNo;
257     if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass())
258         m_is_instance_ptr = eLazyBoolNo;
259     return m_is_instance_ptr == eLazyBoolYes;
260 }
261
262 bool
263 ValueObjectPrinter::PrintLocationIfNeeded ()
264 {
265     if (m_options.m_show_location)
266     {
267         m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
268         return true;
269     }
270     return false;
271 }
272
273 void
274 ValueObjectPrinter::PrintDecl ()
275 {
276     bool show_type = true;
277     // if we are at the root-level and been asked to hide the root's type, then hide it
278     if (m_curr_depth == 0 && m_options.m_hide_root_type)
279         show_type = false;
280     else
281         // otherwise decide according to the usual rules (asked to show types - always at the root level)
282         show_type = m_options.m_show_types || (m_curr_depth == 0 && !m_options.m_flat_output);
283     
284     StreamString typeName;
285     
286     // always show the type at the root level if it is invalid
287     if (show_type)
288     {
289         // Some ValueObjects don't have types (like registers sets). Only print
290         // the type if there is one to print
291         ConstString type_name;
292         if (m_compiler_type.IsValid())
293         {
294             if (m_options.m_use_type_display_name)
295                 type_name = m_valobj->GetDisplayTypeName();
296             else
297                 type_name = m_valobj->GetQualifiedTypeName();
298         }
299         else
300         {
301             // only show an invalid type name if the user explicitly triggered show_type
302             if (m_options.m_show_types)
303                 type_name = ConstString("<invalid type>");
304             else
305                 type_name.Clear();
306         }
307         
308         if (type_name)
309         {
310             std::string type_name_str(type_name.GetCString());
311             if (m_options.m_hide_pointer_value)
312             {
313                 for(auto iter = type_name_str.find(" *");
314                     iter != std::string::npos;
315                     iter = type_name_str.find(" *"))
316                 {
317                     type_name_str.erase(iter, 2);
318                 }
319             }
320             typeName.Printf("%s", type_name_str.c_str());
321         }
322     }
323     
324     StreamString varName;
325     
326     if (m_options.m_flat_output)
327     {
328         // If we are showing types, also qualify the C++ base classes
329         const bool qualify_cxx_base_classes = show_type;
330         if (!m_options.m_hide_name)
331         {
332             m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes);
333         }
334     }
335     else if (!m_options.m_hide_name)
336     {
337         const char *name_cstr = GetRootNameForDisplay("");
338         varName.Printf ("%s", name_cstr);
339     }
340     
341     bool decl_printed = false;
342     if (!m_options.m_decl_printing_helper)
343     {
344         // if the user didn't give us a custom helper, pick one based upon the language, either the one that this printer is bound to, or the preferred one for the ValueObject
345         lldb::LanguageType lang_type = (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) ? m_valobj->GetPreferredDisplayLanguage() : m_options.m_varformat_language;
346         if (Language *lang_plugin = Language::FindPlugin(lang_type))
347         {
348             m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper();
349         }
350     }
351     
352     if (m_options.m_decl_printing_helper)
353     {
354         ConstString type_name_cstr(typeName.GetData());
355         ConstString var_name_cstr(varName.GetData());
356         
357         StreamString dest_stream;
358         if (m_options.m_decl_printing_helper (type_name_cstr,
359                                               var_name_cstr,
360                                               m_options,
361                                               dest_stream))
362         {
363             decl_printed = true;
364             m_stream->Printf("%s", dest_stream.GetData());
365         }
366     }
367     
368     // if the helper failed, or there is none, do a default thing
369     if (!decl_printed)
370     {
371         if (typeName.GetSize())
372             m_stream->Printf("(%s) ", typeName.GetData());
373         if (varName.GetSize())
374             m_stream->Printf("%s =", varName.GetData());
375         else if (!m_options.m_hide_name)
376             m_stream->Printf(" =");
377     }
378 }
379
380 bool
381 ValueObjectPrinter::CheckScopeIfNeeded ()
382 {
383     if (m_options.m_scope_already_checked)
384         return true;
385     return m_valobj->IsInScope();
386 }
387
388 TypeSummaryImpl*
389 ValueObjectPrinter::GetSummaryFormatter (bool null_if_omitted)
390 {
391     if (m_summary_formatter.second == false)
392     {
393         TypeSummaryImpl* entry = m_options.m_summary_sp ? m_options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
394         
395         if (m_options.m_omit_summary_depth > 0)
396             entry = NULL;
397         m_summary_formatter.first = entry;
398         m_summary_formatter.second = true;
399     }
400     if (m_options.m_omit_summary_depth > 0 && null_if_omitted)
401         return nullptr;
402     return m_summary_formatter.first;
403 }
404
405 static bool
406 IsPointerValue (const CompilerType &type)
407 {
408     Flags type_flags(type.GetTypeInfo());
409     if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer))
410         return type_flags.AllClear(eTypeIsBuiltIn);
411     return false;
412 }
413
414 void
415 ValueObjectPrinter::GetValueSummaryError (std::string& value,
416                                           std::string& summary,
417                                           std::string& error)
418 {
419     if (m_options.m_format != eFormatDefault && m_options.m_format != m_valobj->GetFormat())
420     {
421         m_valobj->GetValueAsCString(m_options.m_format,
422                                     value);
423     }
424     else
425     {
426         const char* val_cstr = m_valobj->GetValueAsCString();
427         if (val_cstr)
428             value.assign(val_cstr);
429     }
430     const char* err_cstr = m_valobj->GetError().AsCString();
431     if (err_cstr)
432         error.assign(err_cstr);
433     
434     if (ShouldPrintValueObject())
435     {
436         if (IsNil())
437             summary.assign("nil");
438         else if (IsUninitialized())
439             summary.assign("<uninitialized>");
440         else if (m_options.m_omit_summary_depth == 0)
441         {
442             TypeSummaryImpl* entry = GetSummaryFormatter();
443             if (entry)
444                 m_valobj->GetSummaryAsCString(entry, summary, m_options.m_varformat_language);
445             else
446             {
447                 const char* sum_cstr = m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
448                 if (sum_cstr)
449                     summary.assign(sum_cstr);
450             }
451         }
452     }
453 }
454
455 bool
456 ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
457                                                   bool& summary_printed)
458 {
459     bool error_printed = false;
460     if (ShouldPrintValueObject())
461     {
462         if (!CheckScopeIfNeeded())
463             m_error.assign("out of scope");
464         if (m_error.empty())
465         {
466             GetValueSummaryError(m_value, m_summary, m_error);
467         }
468         if (m_error.size())
469         {
470             // we need to support scenarios in which it is actually fine for a value to have no type
471             // but - on the other hand - if we get an error *AND* have no type, we try to get out
472             // gracefully, since most often that combination means "could not resolve a type"
473             // and the default failure mode is quite ugly
474             if (!m_compiler_type.IsValid())
475             {
476                 m_stream->Printf(" <could not resolve type>");
477                 return false;
478             }
479             
480             error_printed = true;
481             m_stream->Printf (" <%s>\n", m_error.c_str());
482         }
483         else
484         {
485             // Make sure we have a value and make sure the summary didn't
486             // specify that the value should not be printed - and do not print
487             // the value if this thing is nil
488             // (but show the value if the user passes a format explicitly)
489             TypeSummaryImpl* entry = GetSummaryFormatter();
490             if (!IsNil() && !IsUninitialized() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || m_options.m_format != eFormatDefault) || m_summary.empty()) && !m_options.m_hide_value)
491             {
492                 if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {}
493                 else
494                 {
495                     m_stream->Printf(" %s", m_value.c_str());
496                     value_printed = true;
497                 }
498             }
499             
500             if (m_summary.size())
501             {
502                 m_stream->Printf(" %s", m_summary.c_str());
503                 summary_printed = true;
504             }
505         }
506     }
507     return !error_printed;
508 }
509
510 bool
511 ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
512                                                     bool summary_printed)
513 {
514     if (ShouldPrintValueObject())
515     {
516         // let's avoid the overly verbose no description error for a nil thing
517         if (m_options.m_use_objc && !IsNil() && !IsUninitialized())
518         {
519             if (!m_options.m_hide_value || !m_options.m_hide_name)
520                 m_stream->Printf(" ");
521             const char *object_desc = nullptr;
522             if (value_printed || summary_printed)
523                 object_desc = m_valobj->GetObjectDescription();
524             else
525                 object_desc = GetDescriptionForDisplay();
526             if (object_desc && *object_desc)
527             {
528                 m_stream->Printf("%s\n", object_desc);
529                 return true;
530             }
531             else if (value_printed == false && summary_printed == false)
532                 return true;
533             else
534                 return false;
535         }
536     }
537     return true;
538 }
539
540 bool
541 DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root,
542                                                          TypeSummaryImpl* entry,
543                                                          ValueObject *valobj,
544                                                          const std::string& summary)
545 {
546     switch (m_mode)
547     {
548         case Mode::Always:
549             return (m_count > 0);
550         case Mode::Never:
551             return false;
552         case Mode::Default:
553             if (is_root)
554                 m_count = std::min<decltype(m_count)>(m_count,1);
555             return m_count > 0;
556         case Mode::Formatters:
557             if (!entry || entry->DoesPrintChildren(valobj) || summary.empty())
558                 return m_count > 0;
559             return false;
560     }
561     return false;
562 }
563
564 bool
565 DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const
566 {
567     switch (m_mode)
568     {
569         case Mode::Always:
570         case Mode::Default:
571         case Mode::Formatters:
572             return (m_count > 0);
573         case Mode::Never:
574             return false;
575     }
576     return false;
577 }
578
579 bool
580 ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
581                                          DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
582 {
583     const bool is_ref = IsRef ();
584     const bool is_ptr = IsPtr ();
585     const bool is_uninit = IsUninitialized();
586     
587     if (is_uninit)
588         return false;
589     
590     TypeSummaryImpl* entry = GetSummaryFormatter();
591     
592     if (m_options.m_use_objc)
593         return false;
594     
595     if (is_failed_description || m_curr_depth < m_options.m_max_depth)
596     {
597         // We will show children for all concrete types. We won't show
598         // pointer contents unless a pointer depth has been specified.
599         // We won't reference contents unless the reference is the
600         // root object (depth of zero).
601         
602         // Use a new temporary pointer depth in case we override the
603         // current pointer depth below...
604         
605         if (is_ptr || is_ref)
606         {
607             // We have a pointer or reference whose value is an address.
608             // Make sure that address is not NULL
609             AddressType ptr_address_type;
610             if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
611                 return false;
612             
613             const bool is_root_level = m_curr_depth == 0;
614             
615             if (is_ref &&
616                 is_root_level)
617             {
618                 // If this is the root object (depth is zero) that we are showing
619                 // and it is a reference, and no pointer depth has been supplied
620                 // print out what it references. Don't do this at deeper depths
621                 // otherwise we can end up with infinite recursion...
622                 return true;
623             }
624             
625             return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary);
626         }
627         
628         return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
629     }
630     return false;
631 }
632
633 bool
634 ValueObjectPrinter::ShouldExpandEmptyAggregates ()
635 {
636     TypeSummaryImpl* entry = GetSummaryFormatter();
637     
638     if (!entry)
639         return true;
640     
641     return entry->DoesPrintEmptyAggregates();
642 }
643
644 ValueObject*
645 ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
646 {
647     return m_valobj;
648 }
649
650 void
651 ValueObjectPrinter::PrintChildrenPreamble ()
652 {
653     if (m_options.m_flat_output)
654     {
655         if (ShouldPrintValueObject())
656             m_stream->EOL();
657     }
658     else
659     {
660         if (ShouldPrintValueObject())
661             m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
662         m_stream->IndentMore();
663     }
664 }
665
666 void
667 ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
668                                 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
669 {
670     DumpValueObjectOptions child_options(m_options);
671     child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName();
672     child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value)
673     .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
674     
675     if (child_sp.get())
676     {
677         ValueObjectPrinter child_printer(child_sp.get(),
678                                          m_stream,
679                                          child_options,
680                                          (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth,
681                                          m_curr_depth + 1,
682                                          m_printed_instance_pointers);
683         child_printer.PrintValueObject();
684     }
685 }
686
687 uint32_t
688 ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
689 {
690     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
691     
692     size_t num_children = synth_m_valobj->GetNumChildren();
693     print_dotdotdot = false;
694     if (num_children)
695     {
696         const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
697         
698         if (num_children > max_num_children && !m_options.m_ignore_cap)
699         {
700             print_dotdotdot = true;
701             return max_num_children;
702         }
703     }
704     return num_children;
705 }
706
707 void
708 ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
709 {
710     if (!m_options.m_flat_output)
711     {
712         if (print_dotdotdot)
713         {
714             m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
715             m_stream->Indent("...\n");
716         }
717         m_stream->IndentLess();
718         m_stream->Indent("}\n");
719     }
720 }
721
722 bool
723 ValueObjectPrinter::ShouldPrintEmptyBrackets (bool value_printed,
724                                               bool summary_printed)
725 {
726     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
727     
728     if (!IsAggregate())
729         return false;
730     
731     if (m_options.m_reveal_empty_aggregates == false)
732     {
733         if (value_printed || summary_printed)
734             return false;
735     }
736     
737     if (synth_m_valobj->MightHaveChildren())
738         return true;
739     
740     if (m_val_summary_ok)
741         return false;
742     
743     return true;
744 }
745
746 void
747 ValueObjectPrinter::PrintChildren (bool value_printed,
748                                    bool summary_printed,
749                                    const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
750 {
751     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
752     
753     bool print_dotdotdot = false;
754     size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
755     if (num_children)
756     {
757         bool any_children_printed = false;
758         
759         for (size_t idx=0; idx<num_children; ++idx)
760         {
761             ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
762             if (child_sp)
763             {
764                 if (!any_children_printed)
765                 {
766                     PrintChildrenPreamble ();
767                     any_children_printed = true;
768                 }
769                 PrintChild (child_sp, curr_ptr_depth);
770             }
771         }
772         
773         if (any_children_printed)
774             PrintChildrenPostamble (print_dotdotdot);
775         else
776         {
777             if (ShouldPrintEmptyBrackets(value_printed, summary_printed))
778             {
779                 if (ShouldPrintValueObject())
780                     m_stream->PutCString(" {}\n");
781                 else
782                     m_stream->EOL();
783             }
784             else
785                 m_stream->EOL();
786         }
787     }
788     else if (ShouldPrintEmptyBrackets(value_printed, summary_printed))
789     {
790         // Aggregate, no children...
791         if (ShouldPrintValueObject())
792         {
793             // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
794             if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates())
795                 m_stream->PutCString( "\n");
796             else
797                 m_stream->PutCString(" {}\n");
798         }
799     }
800     else
801     {
802         if (ShouldPrintValueObject())
803             m_stream->EOL();
804     }
805 }
806
807 bool
808 ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
809 {
810     if (!GetMostSpecializedValue () || m_valobj == nullptr)
811         return false;
812     
813     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
814     
815     bool print_dotdotdot = false;
816     size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
817     
818     if (num_children)
819     {
820         m_stream->PutChar('(');
821         
822         for (uint32_t idx=0; idx<num_children; ++idx)
823         {
824             lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
825             if (child_sp)
826                 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(m_options.m_use_dynamic, m_options.m_use_synthetic);
827             if (child_sp)
828             {
829                 if (idx)
830                     m_stream->PutCString(", ");
831                 if (!hide_names)
832                 {
833                     const char* name = child_sp.get()->GetName().AsCString();
834                     if (name && *name)
835                     {
836                         m_stream->PutCString(name);
837                         m_stream->PutCString(" = ");
838                     }
839                 }
840                 child_sp->DumpPrintableRepresentation(*m_stream,
841                                                       ValueObject::eValueObjectRepresentationStyleSummary,
842                                                       m_options.m_format,
843                                                       ValueObject::ePrintableRepresentationSpecialCasesDisable);
844             }
845         }
846         
847         if (print_dotdotdot)
848             m_stream->PutCString(", ...)");
849         else
850             m_stream->PutChar(')');
851     }
852     return true;
853 }
854
855 void
856 ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
857                                            bool summary_printed)
858 {
859     // this flag controls whether we tried to display a description for this object and failed
860     // if that happens, we want to display the children, if any
861     bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
862     
863     auto curr_ptr_depth = m_ptr_depth;
864     bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
865     bool print_oneline = (curr_ptr_depth.CanAllowExpansion() ||
866                           m_options.m_show_types ||
867                           !m_options.m_allow_oneliner_mode ||
868                           m_options.m_flat_output ||
869                           m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
870     bool is_instance_ptr = IsInstancePointer();
871     uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS;
872     
873     if (print_children && is_instance_ptr)
874     {
875         instance_ptr_value = m_valobj->GetValueAsUnsigned(0);
876         if (m_printed_instance_pointers->count(instance_ptr_value))
877         {
878             // we already printed this instance-is-pointer thing, so don't expand it
879             m_stream->PutCString(" {...}\n");
880             
881             // we're done here - get out fast
882             return;
883         }
884         else
885             m_printed_instance_pointers->emplace(instance_ptr_value); // remember this guy for future reference
886     }
887     
888     if (print_children)
889     {
890         if (print_oneline)
891         {
892             m_stream->PutChar(' ');
893             PrintChildrenOneLiner (false);
894             m_stream->EOL();
895         }
896         else
897             PrintChildren (value_printed, summary_printed, curr_ptr_depth);
898     }
899     else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
900     {
901         m_stream->PutCString("{...}\n");
902     }
903     else
904         m_stream->EOL();
905 }
906
907 bool
908 ValueObjectPrinter::ShouldPrintValidation ()
909 {
910     return m_options.m_run_validator;
911 }
912
913 bool
914 ValueObjectPrinter::PrintValidationMarkerIfNeeded ()
915 {
916     if (!ShouldPrintValidation())
917         return false;
918     
919     m_validation = m_valobj->GetValidationStatus();
920     
921     if (TypeValidatorResult::Failure == m_validation.first)
922     {
923         m_stream->Printf("! ");
924         return true;
925     }
926     
927     return false;
928 }
929
930 bool
931 ValueObjectPrinter::PrintValidationErrorIfNeeded ()
932 {
933     if (!ShouldPrintValidation())
934         return false;
935     
936     if (TypeValidatorResult::Success == m_validation.first)
937         return false;
938     
939     if (m_validation.second.empty())
940         m_validation.second.assign("unknown error");
941     
942     m_stream->Printf(" ! validation error: %s", m_validation.second.c_str());
943     m_stream->EOL();
944     
945     return true;
946 }