LLDB mainline
TypeSummary.h
Go to the documentation of this file.
1//===-- TypeSummary.h -------------------------------------------*- C++ -*-===//
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
9#ifndef LLDB_DATAFORMATTERS_TYPESUMMARY_H
10#define LLDB_DATAFORMATTERS_TYPESUMMARY_H
11
12#include <cstdint>
13
14#include <functional>
15#include <memory>
16#include <string>
17
19#include "lldb/lldb-public.h"
20
22#include "lldb/Utility/Status.h"
24
25namespace llvm {
26class MemoryBuffer;
27}
28
29namespace lldb_private {
48
50public:
59
60 virtual ~TypeSummaryImpl() = default;
61
62 Kind GetKind() const { return m_kind; }
63
64 class Flags {
65 public:
66 Flags() = default;
67
68 Flags(const Flags &other) : m_flags(other.m_flags) {}
69
70 Flags(uint32_t value) : m_flags(value) {}
71
72 Flags &operator=(const Flags &rhs) {
73 if (&rhs != this)
74 m_flags = rhs.m_flags;
75
76 return *this;
77 }
78
79 Flags &operator=(const uint32_t &rhs) {
80 m_flags = rhs;
81 return *this;
82 }
83
85 m_flags = 0;
86 return *this;
87 }
88
89 bool GetCascades() const {
90 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
91 }
92
93 Flags &SetCascades(bool value = true) {
94 if (value)
95 m_flags |= lldb::eTypeOptionCascade;
96 else
97 m_flags &= ~lldb::eTypeOptionCascade;
98 return *this;
99 }
100
101 bool GetSkipPointers() const {
102 return (m_flags & lldb::eTypeOptionSkipPointers) ==
103 lldb::eTypeOptionSkipPointers;
104 }
105
106 Flags &SetSkipPointers(bool value = true) {
107 if (value)
108 m_flags |= lldb::eTypeOptionSkipPointers;
109 else
110 m_flags &= ~lldb::eTypeOptionSkipPointers;
111 return *this;
112 }
113
114 bool GetSkipReferences() const {
115 return (m_flags & lldb::eTypeOptionSkipReferences) ==
116 lldb::eTypeOptionSkipReferences;
117 }
118
119 Flags &SetSkipReferences(bool value = true) {
120 if (value)
121 m_flags |= lldb::eTypeOptionSkipReferences;
122 else
123 m_flags &= ~lldb::eTypeOptionSkipReferences;
124 return *this;
125 }
126
127 bool GetDontShowChildren() const {
128 return (m_flags & lldb::eTypeOptionHideChildren) ==
129 lldb::eTypeOptionHideChildren;
130 }
131
132 Flags &SetDontShowChildren(bool value = true) {
133 if (value)
134 m_flags |= lldb::eTypeOptionHideChildren;
135 else
136 m_flags &= ~lldb::eTypeOptionHideChildren;
137 return *this;
138 }
139
141 return (m_flags & lldb::eTypeOptionHideEmptyAggregates) ==
142 lldb::eTypeOptionHideEmptyAggregates;
143 }
144
145 Flags &SetHideEmptyAggregates(bool value = true) {
146 if (value)
147 m_flags |= lldb::eTypeOptionHideEmptyAggregates;
148 else
149 m_flags &= ~lldb::eTypeOptionHideEmptyAggregates;
150 return *this;
151 }
152
153 bool GetDontShowValue() const {
154 return (m_flags & lldb::eTypeOptionHideValue) ==
155 lldb::eTypeOptionHideValue;
156 }
157
158 Flags &SetDontShowValue(bool value = true) {
159 if (value)
160 m_flags |= lldb::eTypeOptionHideValue;
161 else
162 m_flags &= ~lldb::eTypeOptionHideValue;
163 return *this;
164 }
165
167 return (m_flags & lldb::eTypeOptionShowOneLiner) ==
168 lldb::eTypeOptionShowOneLiner;
169 }
170
171 Flags &SetShowMembersOneLiner(bool value = true) {
172 if (value)
173 m_flags |= lldb::eTypeOptionShowOneLiner;
174 else
175 m_flags &= ~lldb::eTypeOptionShowOneLiner;
176 return *this;
177 }
178
179 bool GetHideItemNames() const {
180 return (m_flags & lldb::eTypeOptionHideNames) ==
181 lldb::eTypeOptionHideNames;
182 }
183
184 Flags &SetHideItemNames(bool value = true) {
185 if (value)
186 m_flags |= lldb::eTypeOptionHideNames;
187 else
188 m_flags &= ~lldb::eTypeOptionHideNames;
189 return *this;
190 }
191
192 bool GetNonCacheable() const {
193 return (m_flags & lldb::eTypeOptionNonCacheable) ==
194 lldb::eTypeOptionNonCacheable;
195 }
196
197 Flags &SetNonCacheable(bool value = true) {
198 if (value)
199 m_flags |= lldb::eTypeOptionNonCacheable;
200 else
201 m_flags &= ~lldb::eTypeOptionNonCacheable;
202 return *this;
203 }
204
205 uint32_t GetValue() { return m_flags; }
206
207 void SetValue(uint32_t value) { m_flags = value; }
208
209 private:
210 uint32_t m_flags = lldb::eTypeOptionCascade;
211 };
212
213 bool Cascades() const { return m_flags.GetCascades(); }
214
215 bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
216
217 bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
218
219 bool NonCacheable() const { return m_flags.GetNonCacheable(); }
220
221 virtual bool DoesPrintChildren(ValueObject *valobj) const {
222 return !m_flags.GetDontShowChildren();
223 }
224
225 virtual bool DoesPrintEmptyAggregates() const {
226 return !m_flags.GetHideEmptyAggregates();
227 }
228
229 virtual bool DoesPrintValue(ValueObject *valobj) const {
230 return !m_flags.GetDontShowValue();
231 }
232
233 bool IsOneLiner() const { return m_flags.GetShowMembersOneLiner(); }
234
235 virtual bool HideNames(ValueObject *valobj) const {
236 return m_flags.GetHideItemNames();
237 }
238
239 void SetCascades(bool value) { m_flags.SetCascades(value); }
240
241 void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
242
243 void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
244
245 virtual void SetDoesPrintChildren(bool value) {
246 m_flags.SetDontShowChildren(!value);
247 }
248
249 virtual void SetDoesPrintValue(bool value) {
250 m_flags.SetDontShowValue(!value);
251 }
252
253 void SetIsOneLiner(bool value) { m_flags.SetShowMembersOneLiner(value); }
254
255 virtual void SetHideNames(bool value) { m_flags.SetHideItemNames(value); }
256
257 virtual void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
258
259 uint32_t GetOptions() { return m_flags.GetValue(); }
260
261 void SetOptions(uint32_t value) { m_flags.SetValue(value); }
262
263 uint32_t GetPtrMatchDepth() { return m_ptr_match_depth; }
264
265 void SetPtrMatchDepth(uint32_t value) { m_ptr_match_depth = value; }
266
267 // we are using a ValueObject* instead of a ValueObjectSP because we do not
268 // need to hold on to this for extended periods of time and we trust the
269 // ValueObject to stay around for as long as it is required for us to
270 // generate its summary
271 virtual bool FormatObject(ValueObject *valobj, std::string &dest,
272 const TypeSummaryOptions &options) = 0;
273
274 virtual std::string GetDescription() = 0;
275
276 /// Get the name of the Type Summary Provider, either a C++ class, a summary
277 /// string, or a script function name.
278 virtual std::string GetName() = 0;
279
280 /// Get the name of the kind of Summary Provider, either c++, summary string,
281 /// script or python.
282 virtual std::string GetSummaryKindName();
283
284 uint32_t &GetRevision() { return m_my_revision; }
285
286 typedef std::shared_ptr<TypeSummaryImpl> SharedPointer;
287
288protected:
289 uint32_t m_my_revision = 0;
291
293 uint32_t ptr_match_depth = 1);
294
295private:
297 uint32_t m_ptr_match_depth = 1;
299 const TypeSummaryImpl &operator=(const TypeSummaryImpl &) = delete;
300};
301
302// simple string-based summaries, using ${var to show data
304 std::string m_format_str;
307
308 StringSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *f,
309 uint32_t ptr_match_depth = 1);
310
311 ~StringSummaryFormat() override = default;
312
313 const char *GetSummaryString() const { return m_format_str.c_str(); }
314
315 void SetSummaryString(const char *f);
316
317 bool FormatObject(ValueObject *valobj, std::string &dest,
318 const TypeSummaryOptions &options) override;
319
320 std::string GetDescription() override;
321
322 std::string GetName() override;
323
324 static bool classof(const TypeSummaryImpl *S) {
325 return S->GetKind() == Kind::eSummaryString;
326 }
327
328private:
331};
332
333// summaries implemented via a C++ function
335 // we should convert these to SBValue and SBStream if we ever cross the
336 // boundary towards the external world
337 typedef std::function<bool(ValueObject &, Stream &,
338 const TypeSummaryOptions &)>
340
342 std::string m_description;
343
345 const char *description,
346 uint32_t ptr_match_depth = 1);
347
348 ~CXXFunctionSummaryFormat() override = default;
349
351
352 const char *GetTextualInfo() const { return m_description.c_str(); }
353
354 void SetBackendFunction(Callback cb_func) { m_impl = std::move(cb_func); }
355
356 void SetTextualInfo(const char *descr) {
357 if (descr)
358 m_description.assign(descr);
359 else
360 m_description.clear();
361 }
362
363 bool FormatObject(ValueObject *valobj, std::string &dest,
364 const TypeSummaryOptions &options) override;
365
366 std::string GetDescription() override;
367
368 static bool classof(const TypeSummaryImpl *S) {
369 return S->GetKind() == Kind::eCallback;
370 }
371
372 std::string GetName() override;
373
374 typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer;
375
376private:
380};
381
382// Python-based summaries, running script code to show data
384 std::string m_function_name;
385 std::string m_python_script;
388
390 const char *function_name,
391 const char *python_script = nullptr,
392 uint32_t ptr_match_depth = 1);
393
394 ~ScriptSummaryFormat() override = default;
395
396 const char *GetFunctionName() const { return m_function_name.c_str(); }
397
398 const char *GetPythonScript() const { return m_python_script.c_str(); }
399
400 void SetFunctionName(const char *function_name) {
401 if (function_name)
402 m_function_name.assign(function_name);
403 else
404 m_function_name.clear();
405 m_python_script.clear();
406 }
407
408 void SetPythonScript(const char *script) {
409 if (script)
410 m_python_script.assign(script);
411 else
412 m_python_script.clear();
413 }
414
415 bool FormatObject(ValueObject *valobj, std::string &dest,
416 const TypeSummaryOptions &options) override;
417
418 std::string GetDescription() override;
419
420 std::string GetName() override;
421
422 static bool classof(const TypeSummaryImpl *S) {
423 return S->GetKind() == Kind::eScript;
424 }
425
426 typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer;
427
428private:
431};
432
433// Python-based summaries backed by a class, running an instance's
434// `get_summary` method to show data. Unlike ScriptSummaryFormat (a bare
435// function resolved once and cached), the Python object here is itself the
436// cache: it's created lazily on the first call to FormatObject (since this
437// format can be constructed via SBTypeSummary::CreateWithClassName before
438// any debugger/target context exists) and then reused across every
439// subsequent call, for every value of the matching type.
441 std::string m_class_name;
443
445 const char *class_name, uint32_t ptr_match_depth = 1);
446
447 ~ScriptedSummaryFormat() override = default;
448
449 const char *GetClassName() const { return m_class_name.c_str(); }
450
451 void SetClassName(const char *class_name) {
452 if (class_name)
453 m_class_name.assign(class_name);
454 else
455 m_class_name.clear();
456 m_interface_sp.reset();
457 }
458
459 bool FormatObject(ValueObject *valobj, std::string &dest,
460 const TypeSummaryOptions &options) override;
461
462 std::string GetDescription() override;
463
464 std::string GetName() override;
465
466 static bool classof(const TypeSummaryImpl *S) {
467 return S->GetKind() == Kind::eScriptedClass;
468 }
469
470 typedef std::shared_ptr<ScriptedSummaryFormat> SharedPointer;
471
472private:
476};
477
478/// A summary formatter that is defined in LLDB formmater bytecode.
479///
480/// See `BytecodeSyntheticChildren` for the corresponding synthetic formatter.
481///
482/// Formatter bytecode documentation can be found in
483/// lldb/docs/resources/formatterbytecode.rst
485 std::unique_ptr<llvm::MemoryBuffer> m_bytecode;
486
487public:
489 std::unique_ptr<llvm::MemoryBuffer> bytecode);
490 bool FormatObject(ValueObject *valobj, std::string &dest,
491 const TypeSummaryOptions &options) override;
492 std::string GetDescription() override;
493 std::string GetName() override;
494 static bool classof(const TypeSummaryImpl *S) {
495 return S->GetKind() == Kind::eBytecode;
496 }
497};
498
499} // namespace lldb_private
500
501#endif // LLDB_DATAFORMATTERS_TYPESUMMARY_H
static bool classof(const TypeSummaryImpl *S)
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
An error handling class.
Definition Status.h:118
A stream class that can stream formatted output to a file.
Definition Stream.h:28
std::shared_ptr< Object > ObjectSP
Flags & SetNonCacheable(bool value=true)
Flags & operator=(const uint32_t &rhs)
Definition TypeSummary.h:79
Flags & SetCascades(bool value=true)
Definition TypeSummary.h:93
Flags & SetHideEmptyAggregates(bool value=true)
Flags & SetSkipPointers(bool value=true)
Flags & SetHideItemNames(bool value=true)
Flags & operator=(const Flags &rhs)
Definition TypeSummary.h:72
Flags & SetDontShowChildren(bool value=true)
Flags & SetSkipReferences(bool value=true)
Flags & SetShowMembersOneLiner(bool value=true)
Flags & SetDontShowValue(bool value=true)
void SetIsOneLiner(bool value)
virtual bool HideNames(ValueObject *valobj) const
TypeSummaryImpl(const TypeSummaryImpl &)=delete
virtual ~TypeSummaryImpl()=default
virtual std::string GetName()=0
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
virtual std::string GetSummaryKindName()
Get the name of the kind of Summary Provider, either c++, summary string, script or python.
virtual void SetDoesPrintValue(bool value)
void SetSkipsReferences(bool value)
virtual bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options)=0
void SetSkipsPointers(bool value)
virtual bool DoesPrintEmptyAggregates() const
virtual std::string GetDescription()=0
void SetOptions(uint32_t value)
void SetPtrMatchDepth(uint32_t value)
virtual void SetDoesPrintChildren(bool value)
const TypeSummaryImpl & operator=(const TypeSummaryImpl &)=delete
virtual void SetNonCacheable(bool value)
virtual void SetHideNames(bool value)
TypeSummaryImpl(Kind kind, const TypeSummaryImpl::Flags &flags, uint32_t ptr_match_depth=1)
virtual bool DoesPrintValue(ValueObject *valobj) const
std::shared_ptr< TypeSummaryImpl > SharedPointer
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
A class that represents a running process on the host machine.
TypeSummaryCapping
Whether a summary should cap how much data it returns to users or not.
std::shared_ptr< lldb_private::ScriptedStringSummaryInterface > ScriptedStringSummaryInterfaceSP
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< CXXFunctionSummaryFormat > SharedPointer
CXXFunctionSummaryFormat(const CXXFunctionSummaryFormat &)=delete
std::function< bool(ValueObject &, Stream &, const TypeSummaryOptions &)> Callback
void SetTextualInfo(const char *descr)
~CXXFunctionSummaryFormat() override=default
const CXXFunctionSummaryFormat & operator=(const CXXFunctionSummaryFormat &)=delete
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
void SetBackendFunction(Callback cb_func)
CXXFunctionSummaryFormat(const TypeSummaryImpl::Flags &flags, Callback impl, const char *description, uint32_t ptr_match_depth=1)
static bool classof(const TypeSummaryImpl *S)
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
static bool classof(const TypeSummaryImpl *S)
~ScriptSummaryFormat() override=default
const char * GetPythonScript() const
std::string GetDescription() override
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
const char * GetFunctionName() const
ScriptSummaryFormat(const ScriptSummaryFormat &)=delete
void SetPythonScript(const char *script)
const ScriptSummaryFormat & operator=(const ScriptSummaryFormat &)=delete
std::shared_ptr< ScriptSummaryFormat > SharedPointer
StructuredData::ObjectSP m_script_function_sp
void SetFunctionName(const char *function_name)
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)
const ScriptedSummaryFormat & operator=(const ScriptedSummaryFormat &)=delete
std::shared_ptr< ScriptedSummaryFormat > SharedPointer
const char * GetClassName() const
bool FormatObject(ValueObject *valobj, std::string &dest, const TypeSummaryOptions &options) override
ScriptedSummaryFormat(const TypeSummaryImpl::Flags &flags, const char *class_name, uint32_t ptr_match_depth=1)
ScriptedSummaryFormat(const ScriptedSummaryFormat &)=delete
static bool classof(const TypeSummaryImpl *S)
lldb::ScriptedStringSummaryInterfaceSP m_interface_sp
~ScriptedSummaryFormat() override=default
std::string GetDescription() override
std::string GetName() override
Get the name of the Type Summary Provider, either a C++ class, a summary string, or a script function...
void SetClassName(const char *class_name)
const StringSummaryFormat & operator=(const StringSummaryFormat &)=delete
~StringSummaryFormat() override=default
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...
static bool classof(const TypeSummaryImpl *S)
StringSummaryFormat(const StringSummaryFormat &)=delete
const char * GetSummaryString() const
void SetSummaryString(const char *f)
std::string GetDescription() override