1 //===-- TypeSynthetic.h -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef lldb_TypeSynthetic_h_
11 #define lldb_TypeSynthetic_h_
18 #include <initializer_list>
23 // Other libraries and framework includes
25 #include "lldb/lldb-enumerations.h"
26 #include "lldb/lldb-public.h"
28 #include "lldb/Core/ValueObject.h"
29 #include "lldb/Utility/StructuredData.h"
31 namespace lldb_private {
32 class SyntheticChildrenFrontEnd {
34 ValueObject &m_backend;
36 void SetValid(bool valid) { m_valid = valid; }
38 bool IsValid() { return m_valid; }
41 SyntheticChildrenFrontEnd(ValueObject &backend)
42 : m_backend(backend), m_valid(true) {}
44 virtual ~SyntheticChildrenFrontEnd() = default;
46 virtual size_t CalculateNumChildren() = 0;
48 virtual size_t CalculateNumChildren(uint32_t max) {
49 auto count = CalculateNumChildren();
50 return count <= max ? count : max;
53 virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx) = 0;
55 virtual size_t GetIndexOfChildWithName(const ConstString &name) = 0;
57 // this function is assumed to always succeed and it if fails, the front-end
58 // should know to deal
59 // with it in the correct way (most probably, by refusing to return any
61 // the return value of Update() should actually be interpreted as
62 // "ValueObjectSyntheticFilter cache is good/bad"
63 // if =true, ValueObjectSyntheticFilter is allowed to use the children it
64 // fetched previously and cached
65 // if =false, ValueObjectSyntheticFilter must throw away its cache, and query
67 virtual bool Update() = 0;
69 // if this function returns false, then CalculateNumChildren() MUST return 0
71 // might validly decide not to inquire for children given a false return value
73 // if it returns true, then CalculateNumChildren() can return any number >= 0
75 // it should if at all possible be more efficient than CalculateNumChildren()
76 virtual bool MightHaveChildren() = 0;
78 // if this function returns a non-null ValueObject, then the returned
79 // ValueObject will stand
80 // for this ValueObject whenever a "value" request is made to this ValueObject
81 virtual lldb::ValueObjectSP GetSyntheticValue() { return nullptr; }
83 // if this function returns a non-empty ConstString, then clients are expected
85 // as the name of the type of this ValueObject for display purposes
86 virtual ConstString GetSyntheticTypeName() { return ConstString(); }
88 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
89 typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
93 CreateValueObjectFromExpression(llvm::StringRef name,
94 llvm::StringRef expression,
95 const ExecutionContext &exe_ctx);
98 CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
99 const ExecutionContext &exe_ctx,
102 lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name,
103 const DataExtractor &data,
104 const ExecutionContext &exe_ctx,
109 DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
112 class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd {
114 SyntheticValueProviderFrontEnd(ValueObject &backend)
115 : SyntheticChildrenFrontEnd(backend) {}
117 ~SyntheticValueProviderFrontEnd() override = default;
119 size_t CalculateNumChildren() override { return 0; }
121 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { return nullptr; }
123 size_t GetIndexOfChildWithName(const ConstString &name) override {
127 bool Update() override { return false; }
129 bool MightHaveChildren() override { return false; }
131 lldb::ValueObjectSP GetSyntheticValue() override = 0;
134 DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd);
137 class SyntheticChildren {
141 Flags() : m_flags(lldb::eTypeOptionCascade) {}
143 Flags(const Flags &other) : m_flags(other.m_flags) {}
145 Flags(uint32_t value) : m_flags(value) {}
147 Flags &operator=(const Flags &rhs) {
149 m_flags = rhs.m_flags;
154 Flags &operator=(const uint32_t &rhs) {
164 bool GetCascades() const {
165 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
168 Flags &SetCascades(bool value = true) {
170 m_flags |= lldb::eTypeOptionCascade;
172 m_flags &= ~lldb::eTypeOptionCascade;
176 bool GetSkipPointers() const {
177 return (m_flags & lldb::eTypeOptionSkipPointers) ==
178 lldb::eTypeOptionSkipPointers;
181 Flags &SetSkipPointers(bool value = true) {
183 m_flags |= lldb::eTypeOptionSkipPointers;
185 m_flags &= ~lldb::eTypeOptionSkipPointers;
189 bool GetSkipReferences() const {
190 return (m_flags & lldb::eTypeOptionSkipReferences) ==
191 lldb::eTypeOptionSkipReferences;
194 Flags &SetSkipReferences(bool value = true) {
196 m_flags |= lldb::eTypeOptionSkipReferences;
198 m_flags &= ~lldb::eTypeOptionSkipReferences;
202 bool GetNonCacheable() const {
203 return (m_flags & lldb::eTypeOptionNonCacheable) ==
204 lldb::eTypeOptionNonCacheable;
207 Flags &SetNonCacheable(bool value = true) {
209 m_flags |= lldb::eTypeOptionNonCacheable;
211 m_flags &= ~lldb::eTypeOptionNonCacheable;
215 uint32_t GetValue() { return m_flags; }
217 void SetValue(uint32_t value) { m_flags = value; }
223 SyntheticChildren(const Flags &flags) : m_flags(flags) {}
225 virtual ~SyntheticChildren() = default;
227 bool Cascades() const { return m_flags.GetCascades(); }
229 bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
231 bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
233 bool NonCacheable() const { return m_flags.GetNonCacheable(); }
235 void SetCascades(bool value) { m_flags.SetCascades(value); }
237 void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
239 void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
241 void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
243 uint32_t GetOptions() { return m_flags.GetValue(); }
245 void SetOptions(uint32_t value) { m_flags.SetValue(value); }
247 virtual bool IsScripted() = 0;
249 virtual std::string GetDescription() = 0;
251 virtual SyntheticChildrenFrontEnd::AutoPointer
252 GetFrontEnd(ValueObject &backend) = 0;
254 typedef std::shared_ptr<SyntheticChildren> SharedPointer;
256 uint32_t &GetRevision() { return m_my_revision; }
259 uint32_t m_my_revision;
263 DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
266 class TypeFilterImpl : public SyntheticChildren {
267 std::vector<std::string> m_expression_paths;
270 TypeFilterImpl(const SyntheticChildren::Flags &flags)
271 : SyntheticChildren(flags), m_expression_paths() {}
273 TypeFilterImpl(const SyntheticChildren::Flags &flags,
274 const std::initializer_list<const char *> items)
275 : SyntheticChildren(flags), m_expression_paths() {
276 for (auto path : items)
277 AddExpressionPath(path);
280 void AddExpressionPath(const char *path) {
281 AddExpressionPath(std::string(path));
284 void Clear() { m_expression_paths.clear(); }
286 size_t GetCount() const { return m_expression_paths.size(); }
288 const char *GetExpressionPathAtIndex(size_t i) const {
289 return m_expression_paths[i].c_str();
292 bool SetExpressionPathAtIndex(size_t i, const char *path) {
293 return SetExpressionPathAtIndex(i, std::string(path));
296 void AddExpressionPath(const std::string &path);
298 bool SetExpressionPathAtIndex(size_t i, const std::string &path);
300 bool IsScripted() override { return false; }
302 std::string GetDescription() override;
304 class FrontEnd : public SyntheticChildrenFrontEnd {
306 FrontEnd(TypeFilterImpl *flt, ValueObject &backend)
307 : SyntheticChildrenFrontEnd(backend), filter(flt) {}
309 ~FrontEnd() override = default;
311 size_t CalculateNumChildren() override { return filter->GetCount(); }
313 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
314 if (idx >= filter->GetCount())
315 return lldb::ValueObjectSP();
316 return m_backend.GetSyntheticExpressionPathChild(
317 filter->GetExpressionPathAtIndex(idx), true);
320 bool Update() override { return false; }
322 bool MightHaveChildren() override { return filter->GetCount() > 0; }
324 size_t GetIndexOfChildWithName(const ConstString &name) override;
326 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
329 TypeFilterImpl *filter;
331 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
334 SyntheticChildrenFrontEnd::AutoPointer
335 GetFrontEnd(ValueObject &backend) override {
336 return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
339 typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
342 DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
345 class CXXSyntheticChildren : public SyntheticChildren {
347 typedef std::function<SyntheticChildrenFrontEnd *(CXXSyntheticChildren *,
348 lldb::ValueObjectSP)>
349 CreateFrontEndCallback;
350 CXXSyntheticChildren(const SyntheticChildren::Flags &flags,
351 const char *description, CreateFrontEndCallback callback)
352 : SyntheticChildren(flags), m_create_callback(callback),
353 m_description(description ? description : "") {}
355 bool IsScripted() override { return false; }
357 std::string GetDescription() override;
359 SyntheticChildrenFrontEnd::AutoPointer
360 GetFrontEnd(ValueObject &backend) override {
361 return SyntheticChildrenFrontEnd::AutoPointer(
362 m_create_callback(this, backend.GetSP()));
366 CreateFrontEndCallback m_create_callback;
367 std::string m_description;
370 DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
373 #ifndef LLDB_DISABLE_PYTHON
375 class ScriptedSyntheticChildren : public SyntheticChildren {
376 std::string m_python_class;
377 std::string m_python_code;
380 ScriptedSyntheticChildren(const SyntheticChildren::Flags &flags,
381 const char *pclass, const char *pcode = nullptr)
382 : SyntheticChildren(flags), m_python_class(), m_python_code() {
384 m_python_class = pclass;
386 m_python_code = pcode;
389 const char *GetPythonClassName() { return m_python_class.c_str(); }
391 const char *GetPythonCode() { return m_python_code.c_str(); }
393 void SetPythonClassName(const char *fname) {
394 m_python_class.assign(fname);
395 m_python_code.clear();
398 void SetPythonCode(const char *script) { m_python_code.assign(script); }
400 std::string GetDescription() override;
402 bool IsScripted() override { return true; }
404 class FrontEnd : public SyntheticChildrenFrontEnd {
406 FrontEnd(std::string pclass, ValueObject &backend);
408 ~FrontEnd() override;
412 size_t CalculateNumChildren() override;
414 size_t CalculateNumChildren(uint32_t max) override;
416 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
418 bool Update() override;
420 bool MightHaveChildren() override;
422 size_t GetIndexOfChildWithName(const ConstString &name) override;
424 lldb::ValueObjectSP GetSyntheticValue() override;
426 ConstString GetSyntheticTypeName() override;
428 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
431 std::string m_python_class;
432 StructuredData::ObjectSP m_wrapper_sp;
433 ScriptInterpreter *m_interpreter;
435 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
438 SyntheticChildrenFrontEnd::AutoPointer
439 GetFrontEnd(ValueObject &backend) override {
440 auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(
441 new FrontEnd(m_python_class, backend));
442 if (synth_ptr && ((FrontEnd *)synth_ptr.get())->IsValid())
448 DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
451 } // namespace lldb_private
453 #endif // lldb_TypeSynthetic_h_