LLDB mainline
TypeSynthetic.h
Go to the documentation of this file.
1//===-- TypeSynthetic.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_TYPESYNTHETIC_H
10#define LLDB_DATAFORMATTERS_TYPESYNTHETIC_H
11
12#include <cstdint>
13
14#include <functional>
15#include <initializer_list>
16#include <memory>
17#include <string>
18#include <vector>
19
21#include "lldb/lldb-public.h"
22
25
26namespace lldb_private {
28protected:
30
31 void SetValid(bool valid) { m_valid = valid; }
32
33 bool IsValid() { return m_valid; }
34
35public:
37 : m_backend(backend), m_valid(true) {}
38
39 virtual ~SyntheticChildrenFrontEnd() = default;
40
41 virtual size_t CalculateNumChildren() = 0;
42
43 virtual size_t CalculateNumChildren(uint32_t max) {
44 auto count = CalculateNumChildren();
45 return count <= max ? count : max;
46 }
47
48 virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx) = 0;
49
50 virtual size_t GetIndexOfChildWithName(ConstString name) = 0;
51
52 // this function is assumed to always succeed and it if fails, the front-end
53 // should know to deal with it in the correct way (most probably, by refusing
54 // to return any children) the return value of Update() should actually be
55 // interpreted as "ValueObjectSyntheticFilter cache is good/bad" if =true,
56 // ValueObjectSyntheticFilter is allowed to use the children it fetched
57 // previously and cached if =false, ValueObjectSyntheticFilter must throw
58 // away its cache, and query again for children
59 virtual bool Update() = 0;
60
61 // if this function returns false, then CalculateNumChildren() MUST return 0
62 // since UI frontends might validly decide not to inquire for children given
63 // a false return value from this call if it returns true, then
64 // CalculateNumChildren() can return any number >= 0 (0 being valid) it
65 // should if at all possible be more efficient than CalculateNumChildren()
66 virtual bool MightHaveChildren() = 0;
67
68 // if this function returns a non-null ValueObject, then the returned
69 // ValueObject will stand for this ValueObject whenever a "value" request is
70 // made to this ValueObject
71 virtual lldb::ValueObjectSP GetSyntheticValue() { return nullptr; }
72
73 // if this function returns a non-empty ConstString, then clients are
74 // expected to use the return as the name of the type of this ValueObject for
75 // display purposes
77
78 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
79 typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
80
81protected:
82 lldb::ValueObjectSP
83 CreateValueObjectFromExpression(llvm::StringRef name,
84 llvm::StringRef expression,
85 const ExecutionContext &exe_ctx);
86
87 lldb::ValueObjectSP
88 CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
89 const ExecutionContext &exe_ctx,
90 CompilerType type);
91
92 lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name,
93 const DataExtractor &data,
94 const ExecutionContext &exe_ctx,
95 CompilerType type);
96
97private:
98 bool m_valid;
102};
103
105public:
107 : SyntheticChildrenFrontEnd(backend) {}
108
110
111 size_t CalculateNumChildren() override { return 0; }
112
113 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { return nullptr; }
114
115 size_t GetIndexOfChildWithName(ConstString name) override {
116 return UINT32_MAX;
117 }
118
119 bool Update() override { return false; }
120
121 bool MightHaveChildren() override { return false; }
122
123 lldb::ValueObjectSP GetSyntheticValue() override = 0;
124
125private:
127 delete;
130};
131
133public:
134 class Flags {
135 public:
136 Flags() = default;
137
138 Flags(const Flags &other) : m_flags(other.m_flags) {}
139
140 Flags(uint32_t value) : m_flags(value) {}
141
142 Flags &operator=(const Flags &rhs) {
143 if (&rhs != this)
144 m_flags = rhs.m_flags;
145
146 return *this;
147 }
148
149 Flags &operator=(const uint32_t &rhs) {
150 m_flags = rhs;
151 return *this;
152 }
153
155 m_flags = 0;
156 return *this;
157 }
158
159 bool GetCascades() const {
160 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
161 }
162
163 Flags &SetCascades(bool value = true) {
164 if (value)
165 m_flags |= lldb::eTypeOptionCascade;
166 else
167 m_flags &= ~lldb::eTypeOptionCascade;
168 return *this;
169 }
170
171 bool GetSkipPointers() const {
172 return (m_flags & lldb::eTypeOptionSkipPointers) ==
173 lldb::eTypeOptionSkipPointers;
174 }
175
176 Flags &SetSkipPointers(bool value = true) {
177 if (value)
178 m_flags |= lldb::eTypeOptionSkipPointers;
179 else
180 m_flags &= ~lldb::eTypeOptionSkipPointers;
181 return *this;
182 }
183
184 bool GetSkipReferences() const {
185 return (m_flags & lldb::eTypeOptionSkipReferences) ==
186 lldb::eTypeOptionSkipReferences;
187 }
188
189 Flags &SetSkipReferences(bool value = true) {
190 if (value)
191 m_flags |= lldb::eTypeOptionSkipReferences;
192 else
193 m_flags &= ~lldb::eTypeOptionSkipReferences;
194 return *this;
195 }
196
197 bool GetNonCacheable() const {
198 return (m_flags & lldb::eTypeOptionNonCacheable) ==
199 lldb::eTypeOptionNonCacheable;
200 }
201
202 Flags &SetNonCacheable(bool value = true) {
203 if (value)
204 m_flags |= lldb::eTypeOptionNonCacheable;
205 else
206 m_flags &= ~lldb::eTypeOptionNonCacheable;
207 return *this;
208 }
209
211 return (m_flags & lldb::eTypeOptionFrontEndWantsDereference) ==
212 lldb::eTypeOptionFrontEndWantsDereference;
213 }
214
215 Flags &SetFrontEndWantsDereference(bool value = true) {
216 if (value)
217 m_flags |= lldb::eTypeOptionFrontEndWantsDereference;
218 else
219 m_flags &= ~lldb::eTypeOptionFrontEndWantsDereference;
220 return *this;
221 }
222
224
225 void SetValue(uint32_t value) { m_flags = value; }
226
227 private:
228 uint32_t m_flags = lldb::eTypeOptionCascade;
229 };
230
231 SyntheticChildren(const Flags &flags) : m_flags(flags) {}
232
233 virtual ~SyntheticChildren() = default;
234
235 bool Cascades() const { return m_flags.GetCascades(); }
236
237 bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
238
239 bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
240
241 bool NonCacheable() const { return m_flags.GetNonCacheable(); }
242
244
245 void SetCascades(bool value) { m_flags.SetCascades(value); }
246
247 void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
248
249 void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
250
251 void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
252
254
255 void SetOptions(uint32_t value) { m_flags.SetValue(value); }
256
257 virtual bool IsScripted() = 0;
258
259 virtual std::string GetDescription() = 0;
260
263
264 typedef std::shared_ptr<SyntheticChildren> SharedPointer;
265
267
268protected:
271
272private:
275};
276
278 std::vector<std::string> m_expression_paths;
279
280public:
282 : SyntheticChildren(flags) {}
283
285 const std::initializer_list<const char *> items)
286 : SyntheticChildren(flags) {
287 for (auto path : items)
288 AddExpressionPath(path);
289 }
290
291 void AddExpressionPath(const char *path) {
292 AddExpressionPath(std::string(path));
293 }
294
295 void Clear() { m_expression_paths.clear(); }
296
297 size_t GetCount() const { return m_expression_paths.size(); }
298
299 const char *GetExpressionPathAtIndex(size_t i) const {
300 return m_expression_paths[i].c_str();
301 }
302
303 bool SetExpressionPathAtIndex(size_t i, const char *path) {
304 return SetExpressionPathAtIndex(i, std::string(path));
305 }
306
307 void AddExpressionPath(const std::string &path);
308
309 bool SetExpressionPathAtIndex(size_t i, const std::string &path);
310
311 bool IsScripted() override { return false; }
312
313 std::string GetDescription() override;
314
316 public:
318 : SyntheticChildrenFrontEnd(backend), filter(flt) {}
319
320 ~FrontEnd() override = default;
321
322 size_t CalculateNumChildren() override { return filter->GetCount(); }
323
324 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
325 if (idx >= filter->GetCount())
326 return lldb::ValueObjectSP();
328 filter->GetExpressionPathAtIndex(idx), true);
329 }
330
331 bool Update() override { return false; }
332
333 bool MightHaveChildren() override { return filter->GetCount() > 0; }
334
335 size_t GetIndexOfChildWithName(ConstString name) override;
336
337 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
338
339 private:
341
342 FrontEnd(const FrontEnd &) = delete;
343 const FrontEnd &operator=(const FrontEnd &) = delete;
344 };
345
347 GetFrontEnd(ValueObject &backend) override {
348 return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
349 }
350
351 typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
352
353private:
355 const TypeFilterImpl &operator=(const TypeFilterImpl &) = delete;
356};
357
359public:
360 typedef std::function<SyntheticChildrenFrontEnd *(CXXSyntheticChildren *,
361 lldb::ValueObjectSP)>
364 const char *description, CreateFrontEndCallback callback)
365 : SyntheticChildren(flags), m_create_callback(std::move(callback)),
366 m_description(description ? description : "") {}
367
368 bool IsScripted() override { return false; }
369
370 std::string GetDescription() override;
371
373 GetFrontEnd(ValueObject &backend) override {
375 m_create_callback(this, backend.GetSP()));
376 }
377
378protected:
380 std::string m_description;
381
382private:
385};
386
388 std::string m_python_class;
389 std::string m_python_code;
390
391public:
393 const char *pclass, const char *pcode = nullptr)
394 : SyntheticChildren(flags) {
395 if (pclass)
396 m_python_class = pclass;
397 if (pcode)
398 m_python_code = pcode;
399 }
400
401 const char *GetPythonClassName() { return m_python_class.c_str(); }
402
403 const char *GetPythonCode() { return m_python_code.c_str(); }
404
405 void SetPythonClassName(const char *fname) {
406 m_python_class.assign(fname);
407 m_python_code.clear();
408 }
409
410 void SetPythonCode(const char *script) { m_python_code.assign(script); }
411
412 std::string GetDescription() override;
413
414 bool IsScripted() override { return true; }
415
417 public:
418 FrontEnd(std::string pclass, ValueObject &backend);
419
420 ~FrontEnd() override;
421
422 bool IsValid();
423
424 size_t CalculateNumChildren() override;
425
426 size_t CalculateNumChildren(uint32_t max) override;
427
428 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
429
430 bool Update() override;
431
432 bool MightHaveChildren() override;
433
434 size_t GetIndexOfChildWithName(ConstString name) override;
435
436 lldb::ValueObjectSP GetSyntheticValue() override;
437
439
440 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
441
442 private:
443 std::string m_python_class;
446
447 FrontEnd(const FrontEnd &) = delete;
448 const FrontEnd &operator=(const FrontEnd &) = delete;
449 };
450
452 GetFrontEnd(ValueObject &backend) override {
454 new FrontEnd(m_python_class, backend));
455 if (synth_ptr && ((FrontEnd *)synth_ptr.get())->IsValid())
456 return synth_ptr;
457 return nullptr;
458 }
459
460private:
464};
465} // namespace lldb_private
466
467#endif // LLDB_DATAFORMATTERS_TYPESYNTHETIC_H
CXXSyntheticChildren(const CXXSyntheticChildren &)=delete
const CXXSyntheticChildren & operator=(const CXXSyntheticChildren &)=delete
CreateFrontEndCallback m_create_callback
CXXSyntheticChildren(const SyntheticChildren::Flags &flags, const char *description, CreateFrontEndCallback callback)
std::string GetDescription() override
SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend) override
std::function< SyntheticChildrenFrontEnd *(CXXSyntheticChildren *, lldb::ValueObjectSP)> CreateFrontEndCallback
Generic representation of a type in a programming language.
Definition: CompilerType.h:36
A uniqued constant string class.
Definition: ConstString.h:39
An data extractor class.
Definition: DataExtractor.h:48
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
std::shared_ptr< SyntheticChildrenFrontEnd > SharedPointer
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
lldb::ValueObjectSP GetSyntheticValue() override
size_t GetIndexOfChildWithName(ConstString name) override
const FrontEnd & operator=(const FrontEnd &)=delete
SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend) override
void SetPythonClassName(const char *fname)
ScriptedSyntheticChildren(const SyntheticChildren::Flags &flags, const char *pclass, const char *pcode=nullptr)
const ScriptedSyntheticChildren & operator=(const ScriptedSyntheticChildren &)=delete
void SetPythonCode(const char *script)
ScriptedSyntheticChildren(const ScriptedSyntheticChildren &)=delete
std::shared_ptr< Object > ObjectSP
lldb::ValueObjectSP CreateValueObjectFromExpression(llvm::StringRef name, llvm::StringRef expression, const ExecutionContext &exe_ctx)
virtual size_t CalculateNumChildren(uint32_t max)
Definition: TypeSynthetic.h:43
virtual lldb::ValueObjectSP GetSyntheticValue()
Definition: TypeSynthetic.h:71
virtual size_t GetIndexOfChildWithName(ConstString name)=0
std::unique_ptr< SyntheticChildrenFrontEnd > AutoPointer
Definition: TypeSynthetic.h:79
lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name, const DataExtractor &data, const ExecutionContext &exe_ctx, CompilerType type)
std::shared_ptr< SyntheticChildrenFrontEnd > SharedPointer
Definition: TypeSynthetic.h:78
virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx)=0
virtual ConstString GetSyntheticTypeName()
Definition: TypeSynthetic.h:76
SyntheticChildrenFrontEnd(const SyntheticChildrenFrontEnd &)=delete
SyntheticChildrenFrontEnd(ValueObject &backend)
Definition: TypeSynthetic.h:36
lldb::ValueObjectSP CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx, CompilerType type)
const SyntheticChildrenFrontEnd & operator=(const SyntheticChildrenFrontEnd &)=delete
Flags & SetSkipReferences(bool value=true)
Flags & SetFrontEndWantsDereference(bool value=true)
Flags & operator=(const uint32_t &rhs)
Flags & SetSkipPointers(bool value=true)
Flags & SetCascades(bool value=true)
Flags & SetNonCacheable(bool value=true)
Flags & operator=(const Flags &rhs)
const SyntheticChildren & operator=(const SyntheticChildren &)=delete
virtual std::string GetDescription()=0
virtual SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend)=0
void SetSkipsReferences(bool value)
void SetOptions(uint32_t value)
virtual ~SyntheticChildren()=default
SyntheticChildren(const SyntheticChildren &)=delete
SyntheticChildren(const Flags &flags)
std::shared_ptr< SyntheticChildren > SharedPointer
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
size_t GetIndexOfChildWithName(ConstString name) override
SyntheticValueProviderFrontEnd(ValueObject &backend)
SyntheticValueProviderFrontEnd(const SyntheticValueProviderFrontEnd &)=delete
lldb::ValueObjectSP GetSyntheticValue() override=0
const SyntheticValueProviderFrontEnd & operator=(const SyntheticValueProviderFrontEnd &)=delete
FrontEnd(const FrontEnd &)=delete
size_t GetIndexOfChildWithName(ConstString name) override
FrontEnd(TypeFilterImpl *flt, ValueObject &backend)
const FrontEnd & operator=(const FrontEnd &)=delete
lldb::ValueObjectSP GetChildAtIndex(size_t idx) override
std::shared_ptr< SyntheticChildrenFrontEnd > SharedPointer
std::shared_ptr< TypeFilterImpl > SharedPointer
bool SetExpressionPathAtIndex(size_t i, const char *path)
const char * GetExpressionPathAtIndex(size_t i) const
TypeFilterImpl(const SyntheticChildren::Flags &flags, const std::initializer_list< const char * > items)
void AddExpressionPath(const char *path)
std::string GetDescription() override
SyntheticChildrenFrontEnd::AutoPointer GetFrontEnd(ValueObject &backend) override
TypeFilterImpl(const SyntheticChildren::Flags &flags)
std::vector< std::string > m_expression_paths
const TypeFilterImpl & operator=(const TypeFilterImpl &)=delete
TypeFilterImpl(const TypeFilterImpl &)=delete
lldb::ValueObjectSP GetSP()
Definition: ValueObject.h:554
lldb::ValueObjectSP GetSyntheticExpressionPathChild(const char *expression, bool can_create)
#define UINT32_MAX
Definition: lldb-defines.h:19
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Definition: SBAddress.h:15