blob: fec0c5f28570df6f7c43baa843e9cde125e3fd53 [file] [log] [blame]
Enrico Granata4d93b8c2013-09-30 19:11:51 +00001//===-- ValueObjectPrinter.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/DataFormatters/ValueObjectPrinter.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Enrico Granatac8e76492015-10-19 22:04:25 +000016#include "lldb/Core/Stream.h"
17#include "lldb/Core/ValueObject.h"
Enrico Granataa29cb0b2013-10-04 23:14:13 +000018#include "lldb/DataFormatters/DataVisualization.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000019#include "lldb/Interpreter/CommandInterpreter.h"
Enrico Granatac8e76492015-10-19 22:04:25 +000020#include "lldb/Target/Language.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000021#include "lldb/Target/Target.h"
22
23using namespace lldb;
24using namespace lldb_private;
25
Enrico Granatad5957332015-06-03 20:43:54 +000026ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
27 Stream* s)
28{
29 if (valobj)
30 {
31 DumpValueObjectOptions options(*valobj);
32 Init (valobj,s,options,options.m_max_ptr_depth,0);
33 }
34 else
35 {
36 DumpValueObjectOptions options;
37 Init (valobj,s,options,options.m_max_ptr_depth,0);
38 }
39}
40
Enrico Granata4d93b8c2013-09-30 19:11:51 +000041ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
42 Stream* s,
Enrico Granata938d1d62013-10-05 00:20:27 +000043 const DumpValueObjectOptions& options)
Enrico Granata4d93b8c2013-09-30 19:11:51 +000044{
Enrico Granata938d1d62013-10-05 00:20:27 +000045 Init(valobj,s,options,options.m_max_ptr_depth,0);
Enrico Granata4d93b8c2013-09-30 19:11:51 +000046}
47
48ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
49 Stream* s,
50 const DumpValueObjectOptions& options,
Enrico Granatac1b7c092015-07-27 18:34:14 +000051 const DumpValueObjectOptions::PointerDepth& ptr_depth,
Enrico Granata938d1d62013-10-05 00:20:27 +000052 uint32_t curr_depth)
53{
54 Init(valobj,s,options,ptr_depth,curr_depth);
55}
56
57void
58ValueObjectPrinter::Init (ValueObject* valobj,
59 Stream* s,
60 const DumpValueObjectOptions& options,
Enrico Granatac1b7c092015-07-27 18:34:14 +000061 const DumpValueObjectOptions::PointerDepth& ptr_depth,
Enrico Granata938d1d62013-10-05 00:20:27 +000062 uint32_t curr_depth)
63{
64 m_orig_valobj = valobj;
65 m_valobj = nullptr;
66 m_stream = s;
67 this->options = options;
68 m_ptr_depth = ptr_depth;
69 m_curr_depth = curr_depth;
70 assert (m_orig_valobj && "cannot print a NULL ValueObject");
71 assert (m_stream && "cannot print to a NULL Stream");
72 m_should_print = eLazyBoolCalculate;
73 m_is_nil = eLazyBoolCalculate;
74 m_is_ptr = eLazyBoolCalculate;
75 m_is_ref = eLazyBoolCalculate;
76 m_is_aggregate = eLazyBoolCalculate;
77 m_summary_formatter = {nullptr,false};
78 m_value.assign("");
79 m_summary.assign("");
80 m_error.assign("");
81}
Enrico Granata4d93b8c2013-09-30 19:11:51 +000082
83bool
84ValueObjectPrinter::PrintValueObject ()
85{
Enrico Granatad07cfd32014-10-08 18:27:36 +000086 if (!GetMostSpecializedValue () || m_valobj == nullptr)
Enrico Granata4d93b8c2013-09-30 19:11:51 +000087 return false;
88
89 if (ShouldPrintValueObject())
90 {
Enrico Granata0f883ff2014-09-06 02:20:19 +000091 PrintValidationMarkerIfNeeded();
92
Enrico Granata4d93b8c2013-09-30 19:11:51 +000093 PrintLocationIfNeeded();
94 m_stream->Indent();
95
Enrico Granatae0ee1e12015-10-17 01:05:50 +000096 PrintDecl();
Enrico Granata4d93b8c2013-09-30 19:11:51 +000097 }
98
99 bool value_printed = false;
100 bool summary_printed = false;
101
102 bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
103
104 if (val_summary_ok)
105 PrintChildrenIfNeeded (value_printed, summary_printed);
Enrico Granata39938932013-10-03 02:06:02 +0000106 else
107 m_stream->EOL();
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000108
Enrico Granata0f883ff2014-09-06 02:20:19 +0000109 PrintValidationErrorIfNeeded();
110
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000111 return true;
112}
113
114bool
Enrico Granatad07cfd32014-10-08 18:27:36 +0000115ValueObjectPrinter::GetMostSpecializedValue ()
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000116{
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000117 if (m_valobj)
118 return true;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000119 bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
120 if (!update_success)
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000121 {
Enrico Granata106260c2013-10-22 22:42:14 +0000122 m_valobj = m_orig_valobj;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000123 }
124 else
Enrico Granata106260c2013-10-22 22:42:14 +0000125 {
126 if (m_orig_valobj->IsDynamic())
127 {
128 if (options.m_use_dynamic == eNoDynamicValues)
129 {
130 ValueObject *static_value = m_orig_valobj->GetStaticValue().get();
131 if (static_value)
132 m_valobj = static_value;
133 else
134 m_valobj = m_orig_valobj;
135 }
136 else
137 m_valobj = m_orig_valobj;
138 }
139 else
140 {
141 if (options.m_use_dynamic != eNoDynamicValues)
142 {
143 ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(options.m_use_dynamic).get();
144 if (dynamic_value)
145 m_valobj = dynamic_value;
146 else
147 m_valobj = m_orig_valobj;
148 }
149 else
150 m_valobj = m_orig_valobj;
151 }
Enrico Granatad07cfd32014-10-08 18:27:36 +0000152
153 if (m_valobj->IsSynthetic())
154 {
155 if (options.m_use_synthetic == false)
156 {
157 ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
158 if (non_synthetic)
159 m_valobj = non_synthetic;
160 }
161 }
162 else
163 {
164 if (options.m_use_synthetic == true)
165 {
166 ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
167 if (synthetic)
168 m_valobj = synthetic;
169 }
170 }
Enrico Granata106260c2013-10-22 22:42:14 +0000171 }
Bruce Mitchener59b5a372015-09-17 18:43:40 +0000172 m_compiler_type = m_valobj->GetCompilerType();
173 m_type_flags = m_compiler_type.GetTypeInfo ();
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000174 return true;
175}
176
177const char*
178ValueObjectPrinter::GetDescriptionForDisplay ()
179{
180 const char* str = m_valobj->GetObjectDescription();
181 if (!str)
182 str = m_valobj->GetSummaryAsCString();
183 if (!str)
184 str = m_valobj->GetValueAsCString();
185 return str;
186}
187
188const char*
189ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
190{
191 const char *root_valobj_name = options.m_root_valobj_name.empty() ?
192 m_valobj->GetName().AsCString() :
193 options.m_root_valobj_name.c_str();
194 return root_valobj_name ? root_valobj_name : if_fail;
195}
196
197bool
198ValueObjectPrinter::ShouldPrintValueObject ()
199{
200 if (m_should_print == eLazyBoolCalculate)
Enrico Granata622be232014-10-21 20:52:14 +0000201 m_should_print = (options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000202 return m_should_print == eLazyBoolYes;
203}
204
205bool
206ValueObjectPrinter::IsNil ()
207{
208 if (m_is_nil == eLazyBoolCalculate)
209 m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo;
210 return m_is_nil == eLazyBoolYes;
211}
212
213bool
214ValueObjectPrinter::IsPtr ()
215{
216 if (m_is_ptr == eLazyBoolCalculate)
Enrico Granata622be232014-10-21 20:52:14 +0000217 m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000218 return m_is_ptr == eLazyBoolYes;
219}
220
221bool
222ValueObjectPrinter::IsRef ()
223{
224 if (m_is_ref == eLazyBoolCalculate)
Enrico Granata622be232014-10-21 20:52:14 +0000225 m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000226 return m_is_ref == eLazyBoolYes;
227}
228
229bool
230ValueObjectPrinter::IsAggregate ()
231{
232 if (m_is_aggregate == eLazyBoolCalculate)
Enrico Granata622be232014-10-21 20:52:14 +0000233 m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000234 return m_is_aggregate == eLazyBoolYes;
235}
236
237bool
238ValueObjectPrinter::PrintLocationIfNeeded ()
239{
240 if (options.m_show_location)
241 {
242 m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
243 return true;
244 }
245 return false;
246}
247
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000248void
249ValueObjectPrinter::PrintDecl ()
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000250{
251 bool show_type = true;
252 // if we are at the root-level and been asked to hide the root's type, then hide it
253 if (m_curr_depth == 0 && options.m_hide_root_type)
254 show_type = false;
255 else
256 // otherwise decide according to the usual rules (asked to show types - always at the root level)
257 show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output);
258
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000259 StreamString typeName;
260
261 // always show the type at the root level if it is invalid
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000262 if (show_type)
263 {
264 // Some ValueObjects don't have types (like registers sets). Only print
265 // the type if there is one to print
Enrico Granataa126e462014-11-21 18:47:26 +0000266 ConstString type_name;
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000267 if (m_compiler_type.IsValid())
268 {
269 if (options.m_use_type_display_name)
270 type_name = m_valobj->GetDisplayTypeName();
271 else
272 type_name = m_valobj->GetQualifiedTypeName();
273 }
Enrico Granatae8daa2f2014-05-17 19:14:17 +0000274 else
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000275 {
276 // only show an invalid type name if the user explicitly triggered show_type
277 if (options.m_show_types)
278 type_name = ConstString("<invalid type>");
279 else
280 type_name.Clear();
281 }
282
Enrico Granataa126e462014-11-21 18:47:26 +0000283 if (type_name)
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000284 {
285 std::string type_name_str(type_name.GetCString());
286 if (options.m_hide_pointer_value)
287 {
288 for(auto iter = type_name_str.find(" *");
289 iter != std::string::npos;
290 iter = type_name_str.find(" *"))
291 {
292 type_name_str.erase(iter, 2);
293 }
294 }
Enrico Granatac8e76492015-10-19 22:04:25 +0000295 typeName.Printf("%s", type_name_str.c_str());
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000296 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000297 }
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000298
299 StreamString varName;
300
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000301 if (options.m_flat_output)
302 {
303 // If we are showing types, also qualify the C++ base classes
304 const bool qualify_cxx_base_classes = show_type;
305 if (!options.m_hide_name)
306 {
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000307 m_valobj->GetExpressionPath(varName, qualify_cxx_base_classes);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000308 }
309 }
310 else if (!options.m_hide_name)
311 {
312 const char *name_cstr = GetRootNameForDisplay("");
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000313 varName.Printf ("%s", name_cstr);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000314 }
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000315
316 bool decl_printed = false;
Enrico Granatac8e76492015-10-19 22:04:25 +0000317 if (!options.m_decl_printing_helper)
318 {
319 // 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 lldb::LanguageType lang_type = (options.m_varformat_language == lldb::eLanguageTypeUnknown) ? m_valobj->GetPreferredDisplayLanguage() : options.m_varformat_language;
321 if (Language *lang_plugin = Language::FindPlugin(lang_type))
322 {
323 options.m_decl_printing_helper = lang_plugin->GetDeclPrintingHelper();
324 }
325 }
326
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000327 if (options.m_decl_printing_helper)
328 {
329 ConstString type_name_cstr(typeName.GetData());
330 ConstString var_name_cstr(varName.GetData());
331
332 StreamString dest_stream;
333 if (options.m_decl_printing_helper(type_name_cstr,
334 var_name_cstr,
335 options,
336 dest_stream))
337 {
338 decl_printed = true;
339 m_stream->Printf("%s", dest_stream.GetData());
340 }
341 }
342
Enrico Granatac8e76492015-10-19 22:04:25 +0000343 // if the helper failed, or there is none, do a default thing
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000344 if (!decl_printed)
345 {
346 if (typeName.GetSize())
Enrico Granatac8e76492015-10-19 22:04:25 +0000347 m_stream->Printf("(%s) ", typeName.GetData());
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000348 if (varName.GetSize())
349 m_stream->Printf("%s =", varName.GetData());
350 else if (!options.m_hide_name)
351 m_stream->Printf(" =");
352 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000353}
354
355bool
356ValueObjectPrinter::CheckScopeIfNeeded ()
357{
358 if (options.m_scope_already_checked)
359 return true;
360 return m_valobj->IsInScope();
361}
362
363TypeSummaryImpl*
364ValueObjectPrinter::GetSummaryFormatter ()
365{
366 if (m_summary_formatter.second == false)
367 {
368 TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
369
370 if (options.m_omit_summary_depth > 0)
371 entry = NULL;
372 m_summary_formatter.first = entry;
373 m_summary_formatter.second = true;
374 }
375 return m_summary_formatter.first;
376}
377
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000378static bool
379IsPointerValue (const CompilerType &type)
380{
381 Flags type_flags(type.GetTypeInfo());
382 if (type_flags.AnySet(eTypeIsPointer))
383 return type_flags.AllClear(eTypeIsBuiltIn);
384 return false;
385}
386
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000387void
388ValueObjectPrinter::GetValueSummaryError (std::string& value,
389 std::string& summary,
390 std::string& error)
391{
Enrico Granata465f4bc2014-02-15 01:24:44 +0000392 if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat())
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000393 {
Enrico Granata465f4bc2014-02-15 01:24:44 +0000394 m_valobj->GetValueAsCString(options.m_format,
395 value);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000396 }
Enrico Granata465f4bc2014-02-15 01:24:44 +0000397 else
398 {
399 const char* val_cstr = m_valobj->GetValueAsCString();
400 if (val_cstr)
401 value.assign(val_cstr);
402 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000403 const char* err_cstr = m_valobj->GetError().AsCString();
404 if (err_cstr)
405 error.assign(err_cstr);
406
407 if (ShouldPrintValueObject())
408 {
409 if (IsNil())
410 summary.assign("nil");
411 else if (options.m_omit_summary_depth == 0)
412 {
413 TypeSummaryImpl* entry = GetSummaryFormatter();
414 if (entry)
Enrico Granata73e8c4d2015-10-07 02:36:35 +0000415 m_valobj->GetSummaryAsCString(entry, summary, options.m_varformat_language);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000416 else
417 {
Enrico Granata73e8c4d2015-10-07 02:36:35 +0000418 const char* sum_cstr = m_valobj->GetSummaryAsCString(options.m_varformat_language);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000419 if (sum_cstr)
420 summary.assign(sum_cstr);
421 }
422 }
423 }
424}
425
426bool
427ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
428 bool& summary_printed)
429{
430 bool error_printed = false;
431 if (ShouldPrintValueObject())
432 {
433 if (!CheckScopeIfNeeded())
434 m_error.assign("out of scope");
435 if (m_error.empty())
436 {
437 GetValueSummaryError(m_value, m_summary, m_error);
438 }
439 if (m_error.size())
440 {
441 error_printed = true;
442 m_stream->Printf (" <%s>\n", m_error.c_str());
443 }
444 else
445 {
446 // Make sure we have a value and make sure the summary didn't
447 // specify that the value should not be printed - and do not print
448 // the value if this thing is nil
449 // (but show the value if the user passes a format explicitly)
450 TypeSummaryImpl* entry = GetSummaryFormatter();
Enrico Granata8a068e62014-04-23 23:16:25 +0000451 if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value)
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000452 {
Enrico Granatae0ee1e12015-10-17 01:05:50 +0000453 if (options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) {}
454 else
455 {
456 m_stream->Printf(" %s", m_value.c_str());
457 value_printed = true;
458 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000459 }
460
461 if (m_summary.size())
462 {
463 m_stream->Printf(" %s", m_summary.c_str());
464 summary_printed = true;
465 }
466 }
467 }
468 return !error_printed;
469}
470
471bool
472ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
473 bool summary_printed)
474{
475 if (ShouldPrintValueObject())
476 {
477 // let's avoid the overly verbose no description error for a nil thing
478 if (options.m_use_objc && !IsNil())
479 {
480 if (!options.m_hide_value || !options.m_hide_name)
481 m_stream->Printf(" ");
482 const char *object_desc = nullptr;
483 if (value_printed || summary_printed)
484 object_desc = m_valobj->GetObjectDescription();
485 else
486 object_desc = GetDescriptionForDisplay();
487 if (object_desc && *object_desc)
488 {
489 m_stream->Printf("%s\n", object_desc);
490 return true;
491 }
492 else if (value_printed == false && summary_printed == false)
493 return true;
494 else
495 return false;
496 }
497 }
498 return true;
499}
500
501bool
Enrico Granatac1b7c092015-07-27 18:34:14 +0000502DumpValueObjectOptions::PointerDepth::CanAllowExpansion (bool is_root,
503 TypeSummaryImpl* entry,
504 ValueObject *valobj,
505 const std::string& summary)
506{
507 switch (m_mode)
508 {
509 case Mode::Always:
510 return (m_count > 0);
511 case Mode::Never:
512 return false;
513 case Mode::Default:
514 if (is_root)
515 m_count = std::min<decltype(m_count)>(m_count,1);
516 return m_count > 0;
517 case Mode::Formatters:
518 if (!entry || entry->DoesPrintChildren(valobj) || summary.empty())
519 return m_count > 0;
520 return false;
521 }
Zachary Turner84f5b0d2015-09-09 17:25:43 +0000522 return false;
Enrico Granatac1b7c092015-07-27 18:34:14 +0000523}
524
525bool
526DumpValueObjectOptions::PointerDepth::CanAllowExpansion () const
527{
528 switch (m_mode)
529 {
530 case Mode::Always:
531 case Mode::Default:
532 case Mode::Formatters:
533 return (m_count > 0);
534 case Mode::Never:
535 return false;
536 }
Zachary Turner84f5b0d2015-09-09 17:25:43 +0000537 return false;
Enrico Granatac1b7c092015-07-27 18:34:14 +0000538}
539
540bool
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000541ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
Enrico Granatac1b7c092015-07-27 18:34:14 +0000542 DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000543{
544 const bool is_ref = IsRef ();
545 const bool is_ptr = IsPtr ();
546
Enrico Granatac1b7c092015-07-27 18:34:14 +0000547 TypeSummaryImpl* entry = GetSummaryFormatter();
548
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000549 if (is_failed_description || m_curr_depth < options.m_max_depth)
550 {
551 // We will show children for all concrete types. We won't show
552 // pointer contents unless a pointer depth has been specified.
553 // We won't reference contents unless the reference is the
554 // root object (depth of zero).
555
556 // Use a new temporary pointer depth in case we override the
557 // current pointer depth below...
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000558
559 if (is_ptr || is_ref)
560 {
561 // We have a pointer or reference whose value is an address.
562 // Make sure that address is not NULL
563 AddressType ptr_address_type;
564 if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
565 return false;
566
Enrico Granatac1b7c092015-07-27 18:34:14 +0000567 const bool is_root_level = m_curr_depth == 0;
568
569 if (is_ref &&
570 is_root_level)
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000571 {
572 // If this is the root object (depth is zero) that we are showing
573 // and it is a reference, and no pointer depth has been supplied
574 // print out what it references. Don't do this at deeper depths
575 // otherwise we can end up with infinite recursion...
Enrico Granatac1b7c092015-07-27 18:34:14 +0000576 return true;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000577 }
578
Enrico Granatac1b7c092015-07-27 18:34:14 +0000579 return curr_ptr_depth.CanAllowExpansion(false, entry, m_valobj, m_summary);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000580 }
581
Enrico Granata8a068e62014-04-23 23:16:25 +0000582 return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000583 }
584 return false;
585}
586
Siva Chandrad26eb902015-07-24 21:30:58 +0000587bool
588ValueObjectPrinter::ShouldExpandEmptyAggregates ()
589{
590 TypeSummaryImpl* entry = GetSummaryFormatter();
591
592 if (!entry)
593 return true;
594
595 return entry->DoesPrintEmptyAggregates();
596}
597
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000598ValueObject*
599ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
600{
Enrico Granatad07cfd32014-10-08 18:27:36 +0000601 return m_valobj;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000602}
603
604void
605ValueObjectPrinter::PrintChildrenPreamble ()
606{
607 if (options.m_flat_output)
608 {
609 if (ShouldPrintValueObject())
610 m_stream->EOL();
611 }
612 else
613 {
614 if (ShouldPrintValueObject())
615 m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
616 m_stream->IndentMore();
617 }
618}
619
620void
621ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
Enrico Granatac1b7c092015-07-27 18:34:14 +0000622 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000623{
624 DumpValueObjectOptions child_options(options);
Enrico Granata443844c2015-06-17 02:11:48 +0000625 child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000626 child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
627 .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
628 if (child_sp.get())
629 {
630 ValueObjectPrinter child_printer(child_sp.get(),
631 m_stream,
632 child_options,
Enrico Granatac1b7c092015-07-27 18:34:14 +0000633 (IsPtr() || IsRef()) ? --curr_ptr_depth : curr_ptr_depth,
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000634 m_curr_depth + 1);
635 child_printer.PrintValueObject();
636 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000637}
638
639uint32_t
640ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
641{
642 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
643
644 size_t num_children = synth_m_valobj->GetNumChildren();
645 print_dotdotdot = false;
646 if (num_children)
647 {
648 const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
649
650 if (num_children > max_num_children && !options.m_ignore_cap)
651 {
652 print_dotdotdot = true;
653 return max_num_children;
654 }
655 }
656 return num_children;
657}
658
659void
660ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
661{
662 if (!options.m_flat_output)
663 {
664 if (print_dotdotdot)
665 {
666 m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
667 m_stream->Indent("...\n");
668 }
669 m_stream->IndentLess();
670 m_stream->Indent("}\n");
671 }
672}
673
674void
Enrico Granatac1b7c092015-07-27 18:34:14 +0000675ValueObjectPrinter::PrintChildren (bool value_printed,
676 bool summary_printed,
677 const DumpValueObjectOptions::PointerDepth& curr_ptr_depth)
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000678{
679 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
680
681 bool print_dotdotdot = false;
682 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
683 if (num_children)
684 {
685 PrintChildrenPreamble ();
686
687 for (size_t idx=0; idx<num_children; ++idx)
688 {
689 ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
690 PrintChild (child_sp, curr_ptr_depth);
691 }
692
693 PrintChildrenPostamble (print_dotdotdot);
694 }
695 else if (IsAggregate())
696 {
697 // Aggregate, no children...
698 if (ShouldPrintValueObject())
Enrico Granatad07cfd32014-10-08 18:27:36 +0000699 {
700 // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
Siva Chandrad26eb902015-07-24 21:30:58 +0000701 if (m_valobj->DoesProvideSyntheticValue() || !ShouldExpandEmptyAggregates())
Enrico Granatad07cfd32014-10-08 18:27:36 +0000702 m_stream->PutCString( "\n");
703 else
704 m_stream->PutCString(" {}\n");
705 }
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000706 }
707 else
708 {
709 if (ShouldPrintValueObject())
710 m_stream->EOL();
711 }
712}
713
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000714bool
715ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
716{
Enrico Granatad07cfd32014-10-08 18:27:36 +0000717 if (!GetMostSpecializedValue () || m_valobj == nullptr)
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000718 return false;
719
720 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
721
722 bool print_dotdotdot = false;
723 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
724
725 if (num_children)
726 {
727 m_stream->PutChar('(');
728
729 for (uint32_t idx=0; idx<num_children; ++idx)
730 {
731 lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
Enrico Granataddac7612014-10-09 18:47:36 +0000732 if (child_sp)
733 child_sp = child_sp->GetQualifiedRepresentationIfAvailable(options.m_use_dynamic, options.m_use_synthetic);
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000734 if (child_sp)
735 {
736 if (idx)
737 m_stream->PutCString(", ");
738 if (!hide_names)
739 {
740 const char* name = child_sp.get()->GetName().AsCString();
741 if (name && *name)
742 {
743 m_stream->PutCString(name);
744 m_stream->PutCString(" = ");
745 }
746 }
747 child_sp->DumpPrintableRepresentation(*m_stream,
748 ValueObject::eValueObjectRepresentationStyleSummary,
Enrico Granata443844c2015-06-17 02:11:48 +0000749 lldb::eFormatInvalid,
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000750 ValueObject::ePrintableRepresentationSpecialCasesDisable);
751 }
752 }
753
754 if (print_dotdotdot)
755 m_stream->PutCString(", ...)");
756 else
757 m_stream->PutChar(')');
758 }
759 return true;
760}
761
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000762void
763ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
764 bool summary_printed)
765{
766 // this flag controls whether we tried to display a description for this object and failed
767 // if that happens, we want to display the children, if any
768 bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
769
Enrico Granatac1b7c092015-07-27 18:34:14 +0000770 auto curr_ptr_depth = m_ptr_depth;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000771 bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
Enrico Granatac1b7c092015-07-27 18:34:14 +0000772 bool print_oneline = (curr_ptr_depth.CanAllowExpansion() ||
Enrico Granata3fa6dc92015-03-12 22:16:20 +0000773 options.m_show_types ||
774 !options.m_allow_oneliner_mode ||
775 options.m_flat_output ||
776 options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000777
778 if (print_children)
779 {
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000780 if (print_oneline)
781 {
782 m_stream->PutChar(' ');
783 PrintChildrenOneLiner (false);
784 m_stream->EOL();
785 }
786 else
Enrico Granatac1b7c092015-07-27 18:34:14 +0000787 PrintChildren (value_printed, summary_printed, curr_ptr_depth);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000788 }
789 else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
790 {
791 m_stream->PutCString("{...}\n");
792 }
Enrico Granata245b3ca2013-10-03 18:11:24 +0000793 else
794 m_stream->EOL();
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000795}
Enrico Granata0f883ff2014-09-06 02:20:19 +0000796
797bool
798ValueObjectPrinter::ShouldPrintValidation ()
799{
800 return options.m_run_validator;
801}
802
803bool
804ValueObjectPrinter::PrintValidationMarkerIfNeeded ()
805{
806 if (!ShouldPrintValidation())
807 return false;
808
809 m_validation = m_valobj->GetValidationStatus();
810
811 if (TypeValidatorResult::Failure == m_validation.first)
812 {
813 m_stream->Printf("! ");
814 return true;
815 }
816
817 return false;
818}
819
820bool
821ValueObjectPrinter::PrintValidationErrorIfNeeded ()
822{
823 if (!ShouldPrintValidation())
824 return false;
825
826 if (TypeValidatorResult::Success == m_validation.first)
827 return false;
828
829 if (m_validation.second.empty())
830 m_validation.second.assign("unknown error");
831
832 m_stream->Printf(" ! validation error: %s", m_validation.second.c_str());
833 m_stream->EOL();
834
835 return true;
836}