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);
328cf44d96SEnrico Granata         Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
33d5957336SEnrico Granata     }
34d5957336SEnrico Granata     else
35d5957336SEnrico Granata     {
36d5957336SEnrico Granata         DumpValueObjectOptions options;
378cf44d96SEnrico Granata         Init (valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
38d5957336SEnrico Granata     }
39d5957336SEnrico Granata }
40d5957336SEnrico Granata 
414d93b8cdSEnrico Granata ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
424d93b8cdSEnrico Granata                                         Stream* s,
43938d1d67SEnrico Granata                                         const DumpValueObjectOptions& options)
444d93b8cdSEnrico Granata {
458cf44d96SEnrico Granata     Init(valobj,s,options,m_options.m_max_ptr_depth,0, nullptr);
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,
528cf44d96SEnrico Granata                                         uint32_t curr_depth,
538cf44d96SEnrico Granata                                         InstancePointersSetSP printed_instance_pointers)
54938d1d67SEnrico Granata {
558cf44d96SEnrico Granata     Init(valobj,s,options,ptr_depth,curr_depth, printed_instance_pointers);
56938d1d67SEnrico Granata }
57938d1d67SEnrico Granata 
58938d1d67SEnrico Granata void
59938d1d67SEnrico Granata ValueObjectPrinter::Init (ValueObject* valobj,
60938d1d67SEnrico Granata                           Stream* s,
61938d1d67SEnrico Granata                           const DumpValueObjectOptions& options,
62c1b7c09aSEnrico Granata                           const DumpValueObjectOptions::PointerDepth& ptr_depth,
638cf44d96SEnrico Granata                           uint32_t curr_depth,
648cf44d96SEnrico Granata                           InstancePointersSetSP printed_instance_pointers)
65938d1d67SEnrico Granata {
66938d1d67SEnrico Granata     m_orig_valobj = valobj;
67938d1d67SEnrico Granata     m_valobj = nullptr;
68938d1d67SEnrico Granata     m_stream = s;
6926014690SGreg Clayton     m_options = options;
70938d1d67SEnrico Granata     m_ptr_depth = ptr_depth;
71938d1d67SEnrico Granata     m_curr_depth = curr_depth;
72938d1d67SEnrico Granata     assert (m_orig_valobj && "cannot print a NULL ValueObject");
73938d1d67SEnrico Granata     assert (m_stream && "cannot print to a NULL Stream");
74938d1d67SEnrico Granata     m_should_print = eLazyBoolCalculate;
75938d1d67SEnrico Granata     m_is_nil = eLazyBoolCalculate;
76608d67c1SEnrico Granata     m_is_uninit = eLazyBoolCalculate;
77938d1d67SEnrico Granata     m_is_ptr = eLazyBoolCalculate;
78938d1d67SEnrico Granata     m_is_ref = eLazyBoolCalculate;
79938d1d67SEnrico Granata     m_is_aggregate = eLazyBoolCalculate;
808cf44d96SEnrico Granata     m_is_instance_ptr = eLazyBoolCalculate;
81938d1d67SEnrico Granata     m_summary_formatter = {nullptr,false};
82938d1d67SEnrico Granata     m_value.assign("");
83938d1d67SEnrico Granata     m_summary.assign("");
84938d1d67SEnrico Granata     m_error.assign("");
858cf44d96SEnrico Granata     m_val_summary_ok = false;
868cf44d96SEnrico Granata     m_printed_instance_pointers = printed_instance_pointers ? printed_instance_pointers : InstancePointersSetSP(new InstancePointersSet());
87938d1d67SEnrico Granata }
884d93b8cdSEnrico Granata 
894d93b8cdSEnrico Granata bool
904d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueObject ()
914d93b8cdSEnrico Granata {
92d07cfd3aSEnrico Granata     if (!GetMostSpecializedValue () || m_valobj == nullptr)
934d93b8cdSEnrico Granata         return false;
944d93b8cdSEnrico Granata 
954d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
964d93b8cdSEnrico Granata     {
970f883ffbSEnrico Granata         PrintValidationMarkerIfNeeded();
980f883ffbSEnrico Granata 
994d93b8cdSEnrico Granata         PrintLocationIfNeeded();
1004d93b8cdSEnrico Granata         m_stream->Indent();
1014d93b8cdSEnrico Granata 
102e0ee1e1cSEnrico Granata         PrintDecl();
1034d93b8cdSEnrico Granata     }
1044d93b8cdSEnrico Granata 
1054d93b8cdSEnrico Granata     bool value_printed = false;
1064d93b8cdSEnrico Granata     bool summary_printed = false;
1074d93b8cdSEnrico Granata 
1088cf44d96SEnrico Granata     m_val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
1094d93b8cdSEnrico Granata 
1108cf44d96SEnrico Granata     if (m_val_summary_ok)
1114d93b8cdSEnrico Granata         PrintChildrenIfNeeded (value_printed, summary_printed);
11239938938SEnrico Granata     else
1134d93b8cdSEnrico Granata         m_stream->EOL();
1144d93b8cdSEnrico Granata 
1150f883ffbSEnrico Granata     PrintValidationErrorIfNeeded();
1160f883ffbSEnrico Granata 
1174d93b8cdSEnrico Granata     return true;
1184d93b8cdSEnrico Granata }
1194d93b8cdSEnrico Granata 
1204d93b8cdSEnrico Granata bool
121d07cfd3aSEnrico Granata ValueObjectPrinter::GetMostSpecializedValue ()
1224d93b8cdSEnrico Granata {
123a29cb0baSEnrico Granata     if (m_valobj)
124a29cb0baSEnrico Granata         return true;
1254d93b8cdSEnrico Granata     bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
1264d93b8cdSEnrico Granata     if (!update_success)
127106260c5SEnrico Granata     {
128106260c5SEnrico Granata         m_valobj = m_orig_valobj;
129106260c5SEnrico Granata     }
130106260c5SEnrico Granata     else
131106260c5SEnrico Granata     {
132106260c5SEnrico Granata         if (m_orig_valobj->IsDynamic())
133106260c5SEnrico Granata         {
13426014690SGreg Clayton             if (m_options.m_use_dynamic == eNoDynamicValues)
135106260c5SEnrico Granata             {
136106260c5SEnrico Granata                 ValueObject *static_value = m_orig_valobj->GetStaticValue().get();
137106260c5SEnrico Granata                 if (static_value)
138106260c5SEnrico Granata                     m_valobj = static_value;
139106260c5SEnrico Granata                 else
140106260c5SEnrico Granata                     m_valobj = m_orig_valobj;
141106260c5SEnrico Granata             }
142106260c5SEnrico Granata             else
143106260c5SEnrico Granata                 m_valobj = m_orig_valobj;
144106260c5SEnrico Granata         }
145106260c5SEnrico Granata         else
146106260c5SEnrico Granata         {
14726014690SGreg Clayton             if (m_options.m_use_dynamic != eNoDynamicValues)
1484d93b8cdSEnrico Granata             {
14926014690SGreg Clayton                 ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(m_options.m_use_dynamic).get();
1504d93b8cdSEnrico Granata                 if (dynamic_value)
1514d93b8cdSEnrico Granata                     m_valobj = dynamic_value;
1524d93b8cdSEnrico Granata                 else
1534d93b8cdSEnrico Granata                     m_valobj = m_orig_valobj;
1544d93b8cdSEnrico Granata             }
1554d93b8cdSEnrico Granata             else
1564d93b8cdSEnrico Granata                 m_valobj = m_orig_valobj;
157106260c5SEnrico Granata         }
158d07cfd3aSEnrico Granata 
159d07cfd3aSEnrico Granata         if (m_valobj->IsSynthetic())
160d07cfd3aSEnrico Granata         {
16126014690SGreg Clayton             if (m_options.m_use_synthetic == false)
162d07cfd3aSEnrico Granata             {
163d07cfd3aSEnrico Granata                 ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
164d07cfd3aSEnrico Granata                 if (non_synthetic)
165d07cfd3aSEnrico Granata                     m_valobj = non_synthetic;
166d07cfd3aSEnrico Granata             }
167d07cfd3aSEnrico Granata         }
168d07cfd3aSEnrico Granata         else
169d07cfd3aSEnrico Granata         {
17026014690SGreg Clayton             if (m_options.m_use_synthetic == true)
171d07cfd3aSEnrico Granata             {
172d07cfd3aSEnrico Granata                 ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
173d07cfd3aSEnrico Granata                 if (synthetic)
174d07cfd3aSEnrico Granata                     m_valobj = synthetic;
175d07cfd3aSEnrico Granata             }
176d07cfd3aSEnrico Granata         }
177106260c5SEnrico Granata     }
17859b5a37dSBruce Mitchener     m_compiler_type = m_valobj->GetCompilerType();
17959b5a37dSBruce Mitchener     m_type_flags = m_compiler_type.GetTypeInfo ();
1804d93b8cdSEnrico Granata     return true;
1814d93b8cdSEnrico Granata }
1824d93b8cdSEnrico Granata 
1834d93b8cdSEnrico Granata const char*
1844d93b8cdSEnrico Granata ValueObjectPrinter::GetDescriptionForDisplay ()
1854d93b8cdSEnrico Granata {
1864d93b8cdSEnrico Granata     const char* str = m_valobj->GetObjectDescription();
1874d93b8cdSEnrico Granata     if (!str)
1884d93b8cdSEnrico Granata         str = m_valobj->GetSummaryAsCString();
1894d93b8cdSEnrico Granata     if (!str)
1904d93b8cdSEnrico Granata         str = m_valobj->GetValueAsCString();
1914d93b8cdSEnrico Granata     return str;
1924d93b8cdSEnrico Granata }
1934d93b8cdSEnrico Granata 
1944d93b8cdSEnrico Granata const char*
1954d93b8cdSEnrico Granata ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
1964d93b8cdSEnrico Granata {
19726014690SGreg Clayton     const char *root_valobj_name = m_options.m_root_valobj_name.empty() ?
1984d93b8cdSEnrico Granata         m_valobj->GetName().AsCString() :
19926014690SGreg Clayton         m_options.m_root_valobj_name.c_str();
2004d93b8cdSEnrico Granata     return root_valobj_name ? root_valobj_name : if_fail;
2014d93b8cdSEnrico Granata }
2024d93b8cdSEnrico Granata 
2034d93b8cdSEnrico Granata bool
2044d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintValueObject ()
2054d93b8cdSEnrico Granata {
2064d93b8cdSEnrico Granata     if (m_should_print == eLazyBoolCalculate)
20726014690SGreg Clayton         m_should_print = (m_options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
2084d93b8cdSEnrico Granata     return m_should_print == eLazyBoolYes;
2094d93b8cdSEnrico Granata }
2104d93b8cdSEnrico Granata 
2114d93b8cdSEnrico Granata bool
2124d93b8cdSEnrico Granata ValueObjectPrinter::IsNil ()
2134d93b8cdSEnrico Granata {
2144d93b8cdSEnrico Granata     if (m_is_nil == eLazyBoolCalculate)
215608d67c1SEnrico Granata         m_is_nil = m_valobj->IsNilReference() ? eLazyBoolYes : eLazyBoolNo;
2164d93b8cdSEnrico Granata     return m_is_nil == eLazyBoolYes;
2174d93b8cdSEnrico Granata }
2184d93b8cdSEnrico Granata 
2194d93b8cdSEnrico Granata bool
220608d67c1SEnrico Granata ValueObjectPrinter::IsUninitialized ()
221608d67c1SEnrico Granata {
222608d67c1SEnrico Granata     if (m_is_uninit == eLazyBoolCalculate)
223608d67c1SEnrico Granata         m_is_uninit = m_valobj->IsUninitializedReference() ? eLazyBoolYes : eLazyBoolNo;
224608d67c1SEnrico Granata     return m_is_uninit == eLazyBoolYes;
225608d67c1SEnrico Granata }
226608d67c1SEnrico Granata 
227608d67c1SEnrico Granata bool
2284d93b8cdSEnrico Granata ValueObjectPrinter::IsPtr ()
2294d93b8cdSEnrico Granata {
2304d93b8cdSEnrico Granata     if (m_is_ptr == eLazyBoolCalculate)
231622be238SEnrico Granata         m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
2324d93b8cdSEnrico Granata     return m_is_ptr == eLazyBoolYes;
2334d93b8cdSEnrico Granata }
2344d93b8cdSEnrico Granata 
2354d93b8cdSEnrico Granata bool
2364d93b8cdSEnrico Granata ValueObjectPrinter::IsRef ()
2374d93b8cdSEnrico Granata {
2384d93b8cdSEnrico Granata     if (m_is_ref == eLazyBoolCalculate)
239622be238SEnrico Granata         m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
2404d93b8cdSEnrico Granata     return m_is_ref == eLazyBoolYes;
2414d93b8cdSEnrico Granata }
2424d93b8cdSEnrico Granata 
2434d93b8cdSEnrico Granata bool
2444d93b8cdSEnrico Granata ValueObjectPrinter::IsAggregate ()
2454d93b8cdSEnrico Granata {
2464d93b8cdSEnrico Granata     if (m_is_aggregate == eLazyBoolCalculate)
247622be238SEnrico Granata         m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
2484d93b8cdSEnrico Granata     return m_is_aggregate == eLazyBoolYes;
2494d93b8cdSEnrico Granata }
2504d93b8cdSEnrico Granata 
2514d93b8cdSEnrico Granata bool
2528cf44d96SEnrico Granata ValueObjectPrinter::IsInstancePointer ()
2538cf44d96SEnrico Granata {
2548cf44d96SEnrico Granata     // you need to do this check on the value's clang type
2558cf44d96SEnrico Granata     if (m_is_instance_ptr == eLazyBoolCalculate)
2568cf44d96SEnrico Granata         m_is_instance_ptr = (m_valobj->GetValue().GetCompilerType().GetTypeInfo() & eTypeInstanceIsPointer) != 0 ? eLazyBoolYes : eLazyBoolNo;
2578cf44d96SEnrico Granata     if ((eLazyBoolYes == m_is_instance_ptr) && m_valobj->IsBaseClass())
2588cf44d96SEnrico Granata         m_is_instance_ptr = eLazyBoolNo;
2598cf44d96SEnrico Granata     return m_is_instance_ptr == eLazyBoolYes;
2608cf44d96SEnrico Granata }
2618cf44d96SEnrico Granata 
2628cf44d96SEnrico Granata bool
2634d93b8cdSEnrico Granata ValueObjectPrinter::PrintLocationIfNeeded ()
2644d93b8cdSEnrico Granata {
26526014690SGreg Clayton     if (m_options.m_show_location)
2664d93b8cdSEnrico Granata     {
2674d93b8cdSEnrico Granata         m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
2684d93b8cdSEnrico Granata         return true;
2694d93b8cdSEnrico Granata     }
2704d93b8cdSEnrico Granata     return false;
2714d93b8cdSEnrico Granata }
2724d93b8cdSEnrico Granata 
273e0ee1e1cSEnrico Granata void
274e0ee1e1cSEnrico Granata ValueObjectPrinter::PrintDecl ()
2754d93b8cdSEnrico Granata {
2764d93b8cdSEnrico Granata     bool show_type = true;
2774d93b8cdSEnrico Granata     // if we are at the root-level and been asked to hide the root's type, then hide it
27826014690SGreg Clayton     if (m_curr_depth == 0 && m_options.m_hide_root_type)
2794d93b8cdSEnrico Granata         show_type = false;
2804d93b8cdSEnrico Granata     else
2814d93b8cdSEnrico Granata         // otherwise decide according to the usual rules (asked to show types - always at the root level)
28226014690SGreg Clayton         show_type = m_options.m_show_types || (m_curr_depth == 0 && !m_options.m_flat_output);
2834d93b8cdSEnrico Granata 
284e0ee1e1cSEnrico Granata     StreamString typeName;
285e0ee1e1cSEnrico Granata 
286e0ee1e1cSEnrico Granata     // always show the type at the root level if it is invalid
2874d93b8cdSEnrico Granata     if (show_type)
2884d93b8cdSEnrico Granata     {
2894d93b8cdSEnrico Granata         // Some ValueObjects don't have types (like registers sets). Only print
2904d93b8cdSEnrico Granata         // the type if there is one to print
291a126e462SEnrico Granata         ConstString type_name;
292e0ee1e1cSEnrico Granata         if (m_compiler_type.IsValid())
293e0ee1e1cSEnrico Granata         {
29426014690SGreg Clayton             if (m_options.m_use_type_display_name)
295a126e462SEnrico Granata                 type_name = m_valobj->GetDisplayTypeName();
296e8daa2f8SEnrico Granata             else
297a126e462SEnrico Granata                 type_name = m_valobj->GetQualifiedTypeName();
2984d93b8cdSEnrico Granata         }
299e0ee1e1cSEnrico Granata         else
300e0ee1e1cSEnrico Granata         {
301e0ee1e1cSEnrico Granata             // only show an invalid type name if the user explicitly triggered show_type
30226014690SGreg Clayton             if (m_options.m_show_types)
303e0ee1e1cSEnrico Granata                 type_name = ConstString("<invalid type>");
304e0ee1e1cSEnrico Granata             else
305e0ee1e1cSEnrico Granata                 type_name.Clear();
3064d93b8cdSEnrico Granata         }
3074d93b8cdSEnrico Granata 
308e0ee1e1cSEnrico Granata         if (type_name)
3094d93b8cdSEnrico Granata         {
310e0ee1e1cSEnrico Granata             std::string type_name_str(type_name.GetCString());
31126014690SGreg Clayton             if (m_options.m_hide_pointer_value)
312e0ee1e1cSEnrico Granata             {
313e0ee1e1cSEnrico Granata                 for(auto iter = type_name_str.find(" *");
314e0ee1e1cSEnrico Granata                     iter != std::string::npos;
315e0ee1e1cSEnrico Granata                     iter = type_name_str.find(" *"))
316e0ee1e1cSEnrico Granata                 {
317e0ee1e1cSEnrico Granata                     type_name_str.erase(iter, 2);
318e0ee1e1cSEnrico Granata                 }
319e0ee1e1cSEnrico Granata             }
320c8e7649aSEnrico Granata             typeName.Printf("%s", type_name_str.c_str());
321e0ee1e1cSEnrico Granata         }
322e0ee1e1cSEnrico Granata     }
323e0ee1e1cSEnrico Granata 
324e0ee1e1cSEnrico Granata     StreamString varName;
325e0ee1e1cSEnrico Granata 
32626014690SGreg Clayton     if (m_options.m_flat_output)
3274d93b8cdSEnrico Granata     {
3284d93b8cdSEnrico Granata         // If we are showing types, also qualify the C++ base classes
3294d93b8cdSEnrico Granata         const bool qualify_cxx_base_classes = show_type;
33026014690SGreg Clayton         if (!m_options.m_hide_name)
3314d93b8cdSEnrico Granata         {
332e0ee1e1cSEnrico Granata             m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes);
3334d93b8cdSEnrico Granata         }
3344d93b8cdSEnrico Granata     }
33526014690SGreg Clayton     else if (!m_options.m_hide_name)
3364d93b8cdSEnrico Granata     {
3374d93b8cdSEnrico Granata         const char *name_cstr = GetRootNameForDisplay("");
338e0ee1e1cSEnrico Granata         varName.Printf ("%s", name_cstr);
3394d93b8cdSEnrico Granata     }
340e0ee1e1cSEnrico Granata 
341e0ee1e1cSEnrico Granata     bool decl_printed = false;
34226014690SGreg Clayton     if (!m_options.m_decl_printing_helper)
343c8e7649aSEnrico Granata     {
344c8e7649aSEnrico 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
34526014690SGreg Clayton         lldb::LanguageType lang_type = (m_options.m_varformat_language == lldb::eLanguageTypeUnknown) ? m_valobj->GetPreferredDisplayLanguage() : m_options.m_varformat_language;
346c8e7649aSEnrico Granata         if (Language *lang_plugin = Language::FindPlugin(lang_type))
347c8e7649aSEnrico Granata         {
34826014690SGreg Clayton             m_options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper();
349c8e7649aSEnrico Granata         }
350c8e7649aSEnrico Granata     }
351c8e7649aSEnrico Granata 
35226014690SGreg Clayton     if (m_options.m_decl_printing_helper)
353e0ee1e1cSEnrico Granata     {
354e0ee1e1cSEnrico Granata         ConstString type_name_cstr(typeName.GetData());
355e0ee1e1cSEnrico Granata         ConstString var_name_cstr(varName.GetData());
356e0ee1e1cSEnrico Granata 
357e0ee1e1cSEnrico Granata         StreamString dest_stream;
35826014690SGreg Clayton         if (m_options.m_decl_printing_helper (type_name_cstr,
359e0ee1e1cSEnrico Granata                                               var_name_cstr,
36026014690SGreg Clayton                                               m_options,
361e0ee1e1cSEnrico Granata                                               dest_stream))
362e0ee1e1cSEnrico Granata         {
363e0ee1e1cSEnrico Granata             decl_printed = true;
364e0ee1e1cSEnrico Granata             m_stream->Printf("%s", dest_stream.GetData());
365e0ee1e1cSEnrico Granata         }
366e0ee1e1cSEnrico Granata     }
367e0ee1e1cSEnrico Granata 
368c8e7649aSEnrico Granata     // if the helper failed, or there is none, do a default thing
369e0ee1e1cSEnrico Granata     if (!decl_printed)
370e0ee1e1cSEnrico Granata     {
371e0ee1e1cSEnrico Granata         if (typeName.GetSize())
372c8e7649aSEnrico Granata             m_stream->Printf("(%s) ", typeName.GetData());
373e0ee1e1cSEnrico Granata         if (varName.GetSize())
374e0ee1e1cSEnrico Granata             m_stream->Printf("%s =", varName.GetData());
37526014690SGreg Clayton         else if (!m_options.m_hide_name)
376e0ee1e1cSEnrico Granata             m_stream->Printf(" =");
377e0ee1e1cSEnrico Granata     }
3784d93b8cdSEnrico Granata }
3794d93b8cdSEnrico Granata 
3804d93b8cdSEnrico Granata bool
3814d93b8cdSEnrico Granata ValueObjectPrinter::CheckScopeIfNeeded ()
3824d93b8cdSEnrico Granata {
38326014690SGreg Clayton     if (m_options.m_scope_already_checked)
3844d93b8cdSEnrico Granata         return true;
3854d93b8cdSEnrico Granata     return m_valobj->IsInScope();
3864d93b8cdSEnrico Granata }
3874d93b8cdSEnrico Granata 
3884d93b8cdSEnrico Granata TypeSummaryImpl*
3898cf44d96SEnrico Granata ValueObjectPrinter::GetSummaryFormatter (bool null_if_omitted)
3904d93b8cdSEnrico Granata {
3914d93b8cdSEnrico Granata     if (m_summary_formatter.second == false)
3924d93b8cdSEnrico Granata     {
39326014690SGreg Clayton         TypeSummaryImpl* entry = m_options.m_summary_sp ? m_options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
3944d93b8cdSEnrico Granata 
39526014690SGreg Clayton         if (m_options.m_omit_summary_depth > 0)
3964d93b8cdSEnrico Granata             entry = NULL;
3974d93b8cdSEnrico Granata         m_summary_formatter.first = entry;
3984d93b8cdSEnrico Granata         m_summary_formatter.second = true;
3994d93b8cdSEnrico Granata     }
4008cf44d96SEnrico Granata     if (m_options.m_omit_summary_depth > 0 && null_if_omitted)
4018cf44d96SEnrico Granata         return nullptr;
4024d93b8cdSEnrico Granata     return m_summary_formatter.first;
4034d93b8cdSEnrico Granata }
4044d93b8cdSEnrico Granata 
405e0ee1e1cSEnrico Granata static bool
406e0ee1e1cSEnrico Granata IsPointerValue (const CompilerType &type)
407e0ee1e1cSEnrico Granata {
408e0ee1e1cSEnrico Granata     Flags type_flags(type.GetTypeInfo());
4098cf44d96SEnrico Granata     if (type_flags.AnySet(eTypeInstanceIsPointer | eTypeIsPointer))
410e0ee1e1cSEnrico Granata         return type_flags.AllClear(eTypeIsBuiltIn);
411e0ee1e1cSEnrico Granata     return false;
412e0ee1e1cSEnrico Granata }
413e0ee1e1cSEnrico Granata 
4144d93b8cdSEnrico Granata void
4154d93b8cdSEnrico Granata ValueObjectPrinter::GetValueSummaryError (std::string& value,
4164d93b8cdSEnrico Granata                                           std::string& summary,
4174d93b8cdSEnrico Granata                                           std::string& error)
4184d93b8cdSEnrico Granata {
419*520a422bSEnrico Granata     lldb::Format format = m_options.m_format;
420*520a422bSEnrico Granata     // if I am printing synthetized elements, apply the format to those elements only
421*520a422bSEnrico Granata     if (m_options.m_element_count > 0)
422*520a422bSEnrico Granata         m_valobj->GetValueAsCString(lldb::eFormatDefault, value);
423*520a422bSEnrico Granata     else if (format != eFormatDefault && format != m_valobj->GetFormat())
424*520a422bSEnrico Granata         m_valobj->GetValueAsCString(format, value);
425465f4bc2SEnrico Granata     else
426465f4bc2SEnrico Granata     {
4274d93b8cdSEnrico Granata         const char* val_cstr = m_valobj->GetValueAsCString();
428465f4bc2SEnrico Granata         if (val_cstr)
429465f4bc2SEnrico Granata             value.assign(val_cstr);
430465f4bc2SEnrico Granata     }
4314d93b8cdSEnrico Granata     const char* err_cstr = m_valobj->GetError().AsCString();
4324d93b8cdSEnrico Granata     if (err_cstr)
4334d93b8cdSEnrico Granata         error.assign(err_cstr);
4344d93b8cdSEnrico Granata 
4354d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
4364d93b8cdSEnrico Granata     {
4374d93b8cdSEnrico Granata         if (IsNil())
4384d93b8cdSEnrico Granata             summary.assign("nil");
439608d67c1SEnrico Granata         else if (IsUninitialized())
440608d67c1SEnrico Granata             summary.assign("<uninitialized>");
44126014690SGreg Clayton         else if (m_options.m_omit_summary_depth == 0)
4424d93b8cdSEnrico Granata         {
4434d93b8cdSEnrico Granata             TypeSummaryImpl* entry = GetSummaryFormatter();
4444d93b8cdSEnrico Granata             if (entry)
44526014690SGreg Clayton                 m_valobj->GetSummaryAsCString(entry, summary, m_options.m_varformat_language);
4464d93b8cdSEnrico Granata             else
4474d93b8cdSEnrico Granata             {
44826014690SGreg Clayton                 const char* sum_cstr = m_valobj->GetSummaryAsCString(m_options.m_varformat_language);
4494d93b8cdSEnrico Granata                 if (sum_cstr)
4504d93b8cdSEnrico Granata                     summary.assign(sum_cstr);
4514d93b8cdSEnrico Granata             }
4524d93b8cdSEnrico Granata         }
4534d93b8cdSEnrico Granata     }
4544d93b8cdSEnrico Granata }
4554d93b8cdSEnrico Granata 
4564d93b8cdSEnrico Granata bool
4574d93b8cdSEnrico Granata ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
4584d93b8cdSEnrico Granata                                                   bool& summary_printed)
4594d93b8cdSEnrico Granata {
4604d93b8cdSEnrico Granata     bool error_printed = false;
4614d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
4624d93b8cdSEnrico Granata     {
4634d93b8cdSEnrico Granata         if (!CheckScopeIfNeeded())
4644d93b8cdSEnrico Granata             m_error.assign("out of scope");
4654d93b8cdSEnrico Granata         if (m_error.empty())
4664d93b8cdSEnrico Granata         {
4674d93b8cdSEnrico Granata             GetValueSummaryError(m_value, m_summary, m_error);
4684d93b8cdSEnrico Granata         }
4694d93b8cdSEnrico Granata         if (m_error.size())
4704d93b8cdSEnrico Granata         {
4718cf44d96SEnrico Granata             // we need to support scenarios in which it is actually fine for a value to have no type
4728cf44d96SEnrico Granata             // but - on the other hand - if we get an error *AND* have no type, we try to get out
4738cf44d96SEnrico Granata             // gracefully, since most often that combination means "could not resolve a type"
4748cf44d96SEnrico Granata             // and the default failure mode is quite ugly
4758cf44d96SEnrico Granata             if (!m_compiler_type.IsValid())
4768cf44d96SEnrico Granata             {
4778cf44d96SEnrico Granata                 m_stream->Printf(" <could not resolve type>");
4788cf44d96SEnrico Granata                 return false;
4798cf44d96SEnrico Granata             }
4808cf44d96SEnrico Granata 
4814d93b8cdSEnrico Granata             error_printed = true;
4824d93b8cdSEnrico Granata             m_stream->Printf (" <%s>\n", m_error.c_str());
4834d93b8cdSEnrico Granata         }
4844d93b8cdSEnrico Granata         else
4854d93b8cdSEnrico Granata         {
4864d93b8cdSEnrico Granata             // Make sure we have a value and make sure the summary didn't
4874d93b8cdSEnrico Granata             // specify that the value should not be printed - and do not print
4884d93b8cdSEnrico Granata             // the value if this thing is nil
4894d93b8cdSEnrico Granata             // (but show the value if the user passes a format explicitly)
4904d93b8cdSEnrico Granata             TypeSummaryImpl* entry = GetSummaryFormatter();
491608d67c1SEnrico Granata             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)
4924d93b8cdSEnrico Granata             {
49326014690SGreg Clayton                 if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {}
494e0ee1e1cSEnrico Granata                 else
495e0ee1e1cSEnrico Granata                 {
4964d93b8cdSEnrico Granata                     m_stream->Printf(" %s", m_value.c_str());
4974d93b8cdSEnrico Granata                     value_printed = true;
4984d93b8cdSEnrico Granata                 }
499e0ee1e1cSEnrico Granata             }
5004d93b8cdSEnrico Granata 
5014d93b8cdSEnrico Granata             if (m_summary.size())
5024d93b8cdSEnrico Granata             {
5034d93b8cdSEnrico Granata                 m_stream->Printf(" %s", m_summary.c_str());
5044d93b8cdSEnrico Granata                 summary_printed = true;
5054d93b8cdSEnrico Granata             }
5064d93b8cdSEnrico Granata         }
5074d93b8cdSEnrico Granata     }
5084d93b8cdSEnrico Granata     return !error_printed;
5094d93b8cdSEnrico Granata }
5104d93b8cdSEnrico Granata 
5114d93b8cdSEnrico Granata bool
5124d93b8cdSEnrico Granata ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
5134d93b8cdSEnrico Granata                                                     bool summary_printed)
5144d93b8cdSEnrico Granata {
5154d93b8cdSEnrico Granata     if (ShouldPrintValueObject())
5164d93b8cdSEnrico Granata     {
5174d93b8cdSEnrico Granata         // let's avoid the overly verbose no description error for a nil thing
518*520a422bSEnrico Granata         if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && (m_options.m_element_count == 0))
5194d93b8cdSEnrico Granata         {
52026014690SGreg Clayton             if (!m_options.m_hide_value || !m_options.m_hide_name)
5214d93b8cdSEnrico Granata                 m_stream->Printf(" ");
5224d93b8cdSEnrico Granata             const char *object_desc = nullptr;
5234d93b8cdSEnrico Granata             if (value_printed || summary_printed)
5244d93b8cdSEnrico Granata                 object_desc = m_valobj->GetObjectDescription();
5254d93b8cdSEnrico Granata             else
5264d93b8cdSEnrico Granata                 object_desc = GetDescriptionForDisplay();
5274d93b8cdSEnrico Granata             if (object_desc && *object_desc)
5284d93b8cdSEnrico Granata             {
5294d93b8cdSEnrico Granata                 m_stream->Printf("%s\n", object_desc);
5304d93b8cdSEnrico Granata                 return true;
5314d93b8cdSEnrico Granata             }
5324d93b8cdSEnrico Granata             else if (value_printed == false && summary_printed == false)
5334d93b8cdSEnrico Granata                 return true;
5344d93b8cdSEnrico Granata             else
5354d93b8cdSEnrico Granata                 return false;
5364d93b8cdSEnrico Granata         }
5374d93b8cdSEnrico Granata     }
5384d93b8cdSEnrico Granata     return true;
5394d93b8cdSEnrico Granata }
5404d93b8cdSEnrico Granata 
5414d93b8cdSEnrico Granata bool
542c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root,
543c1b7c09aSEnrico Granata                                                          TypeSummaryImpl* entry,
544c1b7c09aSEnrico Granata                                                          ValueObject *valobj,
545c1b7c09aSEnrico Granata                                                          const std::string& summary)
546c1b7c09aSEnrico Granata {
547c1b7c09aSEnrico Granata     switch (m_mode)
548c1b7c09aSEnrico Granata     {
549c1b7c09aSEnrico Granata         case Mode::Always:
550c1b7c09aSEnrico Granata             return (m_count > 0);
551c1b7c09aSEnrico Granata         case Mode::Never:
552c1b7c09aSEnrico Granata             return false;
553c1b7c09aSEnrico Granata         case Mode::Default:
554c1b7c09aSEnrico Granata             if (is_root)
555c1b7c09aSEnrico Granata                 m_count = std::min<decltype(m_count)>(m_count,1);
556c1b7c09aSEnrico Granata             return m_count > 0;
557c1b7c09aSEnrico Granata         case Mode::Formatters:
558c1b7c09aSEnrico Granata             if (!entry || entry->DoesPrintChildren(valobj) || summary.empty())
559c1b7c09aSEnrico Granata                 return m_count > 0;
560c1b7c09aSEnrico Granata             return false;
561c1b7c09aSEnrico Granata     }
56284f5b0dfSZachary Turner     return false;
563c1b7c09aSEnrico Granata }
564c1b7c09aSEnrico Granata 
565c1b7c09aSEnrico Granata bool
566c1b7c09aSEnrico Granata DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const
567c1b7c09aSEnrico Granata {
568c1b7c09aSEnrico Granata     switch (m_mode)
569c1b7c09aSEnrico Granata     {
570c1b7c09aSEnrico Granata         case Mode::Always:
571c1b7c09aSEnrico Granata         case Mode::Default:
572c1b7c09aSEnrico Granata         case Mode::Formatters:
573c1b7c09aSEnrico Granata             return (m_count > 0);
574c1b7c09aSEnrico Granata         case Mode::Never:
575c1b7c09aSEnrico Granata             return false;
576c1b7c09aSEnrico Granata     }
57784f5b0dfSZachary Turner     return false;
578c1b7c09aSEnrico Granata }
579c1b7c09aSEnrico Granata 
580c1b7c09aSEnrico Granata bool
5814d93b8cdSEnrico Granata ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
582c1b7c09aSEnrico Granata                                          DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
5834d93b8cdSEnrico Granata {
5844d93b8cdSEnrico Granata     const bool is_ref = IsRef ();
5854d93b8cdSEnrico Granata     const bool is_ptr = IsPtr ();
586608d67c1SEnrico Granata     const bool is_uninit = IsUninitialized();
587608d67c1SEnrico Granata 
588608d67c1SEnrico Granata     if (is_uninit)
589608d67c1SEnrico Granata         return false;
5904d93b8cdSEnrico Granata 
591*520a422bSEnrico Granata     // if the user has specified an element count, always print children
592*520a422bSEnrico Granata     // as it is explicit user demand being honored
593*520a422bSEnrico Granata     if (m_options.m_element_count > 0)
594*520a422bSEnrico Granata         return true;
595*520a422bSEnrico Granata 
596c1b7c09aSEnrico Granata     TypeSummaryImpl* entry = GetSummaryFormatter();
597c1b7c09aSEnrico Granata 
5988cf44d96SEnrico Granata     if (m_options.m_use_objc)
5998cf44d96SEnrico Granata         return false;
6008cf44d96SEnrico Granata 
60126014690SGreg Clayton     if (is_failed_description || m_curr_depth < m_options.m_max_depth)
6024d93b8cdSEnrico Granata     {
6034d93b8cdSEnrico Granata         // We will show children for all concrete types. We won't show
6044d93b8cdSEnrico Granata         // pointer contents unless a pointer depth has been specified.
6054d93b8cdSEnrico Granata         // We won't reference contents unless the reference is the
6064d93b8cdSEnrico Granata         // root object (depth of zero).
6074d93b8cdSEnrico Granata 
6084d93b8cdSEnrico Granata         // Use a new temporary pointer depth in case we override the
6094d93b8cdSEnrico Granata         // current pointer depth below...
6104d93b8cdSEnrico Granata 
6114d93b8cdSEnrico Granata         if (is_ptr || is_ref)
6124d93b8cdSEnrico Granata         {
6134d93b8cdSEnrico Granata             // We have a pointer or reference whose value is an address.
6144d93b8cdSEnrico Granata             // Make sure that address is not NULL
6154d93b8cdSEnrico Granata             AddressType ptr_address_type;
6164d93b8cdSEnrico Granata             if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
6174d93b8cdSEnrico Granata                 return false;
6184d93b8cdSEnrico Granata 
619c1b7c09aSEnrico Granata             const bool is_root_level = m_curr_depth == 0;
620c1b7c09aSEnrico Granata 
621c1b7c09aSEnrico Granata             if (is_ref &&
622c1b7c09aSEnrico Granata                 is_root_level)
6234d93b8cdSEnrico Granata             {
6244d93b8cdSEnrico Granata                 // If this is the root object (depth is zero) that we are showing
6254d93b8cdSEnrico Granata                 // and it is a reference, and no pointer depth has been supplied
6264d93b8cdSEnrico Granata                 // print out what it references. Don't do this at deeper depths
6274d93b8cdSEnrico Granata                 // otherwise we can end up with infinite recursion...
628c1b7c09aSEnrico Granata                 return true;
6294d93b8cdSEnrico Granata             }
6304d93b8cdSEnrico Granata 
631c1b7c09aSEnrico Granata             return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary);
6324d93b8cdSEnrico Granata         }
6334d93b8cdSEnrico Granata 
6348a068e6cSEnrico Granata         return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
6354d93b8cdSEnrico Granata     }
6364d93b8cdSEnrico Granata     return false;
6374d93b8cdSEnrico Granata }
6384d93b8cdSEnrico Granata 
639d26eb907SSiva Chandra bool
640d26eb907SSiva Chandra ValueObjectPrinter::ShouldExpandEmptyAggregates ()
641d26eb907SSiva Chandra {
642d26eb907SSiva Chandra     TypeSummaryImpl* entry = GetSummaryFormatter();
643d26eb907SSiva Chandra 
644d26eb907SSiva Chandra     if (!entry)
645d26eb907SSiva Chandra         return true;
646d26eb907SSiva Chandra 
647d26eb907SSiva Chandra     return entry->DoesPrintEmptyAggregates();
648d26eb907SSiva Chandra }
649d26eb907SSiva Chandra 
6504d93b8cdSEnrico Granata ValueObject*
6514d93b8cdSEnrico Granata ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
6524d93b8cdSEnrico Granata {
653d07cfd3aSEnrico Granata     return m_valobj;
6544d93b8cdSEnrico Granata }
6554d93b8cdSEnrico Granata 
6564d93b8cdSEnrico Granata void
6574d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPreamble ()
6584d93b8cdSEnrico Granata {
65926014690SGreg Clayton     if (m_options.m_flat_output)
6604d93b8cdSEnrico Granata     {
6614d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
6624d93b8cdSEnrico Granata             m_stream->EOL();
6634d93b8cdSEnrico Granata     }
6644d93b8cdSEnrico Granata     else
6654d93b8cdSEnrico Granata     {
6664d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
6674d93b8cdSEnrico Granata             m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
6684d93b8cdSEnrico Granata         m_stream->IndentMore();
6694d93b8cdSEnrico Granata     }
6704d93b8cdSEnrico Granata }
6714d93b8cdSEnrico Granata 
6724d93b8cdSEnrico Granata void
6734d93b8cdSEnrico Granata ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
674c1b7c09aSEnrico Granata                                 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
6754d93b8cdSEnrico Granata {
676*520a422bSEnrico Granata     const uint32_t consumed_depth = (m_options.m_element_count == 0) ? 1 : 0;
677*520a422bSEnrico Granata     const bool does_consume_ptr_depth = ((IsPtr() && m_options.m_element_count == 0) || IsRef());
678*520a422bSEnrico Granata 
67926014690SGreg Clayton     DumpValueObjectOptions child_options(m_options);
68026014690SGreg Clayton     child_options.SetFormat(m_options.m_format).SetSummary().SetRootValueObjectName();
68126014690SGreg Clayton     child_options.SetScopeChecked(true).SetHideName(m_options.m_hide_name).SetHideValue(m_options.m_hide_value)
682*520a422bSEnrico Granata     .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - consumed_depth : 0)
683*520a422bSEnrico Granata     .SetElementCount(0);
6848cf44d96SEnrico Granata 
6854d93b8cdSEnrico Granata     if (child_sp.get())
6864d93b8cdSEnrico Granata     {
6874d93b8cdSEnrico Granata         ValueObjectPrinter child_printer(child_sp.get(),
6884d93b8cdSEnrico Granata                                          m_stream,
6894d93b8cdSEnrico Granata                                          child_options,
690*520a422bSEnrico Granata                                          does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth,
691*520a422bSEnrico Granata                                          m_curr_depth + consumed_depth,
6928cf44d96SEnrico Granata                                          m_printed_instance_pointers);
6934d93b8cdSEnrico Granata         child_printer.PrintValueObject();
6944d93b8cdSEnrico Granata     }
6954d93b8cdSEnrico Granata }
6964d93b8cdSEnrico Granata 
6974d93b8cdSEnrico Granata uint32_t
6984d93b8cdSEnrico Granata ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
6994d93b8cdSEnrico Granata {
7004d93b8cdSEnrico Granata     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
7014d93b8cdSEnrico Granata 
702*520a422bSEnrico Granata     if (m_options.m_element_count > 0)
703*520a422bSEnrico Granata         return m_options.m_element_count;
704*520a422bSEnrico Granata 
7054d93b8cdSEnrico Granata     size_t num_children = synth_m_valobj->GetNumChildren();
7064d93b8cdSEnrico Granata     print_dotdotdot = false;
7074d93b8cdSEnrico Granata     if (num_children)
7084d93b8cdSEnrico Granata     {
7094d93b8cdSEnrico Granata         const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
7104d93b8cdSEnrico Granata 
71126014690SGreg Clayton         if (num_children > max_num_children && !m_options.m_ignore_cap)
7124d93b8cdSEnrico Granata         {
7134d93b8cdSEnrico Granata             print_dotdotdot = true;
7144d93b8cdSEnrico Granata             return max_num_children;
7154d93b8cdSEnrico Granata         }
7164d93b8cdSEnrico Granata     }
7174d93b8cdSEnrico Granata     return num_children;
7184d93b8cdSEnrico Granata }
7194d93b8cdSEnrico Granata 
7204d93b8cdSEnrico Granata void
7214d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
7224d93b8cdSEnrico Granata {
72326014690SGreg Clayton     if (!m_options.m_flat_output)
7244d93b8cdSEnrico Granata     {
7254d93b8cdSEnrico Granata         if (print_dotdotdot)
7264d93b8cdSEnrico Granata         {
7274d93b8cdSEnrico Granata             m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
7284d93b8cdSEnrico Granata             m_stream->Indent("...\n");
7294d93b8cdSEnrico Granata         }
7304d93b8cdSEnrico Granata         m_stream->IndentLess();
7314d93b8cdSEnrico Granata         m_stream->Indent("}\n");
7324d93b8cdSEnrico Granata     }
7334d93b8cdSEnrico Granata }
7344d93b8cdSEnrico Granata 
7358cf44d96SEnrico Granata bool
7368cf44d96SEnrico Granata ValueObjectPrinter::ShouldPrintEmptyBrackets (bool value_printed,
7378cf44d96SEnrico Granata                                               bool summary_printed)
7388cf44d96SEnrico Granata {
7398cf44d96SEnrico Granata     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
7408cf44d96SEnrico Granata 
7418cf44d96SEnrico Granata     if (!IsAggregate())
7428cf44d96SEnrico Granata         return false;
7438cf44d96SEnrico Granata 
7448cf44d96SEnrico Granata     if (m_options.m_reveal_empty_aggregates == false)
7458cf44d96SEnrico Granata     {
7468cf44d96SEnrico Granata         if (value_printed || summary_printed)
7478cf44d96SEnrico Granata             return false;
7488cf44d96SEnrico Granata     }
7498cf44d96SEnrico Granata 
7508cf44d96SEnrico Granata     if (synth_m_valobj->MightHaveChildren())
7518cf44d96SEnrico Granata         return true;
7528cf44d96SEnrico Granata 
7538cf44d96SEnrico Granata     if (m_val_summary_ok)
7548cf44d96SEnrico Granata         return false;
7558cf44d96SEnrico Granata 
7568cf44d96SEnrico Granata     return true;
7578cf44d96SEnrico Granata }
7588cf44d96SEnrico Granata 
759*520a422bSEnrico Granata ValueObjectSP
760*520a422bSEnrico Granata ValueObjectPrinter::GenerateChild (ValueObject* synth_valobj, size_t idx)
761*520a422bSEnrico Granata {
762*520a422bSEnrico Granata     if (m_options.m_element_count > 0)
763*520a422bSEnrico Granata     {
764*520a422bSEnrico Granata         // if generating pointer-as-array children, use GetSyntheticArrayMember
765*520a422bSEnrico Granata         return synth_valobj->GetSyntheticArrayMember(idx, true);
766*520a422bSEnrico Granata     }
767*520a422bSEnrico Granata     else
768*520a422bSEnrico Granata     {
769*520a422bSEnrico Granata         // otherwise, do the usual thing
770*520a422bSEnrico Granata         return synth_valobj->GetChildAtIndex(idx, true);
771*520a422bSEnrico Granata     }
772*520a422bSEnrico Granata }
773*520a422bSEnrico Granata 
7744d93b8cdSEnrico Granata void
775c1b7c09aSEnrico Granata ValueObjectPrinter::PrintChildren (bool value_printed,
776c1b7c09aSEnrico Granata                                    bool summary_printed,
777c1b7c09aSEnrico Granata                                    const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
7784d93b8cdSEnrico Granata {
7794d93b8cdSEnrico Granata     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
7804d93b8cdSEnrico Granata 
7814d93b8cdSEnrico Granata     bool print_dotdotdot = false;
7824d93b8cdSEnrico Granata     size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
7834d93b8cdSEnrico Granata     if (num_children)
7844d93b8cdSEnrico Granata     {
7858cf44d96SEnrico Granata         bool any_children_printed = false;
7864d93b8cdSEnrico Granata 
7874d93b8cdSEnrico Granata         for (size_t idx=0; idx<num_children; ++idx)
7884d93b8cdSEnrico Granata         {
789*520a422bSEnrico Granata             if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx))
7908cf44d96SEnrico Granata             {
7918cf44d96SEnrico Granata                 if (!any_children_printed)
7928cf44d96SEnrico Granata                 {
7938cf44d96SEnrico Granata                     PrintChildrenPreamble ();
7948cf44d96SEnrico Granata                     any_children_printed = true;
7958cf44d96SEnrico Granata                 }
7964d93b8cdSEnrico Granata                 PrintChild (child_sp, curr_ptr_depth);
7974d93b8cdSEnrico Granata             }
7984d93b8cdSEnrico Granata         }
7998cf44d96SEnrico Granata 
8008cf44d96SEnrico Granata         if (any_children_printed)
8018cf44d96SEnrico Granata             PrintChildrenPostamble (print_dotdotdot);
8028cf44d96SEnrico Granata         else
8038cf44d96SEnrico Granata         {
8048cf44d96SEnrico Granata             if (ShouldPrintEmptyBrackets(value_printed, summary_printed))
8058cf44d96SEnrico Granata             {
8068cf44d96SEnrico Granata                 if (ShouldPrintValueObject())
8078cf44d96SEnrico Granata                     m_stream->PutCString(" {}\n");
8088cf44d96SEnrico Granata                 else
8098cf44d96SEnrico Granata                     m_stream->EOL();
8108cf44d96SEnrico Granata             }
8118cf44d96SEnrico Granata             else
8128cf44d96SEnrico Granata                 m_stream->EOL();
8138cf44d96SEnrico Granata         }
8148cf44d96SEnrico Granata     }
8158cf44d96SEnrico Granata     else if (ShouldPrintEmptyBrackets(value_printed, summary_printed))
8164d93b8cdSEnrico Granata     {
8174d93b8cdSEnrico Granata         // Aggregate, no children...
8184d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
819d07cfd3aSEnrico Granata         {
820d07cfd3aSEnrico Granata             // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
821d26eb907SSiva Chandra             if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates())
822d07cfd3aSEnrico Granata                 m_stream->PutCString( "\n");
823d07cfd3aSEnrico Granata             else
8244d93b8cdSEnrico Granata                 m_stream->PutCString(" {}\n");
8254d93b8cdSEnrico Granata         }
826d07cfd3aSEnrico Granata     }
8274d93b8cdSEnrico Granata     else
8284d93b8cdSEnrico Granata     {
8294d93b8cdSEnrico Granata         if (ShouldPrintValueObject())
8304d93b8cdSEnrico Granata             m_stream->EOL();
8314d93b8cdSEnrico Granata     }
8324d93b8cdSEnrico Granata }
8334d93b8cdSEnrico Granata 
834a29cb0baSEnrico Granata bool
835a29cb0baSEnrico Granata ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
836a29cb0baSEnrico Granata {
837d07cfd3aSEnrico Granata     if (!GetMostSpecializedValue () || m_valobj == nullptr)
838a29cb0baSEnrico Granata         return false;
839a29cb0baSEnrico Granata 
840a29cb0baSEnrico Granata     ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
841a29cb0baSEnrico Granata 
842a29cb0baSEnrico Granata     bool print_dotdotdot = false;
843a29cb0baSEnrico Granata     size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
844a29cb0baSEnrico Granata 
845a29cb0baSEnrico Granata     if (num_children)
846a29cb0baSEnrico Granata     {
847a29cb0baSEnrico Granata         m_stream->PutChar('(');
848a29cb0baSEnrico Granata 
849a29cb0baSEnrico Granata         for (uint32_t idx=0; idx<num_children; ++idx)
850a29cb0baSEnrico Granata         {
851a29cb0baSEnrico Granata             lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
852ddac7611SEnrico Granata             if (child_sp)
85326014690SGreg Clayton                 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(m_options.m_use_dynamic, m_options.m_use_synthetic);
854a29cb0baSEnrico Granata             if (child_sp)
855a29cb0baSEnrico Granata             {
856a29cb0baSEnrico Granata                 if (idx)
857a29cb0baSEnrico Granata                     m_stream->PutCString(", ");
858a29cb0baSEnrico Granata                 if (!hide_names)
859a29cb0baSEnrico Granata                 {
860a29cb0baSEnrico Granata                     const char* name = child_sp.get()->GetName().AsCString();
861a29cb0baSEnrico Granata                     if (name && *name)
862a29cb0baSEnrico Granata                     {
863a29cb0baSEnrico Granata                         m_stream->PutCString(name);
864a29cb0baSEnrico Granata                         m_stream->PutCString(" = ");
865a29cb0baSEnrico Granata                     }
866a29cb0baSEnrico Granata                 }
867a29cb0baSEnrico Granata                 child_sp->DumpPrintableRepresentation(*m_stream,
868a29cb0baSEnrico Granata                                                       ValueObject::eValueObjectRepresentationStyleSummary,
8697aafb6a1SEnrico Granata                                                       m_options.m_format,
870a29cb0baSEnrico Granata                                                       ValueObject::ePrintableRepresentationSpecialCasesDisable);
871a29cb0baSEnrico Granata             }
872a29cb0baSEnrico Granata         }
873a29cb0baSEnrico Granata 
874a29cb0baSEnrico Granata         if (print_dotdotdot)
875a29cb0baSEnrico Granata             m_stream->PutCString(", ...)");
876a29cb0baSEnrico Granata         else
877a29cb0baSEnrico Granata             m_stream->PutChar(')');
878a29cb0baSEnrico Granata     }
879a29cb0baSEnrico Granata     return true;
880a29cb0baSEnrico Granata }
881a29cb0baSEnrico Granata 
8824d93b8cdSEnrico Granata void
8834d93b8cdSEnrico Granata ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
8844d93b8cdSEnrico Granata                                            bool summary_printed)
8854d93b8cdSEnrico Granata {
8864d93b8cdSEnrico Granata     // this flag controls whether we tried to display a description for this object and failed
8874d93b8cdSEnrico Granata     // if that happens, we want to display the children, if any
8884d93b8cdSEnrico Granata     bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
8894d93b8cdSEnrico Granata 
890c1b7c09aSEnrico Granata     auto curr_ptr_depth = m_ptr_depth;
8914d93b8cdSEnrico Granata     bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
892c1b7c09aSEnrico Granata     bool print_oneline = (curr_ptr_depth.CanAllowExpansion() ||
89326014690SGreg Clayton                           m_options.m_show_types ||
89426014690SGreg Clayton                           !m_options.m_allow_oneliner_mode ||
89526014690SGreg Clayton                           m_options.m_flat_output ||
896*520a422bSEnrico Granata                           (m_options.m_element_count > 0) ||
89726014690SGreg Clayton                           m_options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
8988cf44d96SEnrico Granata     bool is_instance_ptr = IsInstancePointer();
8998cf44d96SEnrico Granata     uint64_t instance_ptr_value = LLDB_INVALID_ADDRESS;
9008cf44d96SEnrico Granata 
9018cf44d96SEnrico Granata     if (print_children && is_instance_ptr)
9028cf44d96SEnrico Granata     {
9038cf44d96SEnrico Granata         instance_ptr_value = m_valobj->GetValueAsUnsigned(0);
9048cf44d96SEnrico Granata         if (m_printed_instance_pointers->count(instance_ptr_value))
9058cf44d96SEnrico Granata         {
9068cf44d96SEnrico Granata             // we already printed this instance-is-pointer thing, so don't expand it
9078cf44d96SEnrico Granata             m_stream->PutCString(" {...}\n");
9088cf44d96SEnrico Granata 
9098cf44d96SEnrico Granata             // we're done here - get out fast
9108cf44d96SEnrico Granata             return;
9118cf44d96SEnrico Granata         }
9128cf44d96SEnrico Granata         else
9138cf44d96SEnrico Granata             m_printed_instance_pointers->emplace(instance_ptr_value); // remember this guy for future reference
9148cf44d96SEnrico Granata     }
9154d93b8cdSEnrico Granata 
9164d93b8cdSEnrico Granata     if (print_children)
9174d93b8cdSEnrico Granata     {
918a29cb0baSEnrico Granata         if (print_oneline)
919a29cb0baSEnrico Granata         {
920a29cb0baSEnrico Granata             m_stream->PutChar(' ');
921a29cb0baSEnrico Granata             PrintChildrenOneLiner (false);
922a29cb0baSEnrico Granata             m_stream->EOL();
923a29cb0baSEnrico Granata         }
924a29cb0baSEnrico Granata         else
925c1b7c09aSEnrico Granata             PrintChildren (value_printed, summary_printed, curr_ptr_depth);
9264d93b8cdSEnrico Granata     }
92726014690SGreg Clayton     else if (m_curr_depth >= m_options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
9284d93b8cdSEnrico Granata     {
9294d93b8cdSEnrico Granata         m_stream->PutCString("{...}\n");
9304d93b8cdSEnrico Granata     }
931245b3caaSEnrico Granata     else
932245b3caaSEnrico Granata         m_stream->EOL();
9334d93b8cdSEnrico Granata }
9340f883ffbSEnrico Granata 
9350f883ffbSEnrico Granata bool
9360f883ffbSEnrico Granata ValueObjectPrinter::ShouldPrintValidation ()
9370f883ffbSEnrico Granata {
93826014690SGreg Clayton     return m_options.m_run_validator;
9390f883ffbSEnrico Granata }
9400f883ffbSEnrico Granata 
9410f883ffbSEnrico Granata bool
9420f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationMarkerIfNeeded ()
9430f883ffbSEnrico Granata {
9440f883ffbSEnrico Granata     if (!ShouldPrintValidation())
9450f883ffbSEnrico Granata         return false;
9460f883ffbSEnrico Granata 
9470f883ffbSEnrico Granata     m_validation = m_valobj->GetValidationStatus();
9480f883ffbSEnrico Granata 
9490f883ffbSEnrico Granata     if (TypeValidatorResult::Failure == m_validation.first)
9500f883ffbSEnrico Granata     {
9510f883ffbSEnrico Granata         m_stream->Printf("! ");
9520f883ffbSEnrico Granata         return true;
9530f883ffbSEnrico Granata     }
9540f883ffbSEnrico Granata 
9550f883ffbSEnrico Granata     return false;
9560f883ffbSEnrico Granata }
9570f883ffbSEnrico Granata 
9580f883ffbSEnrico Granata bool
9590f883ffbSEnrico Granata ValueObjectPrinter::PrintValidationErrorIfNeeded ()
9600f883ffbSEnrico Granata {
9610f883ffbSEnrico Granata     if (!ShouldPrintValidation())
9620f883ffbSEnrico Granata         return false;
9630f883ffbSEnrico Granata 
9640f883ffbSEnrico Granata     if (TypeValidatorResult::Success == m_validation.first)
9650f883ffbSEnrico Granata         return false;
9660f883ffbSEnrico Granata 
9670f883ffbSEnrico Granata     if (m_validation.second.empty())
9680f883ffbSEnrico Granata         m_validation.second.assign("unknown error");
9690f883ffbSEnrico Granata 
9700f883ffbSEnrico Granata     m_stream->Printf(" ! validation error: %s", m_validation.second.c_str());
9710f883ffbSEnrico Granata     m_stream->EOL();
9720f883ffbSEnrico Granata 
9730f883ffbSEnrico Granata     return true;
9740f883ffbSEnrico Granata }
975