10b57cec5SDimitry Andric //===-- TypeFormat.h ----------------------------------------------*- C++
20b57cec5SDimitry Andric //-*-===//
30b57cec5SDimitry Andric //
40b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric //
80b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric 
100b57cec5SDimitry Andric #ifndef LLDB_DATAFORMATTERS_TYPEFORMAT_H
110b57cec5SDimitry Andric #define LLDB_DATAFORMATTERS_TYPEFORMAT_H
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include <functional>
140b57cec5SDimitry Andric #include <string>
150b57cec5SDimitry Andric #include <unordered_map>
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h"
190b57cec5SDimitry Andric #include "lldb/lldb-public.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace lldb_private {
240b57cec5SDimitry Andric class TypeFormatImpl {
250b57cec5SDimitry Andric public:
260b57cec5SDimitry Andric   class Flags {
270b57cec5SDimitry Andric   public:
Flags()280b57cec5SDimitry Andric     Flags() {}
290b57cec5SDimitry Andric 
Flags(const Flags & other)300b57cec5SDimitry Andric     Flags(const Flags &other) : m_flags(other.m_flags) {}
310b57cec5SDimitry Andric 
Flags(uint32_t value)320b57cec5SDimitry Andric     Flags(uint32_t value) : m_flags(value) {}
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric     Flags &operator=(const Flags &rhs) {
350b57cec5SDimitry Andric       if (&rhs != this)
360b57cec5SDimitry Andric         m_flags = rhs.m_flags;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric       return *this;
390b57cec5SDimitry Andric     }
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric     Flags &operator=(const uint32_t &rhs) {
420b57cec5SDimitry Andric       m_flags = rhs;
430b57cec5SDimitry Andric       return *this;
440b57cec5SDimitry Andric     }
450b57cec5SDimitry Andric 
Clear()460b57cec5SDimitry Andric     Flags &Clear() {
470b57cec5SDimitry Andric       m_flags = 0;
480b57cec5SDimitry Andric       return *this;
490b57cec5SDimitry Andric     }
500b57cec5SDimitry Andric 
GetCascades()510b57cec5SDimitry Andric     bool GetCascades() const {
520b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
530b57cec5SDimitry Andric     }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric     Flags &SetCascades(bool value = true) {
560b57cec5SDimitry Andric       if (value)
570b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionCascade;
580b57cec5SDimitry Andric       else
590b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionCascade;
600b57cec5SDimitry Andric       return *this;
610b57cec5SDimitry Andric     }
620b57cec5SDimitry Andric 
GetSkipPointers()630b57cec5SDimitry Andric     bool GetSkipPointers() const {
640b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionSkipPointers) ==
650b57cec5SDimitry Andric              lldb::eTypeOptionSkipPointers;
660b57cec5SDimitry Andric     }
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric     Flags &SetSkipPointers(bool value = true) {
690b57cec5SDimitry Andric       if (value)
700b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionSkipPointers;
710b57cec5SDimitry Andric       else
720b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionSkipPointers;
730b57cec5SDimitry Andric       return *this;
740b57cec5SDimitry Andric     }
750b57cec5SDimitry Andric 
GetSkipReferences()760b57cec5SDimitry Andric     bool GetSkipReferences() const {
770b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionSkipReferences) ==
780b57cec5SDimitry Andric              lldb::eTypeOptionSkipReferences;
790b57cec5SDimitry Andric     }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric     Flags &SetSkipReferences(bool value = true) {
820b57cec5SDimitry Andric       if (value)
830b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionSkipReferences;
840b57cec5SDimitry Andric       else
850b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionSkipReferences;
860b57cec5SDimitry Andric       return *this;
870b57cec5SDimitry Andric     }
880b57cec5SDimitry Andric 
GetNonCacheable()890b57cec5SDimitry Andric     bool GetNonCacheable() const {
900b57cec5SDimitry Andric       return (m_flags & lldb::eTypeOptionNonCacheable) ==
910b57cec5SDimitry Andric              lldb::eTypeOptionNonCacheable;
920b57cec5SDimitry Andric     }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric     Flags &SetNonCacheable(bool value = true) {
950b57cec5SDimitry Andric       if (value)
960b57cec5SDimitry Andric         m_flags |= lldb::eTypeOptionNonCacheable;
970b57cec5SDimitry Andric       else
980b57cec5SDimitry Andric         m_flags &= ~lldb::eTypeOptionNonCacheable;
990b57cec5SDimitry Andric       return *this;
1000b57cec5SDimitry Andric     }
1010b57cec5SDimitry Andric 
GetValue()1020b57cec5SDimitry Andric     uint32_t GetValue() { return m_flags; }
1030b57cec5SDimitry Andric 
SetValue(uint32_t value)1040b57cec5SDimitry Andric     void SetValue(uint32_t value) { m_flags = value; }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   private:
1070b57cec5SDimitry Andric     uint32_t m_flags = lldb::eTypeOptionCascade;
1080b57cec5SDimitry Andric   };
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   TypeFormatImpl(const Flags &flags = Flags());
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   typedef std::shared_ptr<TypeFormatImpl> SharedPointer;
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric   virtual ~TypeFormatImpl();
1150b57cec5SDimitry Andric 
Cascades()1160b57cec5SDimitry Andric   bool Cascades() const { return m_flags.GetCascades(); }
1170b57cec5SDimitry Andric 
SkipsPointers()1180b57cec5SDimitry Andric   bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
1190b57cec5SDimitry Andric 
SkipsReferences()1200b57cec5SDimitry Andric   bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
1210b57cec5SDimitry Andric 
NonCacheable()1220b57cec5SDimitry Andric   bool NonCacheable() const { return m_flags.GetNonCacheable(); }
1230b57cec5SDimitry Andric 
SetCascades(bool value)1240b57cec5SDimitry Andric   void SetCascades(bool value) { m_flags.SetCascades(value); }
1250b57cec5SDimitry Andric 
SetSkipsPointers(bool value)1260b57cec5SDimitry Andric   void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
1270b57cec5SDimitry Andric 
SetSkipsReferences(bool value)1280b57cec5SDimitry Andric   void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
1290b57cec5SDimitry Andric 
SetNonCacheable(bool value)1300b57cec5SDimitry Andric   void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
1310b57cec5SDimitry Andric 
GetOptions()1320b57cec5SDimitry Andric   uint32_t GetOptions() { return m_flags.GetValue(); }
1330b57cec5SDimitry Andric 
SetOptions(uint32_t value)1340b57cec5SDimitry Andric   void SetOptions(uint32_t value) { m_flags.SetValue(value); }
1350b57cec5SDimitry Andric 
GetRevision()1360b57cec5SDimitry Andric   uint32_t &GetRevision() { return m_my_revision; }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric   enum class Type { eTypeUnknown, eTypeFormat, eTypeEnum };
1390b57cec5SDimitry Andric 
GetType()1400b57cec5SDimitry Andric   virtual Type GetType() { return Type::eTypeUnknown; }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   // we are using a ValueObject* instead of a ValueObjectSP because we do not
1430b57cec5SDimitry Andric   // need to hold on to this for extended periods of time and we trust the
1440b57cec5SDimitry Andric   // ValueObject to stay around for as long as it is required for us to
1450b57cec5SDimitry Andric   // generate its value
1460b57cec5SDimitry Andric   virtual bool FormatObject(ValueObject *valobj, std::string &dest) const = 0;
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   virtual std::string GetDescription() = 0;
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric protected:
1510b57cec5SDimitry Andric   Flags m_flags;
1520b57cec5SDimitry Andric   uint32_t m_my_revision = 0;
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric private:
1550b57cec5SDimitry Andric   TypeFormatImpl(const TypeFormatImpl &) = delete;
1560b57cec5SDimitry Andric   const TypeFormatImpl &operator=(const TypeFormatImpl &) = delete;
1570b57cec5SDimitry Andric };
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric class TypeFormatImpl_Format : public TypeFormatImpl {
1600b57cec5SDimitry Andric public:
1610b57cec5SDimitry Andric   TypeFormatImpl_Format(lldb::Format f = lldb::eFormatInvalid,
1620b57cec5SDimitry Andric                         const TypeFormatImpl::Flags &flags = Flags());
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   typedef std::shared_ptr<TypeFormatImpl_Format> SharedPointer;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   ~TypeFormatImpl_Format() override;
1670b57cec5SDimitry Andric 
GetFormat()1680b57cec5SDimitry Andric   lldb::Format GetFormat() const { return m_format; }
1690b57cec5SDimitry Andric 
SetFormat(lldb::Format fmt)1700b57cec5SDimitry Andric   void SetFormat(lldb::Format fmt) { m_format = fmt; }
1710b57cec5SDimitry Andric 
GetType()1720b57cec5SDimitry Andric   TypeFormatImpl::Type GetType() override {
1730b57cec5SDimitry Andric     return TypeFormatImpl::Type::eTypeFormat;
1740b57cec5SDimitry Andric   }
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   bool FormatObject(ValueObject *valobj, std::string &dest) const override;
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric   std::string GetDescription() override;
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric protected:
1810b57cec5SDimitry Andric   lldb::Format m_format;
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric private:
1840b57cec5SDimitry Andric   TypeFormatImpl_Format(const TypeFormatImpl_Format &) = delete;
1850b57cec5SDimitry Andric   const TypeFormatImpl_Format &
1860b57cec5SDimitry Andric   operator=(const TypeFormatImpl_Format &) = delete;
1870b57cec5SDimitry Andric };
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric class TypeFormatImpl_EnumType : public TypeFormatImpl {
1900b57cec5SDimitry Andric public:
1910b57cec5SDimitry Andric   TypeFormatImpl_EnumType(ConstString type_name = ConstString(""),
1920b57cec5SDimitry Andric                           const TypeFormatImpl::Flags &flags = Flags());
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric   typedef std::shared_ptr<TypeFormatImpl_EnumType> SharedPointer;
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   ~TypeFormatImpl_EnumType() override;
1970b57cec5SDimitry Andric 
GetTypeName()1980b57cec5SDimitry Andric   ConstString GetTypeName() { return m_enum_type; }
1990b57cec5SDimitry Andric 
SetTypeName(ConstString enum_type)2000b57cec5SDimitry Andric   void SetTypeName(ConstString enum_type) { m_enum_type = enum_type; }
2010b57cec5SDimitry Andric 
GetType()2020b57cec5SDimitry Andric   TypeFormatImpl::Type GetType() override {
2030b57cec5SDimitry Andric     return TypeFormatImpl::Type::eTypeEnum;
2040b57cec5SDimitry Andric   }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   bool FormatObject(ValueObject *valobj, std::string &dest) const override;
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   std::string GetDescription() override;
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric protected:
2110b57cec5SDimitry Andric   ConstString m_enum_type;
2120b57cec5SDimitry Andric   mutable std::unordered_map<void *, CompilerType> m_types;
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric private:
2150b57cec5SDimitry Andric   TypeFormatImpl_EnumType(const TypeFormatImpl_EnumType &) = delete;
2160b57cec5SDimitry Andric   const TypeFormatImpl_EnumType &
2170b57cec5SDimitry Andric   operator=(const TypeFormatImpl_EnumType &) = delete;
218 };
219 } // namespace lldb_private
220 
221 #endif // LLDB_DATAFORMATTERS_TYPEFORMAT_H
222