LLDB mainline
TypeSummary.cpp
Go to the documentation of this file.
1//===-- TypeSummary.cpp ---------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10
11#include "FormatterBytecode.h"
13#include "lldb/lldb-public.h"
14
15#include "lldb/Core/Debugger.h"
20#include "lldb/Target/Target.h"
23
24using namespace lldb;
25using namespace lldb_private;
26
28
30
32 return m_capping;
33}
34
36 m_lang = lang;
37 return *this;
38}
39
42 m_capping = cap;
43 return *this;
44}
45
47 : m_flags(flags), m_kind(kind) {}
48
50 switch (m_kind) {
52 return "string";
53 case Kind::eCallback:
54 return "callback";
55 case Kind::eScript:
56 return "python";
57 case Kind::eInternal:
58 return "c++";
59 case Kind::eBytecode:
60 return "bytecode";
61 }
62}
63
65 const char *format_cstr)
66 : TypeSummaryImpl(Kind::eSummaryString, flags), m_format_str() {
67 SetSummaryString(format_cstr);
68}
69
70void StringSummaryFormat::SetSummaryString(const char *format_cstr) {
72 if (format_cstr && format_cstr[0]) {
73 m_format_str = format_cstr;
74 m_error = FormatEntity::Parse(format_cstr, m_format);
75 } else {
76 m_format_str.clear();
77 m_error.Clear();
78 }
79}
80
81bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
82 const TypeSummaryOptions &options) {
83 if (!valobj) {
84 retval.assign("NULL ValueObject");
85 return false;
86 }
87
91 StackFrame *frame = exe_ctx.GetFramePtr();
92 if (frame)
93 sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
94
95 if (IsOneLiner()) {
96 // We've already checked the case of a NULL valobj above. Let's put in an
97 // assert here to make sure someone doesn't take that out:
98 assert(valobj && "Must have a valid ValueObject to summarize");
99 ValueObjectPrinter printer(*valobj, &s, DumpValueObjectOptions());
100 printer.PrintChildrenOneLiner(HideNames(valobj));
101 retval = std::string(s.GetString());
102 return true;
103 } else {
104 if (FormatEntity::Format(m_format, s, &sc, &exe_ctx,
105 &sc.line_entry.range.GetBaseAddress(), valobj,
106 false, false)) {
107 retval.assign(std::string(s.GetString()));
108 return true;
109 } else {
110 retval.assign("error: summary string parsing error");
111 return false;
112 }
113 }
114}
115
117 StreamString sstr;
118
119 sstr.Printf("`%s`%s%s%s%s%s%s%s%s%s", m_format_str.c_str(),
120 m_error.Fail() ? " error: " : "",
121 m_error.Fail() ? m_error.AsCString() : "",
122 Cascades() ? "" : " (not cascading)",
123 !DoesPrintChildren(nullptr) ? "" : " (show children)",
124 !DoesPrintValue(nullptr) ? " (hide value)" : "",
125 IsOneLiner() ? " (one-line printout)" : "",
126 SkipsPointers() ? " (skip pointers)" : "",
127 SkipsReferences() ? " (skip references)" : "",
128 HideNames(nullptr) ? " (hide member names)" : "");
129 return std::string(sstr.GetString());
130}
131
133
135 const TypeSummaryImpl::Flags &flags, Callback impl, const char *description)
136 : TypeSummaryImpl(Kind::eCallback, flags), m_impl(impl),
137 m_description(description ? description : "") {}
138
140 std::string &dest,
141 const TypeSummaryOptions &options) {
142 dest.clear();
143 StreamString stream;
144 if (!m_impl || !m_impl(*valobj, stream, options))
145 return false;
146 dest = std::string(stream.GetString());
147 return true;
148}
149
151 StreamString sstr;
152 sstr.Printf("%s%s%s%s%s%s%s %s", Cascades() ? "" : " (not cascading)",
153 !DoesPrintChildren(nullptr) ? "" : " (show children)",
154 !DoesPrintValue(nullptr) ? " (hide value)" : "",
155 IsOneLiner() ? " (one-line printout)" : "",
156 SkipsPointers() ? " (skip pointers)" : "",
157 SkipsReferences() ? " (skip references)" : "",
158 HideNames(nullptr) ? " (hide member names)" : "",
159 m_description.c_str());
160 return std::string(sstr.GetString());
161}
162
164
166 const char *function_name,
167 const char *python_script)
168 : TypeSummaryImpl(Kind::eScript, flags), m_function_name(),
169 m_python_script(), m_script_function_sp() {
170 // Take preference in the python script name over the function name.
171 if (function_name) {
172 m_function_name.assign(function_name);
173 m_script_formatter_name = function_name;
174 }
175 if (python_script) {
176 m_python_script.assign(python_script);
177 m_script_formatter_name = python_script;
178 }
179
180 // Python scripts include the tabbing of the function def so we remove the
181 // leading spaces.
183 0, m_script_formatter_name.find_first_not_of(' '));
184}
185
186bool ScriptSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
187 const TypeSummaryOptions &options) {
188 if (!valobj)
189 return false;
190
191 TargetSP target_sp(valobj->GetTargetSP());
192
193 if (!target_sp) {
194 retval.assign("error: no target");
195 return false;
196 }
197
198 ScriptInterpreter *script_interpreter =
199 target_sp->GetDebugger().GetScriptInterpreter();
200
201 if (!script_interpreter) {
202 retval.assign("error: no ScriptInterpreter");
203 return false;
204 }
205
206 return script_interpreter->GetScriptedSummary(
207 m_function_name.c_str(), valobj->GetSP(), m_script_function_sp, options,
208 retval);
209}
210
212 StreamString sstr;
213 sstr.Printf("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
214 !DoesPrintChildren(nullptr) ? "" : " (show children)",
215 !DoesPrintValue(nullptr) ? " (hide value)" : "",
216 IsOneLiner() ? " (one-line printout)" : "",
217 SkipsPointers() ? " (skip pointers)" : "",
218 SkipsReferences() ? " (skip references)" : "",
219 HideNames(nullptr) ? " (hide member names)" : "");
220 if (m_python_script.empty()) {
221 if (m_function_name.empty()) {
222 sstr.PutCString("no backing script");
223 } else {
225 }
226 } else {
228 }
229 return std::string(sstr.GetString());
230}
231
233
235 const TypeSummaryImpl::Flags &flags,
236 std::unique_ptr<llvm::MemoryBuffer> bytecode)
237 : TypeSummaryImpl(Kind::eBytecode, flags), m_bytecode(std::move(bytecode)) {
238}
239
241 std::string &retval,
242 const TypeSummaryOptions &options) {
243 if (!valobj)
244 return false;
245
246 TargetSP target_sp(valobj->GetTargetSP());
247
248 if (!target_sp) {
249 retval.assign("error: no target");
250 return false;
251 }
252
253 std::vector<FormatterBytecode::ControlStackElement> control(
254 {m_bytecode->getBuffer()});
255 FormatterBytecode::DataStack data({valobj->GetSP()});
257 control, data, FormatterBytecode::sel_summary);
258 if (error) {
259 retval = llvm::toString(std::move(error));
260 return false;
261 }
262 if (!data.size()) {
263 retval = "empty stack";
264 return false;
265 }
266 auto &top = data.back();
267 retval = "";
268 llvm::raw_string_ostream os(retval);
269 if (auto s = std::get_if<std::string>(&top))
270 os << *s;
271 else if (auto u = std::get_if<uint64_t>(&top))
272 os << *u;
273 else if (auto i = std::get_if<int64_t>(&top))
274 os << *i;
275 else if (auto valobj = std::get_if<ValueObjectSP>(&top)) {
276 if (!valobj->get())
277 os << "empty object";
278 else
279 os << valobj->get()->GetValueAsCString();
280 } else if (auto type = std::get_if<CompilerType>(&top)) {
281 os << type->TypeDescription();
282 } else if (auto sel = std::get_if<FormatterBytecode::Selectors>(&top)) {
283 os << toString(*sel);
284 }
285 return true;
286}
287
289 StreamString sstr;
290 sstr.Printf("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
291 !DoesPrintChildren(nullptr) ? "" : " (show children)",
292 !DoesPrintValue(nullptr) ? " (hide value)" : "",
293 IsOneLiner() ? " (one-line printout)" : "",
294 SkipsPointers() ? " (skip pointers)" : "",
295 SkipsReferences() ? " (skip references)" : "",
296 HideNames(nullptr) ? " (hide member names)" : "");
297 // FIXME: sstr.PutCString(disassembly);
298 return std::string(sstr.GetString());
299}
300
302 return "LLDB bytecode formatter";
303}
static llvm::raw_ostream & error(Stream &strm)
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:211
std::string GetDescription() override
BytecodeSummaryFormat(const TypeSummaryImpl::Flags &flags, std::unique_ptr< llvm::MemoryBuffer > bytecode)
std::unique_ptr< llvm::MemoryBuffer > m_bytecode
Definition: TypeSummary.h:419
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
StackFrame * GetFramePtr() const
Returns a pointer to the frame object.
virtual bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, std::string &retval)
This base class provides an interface to stack frames.
Definition: StackFrame.h:44
const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
Definition: StackFrame.cpp:301
void Clear()
Clear the object state.
Definition: Status.cpp:215
bool Fail() const
Test for error condition.
Definition: Status.cpp:294
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition: Status.cpp:195
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:65
Defines a symbol context baton that can be handed other debug core functions.
Definition: SymbolContext.h:34
LineEntry line_entry
The LineEntry for a given query.
virtual bool HideNames(ValueObject *valobj) const
Definition: TypeSummary.h:228
virtual std::string GetSummaryKindName()
Get the name of the kind of Summary Provider, either c++, summary string, script or python.
Definition: TypeSummary.cpp:49
virtual bool DoesPrintValue(ValueObject *valobj) const
Definition: TypeSummary.h:222
TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags)
Definition: TypeSummary.cpp:46
virtual bool DoesPrintChildren(ValueObject *valobj) const
Definition: TypeSummary.h:214
lldb::TypeSummaryCapping m_capping
Definition: TypeSummary.h:46
lldb::LanguageType GetLanguage() const
Definition: TypeSummary.cpp:29
TypeSummaryOptions & SetCapping(lldb::TypeSummaryCapping)
Definition: TypeSummary.cpp:41
TypeSummaryOptions & SetLanguage(lldb::LanguageType)
Definition: TypeSummary.cpp:35
lldb::TypeSummaryCapping GetCapping() const
Definition: TypeSummary.cpp:31
bool PrintChildrenOneLiner(bool hide_names)
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:569
lldb::TargetSP GetTargetSP() const
Definition: ValueObject.h:334
virtual const char * GetValueAsCString()
const ExecutionContextRef & GetExecutionContextRef() const
Definition: ValueObject.h:330
Status Parse(const llvm::StringRef &format, Entry &entry)
bool Format(const Entry &entry, Stream &s, const SymbolContext *sc, const ExecutionContext *exe_ctx, const Address *addr, ValueObject *valobj, bool function_changed, bool initial_function)
llvm::Error Interpret(std::vector< ControlStackElement > &control, DataStack &data, Selectors sel)
A class that represents a running process on the host machine.
const char * toString(AppleArm64ExceptionClass EC)
Definition: SBAddress.h:15
TypeSummaryCapping
Whether a summary should cap how much data it returns to users or not.
LanguageType
Programming language type.
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:448
std::function< bool(ValueObject &, Stream &, const TypeSummaryOptions &)> Callback
Definition: TypeSummary.h:325
CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags &flags, Callback impl, const char *description)
std::string GetDescription() override
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
AddressRange range
The section offset address range for this line entry.
Definition: LineEntry.h:137
std::string GetDescription() override
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *function_name, const char *python_script=nullptr)
StructuredData::ObjectSP m_script_function_sp
Definition: TypeSummary.h:372
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
Definition: TypeSummary.cpp:81
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
FormatEntity::Entry m_format
Definition: TypeSummary.h:292
StringSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *f)
Definition: TypeSummary.cpp:64
void SetSummaryString(const char *f)
Definition: TypeSummary.cpp:70
std::string GetDescription() override