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