14d93b8cdSEnrico Granata //===-- ValueObjectPrinter.cpp -------------------------------------*- C++ -*-===//
24d93b8cdSEnrico Granata //
34d93b8cdSEnrico Granata //                     The LLVM Compiler Infrastructure
44d93b8cdSEnrico Granata //
54d93b8cdSEnrico Granata // This file is distributed under the University of Illinois Open Source
64d93b8cdSEnrico Granata // License. See LICENSE.TXT for details.
74d93b8cdSEnrico Granata //
84d93b8cdSEnrico Granata //===----------------------------------------------------------------------===//
94d93b8cdSEnrico Granata 
104d93b8cdSEnrico Granata #include "lldb/DataFormatters/ValueObjectPrinter.h"
114d93b8cdSEnrico Granata 
124d93b8cdSEnrico Granata // C Includes
134d93b8cdSEnrico Granata // C++ Includes
144d93b8cdSEnrico Granata // Other libraries and framework includes
154d93b8cdSEnrico Granata // Project includes
16c8e7649aSEnrico Granata #include "lldb/Core/Stream.h"
17c8e7649aSEnrico Granata #include "lldb/Core/ValueObject.h"
18a29cb0baSEnrico Granata #include "lldb/DataFormatters/DataVisualization.h"
194d93b8cdSEnrico Granata #include "lldb/Interpreter/CommandInterpreter.h"
20c8e7649aSEnrico Granata #include "lldb/Target/Language.h"
214d93b8cdSEnrico Granata #include "lldb/Target/Target.h"
224d93b8cdSEnrico Granata 
234d93b8cdSEnrico Granata using namespace lldb;
244d93b8cdSEnrico Granata using namespace lldb_private;
254d93b8cdSEnrico Granata 
26d5957336SEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
27d5957336SEnrico Granata                                         Stream* s)
28d5957336SEnrico Granata {
29d5957336SEnrico Granata     if (valobj)
30d5957336SEnrico Granata     {
31d5957336SEnrico Granata         DumpValueObjectOptions options(*valobj);
32*26014690SGreg Clayton         Init (valobj,s,options,m_options.m_max_ptr_depth,0);
33d5957336SEnrico Granata     }
34d5957336SEnrico Granata     else
35d5957336SEnrico Granata     {
36d5957336SEnrico Granata         DumpValueObjectOptions options;
37*26014690SGreg Clayton         Init (valobj,s,options,m_options.m_max_ptr_depth,0);
38d5957336SEnrico Granata     }
39d5957336SEnrico Granata }
40d5957336SEnrico Granata 
414d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
424d93b8cdSEnrico Granata                                         Stream* s,
43938d1d67SEnrico Granata                                         const DumpValueObjectOptions& options)
444d93b8cdSEnrico Granata {
45*26014690SGreg Clayton     Init(valobj,s,options,m_options.m_max_ptr_depth,0);
464d93b8cdSEnrico Granata }
474d93b8cdSEnrico Granata 
484d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
494d93b8cdSEnrico Granata                                         Stream* s,
504d93b8cdSEnrico Granata                                         const DumpValueObjectOptions& options,
51c1b7c09aSEnrico Granata                                         const DumpValueObjectOptions::PointerDepth& ptr_depth,
52938d1d67SEnrico Granata                                         uint32_t curr_depth)
53938d1d67SEnrico Granata {
54938d1d67SEnrico Granata     Init(valobj,s,options,ptr_depth,curr_depth);
55938d1d67SEnrico Granata }
56938d1d67SEnrico Granata 
57938d1d67SEnrico Granata void
58938d1d67SEnrico Granata ValueObjectPrinter::Init (ValueObject* valobj,
59938d1d67SEnrico Granata                           Stream* s,
60938d1d67SEnrico Granata                           const DumpValueObjectOptions& options,
61c1b7c09aSEnrico Granata                           const DumpValueObjectOptions::PointerDepth& ptr_depth,
62938d1d67SEnrico Granata                           uint32_t curr_depth)
63938d1d67SEnrico Granata {
64938d1d67SEnrico Granata     m_orig_valobj = valobj;
65938d1d67SEnrico Granata     m_valobj = nullptr;
66938d1d67SEnrico Granata     m_stream = s;
67*26014690SGreg Clayton     m_options = options;
68938d1d67SEnrico Granata     m_ptr_depth = ptr_depth;
69938d1d67SEnrico Granata     m_curr_depth = curr_depth;
70938d1d67SEnrico Granata     assert (m_orig_valobj && "cannot print a NULL ValueObject");
71938d1d67SEnrico Granata     assert (m_stream && "cannot print to a NULL Stream");
72938d1d67SEnrico Granata     m_should_print = eLazyBoolCalculate;
73938d1d67SEnrico Granata     m_is_nil = eLazyBoolCalculate;
74938d1d67SEnrico Granata     m_is_ptr = eLazyBoolCalculate;
75938d1d67SEnrico Granata     m_is_ref = eLazyBoolCalculate;
76938d1d67SEnrico Granata     m_is_aggregate = eLazyBoolCalculate;
77938d1d67SEnrico Granata     m_summary_formatter = {nullptr,false};
78938d1d67SEnrico Granata     m_value.assign("");
79938d1d67SEnrico Granata     m_summary.assign("");
80938d1d67SEnrico Granata     m_error.assign("");
81938d1d67SEnrico Granata }
824d93b8cdSEnrico Granata 
834d93b8cdSEnrico Granata bool
844d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueObject ()
854d93b8cdSEnrico Granata {
86d07cfd3aSEnrico Granata     if (!GetMostSpecializedValue () || m_valobj == nullptr)
874d93b8cdSEnrico Granata         return false;
884d93b8cdSEnrico Granata 
894d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
904d93b8cdSEnrico Granata     {
910f883ffbSEnrico Granata         PrintValidationMarkerIfNeeded();
920f883ffbSEnrico Granata 
934d93b8cdSEnrico Granata         PrintLocationIfNeeded();
944d93b8cdSEnrico Granata         m_stream->Indent();
954d93b8cdSEnrico Granata 
96e0ee1e1cSEnrico Granata         PrintDecl();
974d93b8cdSEnrico Granata     }
984d93b8cdSEnrico Granata 
994d93b8cdSEnrico Granata     bool value_printed = false;
1004d93b8cdSEnrico Granata     bool summary_printed = false;
1014d93b8cdSEnrico Granata 
1024d93b8cdSEnrico Granata     bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
1034d93b8cdSEnrico Granata 
1044d93b8cdSEnrico Granata     if (val_summary_ok)
1054d93b8cdSEnrico Granata         PrintChildrenIfNeeded (value_printed, summary_printed);
10639938938SEnrico Granata     else
1074d93b8cdSEnrico Granata         m_stream->EOL();
1084d93b8cdSEnrico Granata 
1090f883ffbSEnrico Granata     PrintValidationErrorIfNeeded();
1100f883ffbSEnrico Granata 
1114d93b8cdSEnrico Granata     return true;
1124d93b8cdSEnrico Granata }
1134d93b8cdSEnrico Granata 
1144d93b8cdSEnrico Granata bool
115d07cfd3aSEnrico Granata ValueObjectPrinter::GetMostSpecializedValue ()
1164d93b8cdSEnrico Granata {
117a29cb0baSEnrico Granata     if (m_valobj)
118a29cb0baSEnrico Granata         return true;
1194d93b8cdSEnrico Granata     bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
1204d93b8cdSEnrico Granata     if (!update_success)
121106260c5SEnrico Granata     {
122106260c5SEnrico Granata         m_valobj = m_orig_valobj;
123106260c5SEnrico Granata     }
124106260c5SEnrico Granata     else
125106260c5SEnrico Granata     {
126106260c5SEnrico Granata         if (m_orig_valobj->IsDynamic())
127106260c5SEnrico Granata         {
128*26014690SGreg Clayton             if (m_options.m_use_dynamic == eNoDynamicValues)
129106260c5SEnrico Granata             {
130106260c5SEnrico Granata                 ValueObject *static_value = m_orig_valobj->GetStaticValue().get();
131106260c5SEnrico Granata                 if (static_value)
132106260c5SEnrico Granata                     m_valobj = static_value;
133106260c5SEnrico Granata                 else
134106260c5SEnrico Granata                     m_valobj = m_orig_valobj;
135106260c5SEnrico Granata             }
136106260c5SEnrico Granata             else
137106260c5SEnrico Granata                 m_valobj = m_orig_valobj;
138106260c5SEnrico Granata         }
139106260c5SEnrico Granata         else
140106260c5SEnrico Granata         {
141*26014690SGreg Clayton             if (m_options.m_use_dynamic != eNoDynamicValues)
1424d93b8cdSEnrico Granata             {
143*26014690SGreg Clayton                 ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get();
1444d93b8cdSEnrico Granata                 if (dynamic_value)
1454d93b8cdSEnrico Granata                     m_valobj = dynamic_value;
1464d93b8cdSEnrico Granata                 else
1474d93b8cdSEnrico Granata                     m_valobj = m_orig_valobj;
1484d93b8cdSEnrico Granata             }
1494d93b8cdSEnrico Granata             else
1504d93b8cdSEnrico Granata                 m_valobj = m_orig_valobj;
151106260c5SEnrico Granata         }
152d07cfd3aSEnrico Granata 
153d07cfd3aSEnrico Granata         if (m_valobj->IsSynthetic())
154d07cfd3aSEnrico Granata         {
155*26014690SGreg Clayton             if (m_options.m_use_synthetic == false)
156d07cfd3aSEnrico Granata             {
157d07cfd3aSEnrico Granata                 ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
158d07cfd3aSEnrico Granata                 if (non_synthetic)
159d07cfd3aSEnrico Granata                     m_valobj = non_synthetic;
160d07cfd3aSEnrico Granata             }
161d07cfd3aSEnrico Granata         }
162d07cfd3aSEnrico Granata         else
163d07cfd3aSEnrico Granata         {
164*26014690SGreg Clayton             if (m_options.m_use_synthetic == true)
165d07cfd3aSEnrico Granata             {
166d07cfd3aSEnrico Granata                 ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
167d07cfd3aSEnrico Granata                 if (synthetic)
168d07cfd3aSEnrico Granata                     m_valobj = synthetic;
169d07cfd3aSEnrico Granata             }
170d07cfd3aSEnrico Granata         }
171106260c5SEnrico Granata     }
17259b5a37dSBruce Mitchener     m_compiler_type = m_valobj->GetCompilerType();
17359b5a37dSBruce Mitchener     m_type_flags = m_compiler_type.GetTypeInfo ();
1744d93b8cdSEnrico Granata     return true;
1754d93b8cdSEnrico Granata }
1764d93b8cdSEnrico Granata 
1774d93b8cdSEnrico Granata const char*
1784d93b8cdSEnrico Granata ValueObjectPrinter::GetDescriptionForDisplay ()
1794d93b8cdSEnrico Granata {
1804d93b8cdSEnrico Granata     const char* str = m_valobj->GetObjectDescription();
1814d93b8cdSEnrico Granata     if (!str)
1824d93b8cdSEnrico Granata         str = m_valobj->GetSummaryAsCString();
1834d93b8cdSEnrico Granata     if (!str)
1844d93b8cdSEnrico Granata         str = m_valobj->GetValueAsCString();
1854d93b8cdSEnrico Granata     return str;
1864d93b8cdSEnrico Granata }
1874d93b8cdSEnrico Granata 
1884d93b8cdSEnrico Granata const char*
1894d93b8cdSEnrico Granata ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
1904d93b8cdSEnrico Granata {
191*26014690SGreg Clayton     const char *root_valobj_name = m_options.m_root_valobj_name.empty() ?
1924d93b8cdSEnrico Granata         m_valobj->GetName().AsCString() :
193*26014690SGreg Clayton         m_options.m_root_valobj_name.c_str();
1944d93b8cdSEnrico Granata     return root_valobj_name ? root_valobj_name : if_fail;
1954d93b8cdSEnrico Granata }
1964d93b8cdSEnrico Granata 
1974d93b8cdSEnrico Granata bool
1984d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintValueObject ()
1994d93b8cdSEnrico Granata {
2004d93b8cdSEnrico Granata     if (m_should_print == eLazyBoolCalculate)
201*26014690SGreg Clayton         m_should_print = (m_options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
2024d93b8cdSEnrico Granata     return m_should_print == eLazyBoolYes;
2034d93b8cdSEnrico Granata }
2044d93b8cdSEnrico Granata 
2054d93b8cdSEnrico Granata bool
2064d93b8cdSEnrico Granata ValueObjectPrinter::IsNil ()
2074d93b8cdSEnrico Granata {
2084d93b8cdSEnrico Granata     if (m_is_nil == eLazyBoolCalculate)
2094d93b8cdSEnrico Granata         m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo;
2104d93b8cdSEnrico Granata     return m_is_nil == eLazyBoolYes;
2114d93b8cdSEnrico Granata }
2124d93b8cdSEnrico Granata 
2134d93b8cdSEnrico Granata bool
2144d93b8cdSEnrico Granata ValueObjectPrinter::IsPtr ()
2154d93b8cdSEnrico Granata {
2164d93b8cdSEnrico Granata     if (m_is_ptr == eLazyBoolCalculate)
217622be238SEnrico Granata         m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
2184d93b8cdSEnrico Granata     return m_is_ptr == eLazyBoolYes;
2194d93b8cdSEnrico Granata }
2204d93b8cdSEnrico Granata 
2214d93b8cdSEnrico Granata bool
2224d93b8cdSEnrico Granata ValueObjectPrinter::IsRef ()
2234d93b8cdSEnrico Granata {
2244d93b8cdSEnrico Granata     if (m_is_ref == eLazyBoolCalculate)
225622be238SEnrico Granata         m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
2264d93b8cdSEnrico Granata     return m_is_ref == eLazyBoolYes;
2274d93b8cdSEnrico Granata }
2284d93b8cdSEnrico Granata 
2294d93b8cdSEnrico Granata bool
2304d93b8cdSEnrico Granata ValueObjectPrinter::IsAggregate ()
2314d93b8cdSEnrico Granata {
2324d93b8cdSEnrico Granata     if (m_is_aggregate == eLazyBoolCalculate)
233622be238SEnrico Granata         m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
2344d93b8cdSEnrico Granata     return m_is_aggregate == eLazyBoolYes;
2354d93b8cdSEnrico Granata }
2364d93b8cdSEnrico Granata 
2374d93b8cdSEnrico Granata bool
2384d93b8cdSEnrico Granata ValueObjectPrinter::PrintLocationIfNeeded ()
2394d93b8cdSEnrico Granata {
240*26014690SGreg Clayton     if (m_options.m_show_location)
2414d93b8cdSEnrico Granata     {
2424d93b8cdSEnrico Granata         m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
2434d93b8cdSEnrico Granata         return true;
2444d93b8cdSEnrico Granata     }
2454d93b8cdSEnrico Granata     return false;
2464d93b8cdSEnrico Granata }
2474d93b8cdSEnrico Granata 
248e0ee1e1cSEnrico Granata void
249e0ee1e1cSEnrico Granata ValueObjectPrinter::PrintDecl ()
2504d93b8cdSEnrico Granata {
2514d93b8cdSEnrico Granata     bool show_type = true;
2524d93b8cdSEnrico Granata     // if we are at the root-level and been asked to hide the root's type, then hide it
253*26014690SGreg Clayton     if (m_curr_depth == 0 && m_options.m_hide_root_type)
2544d93b8cdSEnrico Granata         show_type = false;
2554d93b8cdSEnrico Granata     else
2564d93b8cdSEnrico Granata         // otherwise decide according to the usual rules (asked to show types - always at the root level)
257*26014690SGreg Clayton         show_type = m_options.m_show_types || (m_curr_depth == 0 && !m_options.m_flat_output);
2584d93b8cdSEnrico Granata 
259e0ee1e1cSEnrico Granata     StreamString typeName;
260e0ee1e1cSEnrico Granata 
261e0ee1e1cSEnrico Granata     // always show the type at the root level if it is invalid
2624d93b8cdSEnrico Granata     if (show_type)
2634d93b8cdSEnrico Granata     {
2644d93b8cdSEnrico Granata         // Some ValueObjects don't have types (like registers sets). Only print
2654d93b8cdSEnrico Granata         // the type if there is one to print
266a126e462SEnrico Granata         ConstString type_name;
267e0ee1e1cSEnrico Granata         if (m_compiler_type.IsValid())
268e0ee1e1cSEnrico Granata         {
269*26014690SGreg Clayton             if (m_options.m_use_type_display_name)
270a126e462SEnrico Granata                 type_name = m_valobj->GetDisplayTypeName();
271e8daa2f8SEnrico Granata             else
272a126e462SEnrico Granata                 type_name = m_valobj->GetQualifiedTypeName();
2734d93b8cdSEnrico Granata         }
274e0ee1e1cSEnrico Granata         else
275e0ee1e1cSEnrico Granata         {
276e0ee1e1cSEnrico Granata             // only show an invalid type name if the user explicitly triggered show_type
277*26014690SGreg Clayton             if (m_options.m_show_types)
278e0ee1e1cSEnrico Granata                 type_name = ConstString("<invalid type>");
279e0ee1e1cSEnrico Granata             else
280e0ee1e1cSEnrico Granata                 type_name.Clear();
2814d93b8cdSEnrico Granata         }
2824d93b8cdSEnrico Granata 
283e0ee1e1cSEnrico Granata         if (type_name)
2844d93b8cdSEnrico Granata         {
285e0ee1e1cSEnrico Granata             std::string type_name_str(type_name.GetCString());
286*26014690SGreg Clayton             if (m_options.m_hide_pointer_value)
287e0ee1e1cSEnrico Granata             {
288e0ee1e1cSEnrico Granata                 for(auto iter = type_name_str.find(" *");
289e0ee1e1cSEnrico Granata                     iter != std::string::npos;
290e0ee1e1cSEnrico Granata                     iter = type_name_str.find(" *"))
291e0ee1e1cSEnrico Granata                 {
292e0ee1e1cSEnrico Granata                     type_name_str.erase(iter, 2);
293e0ee1e1cSEnrico Granata                 }
294e0ee1e1cSEnrico Granata             }
295c8e7649aSEnrico Granata             typeName.Printf("%s", type_name_str.c_str());
296e0ee1e1cSEnrico Granata         }
297e0ee1e1cSEnrico Granata     }
298e0ee1e1cSEnrico Granata 
299e0ee1e1cSEnrico Granata     StreamString varName;
300e0ee1e1cSEnrico Granata 
301*26014690SGreg Clayton     if (m_options.m_flat_output)
3024d93b8cdSEnrico Granata     {
3034d93b8cdSEnrico Granata         // If we are showing types, also qualify the C++ base classes
3044d93b8cdSEnrico Granata         const bool qualify_cxx_base_classes = show_type;
305*26014690SGreg Clayton         if (!m_options.m_hide_name)
3064d93b8cdSEnrico Granata         {
307e0ee1e1cSEnrico Granata             m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes);
3084d93b8cdSEnrico Granata         }
3094d93b8cdSEnrico Granata     }
310*26014690SGreg Clayton     else if (!m_options.m_hide_name)
3114d93b8cdSEnrico Granata     {
3124d93b8cdSEnrico Granata         const char *name_cstr = GetRootNameForDisplay("");
313e0ee1e1cSEnrico Granata         varName.Printf ("%s", name_cstr);
3144d93b8cdSEnrico Granata     }
315e0ee1e1cSEnrico Granata 
316e0ee1e1cSEnrico Granata     bool decl_printed = false;
317*26014690SGreg Clayton     if (!m_options.m_decl_printing_helper)
318c8e7649aSEnrico Granata     {
319c8e7649aSEnrico Granata         // 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
320*26014690SGreg Clayton         lldb::LanguageType lang_type = (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) ? m_valobj->GetPreferredDisplayLanguage() : m_options.m_varformat_language;
321c8e7649aSEnrico Granata         if (Language *lang_plugin = Language::FindPlugin(lang_type))
322c8e7649aSEnrico Granata         {
323*26014690SGreg Clayton             m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper();
324c8e7649aSEnrico Granata         }
325c8e7649aSEnrico Granata     }
326c8e7649aSEnrico Granata 
327*26014690SGreg Clayton     if (m_options.m_decl_printing_helper)
328e0ee1e1cSEnrico Granata     {
329e0ee1e1cSEnrico Granata         ConstString type_name_cstr(typeName.GetData());
330e0ee1e1cSEnrico Granata         ConstString var_name_cstr(varName.GetData());
331e0ee1e1cSEnrico Granata 
332e0ee1e1cSEnrico Granata         StreamString dest_stream;
333*26014690SGreg Clayton         if (m_options.m_decl_printing_helper (type_name_cstr,
334e0ee1e1cSEnrico Granata                                               var_name_cstr,
335*26014690SGreg Clayton                                               m_options,
336e0ee1e1cSEnrico Granata                                               dest_stream))
337e0ee1e1cSEnrico Granata         {
338e0ee1e1cSEnrico Granata             decl_printed = true;
339e0ee1e1cSEnrico Granata             m_stream->Printf("%s", dest_stream.GetData());
340e0ee1e1cSEnrico Granata         }
341e0ee1e1cSEnrico Granata     }
342e0ee1e1cSEnrico Granata 
343c8e7649aSEnrico Granata     // if the helper failed, or there is none, do a default thing
344e0ee1e1cSEnrico Granata     if (!decl_printed)
345e0ee1e1cSEnrico Granata     {
346e0ee1e1cSEnrico Granata         if (typeName.GetSize())
347c8e7649aSEnrico Granata             m_stream->Printf("(%s) ", typeName.GetData());
348e0ee1e1cSEnrico Granata         if (varName.GetSize())
349e0ee1e1cSEnrico Granata             m_stream->Printf("%s =", varName.GetData());
350*26014690SGreg Clayton         else if (!m_options.m_hide_name)
351e0ee1e1cSEnrico Granata             m_stream->Printf(" =");
352e0ee1e1cSEnrico Granata     }
3534d93b8cdSEnrico Granata }
3544d93b8cdSEnrico Granata 
3554d93b8cdSEnrico Granata bool
3564d93b8cdSEnrico Granata ValueObjectPrinter::CheckScopeIfNeeded ()
3574d93b8cdSEnrico Granata {
358*26014690SGreg Clayton     if (m_options.m_scope_already_checked)
3594d93b8cdSEnrico Granata         return true;
3604d93b8cdSEnrico Granata     return m_valobj->IsInScope();
3614d93b8cdSEnrico Granata }
3624d93b8cdSEnrico Granata 
3634d93b8cdSEnrico Granata TypeSummaryImpl*
3644d93b8cdSEnrico Granata ValueObjectPrinter::GetSummaryFormatter ()
3654d93b8cdSEnrico Granata {
3664d93b8cdSEnrico Granata     if (m_summary_formatter.second == false)
3674d93b8cdSEnrico Granata     {
368*26014690SGreg Clayton         TypeSummaryImpl* entry = m_options.m_summary_sp ? m_options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
3694d93b8cdSEnrico Granata 
370*26014690SGreg Clayton         if (m_options.m_omit_summary_depth > 0)
3714d93b8cdSEnrico Granata             entry = NULL;
3724d93b8cdSEnrico Granata         m_summary_formatter.first = entry;
3734d93b8cdSEnrico Granata         m_summary_formatter.second = true;
3744d93b8cdSEnrico Granata     }
3754d93b8cdSEnrico Granata     return m_summary_formatter.first;
3764d93b8cdSEnrico Granata }
3774d93b8cdSEnrico Granata 
378e0ee1e1cSEnrico Granata static bool
379e0ee1e1cSEnrico Granata IsPointerValue (const CompilerType &type)
380e0ee1e1cSEnrico Granata {
381e0ee1e1cSEnrico Granata     Flags type_flags(type.GetTypeInfo());
382e0ee1e1cSEnrico Granata     if (type_flags.AnySet(eTypeIsPointer))
383e0ee1e1cSEnrico Granata         return type_flags.AllClear(eTypeIsBuiltIn);
384e0ee1e1cSEnrico Granata     return false;
385e0ee1e1cSEnrico Granata }
386e0ee1e1cSEnrico Granata 
3874d93b8cdSEnrico Granata void
3884d93b8cdSEnrico Granata ValueObjectPrinter::GetValueSummaryError (std::string& value,
3894d93b8cdSEnrico Granata                                           std::string& summary,
3904d93b8cdSEnrico Granata                                           std::string& error)
3914d93b8cdSEnrico Granata {
392*26014690SGreg Clayton     if (m_options.m_format != eFormatDefault && m_options.m_format != m_valobj->GetFormat())
3934d93b8cdSEnrico Granata     {
394*26014690SGreg Clayton         m_valobj->GetValueAsCString(m_options.m_format,
395465f4bc2SEnrico Granata                                     value);
3964d93b8cdSEnrico Granata     }
397465f4bc2SEnrico Granata     else
398465f4bc2SEnrico Granata     {
3994d93b8cdSEnrico Granata         const char* val_cstr = m_valobj->GetValueAsCString();
400465f4bc2SEnrico Granata         if (val_cstr)
401465f4bc2SEnrico Granata             value.assign(val_cstr);
402465f4bc2SEnrico Granata     }
4034d93b8cdSEnrico Granata     const char* err_cstr = m_valobj->GetError().AsCString();
4044d93b8cdSEnrico Granata     if (err_cstr)
4054d93b8cdSEnrico Granata         error.assign(err_cstr);
4064d93b8cdSEnrico Granata 
4074d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
4084d93b8cdSEnrico Granata     {
4094d93b8cdSEnrico Granata         if (IsNil())
4104d93b8cdSEnrico Granata             summary.assign("nil");
411*26014690SGreg Clayton         else if (m_options.m_omit_summary_depth == 0)
4124d93b8cdSEnrico Granata         {
4134d93b8cdSEnrico Granata             TypeSummaryImpl* entry = GetSummaryFormatter();
4144d93b8cdSEnrico Granata             if (entry)
415*26014690SGreg Clayton                 m_valobj->GetSummaryAsCString(entry, summary, m_options.m_varformat_language);
4164d93b8cdSEnrico Granata             else
4174d93b8cdSEnrico Granata             {
418*26014690SGreg Clayton                 const char* sum_cstr = m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
4194d93b8cdSEnrico Granata                 if (sum_cstr)
4204d93b8cdSEnrico Granata                     summary.assign(sum_cstr);
4214d93b8cdSEnrico Granata             }
4224d93b8cdSEnrico Granata         }
4234d93b8cdSEnrico Granata     }
4244d93b8cdSEnrico Granata }
4254d93b8cdSEnrico Granata 
4264d93b8cdSEnrico Granata bool
4274d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
4284d93b8cdSEnrico Granata                                                   bool& summary_printed)
4294d93b8cdSEnrico Granata {
4304d93b8cdSEnrico Granata     bool error_printed = false;
4314d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
4324d93b8cdSEnrico Granata     {
4334d93b8cdSEnrico Granata         if (!CheckScopeIfNeeded())
4344d93b8cdSEnrico Granata             m_error.assign("out of scope");
4354d93b8cdSEnrico Granata         if (m_error.empty())
4364d93b8cdSEnrico Granata         {
4374d93b8cdSEnrico Granata             GetValueSummaryError(m_value, m_summary, m_error);
4384d93b8cdSEnrico Granata         }
4394d93b8cdSEnrico Granata         if (m_error.size())
4404d93b8cdSEnrico Granata         {
4414d93b8cdSEnrico Granata             error_printed = true;
4424d93b8cdSEnrico Granata             m_stream->Printf (" <%s>\n", m_error.c_str());
4434d93b8cdSEnrico Granata         }
4444d93b8cdSEnrico Granata         else
4454d93b8cdSEnrico Granata         {
4464d93b8cdSEnrico Granata             // Make sure we have a value and make sure the summary didn't
4474d93b8cdSEnrico Granata             // specify that the value should not be printed - and do not print
4484d93b8cdSEnrico Granata             // the value if this thing is nil
4494d93b8cdSEnrico Granata             // (but show the value if the user passes a format explicitly)
4504d93b8cdSEnrico Granata             TypeSummaryImpl* entry = GetSummaryFormatter();
451*26014690SGreg Clayton             if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || m_options.m_format != eFormatDefault) || m_summary.empty()) && !m_options.m_hide_value)
4524d93b8cdSEnrico Granata             {
453*26014690SGreg Clayton                 if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {}
454e0ee1e1cSEnrico Granata                 else
455e0ee1e1cSEnrico Granata                 {
4564d93b8cdSEnrico Granata                     m_stream->Printf(" %s", m_value.c_str());
4574d93b8cdSEnrico Granata                     value_printed = true;
4584d93b8cdSEnrico Granata                 }
459e0ee1e1cSEnrico Granata             }
4604d93b8cdSEnrico Granata 
4614d93b8cdSEnrico Granata             if (m_summary.size())
4624d93b8cdSEnrico Granata             {
4634d93b8cdSEnrico Granata                 m_stream->Printf(" %s", m_summary.c_str());
4644d93b8cdSEnrico Granata                 summary_printed = true;
4654d93b8cdSEnrico Granata             }
4664d93b8cdSEnrico Granata         }
4674d93b8cdSEnrico Granata     }
4684d93b8cdSEnrico Granata     return !error_printed;
4694d93b8cdSEnrico Granata }
4704d93b8cdSEnrico Granata 
4714d93b8cdSEnrico Granata bool
4724d93b8cdSEnrico Granata ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
4734d93b8cdSEnrico Granata                                                     bool summary_printed)
4744d93b8cdSEnrico Granata {
4754d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
4764d93b8cdSEnrico Granata     {
4774d93b8cdSEnrico Granata         // let's avoid the overly verbose no description error for a nil thing
478*26014690SGreg Clayton         if (m_options.m_use_objc && !IsNil())
4794d93b8cdSEnrico Granata         {
480*26014690SGreg Clayton             if (!m_options.m_hide_value || !m_options.m_hide_name)
4814d93b8cdSEnrico Granata                 m_stream->Printf(" ");
4824d93b8cdSEnrico Granata             const char *object_desc = nullptr;
4834d93b8cdSEnrico Granata             if (value_printed || summary_printed)
4844d93b8cdSEnrico Granata                 object_desc = m_valobj->GetObjectDescription();
4854d93b8cdSEnrico Granata             else
4864d93b8cdSEnrico Granata                 object_desc = GetDescriptionForDisplay();
4874d93b8cdSEnrico Granata             if (object_desc && *object_desc)
4884d93b8cdSEnrico Granata             {
4894d93b8cdSEnrico Granata                 m_stream->Printf("%s\n", object_desc);
4904d93b8cdSEnrico Granata                 return true;
4914d93b8cdSEnrico Granata             }
4924d93b8cdSEnrico Granata             else if (value_printed == false && summary_printed == false)
4934d93b8cdSEnrico Granata                 return true;
4944d93b8cdSEnrico Granata             else
4954d93b8cdSEnrico Granata                 return false;
4964d93b8cdSEnrico Granata         }
4974d93b8cdSEnrico Granata     }
4984d93b8cdSEnrico Granata     return true;
4994d93b8cdSEnrico Granata }
5004d93b8cdSEnrico Granata 
5014d93b8cdSEnrico Granata bool
502c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root,
503c1b7c09aSEnrico Granata                                                          TypeSummaryImpl* entry,
504c1b7c09aSEnrico Granata                                                          ValueObject *valobj,
505c1b7c09aSEnrico Granata                                                          const std::string& summary)
506c1b7c09aSEnrico Granata {
507c1b7c09aSEnrico Granata     switch (m_mode)
508c1b7c09aSEnrico Granata     {
509c1b7c09aSEnrico Granata         case Mode::Always:
510c1b7c09aSEnrico Granata             return (m_count > 0);
511c1b7c09aSEnrico Granata         case Mode::Never:
512c1b7c09aSEnrico Granata             return false;
513c1b7c09aSEnrico Granata         case Mode::Default:
514c1b7c09aSEnrico Granata             if (is_root)
515c1b7c09aSEnrico Granata                 m_count = std::min<decltype(m_count)>(m_count,1);
516c1b7c09aSEnrico Granata             return m_count > 0;
517c1b7c09aSEnrico Granata         case Mode::Formatters:
518c1b7c09aSEnrico Granata             if (!entry || entry->DoesPrintChildren(valobj) || summary.empty())
519c1b7c09aSEnrico Granata                 return m_count > 0;
520c1b7c09aSEnrico Granata             return false;
521c1b7c09aSEnrico Granata     }
52284f5b0dfSZachary Turner     return false;
523c1b7c09aSEnrico Granata }
524c1b7c09aSEnrico Granata 
525c1b7c09aSEnrico Granata bool
526c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const
527c1b7c09aSEnrico Granata {
528c1b7c09aSEnrico Granata     switch (m_mode)
529c1b7c09aSEnrico Granata     {
530c1b7c09aSEnrico Granata         case Mode::Always:
531c1b7c09aSEnrico Granata         case Mode::Default:
532c1b7c09aSEnrico Granata         case Mode::Formatters:
533c1b7c09aSEnrico Granata             return (m_count > 0);
534c1b7c09aSEnrico Granata         case Mode::Never:
535c1b7c09aSEnrico Granata             return false;
536c1b7c09aSEnrico Granata     }
53784f5b0dfSZachary Turner     return false;
538c1b7c09aSEnrico Granata }
539c1b7c09aSEnrico Granata 
540c1b7c09aSEnrico Granata bool
5414d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
542c1b7c09aSEnrico Granata                                          DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
5434d93b8cdSEnrico Granata {
5444d93b8cdSEnrico Granata     const bool is_ref = IsRef ();
5454d93b8cdSEnrico Granata     const bool is_ptr = IsPtr ();
5464d93b8cdSEnrico Granata 
547c1b7c09aSEnrico Granata     TypeSummaryImpl* entry = GetSummaryFormatter();
548c1b7c09aSEnrico Granata 
549*26014690SGreg Clayton     if (is_failed_description || m_curr_depth < m_options.m_max_depth)
5504d93b8cdSEnrico Granata     {
5514d93b8cdSEnrico Granata         // We will show children for all concrete types. We won't show
5524d93b8cdSEnrico Granata         // pointer contents unless a pointer depth has been specified.
5534d93b8cdSEnrico Granata         // We won't reference contents unless the reference is the
5544d93b8cdSEnrico Granata         // root object (depth of zero).
5554d93b8cdSEnrico Granata 
5564d93b8cdSEnrico Granata         // Use a new temporary pointer depth in case we override the
5574d93b8cdSEnrico Granata         // current pointer depth below...
5584d93b8cdSEnrico Granata 
5594d93b8cdSEnrico Granata         if (is_ptr || is_ref)
5604d93b8cdSEnrico Granata         {
5614d93b8cdSEnrico Granata             // We have a pointer or reference whose value is an address.
5624d93b8cdSEnrico Granata             // Make sure that address is not NULL
5634d93b8cdSEnrico Granata             AddressType ptr_address_type;
5644d93b8cdSEnrico Granata             if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
5654d93b8cdSEnrico Granata                 return false;
5664d93b8cdSEnrico Granata 
567c1b7c09aSEnrico Granata             const bool is_root_level = m_curr_depth == 0;
568c1b7c09aSEnrico Granata 
569c1b7c09aSEnrico Granata             if (is_ref &&
570c1b7c09aSEnrico Granata                 is_root_level)
5714d93b8cdSEnrico Granata             {
5724d93b8cdSEnrico Granata                 // If this is the root object (depth is zero) that we are showing
5734d93b8cdSEnrico Granata                 // and it is a reference, and no pointer depth has been supplied
5744d93b8cdSEnrico Granata                 // print out what it references. Don't do this at deeper depths
5754d93b8cdSEnrico Granata                 // otherwise we can end up with infinite recursion...
576c1b7c09aSEnrico Granata                 return true;
5774d93b8cdSEnrico Granata             }
5784d93b8cdSEnrico Granata 
579c1b7c09aSEnrico Granata             return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary);
5804d93b8cdSEnrico Granata         }
5814d93b8cdSEnrico Granata 
5828a068e6cSEnrico Granata         return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
5834d93b8cdSEnrico Granata     }
5844d93b8cdSEnrico Granata     return false;
5854d93b8cdSEnrico Granata }
5864d93b8cdSEnrico Granata 
587d26eb907SSiva Chandra bool
588d26eb907SSiva Chandra ValueObjectPrinter::ShouldExpandEmptyAggregates ()
589d26eb907SSiva Chandra {
590d26eb907SSiva Chandra     TypeSummaryImpl* entry = GetSummaryFormatter();
591d26eb907SSiva Chandra 
592d26eb907SSiva Chandra     if (!entry)
593d26eb907SSiva Chandra         return true;
594d26eb907SSiva Chandra 
595d26eb907SSiva Chandra     return entry->DoesPrintEmptyAggregates();
596d26eb907SSiva Chandra }
597d26eb907SSiva Chandra 
5984d93b8cdSEnrico Granata ValueObject*
5994d93b8cdSEnrico Granata ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
6004d93b8cdSEnrico Granata {
601d07cfd3aSEnrico Granata     return m_valobj;
6024d93b8cdSEnrico Granata }
6034d93b8cdSEnrico Granata 
6044d93b8cdSEnrico Granata void
6054d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPreamble ()
6064d93b8cdSEnrico Granata {
607*26014690SGreg Clayton     if (m_options.m_flat_output)
6084d93b8cdSEnrico Granata     {
6094d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
6104d93b8cdSEnrico Granata             m_stream->EOL();
6114d93b8cdSEnrico Granata     }
6124d93b8cdSEnrico Granata     else
6134d93b8cdSEnrico Granata     {
6144d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
6154d93b8cdSEnrico Granata             m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
6164d93b8cdSEnrico Granata         m_stream->IndentMore();
6174d93b8cdSEnrico Granata     }
6184d93b8cdSEnrico Granata }
6194d93b8cdSEnrico Granata 
6204d93b8cdSEnrico Granata void
6214d93b8cdSEnrico Granata ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
622c1b7c09aSEnrico Granata                                 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
6234d93b8cdSEnrico Granata {
624*26014690SGreg Clayton     DumpValueObjectOptions child_options(m_options);
625*26014690SGreg Clayton     child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName();
626*26014690SGreg Clayton     child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value)
6274d93b8cdSEnrico Granata     .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
6284d93b8cdSEnrico Granata     if (child_sp.get())
6294d93b8cdSEnrico Granata     {
6304d93b8cdSEnrico Granata         ValueObjectPrinter child_printer(child_sp.get(),
6314d93b8cdSEnrico Granata                                          m_stream,
6324d93b8cdSEnrico Granata                                          child_options,
633c1b7c09aSEnrico Granata                                          (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth,
6344d93b8cdSEnrico Granata                                          m_curr_depth + 1);
6354d93b8cdSEnrico Granata         child_printer.PrintValueObject();
6364d93b8cdSEnrico Granata     }
6374d93b8cdSEnrico Granata }
6384d93b8cdSEnrico Granata 
6394d93b8cdSEnrico Granata uint32_t
6404d93b8cdSEnrico Granata ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
6414d93b8cdSEnrico Granata {
6424d93b8cdSEnrico Granata     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
6434d93b8cdSEnrico Granata 
6444d93b8cdSEnrico Granata     size_t num_children = synth_m_valobj->GetNumChildren();
6454d93b8cdSEnrico Granata     print_dotdotdot = false;
6464d93b8cdSEnrico Granata     if (num_children)
6474d93b8cdSEnrico Granata     {
6484d93b8cdSEnrico Granata         const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
6494d93b8cdSEnrico Granata 
650*26014690SGreg Clayton         if (num_children > max_num_children && !m_options.m_ignore_cap)
6514d93b8cdSEnrico Granata         {
6524d93b8cdSEnrico Granata             print_dotdotdot = true;
6534d93b8cdSEnrico Granata             return max_num_children;
6544d93b8cdSEnrico Granata         }
6554d93b8cdSEnrico Granata     }
6564d93b8cdSEnrico Granata     return num_children;
6574d93b8cdSEnrico Granata }
6584d93b8cdSEnrico Granata 
6594d93b8cdSEnrico Granata void
6604d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
6614d93b8cdSEnrico Granata {
662*26014690SGreg Clayton     if (!m_options.m_flat_output)
6634d93b8cdSEnrico Granata     {
6644d93b8cdSEnrico Granata         if (print_dotdotdot)
6654d93b8cdSEnrico Granata         {
6664d93b8cdSEnrico Granata             m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
6674d93b8cdSEnrico Granata             m_stream->Indent("...\n");
6684d93b8cdSEnrico Granata         }
6694d93b8cdSEnrico Granata         m_stream->IndentLess();
6704d93b8cdSEnrico Granata         m_stream->Indent("}\n");
6714d93b8cdSEnrico Granata     }
6724d93b8cdSEnrico Granata }
6734d93b8cdSEnrico Granata 
6744d93b8cdSEnrico Granata void
675c1b7c09aSEnrico Granata ValueObjectPrinter::PrintChildren (bool value_printed,
676c1b7c09aSEnrico Granata                                    bool summary_printed,
677c1b7c09aSEnrico Granata                                    const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
6784d93b8cdSEnrico Granata {
6794d93b8cdSEnrico Granata     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
6804d93b8cdSEnrico Granata 
6814d93b8cdSEnrico Granata     bool print_dotdotdot = false;
6824d93b8cdSEnrico Granata     size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
6834d93b8cdSEnrico Granata     if (num_children)
6844d93b8cdSEnrico Granata     {
6854d93b8cdSEnrico Granata         PrintChildrenPreamble ();
6864d93b8cdSEnrico Granata 
6874d93b8cdSEnrico Granata         for (size_t idx=0; idx<num_children; ++idx)
6884d93b8cdSEnrico Granata         {
6894d93b8cdSEnrico Granata             ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
6904d93b8cdSEnrico Granata             PrintChild (child_sp, curr_ptr_depth);
6914d93b8cdSEnrico Granata         }
6924d93b8cdSEnrico Granata 
6934d93b8cdSEnrico Granata         PrintChildrenPostamble (print_dotdotdot);
6944d93b8cdSEnrico Granata     }
6954d93b8cdSEnrico Granata     else if (IsAggregate())
6964d93b8cdSEnrico Granata     {
6974d93b8cdSEnrico Granata         // Aggregate, no children...
6984d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
699d07cfd3aSEnrico Granata         {
700d07cfd3aSEnrico Granata             // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
701d26eb907SSiva Chandra             if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates())
702d07cfd3aSEnrico Granata                 m_stream->PutCString( "\n");
703d07cfd3aSEnrico Granata             else
7044d93b8cdSEnrico Granata                 m_stream->PutCString(" {}\n");
7054d93b8cdSEnrico Granata         }
706d07cfd3aSEnrico Granata     }
7074d93b8cdSEnrico Granata     else
7084d93b8cdSEnrico Granata     {
7094d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
7104d93b8cdSEnrico Granata             m_stream->EOL();
7114d93b8cdSEnrico Granata     }
7124d93b8cdSEnrico Granata }
7134d93b8cdSEnrico Granata 
714a29cb0baSEnrico Granata bool
715a29cb0baSEnrico Granata ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
716a29cb0baSEnrico Granata {
717d07cfd3aSEnrico Granata     if (!GetMostSpecializedValue () || m_valobj == nullptr)
718a29cb0baSEnrico Granata         return false;
719a29cb0baSEnrico Granata 
720a29cb0baSEnrico Granata     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
721a29cb0baSEnrico Granata 
722a29cb0baSEnrico Granata     bool print_dotdotdot = false;
723a29cb0baSEnrico Granata     size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
724a29cb0baSEnrico Granata 
725a29cb0baSEnrico Granata     if (num_children)
726a29cb0baSEnrico Granata     {
727a29cb0baSEnrico Granata         m_stream->PutChar('(');
728a29cb0baSEnrico Granata 
729a29cb0baSEnrico Granata         for (uint32_t idx=0; idx<num_children; ++idx)
730a29cb0baSEnrico Granata         {
731a29cb0baSEnrico Granata             lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
732ddac7611SEnrico Granata             if (child_sp)
733*26014690SGreg Clayton                 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(m_options.m_use_dynamic, m_options.m_use_synthetic);
734a29cb0baSEnrico Granata             if (child_sp)
735a29cb0baSEnrico Granata             {
736a29cb0baSEnrico Granata                 if (idx)
737a29cb0baSEnrico Granata                     m_stream->PutCString(", ");
738a29cb0baSEnrico Granata                 if (!hide_names)
739a29cb0baSEnrico Granata                 {
740a29cb0baSEnrico Granata                     const char* name = child_sp.get()->GetName().AsCString();
741a29cb0baSEnrico Granata                     if (name && *name)
742a29cb0baSEnrico Granata                     {
743a29cb0baSEnrico Granata                         m_stream->PutCString(name);
744a29cb0baSEnrico Granata                         m_stream->PutCString(" = ");
745a29cb0baSEnrico Granata                     }
746a29cb0baSEnrico Granata                 }
747a29cb0baSEnrico Granata                 child_sp->DumpPrintableRepresentation(*m_stream,
748a29cb0baSEnrico Granata                                                       ValueObject::eValueObjectRepresentationStyleSummary,
749443844c4SEnrico Granata                                                       lldb::eFormatInvalid,
750a29cb0baSEnrico Granata                                                       ValueObject::ePrintableRepresentationSpecialCasesDisable);
751a29cb0baSEnrico Granata             }
752a29cb0baSEnrico Granata         }
753a29cb0baSEnrico Granata 
754a29cb0baSEnrico Granata         if (print_dotdotdot)
755a29cb0baSEnrico Granata             m_stream->PutCString(", ...)");
756a29cb0baSEnrico Granata         else
757a29cb0baSEnrico Granata             m_stream->PutChar(')');
758a29cb0baSEnrico Granata     }
759a29cb0baSEnrico Granata     return true;
760a29cb0baSEnrico Granata }
761a29cb0baSEnrico Granata 
7624d93b8cdSEnrico Granata void
7634d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
7644d93b8cdSEnrico Granata                                            bool summary_printed)
7654d93b8cdSEnrico Granata {
7664d93b8cdSEnrico Granata     // this flag controls whether we tried to display a description for this object and failed
7674d93b8cdSEnrico Granata     // if that happens, we want to display the children, if any
7684d93b8cdSEnrico Granata     bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
7694d93b8cdSEnrico Granata 
770c1b7c09aSEnrico Granata     auto curr_ptr_depth = m_ptr_depth;
7714d93b8cdSEnrico Granata     bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
772c1b7c09aSEnrico Granata     bool print_oneline = (curr_ptr_depth.CanAllowExpansion() ||
773*26014690SGreg Clayton                           m_options.m_show_types ||
774*26014690SGreg Clayton                           !m_options.m_allow_oneliner_mode ||
775*26014690SGreg Clayton                           m_options.m_flat_output ||
776*26014690SGreg Clayton                           m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
7774d93b8cdSEnrico Granata 
7784d93b8cdSEnrico Granata     if (print_children)
7794d93b8cdSEnrico Granata     {
780a29cb0baSEnrico Granata         if (print_oneline)
781a29cb0baSEnrico Granata         {
782a29cb0baSEnrico Granata             m_stream->PutChar(' ');
783a29cb0baSEnrico Granata             PrintChildrenOneLiner (false);
784a29cb0baSEnrico Granata             m_stream->EOL();
785a29cb0baSEnrico Granata         }
786a29cb0baSEnrico Granata         else
787c1b7c09aSEnrico Granata             PrintChildren (value_printed, summary_printed, curr_ptr_depth);
7884d93b8cdSEnrico Granata     }
789*26014690SGreg Clayton     else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
7904d93b8cdSEnrico Granata     {
7914d93b8cdSEnrico Granata             m_stream->PutCString("{...}\n");
7924d93b8cdSEnrico Granata     }
793245b3caaSEnrico Granata     else
794245b3caaSEnrico Granata         m_stream->EOL();
7954d93b8cdSEnrico Granata }
7960f883ffbSEnrico Granata 
7970f883ffbSEnrico Granata bool
7980f883ffbSEnrico Granata ValueObjectPrinter::ShouldPrintValidation ()
7990f883ffbSEnrico Granata {
800*26014690SGreg Clayton     return m_options.m_run_validator;
8010f883ffbSEnrico Granata }
8020f883ffbSEnrico Granata 
8030f883ffbSEnrico Granata bool
8040f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationMarkerIfNeeded ()
8050f883ffbSEnrico Granata {
8060f883ffbSEnrico Granata     if (!ShouldPrintValidation())
8070f883ffbSEnrico Granata         return false;
8080f883ffbSEnrico Granata 
8090f883ffbSEnrico Granata     m_validation = m_valobj->GetValidationStatus();
8100f883ffbSEnrico Granata 
8110f883ffbSEnrico Granata     if (TypeValidatorResult::Failure == m_validation.first)
8120f883ffbSEnrico Granata     {
8130f883ffbSEnrico Granata         m_stream->Printf("! ");
8140f883ffbSEnrico Granata         return true;
8150f883ffbSEnrico Granata     }
8160f883ffbSEnrico Granata 
8170f883ffbSEnrico Granata     return false;
8180f883ffbSEnrico Granata }
8190f883ffbSEnrico Granata 
8200f883ffbSEnrico Granata bool
8210f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationErrorIfNeeded ()
8220f883ffbSEnrico Granata {
8230f883ffbSEnrico Granata     if (!ShouldPrintValidation())
8240f883ffbSEnrico Granata         return false;
8250f883ffbSEnrico Granata 
8260f883ffbSEnrico Granata     if (TypeValidatorResult::Success == m_validation.first)
8270f883ffbSEnrico Granata         return false;
8280f883ffbSEnrico Granata 
8290f883ffbSEnrico Granata     if (m_validation.second.empty())
8300f883ffbSEnrico Granata         m_validation.second.assign("unknown error");
8310f883ffbSEnrico Granata 
8320f883ffbSEnrico Granata     m_stream->Printf(" ! validation error: %s", m_validation.second.c_str());
8330f883ffbSEnrico Granata     m_stream->EOL();
8340f883ffbSEnrico Granata 
8350f883ffbSEnrico Granata     return true;
8360f883ffbSEnrico Granata }
837