ValueObjectPrinter.cpp revision 288943
1//===-- ValueObjectPrinter.cpp -------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/DataFormatters/ValueObjectPrinter.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Core/Debugger.h"
17#include "lldb/DataFormatters/DataVisualization.h"
18#include "lldb/Interpreter/CommandInterpreter.h"
19#include "lldb/Target/Target.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24DumpValueObjectOptions::DumpValueObjectOptions (ValueObject& valobj) :
25DumpValueObjectOptions()
26{
27    m_use_dynamic = valobj.GetDynamicValueType();
28    m_use_synthetic = valobj.IsSynthetic();
29}
30
31ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
32                                        Stream* s)
33{
34    if (valobj)
35    {
36        DumpValueObjectOptions options(*valobj);
37        Init (valobj,s,options,options.m_max_ptr_depth,0);
38    }
39    else
40    {
41        DumpValueObjectOptions options;
42        Init (valobj,s,options,options.m_max_ptr_depth,0);
43    }
44}
45
46ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
47                                        Stream* s,
48                                        const DumpValueObjectOptions& options)
49{
50    Init(valobj,s,options,options.m_max_ptr_depth,0);
51}
52
53ValueObjectPrinter::ValueObjectPrinter (ValueObject* valobj,
54                                        Stream* s,
55                                        const DumpValueObjectOptions& options,
56                                        uint32_t ptr_depth,
57                                        uint32_t curr_depth)
58{
59    Init(valobj,s,options,ptr_depth,curr_depth);
60}
61
62void
63ValueObjectPrinter::Init (ValueObject* valobj,
64                          Stream* s,
65                          const DumpValueObjectOptions& options,
66                          uint32_t ptr_depth,
67                          uint32_t curr_depth)
68{
69    m_orig_valobj = valobj;
70    m_valobj = nullptr;
71    m_stream = s;
72    this->options = options;
73    m_ptr_depth = ptr_depth;
74    m_curr_depth = curr_depth;
75    assert (m_orig_valobj && "cannot print a NULL ValueObject");
76    assert (m_stream && "cannot print to a NULL Stream");
77    m_should_print = eLazyBoolCalculate;
78    m_is_nil = eLazyBoolCalculate;
79    m_is_ptr = eLazyBoolCalculate;
80    m_is_ref = eLazyBoolCalculate;
81    m_is_aggregate = eLazyBoolCalculate;
82    m_summary_formatter = {nullptr,false};
83    m_value.assign("");
84    m_summary.assign("");
85    m_error.assign("");
86}
87
88bool
89ValueObjectPrinter::PrintValueObject ()
90{
91    if (!GetMostSpecializedValue () || m_valobj == nullptr)
92        return false;
93
94    if (ShouldPrintValueObject())
95    {
96        PrintValidationMarkerIfNeeded();
97
98        PrintLocationIfNeeded();
99        m_stream->Indent();
100
101        bool show_type = PrintTypeIfNeeded();
102
103        PrintNameIfNeeded(show_type);
104    }
105
106    bool value_printed = false;
107    bool summary_printed = false;
108
109    bool val_summary_ok = PrintValueAndSummaryIfNeeded (value_printed,summary_printed);
110
111    if (val_summary_ok)
112        PrintChildrenIfNeeded (value_printed, summary_printed);
113    else
114        m_stream->EOL();
115
116    PrintValidationErrorIfNeeded();
117
118    return true;
119}
120
121bool
122ValueObjectPrinter::GetMostSpecializedValue ()
123{
124    if (m_valobj)
125        return true;
126    bool update_success = m_orig_valobj->UpdateValueIfNeeded (true);
127    if (!update_success)
128    {
129        m_valobj = m_orig_valobj;
130    }
131    else
132    {
133        if (m_orig_valobj->IsDynamic())
134        {
135            if (options.m_use_dynamic == eNoDynamicValues)
136            {
137                ValueObject *static_value = m_orig_valobj->GetStaticValue().get();
138                if (static_value)
139                    m_valobj = static_value;
140                else
141                    m_valobj = m_orig_valobj;
142            }
143            else
144                m_valobj = m_orig_valobj;
145        }
146        else
147        {
148            if (options.m_use_dynamic != eNoDynamicValues)
149            {
150                ValueObject *dynamic_value = m_orig_valobj->GetDynamicValue(options.m_use_dynamic).get();
151                if (dynamic_value)
152                    m_valobj = dynamic_value;
153                else
154                    m_valobj = m_orig_valobj;
155            }
156            else
157                m_valobj = m_orig_valobj;
158        }
159
160        if (m_valobj->IsSynthetic())
161        {
162            if (options.m_use_synthetic == false)
163            {
164                ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get();
165                if (non_synthetic)
166                    m_valobj = non_synthetic;
167            }
168        }
169        else
170        {
171            if (options.m_use_synthetic == true)
172            {
173                ValueObject *synthetic = m_valobj->GetSyntheticValue().get();
174                if (synthetic)
175                    m_valobj = synthetic;
176            }
177        }
178    }
179    m_clang_type = m_valobj->GetClangType();
180    m_type_flags = m_clang_type.GetTypeInfo ();
181    return true;
182}
183
184const char*
185ValueObjectPrinter::GetDescriptionForDisplay ()
186{
187    const char* str = m_valobj->GetObjectDescription();
188    if (!str)
189        str = m_valobj->GetSummaryAsCString();
190    if (!str)
191        str = m_valobj->GetValueAsCString();
192    return str;
193}
194
195const char*
196ValueObjectPrinter::GetRootNameForDisplay (const char* if_fail)
197{
198    const char *root_valobj_name = options.m_root_valobj_name.empty() ?
199        m_valobj->GetName().AsCString() :
200        options.m_root_valobj_name.c_str();
201    return root_valobj_name ? root_valobj_name : if_fail;
202}
203
204bool
205ValueObjectPrinter::ShouldPrintValueObject ()
206{
207    if (m_should_print == eLazyBoolCalculate)
208        m_should_print = (options.m_flat_output == false || m_type_flags.Test (eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo;
209    return m_should_print == eLazyBoolYes;
210}
211
212bool
213ValueObjectPrinter::IsNil ()
214{
215    if (m_is_nil == eLazyBoolCalculate)
216        m_is_nil = m_valobj->IsObjCNil() ? eLazyBoolYes : eLazyBoolNo;
217    return m_is_nil == eLazyBoolYes;
218}
219
220bool
221ValueObjectPrinter::IsPtr ()
222{
223    if (m_is_ptr == eLazyBoolCalculate)
224        m_is_ptr = m_type_flags.Test (eTypeIsPointer) ? eLazyBoolYes : eLazyBoolNo;
225    return m_is_ptr == eLazyBoolYes;
226}
227
228bool
229ValueObjectPrinter::IsRef ()
230{
231    if (m_is_ref == eLazyBoolCalculate)
232        m_is_ref = m_type_flags.Test (eTypeIsReference) ? eLazyBoolYes : eLazyBoolNo;
233    return m_is_ref == eLazyBoolYes;
234}
235
236bool
237ValueObjectPrinter::IsAggregate ()
238{
239    if (m_is_aggregate == eLazyBoolCalculate)
240        m_is_aggregate = m_type_flags.Test (eTypeHasChildren) ? eLazyBoolYes : eLazyBoolNo;
241    return m_is_aggregate == eLazyBoolYes;
242}
243
244bool
245ValueObjectPrinter::PrintLocationIfNeeded ()
246{
247    if (options.m_show_location)
248    {
249        m_stream->Printf("%s: ", m_valobj->GetLocationAsCString());
250        return true;
251    }
252    return false;
253}
254
255bool
256ValueObjectPrinter::PrintTypeIfNeeded ()
257{
258    bool show_type = true;
259    // if we are at the root-level and been asked to hide the root's type, then hide it
260    if (m_curr_depth == 0 && options.m_hide_root_type)
261        show_type = false;
262    else
263        // otherwise decide according to the usual rules (asked to show types - always at the root level)
264        show_type = options.m_show_types || (m_curr_depth == 0 && !options.m_flat_output);
265
266    if (show_type)
267    {
268        // Some ValueObjects don't have types (like registers sets). Only print
269        // the type if there is one to print
270        ConstString type_name;
271        if (options.m_use_type_display_name)
272            type_name = m_valobj->GetDisplayTypeName();
273        else
274            type_name = m_valobj->GetQualifiedTypeName();
275        if (type_name)
276            m_stream->Printf("(%s) ", type_name.GetCString());
277        else
278            show_type = false;
279    }
280    return show_type;
281}
282
283bool
284ValueObjectPrinter::PrintNameIfNeeded (bool show_type)
285{
286    if (options.m_flat_output)
287    {
288        // If we are showing types, also qualify the C++ base classes
289        const bool qualify_cxx_base_classes = show_type;
290        if (!options.m_hide_name)
291        {
292            m_valobj->GetExpressionPath(*m_stream, qualify_cxx_base_classes);
293            m_stream->PutCString(" =");
294            return true;
295        }
296    }
297    else if (!options.m_hide_name)
298    {
299        const char *name_cstr = GetRootNameForDisplay("");
300        m_stream->Printf ("%s =", name_cstr);
301        return true;
302    }
303    return false;
304}
305
306bool
307ValueObjectPrinter::CheckScopeIfNeeded ()
308{
309    if (options.m_scope_already_checked)
310        return true;
311    return m_valobj->IsInScope();
312}
313
314TypeSummaryImpl*
315ValueObjectPrinter::GetSummaryFormatter ()
316{
317    if (m_summary_formatter.second == false)
318    {
319        TypeSummaryImpl* entry = options.m_summary_sp ? options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get();
320
321        if (options.m_omit_summary_depth > 0)
322            entry = NULL;
323        m_summary_formatter.first = entry;
324        m_summary_formatter.second = true;
325    }
326    return m_summary_formatter.first;
327}
328
329void
330ValueObjectPrinter::GetValueSummaryError (std::string& value,
331                                          std::string& summary,
332                                          std::string& error)
333{
334    if (options.m_format != eFormatDefault && options.m_format != m_valobj->GetFormat())
335    {
336        m_valobj->GetValueAsCString(options.m_format,
337                                    value);
338    }
339    else
340    {
341        const char* val_cstr = m_valobj->GetValueAsCString();
342        if (val_cstr)
343            value.assign(val_cstr);
344    }
345    const char* err_cstr = m_valobj->GetError().AsCString();
346    if (err_cstr)
347        error.assign(err_cstr);
348
349    if (ShouldPrintValueObject())
350    {
351        if (IsNil())
352            summary.assign("nil");
353        else if (options.m_omit_summary_depth == 0)
354        {
355            TypeSummaryImpl* entry = GetSummaryFormatter();
356            if (entry)
357                m_valobj->GetSummaryAsCString(entry, summary);
358            else
359            {
360                const char* sum_cstr = m_valobj->GetSummaryAsCString();
361                if (sum_cstr)
362                    summary.assign(sum_cstr);
363            }
364        }
365    }
366}
367
368bool
369ValueObjectPrinter::PrintValueAndSummaryIfNeeded (bool& value_printed,
370                                                  bool& summary_printed)
371{
372    bool error_printed = false;
373    if (ShouldPrintValueObject())
374    {
375        if (!CheckScopeIfNeeded())
376            m_error.assign("out of scope");
377        if (m_error.empty())
378        {
379            GetValueSummaryError(m_value, m_summary, m_error);
380        }
381        if (m_error.size())
382        {
383            error_printed = true;
384            m_stream->Printf (" <%s>\n", m_error.c_str());
385        }
386        else
387        {
388            // Make sure we have a value and make sure the summary didn't
389            // specify that the value should not be printed - and do not print
390            // the value if this thing is nil
391            // (but show the value if the user passes a format explicitly)
392            TypeSummaryImpl* entry = GetSummaryFormatter();
393            if (!IsNil() && !m_value.empty() && (entry == NULL || (entry->DoesPrintValue(m_valobj) || options.m_format != eFormatDefault) || m_summary.empty()) && !options.m_hide_value)
394            {
395                m_stream->Printf(" %s", m_value.c_str());
396                value_printed = true;
397            }
398
399            if (m_summary.size())
400            {
401                m_stream->Printf(" %s", m_summary.c_str());
402                summary_printed = true;
403            }
404        }
405    }
406    return !error_printed;
407}
408
409bool
410ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
411                                                    bool summary_printed)
412{
413    if (ShouldPrintValueObject())
414    {
415        // let's avoid the overly verbose no description error for a nil thing
416        if (options.m_use_objc && !IsNil())
417        {
418            if (!options.m_hide_value || !options.m_hide_name)
419                m_stream->Printf(" ");
420            const char *object_desc = nullptr;
421            if (value_printed || summary_printed)
422                object_desc = m_valobj->GetObjectDescription();
423            else
424                object_desc = GetDescriptionForDisplay();
425            if (object_desc && *object_desc)
426            {
427                m_stream->Printf("%s\n", object_desc);
428                return true;
429            }
430            else if (value_printed == false && summary_printed == false)
431                return true;
432            else
433                return false;
434        }
435    }
436    return true;
437}
438
439bool
440ValueObjectPrinter::ShouldPrintChildren (bool is_failed_description,
441                                         uint32_t& curr_ptr_depth)
442{
443    const bool is_ref = IsRef ();
444    const bool is_ptr = IsPtr ();
445
446    if (is_failed_description || m_curr_depth < options.m_max_depth)
447    {
448        // We will show children for all concrete types. We won't show
449        // pointer contents unless a pointer depth has been specified.
450        // We won't reference contents unless the reference is the
451        // root object (depth of zero).
452
453        // Use a new temporary pointer depth in case we override the
454        // current pointer depth below...
455
456        if (is_ptr || is_ref)
457        {
458            // We have a pointer or reference whose value is an address.
459            // Make sure that address is not NULL
460            AddressType ptr_address_type;
461            if (m_valobj->GetPointerValue (&ptr_address_type) == 0)
462                return false;
463
464            else if (is_ref && m_curr_depth == 0 && curr_ptr_depth == 0)
465            {
466                // If this is the root object (depth is zero) that we are showing
467                // and it is a reference, and no pointer depth has been supplied
468                // print out what it references. Don't do this at deeper depths
469                // otherwise we can end up with infinite recursion...
470                curr_ptr_depth = 1;
471            }
472
473            return (curr_ptr_depth > 0);
474        }
475
476        TypeSummaryImpl* entry = GetSummaryFormatter();
477
478        return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty());
479    }
480    return false;
481}
482
483ValueObject*
484ValueObjectPrinter::GetValueObjectForChildrenGeneration ()
485{
486    return m_valobj;
487}
488
489void
490ValueObjectPrinter::PrintChildrenPreamble ()
491{
492    if (options.m_flat_output)
493    {
494        if (ShouldPrintValueObject())
495            m_stream->EOL();
496    }
497    else
498    {
499        if (ShouldPrintValueObject())
500            m_stream->PutCString(IsRef () ? ": {\n" : " {\n");
501        m_stream->IndentMore();
502    }
503}
504
505void
506ValueObjectPrinter::PrintChild (ValueObjectSP child_sp,
507                                uint32_t curr_ptr_depth)
508{
509    DumpValueObjectOptions child_options(options);
510    child_options.SetFormat(options.m_format).SetSummary().SetRootValueObjectName();
511    child_options.SetScopeChecked(true).SetHideName(options.m_hide_name).SetHideValue(options.m_hide_value)
512    .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - 1 : 0);
513    if (child_sp.get())
514    {
515        ValueObjectPrinter child_printer(child_sp.get(),
516                                         m_stream,
517                                         child_options,
518                                         (IsPtr() || IsRef()) && curr_ptr_depth >= 1 ? curr_ptr_depth - 1 : curr_ptr_depth,
519                                         m_curr_depth + 1);
520        child_printer.PrintValueObject();
521    }
522
523}
524
525uint32_t
526ValueObjectPrinter::GetMaxNumChildrenToPrint (bool& print_dotdotdot)
527{
528    ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
529
530    size_t num_children = synth_m_valobj->GetNumChildren();
531    print_dotdotdot = false;
532    if (num_children)
533    {
534        const size_t max_num_children = m_valobj->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
535
536        if (num_children > max_num_children && !options.m_ignore_cap)
537        {
538            print_dotdotdot = true;
539            return max_num_children;
540        }
541    }
542    return num_children;
543}
544
545void
546ValueObjectPrinter::PrintChildrenPostamble (bool print_dotdotdot)
547{
548    if (!options.m_flat_output)
549    {
550        if (print_dotdotdot)
551        {
552            m_valobj->GetTargetSP()->GetDebugger().GetCommandInterpreter().ChildrenTruncated();
553            m_stream->Indent("...\n");
554        }
555        m_stream->IndentLess();
556        m_stream->Indent("}\n");
557    }
558}
559
560void
561ValueObjectPrinter::PrintChildren (uint32_t curr_ptr_depth)
562{
563    ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
564
565    bool print_dotdotdot = false;
566    size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
567    if (num_children)
568    {
569        PrintChildrenPreamble ();
570
571        for (size_t idx=0; idx<num_children; ++idx)
572        {
573            ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
574            PrintChild (child_sp, curr_ptr_depth);
575        }
576
577        PrintChildrenPostamble (print_dotdotdot);
578    }
579    else if (IsAggregate())
580    {
581        // Aggregate, no children...
582        if (ShouldPrintValueObject())
583        {
584            // if it has a synthetic value, then don't print {}, the synthetic children are probably only being used to vend a value
585            if (m_valobj->DoesProvideSyntheticValue())
586                m_stream->PutCString( "\n");
587            else
588                m_stream->PutCString(" {}\n");
589        }
590    }
591    else
592    {
593        if (ShouldPrintValueObject())
594            m_stream->EOL();
595    }
596}
597
598bool
599ValueObjectPrinter::PrintChildrenOneLiner (bool hide_names)
600{
601    if (!GetMostSpecializedValue () || m_valobj == nullptr)
602        return false;
603
604    ValueObject* synth_m_valobj = GetValueObjectForChildrenGeneration();
605
606    bool print_dotdotdot = false;
607    size_t num_children = GetMaxNumChildrenToPrint(print_dotdotdot);
608
609    if (num_children)
610    {
611        m_stream->PutChar('(');
612
613        for (uint32_t idx=0; idx<num_children; ++idx)
614        {
615            lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true));
616            if (child_sp)
617                child_sp = child_sp->GetQualifiedRepresentationIfAvailable(options.m_use_dynamic, options.m_use_synthetic);
618            if (child_sp)
619            {
620                if (idx)
621                    m_stream->PutCString(", ");
622                if (!hide_names)
623                {
624                    const char* name = child_sp.get()->GetName().AsCString();
625                    if (name && *name)
626                    {
627                        m_stream->PutCString(name);
628                        m_stream->PutCString(" = ");
629                    }
630                }
631                child_sp->DumpPrintableRepresentation(*m_stream,
632                                                      ValueObject::eValueObjectRepresentationStyleSummary,
633                                                      lldb::eFormatInvalid,
634                                                      ValueObject::ePrintableRepresentationSpecialCasesDisable);
635            }
636        }
637
638        if (print_dotdotdot)
639            m_stream->PutCString(", ...)");
640        else
641            m_stream->PutChar(')');
642    }
643    return true;
644}
645
646void
647ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
648                                           bool summary_printed)
649{
650    // this flag controls whether we tried to display a description for this object and failed
651    // if that happens, we want to display the children, if any
652    bool is_failed_description = !PrintObjectDescriptionIfNeeded(value_printed, summary_printed);
653
654    uint32_t curr_ptr_depth = m_ptr_depth;
655    bool print_children = ShouldPrintChildren (is_failed_description,curr_ptr_depth);
656    bool print_oneline = (curr_ptr_depth > 0 ||
657                          options.m_show_types ||
658                          !options.m_allow_oneliner_mode ||
659                          options.m_flat_output ||
660                          options.m_show_location) ? false : DataVisualization::ShouldPrintAsOneLiner(*m_valobj);
661
662    if (print_children)
663    {
664        if (print_oneline)
665        {
666            m_stream->PutChar(' ');
667            PrintChildrenOneLiner (false);
668            m_stream->EOL();
669        }
670        else
671            PrintChildren (curr_ptr_depth);
672    }
673    else if (m_curr_depth >= options.m_max_depth && IsAggregate() && ShouldPrintValueObject())
674    {
675            m_stream->PutCString("{...}\n");
676    }
677    else
678        m_stream->EOL();
679}
680
681bool
682ValueObjectPrinter::ShouldPrintValidation ()
683{
684    return options.m_run_validator;
685}
686
687bool
688ValueObjectPrinter::PrintValidationMarkerIfNeeded ()
689{
690    if (!ShouldPrintValidation())
691        return false;
692
693    m_validation = m_valobj->GetValidationStatus();
694
695    if (TypeValidatorResult::Failure == m_validation.first)
696    {
697        m_stream->Printf("! ");
698        return true;
699    }
700
701    return false;
702}
703
704bool
705ValueObjectPrinter::PrintValidationErrorIfNeeded ()
706{
707    if (!ShouldPrintValidation())
708        return false;
709
710    if (TypeValidatorResult::Success == m_validation.first)
711        return false;
712
713    if (m_validation.second.empty())
714        m_validation.second.assign("unknown error");
715
716    m_stream->Printf(" ! validation error: %s", m_validation.second.c_str());
717    m_stream->EOL();
718
719    return true;
720}
721