14
14
#include " lldb/Target/Target.h"
15
15
#include " lldb/Utility/Stream.h"
16
16
#include " lldb/ValueObject/ValueObject.h"
17
+ #include " llvm/Support/Error.h"
17
18
#include " llvm/Support/MathExtras.h"
18
19
#include < cstdint>
20
+ #include < optional>
19
21
20
22
using namespace lldb ;
21
23
using namespace lldb_private ;
@@ -69,6 +71,18 @@ void ValueObjectPrinter::Init(
69
71
SetupMostSpecializedValue ();
70
72
}
71
73
74
+ static const char *maybeNewline (const std::string &s) {
75
+ // If the string already ends with a \n don't add another one.
76
+ if (s.empty () || s.back () != ' \n ' )
77
+ return " \n " ;
78
+ return " " ;
79
+ }
80
+
81
+ bool ValueObjectPrinter::ShouldPrintObjectDescription () {
82
+ return ShouldPrintValueObject () && m_options.m_use_object_desc && !IsNil () &&
83
+ !IsUninitialized () && !m_options.m_pointer_as_array ;
84
+ }
85
+
72
86
llvm::Error ValueObjectPrinter::PrintValueObject () {
73
87
// If the incoming ValueObject is in an error state, the best we're going to
74
88
// get out of it is its type. But if we don't even have that, just print
@@ -77,6 +91,25 @@ llvm::Error ValueObjectPrinter::PrintValueObject() {
77
91
!m_orig_valobj.GetCompilerType ().IsValid ())
78
92
return m_orig_valobj.GetError ().ToError ();
79
93
94
+ std::optional<std::string> object_desc;
95
+ if (ShouldPrintObjectDescription ()) {
96
+ // The object description is invoked now, but not printed until after
97
+ // value/summary. Calling GetObjectDescription at the outset of printing
98
+ // allows for early discovery of errors. In the case of an error, the value
99
+ // object is printed normally.
100
+ llvm::Expected<std::string> object_desc_or_err =
101
+ GetMostSpecializedValue ().GetObjectDescription ();
102
+ if (!object_desc_or_err) {
103
+ auto error_msg = toString (object_desc_or_err.takeError ());
104
+ *m_stream << " error: " << error_msg << maybeNewline (error_msg);
105
+
106
+ // Print the value object directly.
107
+ m_options.DisableObjectDescription ();
108
+ } else {
109
+ object_desc = *object_desc_or_err;
110
+ }
111
+ }
112
+
80
113
if (ShouldPrintValueObject ()) {
81
114
PrintLocationIfNeeded ();
82
115
m_stream->Indent ();
@@ -90,8 +123,10 @@ llvm::Error ValueObjectPrinter::PrintValueObject() {
90
123
m_val_summary_ok =
91
124
PrintValueAndSummaryIfNeeded (value_printed, summary_printed);
92
125
93
- if (m_val_summary_ok)
126
+ if (m_val_summary_ok) {
127
+ PrintObjectDescriptionIfNeeded (object_desc);
94
128
return PrintChildrenIfNeeded (value_printed, summary_printed);
129
+ }
95
130
m_stream->EOL ();
96
131
97
132
return llvm::Error::success ();
@@ -144,24 +179,6 @@ void ValueObjectPrinter::SetupMostSpecializedValue() {
144
179
" SetupMostSpecialized value must compute a valid ValueObject" );
145
180
}
146
181
147
- llvm::Expected<std::string> ValueObjectPrinter::GetDescriptionForDisplay () {
148
- ValueObject &valobj = GetMostSpecializedValue ();
149
- llvm::Expected<std::string> maybe_str = valobj.GetObjectDescription ();
150
- if (maybe_str)
151
- return maybe_str;
152
-
153
- const char *str = nullptr ;
154
- if (!str)
155
- str = valobj.GetSummaryAsCString ();
156
- if (!str)
157
- str = valobj.GetValueAsCString ();
158
-
159
- if (!str)
160
- return maybe_str;
161
- llvm::consumeError (maybe_str.takeError ());
162
- return str;
163
- }
164
-
165
182
const char *ValueObjectPrinter::GetRootNameForDisplay () {
166
183
const char *root_valobj_name =
167
184
m_options.m_root_valobj_name .empty ()
@@ -468,38 +485,14 @@ bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed,
468
485
return !error_printed;
469
486
}
470
487
471
- llvm::Error
472
- ValueObjectPrinter::PrintObjectDescriptionIfNeeded (bool value_printed,
473
- bool summary_printed) {
474
- if (ShouldPrintValueObject ()) {
475
- // let's avoid the overly verbose no description error for a nil thing
476
- if (m_options.m_use_objc && !IsNil () && !IsUninitialized () &&
477
- (!m_options.m_pointer_as_array )) {
478
- if (!m_options.m_hide_value || ShouldShowName ())
479
- *m_stream << ' ' ;
480
- llvm::Expected<std::string> object_desc =
481
- (value_printed || summary_printed)
482
- ? GetMostSpecializedValue ().GetObjectDescription ()
483
- : GetDescriptionForDisplay ();
484
- if (!object_desc) {
485
- // If no value or summary was printed, surface the error.
486
- if (!value_printed && !summary_printed)
487
- return object_desc.takeError ();
488
- // Otherwise gently nudge the user that they should have used
489
- // `p` instead of `po`. Unfortunately we cannot be more direct
490
- // about this, because we don't actually know what the user did.
491
- *m_stream << " warning: no object description available\n " ;
492
- llvm::consumeError (object_desc.takeError ());
493
- } else {
494
- *m_stream << *object_desc;
495
- // If the description already ends with a \n don't add another one.
496
- if (object_desc->empty () || object_desc->back () != ' \n ' )
497
- *m_stream << ' \n ' ;
498
- }
499
- return llvm::Error::success ();
500
- }
501
- }
502
- return llvm::Error::success ();
488
+ void ValueObjectPrinter::PrintObjectDescriptionIfNeeded (
489
+ std::optional<std::string> object_desc) {
490
+ if (!object_desc)
491
+ return ;
492
+
493
+ if (!m_options.m_hide_value || ShouldShowName ())
494
+ *m_stream << ' ' ;
495
+ *m_stream << *object_desc << maybeNewline (*object_desc);
503
496
}
504
497
505
498
bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion (
@@ -552,7 +545,7 @@ bool ValueObjectPrinter::ShouldPrintChildren(
552
545
if (m_options.m_pointer_as_array )
553
546
return true ;
554
547
555
- if (m_options.m_use_objc )
548
+ if (m_options.m_use_object_desc )
556
549
return false ;
557
550
558
551
bool print_children = true ;
@@ -849,9 +842,6 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) {
849
842
850
843
llvm::Error ValueObjectPrinter::PrintChildrenIfNeeded (bool value_printed,
851
844
bool summary_printed) {
852
- auto error = PrintObjectDescriptionIfNeeded (value_printed, summary_printed);
853
- if (error)
854
- return error;
855
845
856
846
ValueObject &valobj = GetMostSpecializedValue ();
857
847
0 commit comments