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"
14#include "lldb/lldb-public.h"
15
16#include "lldb/Core/Debugger.h"
21#include "lldb/Target/Target.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
29
31
35
40
46
48 uint32_t ptr_match_depth)
49 : m_flags(flags), m_kind(kind), m_ptr_match_depth(ptr_match_depth) {}
50
52 switch (m_kind) {
54 return "string";
55 case Kind::eCallback:
56 return "callback";
57 case Kind::eScript:
58 return "python";
59 case Kind::eInternal:
60 return "c++";
61 case Kind::eBytecode:
62 return "bytecode";
63 }
64 llvm_unreachable("Unknown type kind name");
65}
66
68 const char *format_cstr,
69 uint32_t ptr_match_depth)
70 : TypeSummaryImpl(Kind::eSummaryString, flags, ptr_match_depth),
71 m_format_str() {
72 SetSummaryString(format_cstr);
73}
74
75void StringSummaryFormat::SetSummaryString(const char *format_cstr) {
76 m_format.Clear();
77 if (format_cstr && format_cstr[0]) {
78 m_format_str = format_cstr;
79 m_error = FormatEntity::Parse(format_cstr, m_format);
80 } else {
81 m_format_str.clear();
82 m_error.Clear();
83 }
84}
85
86bool StringSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
87 const TypeSummaryOptions &options) {
88 if (!valobj) {
89 retval.assign("NULL ValueObject");
90 return false;
91 }
92
96 StackFrame *frame = exe_ctx.GetFramePtr();
97 if (frame)
98 sc = frame->GetSymbolContext(lldb::eSymbolContextEverything);
99
100 if (IsOneLiner()) {
101 // We've already checked the case of a NULL valobj above. Let's put in an
102 // assert here to make sure someone doesn't take that out:
103 assert(valobj && "Must have a valid ValueObject to summarize");
104 ValueObjectPrinter printer(*valobj, &s, DumpValueObjectOptions());
105 printer.PrintChildrenOneLiner(HideNames(valobj));
106 retval = std::string(s.GetString());
107 return true;
108 } else {
110 &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), false, false)
111 .Format(m_format, s, valobj)) {
112 retval.assign(std::string(s.GetString()));
113 return true;
114 } else {
115 retval.assign("error: summary string parsing error");
116 return false;
117 }
118 }
119}
120
122 StreamString sstr;
123
124 sstr.Printf("`%s`%s%s%s%s%s%s%s%s%s ptr-match-depth=%u", m_format_str.c_str(),
125 m_error.Fail() ? " error: " : "",
126 m_error.Fail() ? m_error.AsCString() : "",
127 Cascades() ? "" : " (not cascading)",
128 !DoesPrintChildren(nullptr) ? "" : " (show children)",
129 !DoesPrintValue(nullptr) ? " (hide value)" : "",
130 IsOneLiner() ? " (one-line printout)" : "",
131 SkipsPointers() ? " (skip pointers)" : "",
132 SkipsReferences() ? " (skip references)" : "",
133 HideNames(nullptr) ? " (hide member names)" : "",
135 return std::string(sstr.GetString());
136}
137
139
141 const TypeSummaryImpl::Flags &flags, Callback impl, const char *description,
142 uint32_t ptr_match_depth)
143 : TypeSummaryImpl(Kind::eCallback, flags, ptr_match_depth), m_impl(impl),
144 m_description(description ? description : "") {}
145
147 std::string &dest,
148 const TypeSummaryOptions &options) {
149 dest.clear();
150 StreamString stream;
151 if (!m_impl || !m_impl(*valobj, stream, options))
152 return false;
153 dest = std::string(stream.GetString());
154 return true;
155}
156
158 StreamString sstr;
159 sstr.Printf("%s%s%s%s%s%s%s ptr-match-depth=%u %s",
160 Cascades() ? "" : " (not cascading)",
161 !DoesPrintChildren(nullptr) ? "" : " (show children)",
162 !DoesPrintValue(nullptr) ? " (hide value)" : "",
163 IsOneLiner() ? " (one-line printout)" : "",
164 SkipsPointers() ? " (skip pointers)" : "",
165 SkipsReferences() ? " (skip references)" : "",
166 HideNames(nullptr) ? " (hide member names)" : "",
168 return std::string(sstr.GetString());
169}
170
172
174 const char *function_name,
175 const char *python_script,
176 uint32_t ptr_match_depth)
177 : TypeSummaryImpl(Kind::eScript, flags, ptr_match_depth), m_function_name(),
179 // Take preference in the python script name over the function name.
180 if (function_name) {
181 m_function_name.assign(function_name);
182 m_script_formatter_name = function_name;
183 }
184 if (python_script) {
185 m_python_script.assign(python_script);
186 m_script_formatter_name = python_script;
187 }
188
189 // Python scripts include the tabbing of the function def so we remove the
190 // leading spaces.
192 0, m_script_formatter_name.find_first_not_of(' '));
193}
194
195bool ScriptSummaryFormat::FormatObject(ValueObject *valobj, std::string &retval,
196 const TypeSummaryOptions &options) {
197 if (!valobj)
198 return false;
199
200 TargetSP target_sp(valobj->GetTargetSP());
201
202 if (!target_sp) {
203 retval.assign("error: no target");
204 return false;
205 }
206
207 ScriptInterpreter *script_interpreter =
208 target_sp->GetDebugger().GetScriptInterpreter();
209
210 if (!script_interpreter) {
211 retval.assign("error: no ScriptInterpreter");
212 return false;
213 }
214
215 return script_interpreter->GetScriptedSummary(
216 m_function_name.c_str(), valobj->GetSP(), m_script_function_sp, options,
217 retval);
218}
219
221 StreamString sstr;
222 sstr.Printf("%s%s%s%s%s%s%s ptr-match-depth=%u\n ",
223 Cascades() ? "" : " (not cascading)",
224 !DoesPrintChildren(nullptr) ? "" : " (show children)",
225 !DoesPrintValue(nullptr) ? " (hide value)" : "",
226 IsOneLiner() ? " (one-line printout)" : "",
227 SkipsPointers() ? " (skip pointers)" : "",
228 SkipsReferences() ? " (skip references)" : "",
229 HideNames(nullptr) ? " (hide member names)" : "",
231 if (m_python_script.empty()) {
232 if (m_function_name.empty()) {
233 sstr.PutCString("no backing script");
234 } else {
236 }
237 } else {
239 }
240 return std::string(sstr.GetString());
241}
242
244
246 const TypeSummaryImpl::Flags &flags,
247 std::unique_ptr<llvm::MemoryBuffer> bytecode)
248 : TypeSummaryImpl(Kind::eBytecode, flags), m_bytecode(std::move(bytecode)) {
249}
250
252 std::string &retval,
253 const TypeSummaryOptions &options) {
254 if (!valobj)
255 return false;
256
257 TargetSP target_sp(valobj->GetTargetSP());
258
259 if (!target_sp) {
260 retval.assign("error: no target");
261 return false;
262 }
263
264 std::vector<FormatterBytecode::ControlStackElement> control(
265 {m_bytecode->getBuffer()});
266 FormatterBytecode::DataStack data({valobj->GetSP()});
268 control, data, FormatterBytecode::sel_summary);
269 if (error) {
270 retval = llvm::toString(std::move(error));
271 return false;
272 }
273 if (!data.size()) {
274 retval = "empty stack";
275 return false;
276 }
277 auto &top = data.back();
278 retval = "";
279 llvm::raw_string_ostream os(retval);
280 if (auto s = std::get_if<std::string>(&top))
281 os << *s;
282 else if (auto u = std::get_if<uint64_t>(&top))
283 os << *u;
284 else if (auto i = std::get_if<int64_t>(&top))
285 os << *i;
286 else if (auto valobj = std::get_if<ValueObjectSP>(&top)) {
287 if (!valobj->get())
288 os << "empty object";
289 else
290 os << valobj->get()->GetValueAsCString();
291 } else if (auto type = std::get_if<CompilerType>(&top)) {
292 os << type->TypeDescription();
293 } else if (auto sel = std::get_if<FormatterBytecode::Selectors>(&top)) {
294 os << toString(*sel);
295 }
296 return true;
297}
298
300 StreamString sstr;
301 sstr.Printf("%s%s%s%s%s%s%s\n ", Cascades() ? "" : " (not cascading)",
302 !DoesPrintChildren(nullptr) ? "" : " (show children)",
303 !DoesPrintValue(nullptr) ? " (hide value)" : "",
304 IsOneLiner() ? " (one-line printout)" : "",
305 SkipsPointers() ? " (skip pointers)" : "",
306 SkipsReferences() ? " (skip references)" : "",
307 HideNames(nullptr) ? " (hide member names)" : "");
308 // FIXME: sstr.PutCString(disassembly);
309 return std::string(sstr.GetString());
310}
311
313 return "LLDB bytecode formatter";
314}
static llvm::raw_ostream & error(Stream &strm)
Address & GetBaseAddress()
Get accessor for the base address of the range.
std::string GetDescription() override
BytecodeSummaryFormat(const TypeSummaryImpl::Flags &flags, std::unique_ptr< llvm::MemoryBuffer > bytecode)
std::unique_ptr< llvm::MemoryBuffer > m_bytecode
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.
bool Format(const Entry &entry, Stream &s, ValueObject *valobj=nullptr)
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
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
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.
LineEntry line_entry
The LineEntry for a given query.
virtual bool HideNames(ValueObject *valobj) const
virtual std::string GetSummaryKindName()
Get the name of the kind of Summary Provider, either c++, summary string, script or python.
TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags, uint32_t ptr_match_depth=1)
virtual bool DoesPrintValue(ValueObject *valobj) const
virtual bool DoesPrintChildren(ValueObject *valobj) const
lldb::TypeSummaryCapping m_capping
Definition TypeSummary.h:46
lldb::LanguageType GetLanguage() const
TypeSummaryOptions & SetCapping(lldb::TypeSummaryCapping)
TypeSummaryOptions & SetLanguage(lldb::LanguageType)
lldb::TypeSummaryCapping GetCapping() const
bool PrintChildrenOneLiner(bool hide_names)
lldb::ValueObjectSP GetSP()
lldb::TargetSP GetTargetSP() const
virtual const char * GetValueAsCString()
const ExecutionContextRef & GetExecutionContextRef() const
Status Parse(const llvm::StringRef &format, Entry &entry)
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)
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
std::function< bool(ValueObject &, Stream &, const TypeSummaryOptions &)> Callback
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags &flags, Callback impl, const char *description, uint32_t ptr_match_depth=1)
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
StructuredData::ObjectSP m_script_function_sp
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
ScriptSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *function_name, const char *python_script=nullptr, uint32_t ptr_match_depth=1)
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
StringSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *f, uint32_t ptr_match_depth=1)
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
void SetSummaryString(const char *f)
std::string GetDescription() override