1 //===-- TypeFormat.h ----------------------------------------------*- C++ 2 //-*-===// 3 // 4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5 // See https://llvm.org/LICENSE.txt for license information. 6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef LLDB_DATAFORMATTERS_TYPEFORMAT_H 11 #define LLDB_DATAFORMATTERS_TYPEFORMAT_H 12 13 #include <functional> 14 #include <string> 15 #include <unordered_map> 16 17 18 #include "lldb/lldb-enumerations.h" 19 #include "lldb/lldb-public.h" 20 21 #include "lldb/ValueObject/ValueObject.h" 22 23 namespace lldb_private { 24 class TypeFormatImpl { 25 public: 26 class Flags { 27 public: Flags()28 Flags() {} 29 Flags(const Flags & other)30 Flags(const Flags &other) : m_flags(other.m_flags) {} 31 Flags(uint32_t value)32 Flags(uint32_t value) : m_flags(value) {} 33 34 Flags &operator=(const Flags &rhs) { 35 if (&rhs != this) 36 m_flags = rhs.m_flags; 37 38 return *this; 39 } 40 41 Flags &operator=(const uint32_t &rhs) { 42 m_flags = rhs; 43 return *this; 44 } 45 Clear()46 Flags &Clear() { 47 m_flags = 0; 48 return *this; 49 } 50 GetCascades()51 bool GetCascades() const { 52 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade; 53 } 54 55 Flags &SetCascades(bool value = true) { 56 if (value) 57 m_flags |= lldb::eTypeOptionCascade; 58 else 59 m_flags &= ~lldb::eTypeOptionCascade; 60 return *this; 61 } 62 GetSkipPointers()63 bool GetSkipPointers() const { 64 return (m_flags & lldb::eTypeOptionSkipPointers) == 65 lldb::eTypeOptionSkipPointers; 66 } 67 68 Flags &SetSkipPointers(bool value = true) { 69 if (value) 70 m_flags |= lldb::eTypeOptionSkipPointers; 71 else 72 m_flags &= ~lldb::eTypeOptionSkipPointers; 73 return *this; 74 } 75 GetSkipReferences()76 bool GetSkipReferences() const { 77 return (m_flags & lldb::eTypeOptionSkipReferences) == 78 lldb::eTypeOptionSkipReferences; 79 } 80 81 Flags &SetSkipReferences(bool value = true) { 82 if (value) 83 m_flags |= lldb::eTypeOptionSkipReferences; 84 else 85 m_flags &= ~lldb::eTypeOptionSkipReferences; 86 return *this; 87 } 88 GetNonCacheable()89 bool GetNonCacheable() const { 90 return (m_flags & lldb::eTypeOptionNonCacheable) == 91 lldb::eTypeOptionNonCacheable; 92 } 93 94 Flags &SetNonCacheable(bool value = true) { 95 if (value) 96 m_flags |= lldb::eTypeOptionNonCacheable; 97 else 98 m_flags &= ~lldb::eTypeOptionNonCacheable; 99 return *this; 100 } 101 GetValue()102 uint32_t GetValue() { return m_flags; } 103 SetValue(uint32_t value)104 void SetValue(uint32_t value) { m_flags = value; } 105 106 private: 107 uint32_t m_flags = lldb::eTypeOptionCascade; 108 }; 109 110 TypeFormatImpl(const Flags &flags = Flags()); 111 112 typedef std::shared_ptr<TypeFormatImpl> SharedPointer; 113 114 virtual ~TypeFormatImpl(); 115 Cascades()116 bool Cascades() const { return m_flags.GetCascades(); } 117 SkipsPointers()118 bool SkipsPointers() const { return m_flags.GetSkipPointers(); } 119 SkipsReferences()120 bool SkipsReferences() const { return m_flags.GetSkipReferences(); } 121 NonCacheable()122 bool NonCacheable() const { return m_flags.GetNonCacheable(); } 123 SetCascades(bool value)124 void SetCascades(bool value) { m_flags.SetCascades(value); } 125 SetSkipsPointers(bool value)126 void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); } 127 SetSkipsReferences(bool value)128 void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); } 129 SetNonCacheable(bool value)130 void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); } 131 GetOptions()132 uint32_t GetOptions() { return m_flags.GetValue(); } 133 SetOptions(uint32_t value)134 void SetOptions(uint32_t value) { m_flags.SetValue(value); } 135 GetPtrMatchDepth()136 uint32_t GetPtrMatchDepth() { return m_ptr_match_depth; } 137 SetPtrMatchDepth(uint32_t value)138 void SetPtrMatchDepth(uint32_t value) { m_ptr_match_depth = value; } 139 GetRevision()140 uint32_t &GetRevision() { return m_my_revision; } 141 142 enum class Type { eTypeUnknown, eTypeFormat, eTypeEnum }; 143 GetType()144 virtual Type GetType() { return Type::eTypeUnknown; } 145 146 // we are using a ValueObject* instead of a ValueObjectSP because we do not 147 // need to hold on to this for extended periods of time and we trust the 148 // ValueObject to stay around for as long as it is required for us to 149 // generate its value 150 virtual bool FormatObject(ValueObject *valobj, std::string &dest) const = 0; 151 152 virtual std::string GetDescription() = 0; 153 154 protected: 155 Flags m_flags; 156 uint32_t m_my_revision = 0; 157 uint32_t m_ptr_match_depth = 1; 158 159 private: 160 TypeFormatImpl(const TypeFormatImpl &) = delete; 161 const TypeFormatImpl &operator=(const TypeFormatImpl &) = delete; 162 }; 163 164 class TypeFormatImpl_Format : public TypeFormatImpl { 165 public: 166 TypeFormatImpl_Format(lldb::Format f = lldb::eFormatInvalid, 167 const TypeFormatImpl::Flags &flags = Flags()); 168 169 typedef std::shared_ptr<TypeFormatImpl_Format> SharedPointer; 170 171 ~TypeFormatImpl_Format() override; 172 GetFormat()173 lldb::Format GetFormat() const { return m_format; } 174 SetFormat(lldb::Format fmt)175 void SetFormat(lldb::Format fmt) { m_format = fmt; } 176 GetType()177 TypeFormatImpl::Type GetType() override { 178 return TypeFormatImpl::Type::eTypeFormat; 179 } 180 181 bool FormatObject(ValueObject *valobj, std::string &dest) const override; 182 183 std::string GetDescription() override; 184 185 protected: 186 lldb::Format m_format; 187 188 private: 189 TypeFormatImpl_Format(const TypeFormatImpl_Format &) = delete; 190 const TypeFormatImpl_Format & 191 operator=(const TypeFormatImpl_Format &) = delete; 192 }; 193 194 class TypeFormatImpl_EnumType : public TypeFormatImpl { 195 public: 196 TypeFormatImpl_EnumType(ConstString type_name = ConstString(""), 197 const TypeFormatImpl::Flags &flags = Flags()); 198 199 typedef std::shared_ptr<TypeFormatImpl_EnumType> SharedPointer; 200 201 ~TypeFormatImpl_EnumType() override; 202 GetTypeName()203 ConstString GetTypeName() { return m_enum_type; } 204 SetTypeName(ConstString enum_type)205 void SetTypeName(ConstString enum_type) { m_enum_type = enum_type; } 206 GetType()207 TypeFormatImpl::Type GetType() override { 208 return TypeFormatImpl::Type::eTypeEnum; 209 } 210 211 bool FormatObject(ValueObject *valobj, std::string &dest) const override; 212 213 std::string GetDescription() override; 214 215 protected: 216 ConstString m_enum_type; 217 mutable std::unordered_map<void *, CompilerType> m_types; 218 219 private: 220 TypeFormatImpl_EnumType(const TypeFormatImpl_EnumType &) = delete; 221 const TypeFormatImpl_EnumType & 222 operator=(const TypeFormatImpl_EnumType &) = delete; 223 }; 224 } // namespace lldb_private 225 226 #endif // LLDB_DATAFORMATTERS_TYPEFORMAT_H 227