blob: 7da5450bcd247c057e955434a84614455d1c6274 [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
16#include "lldb/Core/Debugger.h"
Enrico Granataa29cb0b2013-10-04 23:14:13 +000017#include "lldb/DataFormatters/DataVisualization.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000018#include "lldb/Interpreter/CommandInterpreter.h"
19#include "lldb/Target/Target.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
25 Stream* s,
26 const DumpValueObjectOptions& options) :
27 m_orig_valobj(valobj),
28 m_valobj(nullptr),
29 m_stream(s),
30 options(options),
31 m_ptr_depth(options.m_max_ptr_depth),
32 m_curr_depth(0),
33 m_should_print(eLazyBoolCalculate),
34 m_is_nil(eLazyBoolCalculate),
35 m_is_ptr(eLazyBoolCalculate),
36 m_is_ref(eLazyBoolCalculate),
37 m_is_aggregate(eLazyBoolCalculate),
38 m_summary_formatter({nullptr,false}),
39 m_value(),
40 m_summary(),
41 m_error()
42{
43 assert (m_orig_valobj && "cannot print a NULL ValueObject");
44 assert (m_stream && "cannot print to a NULL Stream");
45}
46
47ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
48 Stream* s,
49 const DumpValueObjectOptions& options,
50 uint32_t ptr_depth,
51 uint32_t curr_depth) :
Daniel Malea73435af2013-09-30 23:12:05 +000052 m_orig_valobj(valobj),
53 m_valobj(nullptr),
54 m_stream(s),
55 options(options),
56 m_ptr_depth(ptr_depth),
57 m_curr_depth(curr_depth),
58 m_should_print(eLazyBoolCalculate),
59 m_is_nil(eLazyBoolCalculate),
60 m_is_ptr(eLazyBoolCalculate),
61 m_is_ref(eLazyBoolCalculate),
62 m_is_aggregate(eLazyBoolCalculate),
63 m_summary_formatter({nullptr,false}),
64 m_value(),
65 m_summary(),
66 m_error()
67{ }
Enrico Granata4d93b8c2013-09-30 19:11:51 +000068
69bool
70ValueObjectPrinter::PrintValueObject ()
71{
72 if (!GetDynamicValueIfNeeded () || m_valobj == nullptr)
73 return false;
74
75 if (ShouldPrintValueObject())
76 {
77 PrintLocationIfNeeded();
78 m_stream->Indent();
79
80 bool show_type = PrintTypeIfNeeded();
81
82 PrintNameIfNeeded(show_type);
83 }
84
85 bool value_printed = false;
86 bool summary_printed = false;
87
88 bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
89
90 if (val_summary_ok)
91 PrintChildrenIfNeeded (value_printed, summary_printed);
Enrico Granata39938932013-10-03 02:06:02 +000092 else
93 m_stream->EOL();
Enrico Granata4d93b8c2013-09-30 19:11:51 +000094
95 return true;
96}
97
98bool
99ValueObjectPrinter::GetDynamicValueIfNeeded ()
100{
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000101 if (m_valobj)
102 return true;
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000103 bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
104 if (!update_success)
105 return false;
106 if (options.m_use_dynamic != eNoDynamicValues)
107 {
108 ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(options.m_use_dynamic).get();
109 if (dynamic_value)
110 m_valobj = dynamic_value;
111 else
112 m_valobj = m_orig_valobj;
113 }
114 else
115 m_valobj = m_orig_valobj;
116 m_clang_type = m_valobj->GetClangType();
117 m_type_flags = m_clang_type.GetTypeInfo ();
118 return true;
119}
120
121const char*
122ValueObjectPrinter::GetDescriptionForDisplay ()
123{
124 const char* str = m_valobj->GetObjectDescription();
125 if (!str)
126 str = m_valobj->GetSummaryAsCString();
127 if (!str)
128 str = m_valobj->GetValueAsCString();
129 return str;
130}
131
132const char*
133ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
134{
135 const char *root_valobj_name = options.m_root_valobj_name.empty() ?
136 m_valobj->GetName().AsCString() :
137 options.m_root_valobj_name.c_str();
138 return root_valobj_name ? root_valobj_name : if_fail;
139}
140
141bool
142ValueObjectPrinter::ShouldPrintValueObject ()
143{
144 if (m_should_print == eLazyBoolCalculate)
145 m_should_print = (options.m_flat_output == false || m_type_flags.Test (ClangASTType::eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
146 return m_should_print == eLazyBoolYes;
147}
148
149bool
150ValueObjectPrinter::IsNil ()
151{
152 if (m_is_nil == eLazyBoolCalculate)
153 m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo;
154 return m_is_nil == eLazyBoolYes;
155}
156
157bool
158ValueObjectPrinter::IsPtr ()
159{
160 if (m_is_ptr == eLazyBoolCalculate)
161 m_is_ptr = m_type_flags.Test (ClangASTType::eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
162 return m_is_ptr == eLazyBoolYes;
163}
164
165bool
166ValueObjectPrinter::IsRef ()
167{
168 if (m_is_ref == eLazyBoolCalculate)
169 m_is_ref = m_type_flags.Test (ClangASTType::eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
170 return m_is_ref == eLazyBoolYes;
171}
172
173bool
174ValueObjectPrinter::IsAggregate ()
175{
176 if (m_is_aggregate == eLazyBoolCalculate)
177 m_is_aggregate = m_type_flags.Test (ClangASTType::eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
178 return m_is_aggregate == eLazyBoolYes;
179}
180
181bool
182ValueObjectPrinter::PrintLocationIfNeeded ()
183{
184 if (options.m_show_location)
185 {
186 m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
187 return true;
188 }
189 return false;
190}
191
192bool
193ValueObjectPrinter::PrintTypeIfNeeded ()
194{
195 bool show_type = true;
196 // if we are at the root-level and been asked to hide the root's type, then hide it
197 if (m_curr_depth == 0 && options.m_hide_root_type)
198 show_type = false;
199 else
200 // otherwise decide according to the usual rules (asked to show types - always at the root level)
201 show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output);
202
203 if (show_type)
204 {
205 // Some ValueObjects don't have types (like registers sets). Only print
206 // the type if there is one to print
207 ConstString qualified_type_name(m_valobj->GetQualifiedTypeName());
208 if (qualified_type_name)
209 m_stream->Printf("(%s) ", qualified_type_name.GetCString());
210 else
211 show_type = false;
212 }
213 return show_type;
214}
215
216bool
217ValueObjectPrinter::PrintNameIfNeeded (bool show_type)
218{
219 if (options.m_flat_output)
220 {
221 // If we are showing types, also qualify the C++ base classes
222 const bool qualify_cxx_base_classes = show_type;
223 if (!options.m_hide_name)
224 {
225 m_valobj->GetExpressionPath(*m_stream, qualify_cxx_base_classes);
226 m_stream->PutCString(" =");
227 return true;
228 }
229 }
230 else if (!options.m_hide_name)
231 {
232 const char *name_cstr = GetRootNameForDisplay("");
233 m_stream->Printf ("%s =", name_cstr);
234 return true;
235 }
236 return false;
237}
238
239bool
240ValueObjectPrinter::CheckScopeIfNeeded ()
241{
242 if (options.m_scope_already_checked)
243 return true;
244 return m_valobj->IsInScope();
245}
246
247TypeSummaryImpl*
248ValueObjectPrinter::GetSummaryFormatter ()
249{
250 if (m_summary_formatter.second == false)
251 {
252 TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
253
254 if (options.m_omit_summary_depth > 0)
255 entry = NULL;
256 m_summary_formatter.first = entry;
257 m_summary_formatter.second = true;
258 }
259 return m_summary_formatter.first;
260}
261
262void
263ValueObjectPrinter::GetValueSummaryError (std::string& value,
264 std::string& summary,
265 std::string& error)
266{
267 if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat())
268 {
269 m_valobj->GetValueAsCString(options.m_format,
270 value);
271 }
272 else
273 {
274 const char* val_cstr = m_valobj->GetValueAsCString();
275 if (val_cstr)
276 value.assign(val_cstr);
277 }
278 const char* err_cstr = m_valobj->GetError().AsCString();
279 if (err_cstr)
280 error.assign(err_cstr);
281
282 if (ShouldPrintValueObject())
283 {
284 if (IsNil())
285 summary.assign("nil");
286 else if (options.m_omit_summary_depth == 0)
287 {
288 TypeSummaryImpl* entry = GetSummaryFormatter();
289 if (entry)
290 m_valobj->GetSummaryAsCString(entry, summary);
291 else
292 {
293 const char* sum_cstr = m_valobj->GetSummaryAsCString();
294 if (sum_cstr)
295 summary.assign(sum_cstr);
296 }
297 }
298 }
299}
300
301bool
302ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
303 bool& summary_printed)
304{
305 bool error_printed = false;
306 if (ShouldPrintValueObject())
307 {
308 if (!CheckScopeIfNeeded())
309 m_error.assign("out of scope");
310 if (m_error.empty())
311 {
312 GetValueSummaryError(m_value, m_summary, m_error);
313 }
314 if (m_error.size())
315 {
316 error_printed = true;
317 m_stream->Printf (" <%s>\n", m_error.c_str());
318 }
319 else
320 {
321 // Make sure we have a value and make sure the summary didn't
322 // specify that the value should not be printed - and do not print
323 // the value if this thing is nil
324 // (but show the value if the user passes a format explicitly)
325 TypeSummaryImpl* entry = GetSummaryFormatter();
326 if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue() || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value)
327 {
328 m_stream->Printf(" %s", m_value.c_str());
329 value_printed = true;
330 }
331
332 if (m_summary.size())
333 {
334 m_stream->Printf(" %s", m_summary.c_str());
335 summary_printed = true;
336 }
337 }
338 }
339 return !error_printed;
340}
341
342bool
343ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
344 bool summary_printed)
345{
346 if (ShouldPrintValueObject())
347 {
348 // let's avoid the overly verbose no description error for a nil thing
349 if (options.m_use_objc && !IsNil())
350 {
351 if (!options.m_hide_value || !options.m_hide_name)
352 m_stream->Printf(" ");
353 const char *object_desc = nullptr;
354 if (value_printed || summary_printed)
355 object_desc = m_valobj->GetObjectDescription();
356 else
357 object_desc = GetDescriptionForDisplay();
358 if (object_desc && *object_desc)
359 {
360 m_stream->Printf("%s\n", object_desc);
361 return true;
362 }
363 else if (value_printed == false && summary_printed == false)
364 return true;
365 else
366 return false;
367 }
368 }
369 return true;
370}
371
372bool
373ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
374 uint32_t& curr_ptr_depth)
375{
376 const bool is_ref = IsRef ();
377 const bool is_ptr = IsPtr ();
378
379 if (is_failed_description || m_curr_depth < options.m_max_depth)
380 {
381 // We will show children for all concrete types. We won't show
382 // pointer contents unless a pointer depth has been specified.
383 // We won't reference contents unless the reference is the
384 // root object (depth of zero).
385
386 // Use a new temporary pointer depth in case we override the
387 // current pointer depth below...
388 uint32_t curr_ptr_depth = m_ptr_depth;
389
390 if (is_ptr || is_ref)
391 {
392 // We have a pointer or reference whose value is an address.
393 // Make sure that address is not NULL
394 AddressType ptr_address_type;
395 if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
396 return false;
397
398 else if (is_ref && m_curr_depth == 0)
399 {
400 // If this is the root object (depth is zero) that we are showing
401 // and it is a reference, and no pointer depth has been supplied
402 // print out what it references. Don't do this at deeper depths
403 // otherwise we can end up with infinite recursion...
404 curr_ptr_depth = 1;
405 }
406
407 if (curr_ptr_depth == 0)
408 return false;
409 }
410
411 TypeSummaryImpl* entry = GetSummaryFormatter();
412
413 return (!entry || entry->DoesPrintChildren() || m_summary.empty());
414 }
415 return false;
416}
417
418ValueObject*
419ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
420{
421 ValueObjectSP synth_valobj_sp = m_valobj->GetSyntheticValue (options.m_use_synthetic);
422 return (synth_valobj_sp ? synth_valobj_sp.get() : m_valobj);
423}
424
425void
426ValueObjectPrinter::PrintChildrenPreamble ()
427{
428 if (options.m_flat_output)
429 {
430 if (ShouldPrintValueObject())
431 m_stream->EOL();
432 }
433 else
434 {
435 if (ShouldPrintValueObject())
436 m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
437 m_stream->IndentMore();
438 }
439}
440
441void
442ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
443 uint32_t curr_ptr_depth)
444{
445 DumpValueObjectOptions child_options(options);
446 child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
447 child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
448 .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
449 if (child_sp.get())
450 {
451 ValueObjectPrinter child_printer(child_sp.get(),
452 m_stream,
453 child_options,
454 (IsPtr() || IsRef()) ? curr_ptr_depth - 1 : curr_ptr_depth,
455 m_curr_depth + 1);
456 child_printer.PrintValueObject();
457 }
458
459}
460
461uint32_t
462ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
463{
464 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
465
466 size_t num_children = synth_m_valobj->GetNumChildren();
467 print_dotdotdot = false;
468 if (num_children)
469 {
470 const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
471
472 if (num_children > max_num_children && !options.m_ignore_cap)
473 {
474 print_dotdotdot = true;
475 return max_num_children;
476 }
477 }
478 return num_children;
479}
480
481void
482ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
483{
484 if (!options.m_flat_output)
485 {
486 if (print_dotdotdot)
487 {
488 m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
489 m_stream->Indent("...\n");
490 }
491 m_stream->IndentLess();
492 m_stream->Indent("}\n");
493 }
494}
495
496void
497ValueObjectPrinter::PrintChildren (uint32_t curr_ptr_depth)
498{
499 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
500
501 bool print_dotdotdot = false;
502 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
503 if (num_children)
504 {
505 PrintChildrenPreamble ();
506
507 for (size_t idx=0; idx<num_children; ++idx)
508 {
509 ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
510 PrintChild (child_sp, curr_ptr_depth);
511 }
512
513 PrintChildrenPostamble (print_dotdotdot);
514 }
515 else if (IsAggregate())
516 {
517 // Aggregate, no children...
518 if (ShouldPrintValueObject())
519 m_stream->PutCString(" {}\n");
520 }
521 else
522 {
523 if (ShouldPrintValueObject())
524 m_stream->EOL();
525 }
526}
527
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000528bool
529ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
530{
531 if (!GetDynamicValueIfNeeded () || m_valobj == nullptr)
532 return false;
533
534 ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
535
536 bool print_dotdotdot = false;
537 size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
538
539 if (num_children)
540 {
541 m_stream->PutChar('(');
542
543 for (uint32_t idx=0; idx<num_children; ++idx)
544 {
545 lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
546 lldb::ValueObjectSP child_dyn_sp = child_sp.get() ? child_sp->GetDynamicValue(options.m_use_dynamic) : child_sp;
547 if (child_dyn_sp)
548 child_sp = child_dyn_sp;
549 if (child_sp)
550 {
551 if (idx)
552 m_stream->PutCString(", ");
553 if (!hide_names)
554 {
555 const char* name = child_sp.get()->GetName().AsCString();
556 if (name && *name)
557 {
558 m_stream->PutCString(name);
559 m_stream->PutCString(" = ");
560 }
561 }
562 child_sp->DumpPrintableRepresentation(*m_stream,
563 ValueObject::eValueObjectRepresentationStyleSummary,
564 lldb::eFormatInvalid,
565 ValueObject::ePrintableRepresentationSpecialCasesDisable);
566 }
567 }
568
569 if (print_dotdotdot)
570 m_stream->PutCString(", ...)");
571 else
572 m_stream->PutChar(')');
573 }
574 return true;
575}
576
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000577void
578ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
579 bool summary_printed)
580{
581 // this flag controls whether we tried to display a description for this object and failed
582 // if that happens, we want to display the children, if any
583 bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
584
585 uint32_t curr_ptr_depth = m_ptr_depth;
586 bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000587 bool print_oneline = (curr_ptr_depth > 0 || options.m_show_types) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000588
589 if (print_children)
590 {
Enrico Granataa29cb0b2013-10-04 23:14:13 +0000591 if (print_oneline)
592 {
593 m_stream->PutChar(' ');
594 PrintChildrenOneLiner (false);
595 m_stream->EOL();
596 }
597 else
598 PrintChildren (curr_ptr_depth);
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000599 }
600 else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
601 {
602 m_stream->PutCString("{...}\n");
603 }
Enrico Granata245b3ca2013-10-03 18:11:24 +0000604 else
605 m_stream->EOL();
Enrico Granata4d93b8c2013-09-30 19:11:51 +0000606}