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_
17 #include <initializer_list>
23 // Other libraries and framework includes
25 #include "lldb/lldb-public.h"
26 #include "lldb/lldb-enumerations.h"
28 #include "lldb/Core/StructuredData.h"
29 #include "lldb/Core/ValueObject.h"
31 namespace lldb_private {
32 class SyntheticChildrenFrontEnd
35 ValueObject &m_backend;
50 SyntheticChildrenFrontEnd (ValueObject &backend) :
56 ~SyntheticChildrenFrontEnd() = default;
59 CalculateNumChildren () = 0;
62 CalculateNumChildren (uint32_t max)
64 auto count = CalculateNumChildren ();
65 return count <= max ? count : max;
68 virtual lldb::ValueObjectSP
69 GetChildAtIndex (size_t idx) = 0;
72 GetIndexOfChildWithName (const ConstString &name) = 0;
74 // this function is assumed to always succeed and it if fails, the front-end should know to deal
75 // with it in the correct way (most probably, by refusing to return any children)
76 // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
77 // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
78 // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
82 // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
83 // might validly decide not to inquire for children given a false return value from this call
84 // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
85 // it should if at all possible be more efficient than CalculateNumChildren()
87 MightHaveChildren () = 0;
89 // if this function returns a non-null ValueObject, then the returned ValueObject will stand
90 // for this ValueObject whenever a "value" request is made to this ValueObject
91 virtual lldb::ValueObjectSP
92 GetSyntheticValue () { return nullptr; }
94 // if this function returns a non-empty ConstString, then clients are expected to use the return
95 // as the name of the type of this ValueObject for display purposes
97 GetSyntheticTypeName () { return ConstString(); }
99 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
100 typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
104 CreateValueObjectFromExpression (const char* name,
105 const char* expression,
106 const ExecutionContext& exe_ctx);
109 CreateValueObjectFromAddress (const char* name,
111 const ExecutionContext& exe_ctx,
115 CreateValueObjectFromData (const char* name,
116 const DataExtractor& data,
117 const ExecutionContext& exe_ctx,
122 DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
125 class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd
128 SyntheticValueProviderFrontEnd (ValueObject &backend) :
129 SyntheticChildrenFrontEnd(backend)
132 ~SyntheticValueProviderFrontEnd() override = default;
135 CalculateNumChildren() override { return 0; }
138 GetChildAtIndex(size_t idx) override { return nullptr; }
141 GetIndexOfChildWithName(const ConstString &name) override { return UINT32_MAX; }
144 Update() override { return false; }
147 MightHaveChildren () override { return false; }
150 GetSyntheticValue() override = 0;
153 DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd);
156 class SyntheticChildren
164 m_flags (lldb::eTypeOptionCascade)
167 Flags (const Flags& other) :
168 m_flags (other.m_flags)
171 Flags (uint32_t value) :
176 operator = (const Flags& rhs)
179 m_flags = rhs.m_flags;
185 operator = (const uint32_t& rhs)
201 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
205 SetCascades (bool value = true)
208 m_flags |= lldb::eTypeOptionCascade;
210 m_flags &= ~lldb::eTypeOptionCascade;
215 GetSkipPointers () const
217 return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
221 SetSkipPointers (bool value = true)
224 m_flags |= lldb::eTypeOptionSkipPointers;
226 m_flags &= ~lldb::eTypeOptionSkipPointers;
231 GetSkipReferences () const
233 return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
237 SetSkipReferences (bool value = true)
240 m_flags |= lldb::eTypeOptionSkipReferences;
242 m_flags &= ~lldb::eTypeOptionSkipReferences;
247 GetNonCacheable () const
249 return (m_flags & lldb::eTypeOptionNonCacheable) == lldb::eTypeOptionNonCacheable;
253 SetNonCacheable (bool value = true)
256 m_flags |= lldb::eTypeOptionNonCacheable;
258 m_flags &= ~lldb::eTypeOptionNonCacheable;
269 SetValue (uint32_t value)
278 SyntheticChildren (const Flags& flags) :
284 ~SyntheticChildren() = default;
289 return m_flags.GetCascades();
293 SkipsPointers () const
295 return m_flags.GetSkipPointers();
299 SkipsReferences () const
301 return m_flags.GetSkipReferences();
305 NonCacheable () const
307 return m_flags.GetNonCacheable();
311 SetCascades (bool value)
313 m_flags.SetCascades(value);
317 SetSkipsPointers (bool value)
319 m_flags.SetSkipPointers(value);
323 SetSkipsReferences (bool value)
325 m_flags.SetSkipReferences(value);
329 SetNonCacheable (bool value)
331 m_flags.SetNonCacheable(value);
337 return m_flags.GetValue();
341 SetOptions (uint32_t value)
343 m_flags.SetValue(value);
350 GetDescription () = 0;
352 virtual SyntheticChildrenFrontEnd::AutoPointer
353 GetFrontEnd (ValueObject &backend) = 0;
355 typedef std::shared_ptr<SyntheticChildren> SharedPointer;
360 return m_my_revision;
364 uint32_t m_my_revision;
368 DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
371 class TypeFilterImpl : public SyntheticChildren
373 std::vector<std::string> m_expression_paths;
375 TypeFilterImpl(const SyntheticChildren::Flags& flags) :
376 SyntheticChildren(flags),
381 TypeFilterImpl(const SyntheticChildren::Flags& flags,
382 const std::initializer_list<const char*> items) :
383 SyntheticChildren(flags),
386 for (auto path : items)
387 AddExpressionPath (path);
391 AddExpressionPath (const char* path)
393 AddExpressionPath(std::string(path));
399 m_expression_paths.clear();
405 return m_expression_paths.size();
409 GetExpressionPathAtIndex(size_t i) const
411 return m_expression_paths[i].c_str();
415 SetExpressionPathAtIndex (size_t i, const char* path)
417 return SetExpressionPathAtIndex(i, std::string(path));
421 AddExpressionPath (const std::string& path);
424 SetExpressionPathAtIndex (size_t i, const std::string& path);
427 IsScripted() override
433 GetDescription() override;
435 class FrontEnd : public SyntheticChildrenFrontEnd
438 FrontEnd(TypeFilterImpl* flt,
439 ValueObject &backend) :
440 SyntheticChildrenFrontEnd(backend),
444 ~FrontEnd() override = default;
447 CalculateNumChildren() override
449 return filter->GetCount();
453 GetChildAtIndex(size_t idx) override
455 if (idx >= filter->GetCount())
456 return lldb::ValueObjectSP();
457 return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
461 Update() override { return false; }
464 MightHaveChildren() override
466 return filter->GetCount() > 0;
470 GetIndexOfChildWithName(const ConstString &name) override;
472 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
475 TypeFilterImpl* filter;
477 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
480 SyntheticChildrenFrontEnd::AutoPointer
481 GetFrontEnd(ValueObject &backend) override
483 return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
486 typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
489 DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
492 class CXXSyntheticChildren : public SyntheticChildren
495 typedef std::function<SyntheticChildrenFrontEnd*(CXXSyntheticChildren*, lldb::ValueObjectSP)> CreateFrontEndCallback;
496 CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
497 const char* description,
498 CreateFrontEndCallback callback) :
499 SyntheticChildren(flags),
500 m_create_callback(callback),
501 m_description(description ? description : "")
506 IsScripted() override
512 GetDescription() override;
514 SyntheticChildrenFrontEnd::AutoPointer
515 GetFrontEnd(ValueObject &backend) override
517 return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
521 CreateFrontEndCallback m_create_callback;
522 std::string m_description;
525 DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
528 #ifndef LLDB_DISABLE_PYTHON
530 class ScriptedSyntheticChildren : public SyntheticChildren
532 std::string m_python_class;
533 std::string m_python_code;
536 ScriptedSyntheticChildren(const SyntheticChildren::Flags& flags,
538 const char* pcode = nullptr) :
539 SyntheticChildren(flags),
544 m_python_class = pclass;
546 m_python_code = pcode;
550 GetPythonClassName ()
552 return m_python_class.c_str();
558 return m_python_code.c_str();
562 SetPythonClassName (const char* fname)
564 m_python_class.assign(fname);
565 m_python_code.clear();
569 SetPythonCode (const char* script)
571 m_python_code.assign(script);
575 GetDescription() override;
578 IsScripted() override
583 class FrontEnd : public SyntheticChildrenFrontEnd
586 FrontEnd (std::string pclass,
587 ValueObject &backend);
589 ~FrontEnd() override;
595 CalculateNumChildren() override;
598 CalculateNumChildren(uint32_t max) override;
601 GetChildAtIndex(size_t idx) override;
607 MightHaveChildren() override;
610 GetIndexOfChildWithName(const ConstString &name) override;
613 GetSyntheticValue() override;
616 GetSyntheticTypeName () override;
618 typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
621 std::string m_python_class;
622 StructuredData::ObjectSP m_wrapper_sp;
623 ScriptInterpreter *m_interpreter;
625 DISALLOW_COPY_AND_ASSIGN(FrontEnd);
628 SyntheticChildrenFrontEnd::AutoPointer
629 GetFrontEnd(ValueObject &backend) override
631 auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
632 if (synth_ptr && ((FrontEnd*)synth_ptr.get())->IsValid())
638 DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
641 } // namespace lldb_private
643 #endif // lldb_TypeSynthetic_h_