10b57cec5SDimitry Andric //===-- TypeSynthetic.h -----------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
95ffd83dbSDimitry Andric #ifndef LLDB_DATAFORMATTERS_TYPESYNTHETIC_H
105ffd83dbSDimitry Andric #define LLDB_DATAFORMATTERS_TYPESYNTHETIC_H
110b57cec5SDimitry Andric 
12fe6060f1SDimitry Andric #include <cstdint>
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include <functional>
150b57cec5SDimitry Andric #include <initializer_list>
160b57cec5SDimitry Andric #include <memory>
170b57cec5SDimitry Andric #include <string>
180b57cec5SDimitry Andric #include <vector>
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h"
210b57cec5SDimitry Andric #include "lldb/lldb-public.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h"
240b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h"
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace lldb_private {
270b57cec5SDimitry Andric class SyntheticChildrenFrontEnd {
280b57cec5SDimitry Andric protected:
290b57cec5SDimitry Andric   ValueObject &m_backend;
300b57cec5SDimitry Andric 
SetValid(bool valid)310b57cec5SDimitry Andric   void SetValid(bool valid) { m_valid = valid; }
320b57cec5SDimitry Andric 
IsValid()330b57cec5SDimitry Andric   bool IsValid() { return m_valid; }
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric public:
SyntheticChildrenFrontEnd(ValueObject & backend)360b57cec5SDimitry Andric   SyntheticChildrenFrontEnd(ValueObject &backend)
370b57cec5SDimitry Andric       : m_backend(backend), m_valid(true) {}
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   virtual ~SyntheticChildrenFrontEnd() = default;
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   virtual size_t CalculateNumChildren() = 0;
420b57cec5SDimitry Andric 
CalculateNumChildren(uint32_t max)430b57cec5SDimitry Andric   virtual size_t CalculateNumChildren(uint32_t max) {
440b57cec5SDimitry Andric     auto count = CalculateNumChildren();
450b57cec5SDimitry Andric     return count <= max ? count : max;
460b57cec5SDimitry Andric   }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric   virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx) = 0;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   virtual size_t GetIndexOfChildWithName(ConstString name) = 0;
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric   // this function is assumed to always succeed and it if fails, the front-end
530b57cec5SDimitry Andric   // should know to deal with it in the correct way (most probably, by refusing
540b57cec5SDimitry Andric   // to return any children) the return value of Update() should actually be
550b57cec5SDimitry Andric   // interpreted as "ValueObjectSyntheticFilter cache is good/bad" if =true,
560b57cec5SDimitry Andric   // ValueObjectSyntheticFilter is allowed to use the children it fetched
570b57cec5SDimitry Andric   // previously and cached if =false, ValueObjectSyntheticFilter must throw
580b57cec5SDimitry Andric   // away its cache, and query again for children
590b57cec5SDimitry Andric   virtual bool Update() = 0;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   // if this function returns false, then CalculateNumChildren() MUST return 0
620b57cec5SDimitry Andric   // since UI frontends might validly decide not to inquire for children given
630b57cec5SDimitry Andric   // a false return value from this call if it returns true, then
640b57cec5SDimitry Andric   // CalculateNumChildren() can return any number >= 0 (0 being valid) it
650b57cec5SDimitry Andric   // should if at all possible be more efficient than CalculateNumChildren()
660b57cec5SDimitry Andric   virtual bool MightHaveChildren() = 0;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   // if this function returns a non-null ValueObject, then the returned
690b57cec5SDimitry Andric   // ValueObject will stand for this ValueObject whenever a "value" request is
700b57cec5SDimitry Andric   // made to this ValueObject
GetSyntheticValue()710b57cec5SDimitry Andric   virtual lldb::ValueObjectSP GetSyntheticValue() { return nullptr; }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric   // if this function returns a non-empty ConstString, then clients are
740b57cec5SDimitry Andric   // expected to use the return as the name of the type of this ValueObject for
750b57cec5SDimitry Andric   // display purposes
GetSyntheticTypeName()760b57cec5SDimitry Andric   virtual ConstString GetSyntheticTypeName() { return ConstString(); }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric   typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
790b57cec5SDimitry Andric   typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric protected:
820b57cec5SDimitry Andric   lldb::ValueObjectSP
830b57cec5SDimitry Andric   CreateValueObjectFromExpression(llvm::StringRef name,
840b57cec5SDimitry Andric                                   llvm::StringRef expression,
850b57cec5SDimitry Andric                                   const ExecutionContext &exe_ctx);
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   lldb::ValueObjectSP
880b57cec5SDimitry Andric   CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
890b57cec5SDimitry Andric                                const ExecutionContext &exe_ctx,
900b57cec5SDimitry Andric                                CompilerType type);
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name,
930b57cec5SDimitry Andric                                                 const DataExtractor &data,
940b57cec5SDimitry Andric                                                 const ExecutionContext &exe_ctx,
950b57cec5SDimitry Andric                                                 CompilerType type);
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric private:
980b57cec5SDimitry Andric   bool m_valid;
995ffd83dbSDimitry Andric   SyntheticChildrenFrontEnd(const SyntheticChildrenFrontEnd &) = delete;
1005ffd83dbSDimitry Andric   const SyntheticChildrenFrontEnd &
1015ffd83dbSDimitry Andric   operator=(const SyntheticChildrenFrontEnd &) = delete;
1020b57cec5SDimitry Andric };
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd {
1050b57cec5SDimitry Andric public:
SyntheticValueProviderFrontEnd(ValueObject & backend)1060b57cec5SDimitry Andric   SyntheticValueProviderFrontEnd(ValueObject &backend)
1070b57cec5SDimitry Andric       : SyntheticChildrenFrontEnd(backend) {}
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   ~SyntheticValueProviderFrontEnd() override = default;
1100b57cec5SDimitry Andric 
CalculateNumChildren()1110b57cec5SDimitry Andric   size_t CalculateNumChildren() override { return 0; }
1120b57cec5SDimitry Andric 
GetChildAtIndex(size_t idx)1130b57cec5SDimitry Andric   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { return nullptr; }
1140b57cec5SDimitry Andric 
GetIndexOfChildWithName(ConstString name)1150b57cec5SDimitry Andric   size_t GetIndexOfChildWithName(ConstString name) override {
1160b57cec5SDimitry Andric     return UINT32_MAX;
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric 
Update()1190b57cec5SDimitry Andric   bool Update() override { return false; }
1200b57cec5SDimitry Andric 
MightHaveChildren()1210b57cec5SDimitry Andric   bool MightHaveChildren() override { return false; }
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   lldb::ValueObjectSP GetSyntheticValue() override = 0;
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric private:
1265ffd83dbSDimitry Andric   SyntheticValueProviderFrontEnd(const SyntheticValueProviderFrontEnd &) =
1275ffd83dbSDimitry Andric       delete;
1285ffd83dbSDimitry Andric   const SyntheticValueProviderFrontEnd &
1295ffd83dbSDimitry Andric   operator=(const SyntheticValueProviderFrontEnd &) = delete;
1300b57cec5SDimitry Andric };
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric class SyntheticChildren {
1330b57cec5SDimitry Andric public:
1340b57cec5SDimitry Andric   class Flags {
1350b57cec5SDimitry Andric   public:
136fe6060f1SDimitry Andric     Flags() = default;
1370b57cec5SDimitry Andric 
Flags(const Flags & other)1380b57cec5SDimitry Andric     Flags(const Flags &other) : m_flags(other.m_flags) {}
1390b57cec5SDimitry Andric 
Flags(uint32_t value)1400b57cec5SDimitry Andric     Flags(uint32_t value) : m_flags(value) {}
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric     Flags &operator=(const Flags &rhs) {
1430b57cec5SDimitry Andric       if (&rhs != this)
1440b57cec5SDimitry Andric         m_flags = rhs.m_flags;
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric       return *this;
1470b57cec5SDimitry Andric     }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric     Flags &operator=(const uint32_t &rhs) {
1500b57cec5SDimitry Andric       m_flags = rhs;
1510b57cec5SDimitry Andric       return *this;
1520b57cec5SDimitry Andric     }
1530b57cec5SDimitry Andric 
Clear()1540b57cec5SDimitry Andric     Flags &Clear() {
1550b57cec5SDimitry Andric       m_flags = 0;
1560b57cec5SDimitry Andric       return *this;
1570b57cec5SDimitry Andric     }
1580b57cec5SDimitry Andric 
GetCascades()1590b57cec5SDimitry Andric     bool GetCascades() const {
1600b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
1610b57cec5SDimitry Andric     }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric     Flags &SetCascades(bool value = true) {
1640b57cec5SDimitry Andric       if (value)
1650b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionCascade;
1660b57cec5SDimitry Andric       else
1670b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionCascade;
1680b57cec5SDimitry Andric       return *this;
1690b57cec5SDimitry Andric     }
1700b57cec5SDimitry Andric 
GetSkipPointers()1710b57cec5SDimitry Andric     bool GetSkipPointers() const {
1720b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionSkipPointers) ==
1730b57cec5SDimitry Andric              lldb::eTypeOptionSkipPointers;
1740b57cec5SDimitry Andric     }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric     Flags &SetSkipPointers(bool value = true) {
1770b57cec5SDimitry Andric       if (value)
1780b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionSkipPointers;
1790b57cec5SDimitry Andric       else
1800b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionSkipPointers;
1810b57cec5SDimitry Andric       return *this;
1820b57cec5SDimitry Andric     }
1830b57cec5SDimitry Andric 
GetSkipReferences()1840b57cec5SDimitry Andric     bool GetSkipReferences() const {
1850b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionSkipReferences) ==
1860b57cec5SDimitry Andric              lldb::eTypeOptionSkipReferences;
1870b57cec5SDimitry Andric     }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric     Flags &SetSkipReferences(bool value = true) {
1900b57cec5SDimitry Andric       if (value)
1910b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionSkipReferences;
1920b57cec5SDimitry Andric       else
1930b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionSkipReferences;
1940b57cec5SDimitry Andric       return *this;
1950b57cec5SDimitry Andric     }
1960b57cec5SDimitry Andric 
GetNonCacheable()1970b57cec5SDimitry Andric     bool GetNonCacheable() const {
1980b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionNonCacheable) ==
1990b57cec5SDimitry Andric              lldb::eTypeOptionNonCacheable;
2000b57cec5SDimitry Andric     }
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric     Flags &SetNonCacheable(bool value = true) {
2030b57cec5SDimitry Andric       if (value)
2040b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionNonCacheable;
2050b57cec5SDimitry Andric       else
2060b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionNonCacheable;
2070b57cec5SDimitry Andric       return *this;
2080b57cec5SDimitry Andric     }
2090b57cec5SDimitry Andric 
GetFrontEndWantsDereference()2100b57cec5SDimitry Andric     bool GetFrontEndWantsDereference() const {
2110b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionFrontEndWantsDereference) ==
2120b57cec5SDimitry Andric              lldb::eTypeOptionFrontEndWantsDereference;
2130b57cec5SDimitry Andric     }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric     Flags &SetFrontEndWantsDereference(bool value = true) {
2160b57cec5SDimitry Andric       if (value)
2170b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionFrontEndWantsDereference;
2180b57cec5SDimitry Andric       else
2190b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionFrontEndWantsDereference;
2200b57cec5SDimitry Andric       return *this;
2210b57cec5SDimitry Andric     }
2220b57cec5SDimitry Andric 
GetValue()2230b57cec5SDimitry Andric     uint32_t GetValue() { return m_flags; }
2240b57cec5SDimitry Andric 
SetValue(uint32_t value)2250b57cec5SDimitry Andric     void SetValue(uint32_t value) { m_flags = value; }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric   private:
228fe6060f1SDimitry Andric     uint32_t m_flags = lldb::eTypeOptionCascade;
2290b57cec5SDimitry Andric   };
2300b57cec5SDimitry Andric 
2315f757f3fSDimitry Andric   SyntheticChildren(const Flags &flags);
2320b57cec5SDimitry Andric 
2335f757f3fSDimitry Andric   virtual ~SyntheticChildren();
2340b57cec5SDimitry Andric 
Cascades()2350b57cec5SDimitry Andric   bool Cascades() const { return m_flags.GetCascades(); }
2360b57cec5SDimitry Andric 
SkipsPointers()2370b57cec5SDimitry Andric   bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
2380b57cec5SDimitry Andric 
SkipsReferences()2390b57cec5SDimitry Andric   bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
2400b57cec5SDimitry Andric 
NonCacheable()2410b57cec5SDimitry Andric   bool NonCacheable() const { return m_flags.GetNonCacheable(); }
2420b57cec5SDimitry Andric 
WantsDereference()2430b57cec5SDimitry Andric   bool WantsDereference() const { return m_flags.GetFrontEndWantsDereference();}
2440b57cec5SDimitry Andric 
SetCascades(bool value)2450b57cec5SDimitry Andric   void SetCascades(bool value) { m_flags.SetCascades(value); }
2460b57cec5SDimitry Andric 
SetSkipsPointers(bool value)2470b57cec5SDimitry Andric   void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
2480b57cec5SDimitry Andric 
SetSkipsReferences(bool value)2490b57cec5SDimitry Andric   void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
2500b57cec5SDimitry Andric 
SetNonCacheable(bool value)2510b57cec5SDimitry Andric   void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
2520b57cec5SDimitry Andric 
GetOptions()2530b57cec5SDimitry Andric   uint32_t GetOptions() { return m_flags.GetValue(); }
2540b57cec5SDimitry Andric 
SetOptions(uint32_t value)2550b57cec5SDimitry Andric   void SetOptions(uint32_t value) { m_flags.SetValue(value); }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   virtual bool IsScripted() = 0;
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   virtual std::string GetDescription() = 0;
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric   virtual SyntheticChildrenFrontEnd::AutoPointer
2620b57cec5SDimitry Andric   GetFrontEnd(ValueObject &backend) = 0;
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric   typedef std::shared_ptr<SyntheticChildren> SharedPointer;
2650b57cec5SDimitry Andric 
GetRevision()2660b57cec5SDimitry Andric   uint32_t &GetRevision() { return m_my_revision; }
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric protected:
269fcaf7f86SDimitry Andric   uint32_t m_my_revision = 0;
2700b57cec5SDimitry Andric   Flags m_flags;
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric private:
2735ffd83dbSDimitry Andric   SyntheticChildren(const SyntheticChildren &) = delete;
2745ffd83dbSDimitry Andric   const SyntheticChildren &operator=(const SyntheticChildren &) = delete;
2750b57cec5SDimitry Andric };
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric class TypeFilterImpl : public SyntheticChildren {
2780b57cec5SDimitry Andric   std::vector<std::string> m_expression_paths;
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric public:
TypeFilterImpl(const SyntheticChildren::Flags & flags)2810b57cec5SDimitry Andric   TypeFilterImpl(const SyntheticChildren::Flags &flags)
28204eeddc0SDimitry Andric       : SyntheticChildren(flags) {}
2830b57cec5SDimitry Andric 
TypeFilterImpl(const SyntheticChildren::Flags & flags,const std::initializer_list<const char * > items)2840b57cec5SDimitry Andric   TypeFilterImpl(const SyntheticChildren::Flags &flags,
2850b57cec5SDimitry Andric                  const std::initializer_list<const char *> items)
28604eeddc0SDimitry Andric       : SyntheticChildren(flags) {
2870b57cec5SDimitry Andric     for (auto path : items)
2880b57cec5SDimitry Andric       AddExpressionPath(path);
2890b57cec5SDimitry Andric   }
2900b57cec5SDimitry Andric 
AddExpressionPath(const char * path)2910b57cec5SDimitry Andric   void AddExpressionPath(const char *path) {
2920b57cec5SDimitry Andric     AddExpressionPath(std::string(path));
2930b57cec5SDimitry Andric   }
2940b57cec5SDimitry Andric 
Clear()2950b57cec5SDimitry Andric   void Clear() { m_expression_paths.clear(); }
2960b57cec5SDimitry Andric 
GetCount()2970b57cec5SDimitry Andric   size_t GetCount() const { return m_expression_paths.size(); }
2980b57cec5SDimitry Andric 
GetExpressionPathAtIndex(size_t i)2990b57cec5SDimitry Andric   const char *GetExpressionPathAtIndex(size_t i) const {
3000b57cec5SDimitry Andric     return m_expression_paths[i].c_str();
3010b57cec5SDimitry Andric   }
3020b57cec5SDimitry Andric 
SetExpressionPathAtIndex(size_t i,const char * path)3030b57cec5SDimitry Andric   bool SetExpressionPathAtIndex(size_t i, const char *path) {
3040b57cec5SDimitry Andric     return SetExpressionPathAtIndex(i, std::string(path));
3050b57cec5SDimitry Andric   }
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   void AddExpressionPath(const std::string &path);
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   bool SetExpressionPathAtIndex(size_t i, const std::string &path);
3100b57cec5SDimitry Andric 
IsScripted()3110b57cec5SDimitry Andric   bool IsScripted() override { return false; }
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   std::string GetDescription() override;
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   class FrontEnd : public SyntheticChildrenFrontEnd {
3160b57cec5SDimitry Andric   public:
FrontEnd(TypeFilterImpl * flt,ValueObject & backend)3170b57cec5SDimitry Andric     FrontEnd(TypeFilterImpl *flt, ValueObject &backend)
3180b57cec5SDimitry Andric         : SyntheticChildrenFrontEnd(backend), filter(flt) {}
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric     ~FrontEnd() override = default;
3210b57cec5SDimitry Andric 
CalculateNumChildren()3220b57cec5SDimitry Andric     size_t CalculateNumChildren() override { return filter->GetCount(); }
3230b57cec5SDimitry Andric 
GetChildAtIndex(size_t idx)3240b57cec5SDimitry Andric     lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
3250b57cec5SDimitry Andric       if (idx >= filter->GetCount())
3260b57cec5SDimitry Andric         return lldb::ValueObjectSP();
3270b57cec5SDimitry Andric       return m_backend.GetSyntheticExpressionPathChild(
3280b57cec5SDimitry Andric           filter->GetExpressionPathAtIndex(idx), true);
3290b57cec5SDimitry Andric     }
3300b57cec5SDimitry Andric 
Update()3310b57cec5SDimitry Andric     bool Update() override { return false; }
3320b57cec5SDimitry Andric 
MightHaveChildren()3330b57cec5SDimitry Andric     bool MightHaveChildren() override { return filter->GetCount() > 0; }
3340b57cec5SDimitry Andric 
3350b57cec5SDimitry Andric     size_t GetIndexOfChildWithName(ConstString name) override;
3360b57cec5SDimitry Andric 
3370b57cec5SDimitry Andric     typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   private:
3400b57cec5SDimitry Andric     TypeFilterImpl *filter;
3410b57cec5SDimitry Andric 
3425ffd83dbSDimitry Andric     FrontEnd(const FrontEnd &) = delete;
3435ffd83dbSDimitry Andric     const FrontEnd &operator=(const FrontEnd &) = delete;
3440b57cec5SDimitry Andric   };
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric   SyntheticChildrenFrontEnd::AutoPointer
GetFrontEnd(ValueObject & backend)3470b57cec5SDimitry Andric   GetFrontEnd(ValueObject &backend) override {
3480b57cec5SDimitry Andric     return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
3490b57cec5SDimitry Andric   }
3500b57cec5SDimitry Andric 
3510b57cec5SDimitry Andric   typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric private:
3545ffd83dbSDimitry Andric   TypeFilterImpl(const TypeFilterImpl &) = delete;
3555ffd83dbSDimitry Andric   const TypeFilterImpl &operator=(const TypeFilterImpl &) = delete;
3560b57cec5SDimitry Andric };
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric class CXXSyntheticChildren : public SyntheticChildren {
3590b57cec5SDimitry Andric public:
3600b57cec5SDimitry Andric   typedef std::function<SyntheticChildrenFrontEnd *(CXXSyntheticChildren *,
3610b57cec5SDimitry Andric                                                     lldb::ValueObjectSP)>
3620b57cec5SDimitry Andric       CreateFrontEndCallback;
3630b57cec5SDimitry Andric   CXXSyntheticChildren(const SyntheticChildren::Flags &flags,
3645f757f3fSDimitry Andric                        const char *description, CreateFrontEndCallback callback);
3655f757f3fSDimitry Andric 
3665f757f3fSDimitry Andric   virtual ~CXXSyntheticChildren();
3670b57cec5SDimitry Andric 
IsScripted()3680b57cec5SDimitry Andric   bool IsScripted() override { return false; }
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   std::string GetDescription() override;
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   SyntheticChildrenFrontEnd::AutoPointer
GetFrontEnd(ValueObject & backend)3730b57cec5SDimitry Andric   GetFrontEnd(ValueObject &backend) override {
3740b57cec5SDimitry Andric     return SyntheticChildrenFrontEnd::AutoPointer(
3750b57cec5SDimitry Andric         m_create_callback(this, backend.GetSP()));
3760b57cec5SDimitry Andric   }
3770b57cec5SDimitry Andric 
3780b57cec5SDimitry Andric protected:
3790b57cec5SDimitry Andric   CreateFrontEndCallback m_create_callback;
3800b57cec5SDimitry Andric   std::string m_description;
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric private:
3835ffd83dbSDimitry Andric   CXXSyntheticChildren(const CXXSyntheticChildren &) = delete;
3845ffd83dbSDimitry Andric   const CXXSyntheticChildren &operator=(const CXXSyntheticChildren &) = delete;
3850b57cec5SDimitry Andric };
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric class ScriptedSyntheticChildren : public SyntheticChildren {
3880b57cec5SDimitry Andric   std::string m_python_class;
3890b57cec5SDimitry Andric   std::string m_python_code;
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric public:
3920b57cec5SDimitry Andric   ScriptedSyntheticChildren(const SyntheticChildren::Flags &flags,
3930b57cec5SDimitry Andric                             const char *pclass, const char *pcode = nullptr)
SyntheticChildren(flags)39404eeddc0SDimitry Andric       : SyntheticChildren(flags) {
3950b57cec5SDimitry Andric     if (pclass)
3960b57cec5SDimitry Andric       m_python_class = pclass;
3970b57cec5SDimitry Andric     if (pcode)
3980b57cec5SDimitry Andric       m_python_code = pcode;
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric 
GetPythonClassName()4010b57cec5SDimitry Andric   const char *GetPythonClassName() { return m_python_class.c_str(); }
4020b57cec5SDimitry Andric 
GetPythonCode()4030b57cec5SDimitry Andric   const char *GetPythonCode() { return m_python_code.c_str(); }
4040b57cec5SDimitry Andric 
SetPythonClassName(const char * fname)4050b57cec5SDimitry Andric   void SetPythonClassName(const char *fname) {
4060b57cec5SDimitry Andric     m_python_class.assign(fname);
4070b57cec5SDimitry Andric     m_python_code.clear();
4080b57cec5SDimitry Andric   }
4090b57cec5SDimitry Andric 
SetPythonCode(const char * script)4100b57cec5SDimitry Andric   void SetPythonCode(const char *script) { m_python_code.assign(script); }
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   std::string GetDescription() override;
4130b57cec5SDimitry Andric 
IsScripted()4140b57cec5SDimitry Andric   bool IsScripted() override { return true; }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   class FrontEnd : public SyntheticChildrenFrontEnd {
4170b57cec5SDimitry Andric   public:
4180b57cec5SDimitry Andric     FrontEnd(std::string pclass, ValueObject &backend);
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric     ~FrontEnd() override;
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric     bool IsValid();
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric     size_t CalculateNumChildren() override;
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric     size_t CalculateNumChildren(uint32_t max) override;
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric     lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric     bool Update() override;
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric     bool MightHaveChildren() override;
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric     size_t GetIndexOfChildWithName(ConstString name) override;
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric     lldb::ValueObjectSP GetSyntheticValue() override;
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric     ConstString GetSyntheticTypeName() override;
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric     typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric   private:
4430b57cec5SDimitry Andric     std::string m_python_class;
4440b57cec5SDimitry Andric     StructuredData::ObjectSP m_wrapper_sp;
4450b57cec5SDimitry Andric     ScriptInterpreter *m_interpreter;
4460b57cec5SDimitry Andric 
4475ffd83dbSDimitry Andric     FrontEnd(const FrontEnd &) = delete;
4485ffd83dbSDimitry Andric     const FrontEnd &operator=(const FrontEnd &) = delete;
4490b57cec5SDimitry Andric   };
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   SyntheticChildrenFrontEnd::AutoPointer
GetFrontEnd(ValueObject & backend)4520b57cec5SDimitry Andric   GetFrontEnd(ValueObject &backend) override {
4530b57cec5SDimitry Andric     auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(
4540b57cec5SDimitry Andric         new FrontEnd(m_python_class, backend));
4550b57cec5SDimitry Andric     if (synth_ptr && ((FrontEnd *)synth_ptr.get())->IsValid())
4560b57cec5SDimitry Andric       return synth_ptr;
4570b57cec5SDimitry Andric     return nullptr;
4580b57cec5SDimitry Andric   }
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric private:
4615ffd83dbSDimitry Andric   ScriptedSyntheticChildren(const ScriptedSyntheticChildren &) = delete;
4625ffd83dbSDimitry Andric   const ScriptedSyntheticChildren &
4635ffd83dbSDimitry Andric   operator=(const ScriptedSyntheticChildren &) = delete;
4640b57cec5SDimitry Andric };
4650b57cec5SDimitry Andric } // namespace lldb_private
4660b57cec5SDimitry Andric 
4675ffd83dbSDimitry Andric #endif // LLDB_DATAFORMATTERS_TYPESYNTHETIC_H
468