]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/lldb/DataFormatters/TypeSynthetic.h
Vendor import of lldb trunk r338150:
[FreeBSD/FreeBSD.git] / include / lldb / DataFormatters / TypeSynthetic.h
1 //===-- TypeSynthetic.h -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef lldb_TypeSynthetic_h_
11 #define lldb_TypeSynthetic_h_
12
13 // C Includes
14 #include <stdint.h>
15
16 // C++ Includes
17 #include <functional>
18 #include <initializer_list>
19 #include <memory>
20 #include <string>
21 #include <vector>
22
23 // Other libraries and framework includes
24 // Project includes
25 #include "lldb/lldb-enumerations.h"
26 #include "lldb/lldb-public.h"
27
28 #include "lldb/Core/ValueObject.h"
29 #include "lldb/Utility/StructuredData.h"
30
31 namespace lldb_private {
32 class SyntheticChildrenFrontEnd {
33 protected:
34   ValueObject &m_backend;
35
36   void SetValid(bool valid) { m_valid = valid; }
37
38   bool IsValid() { return m_valid; }
39
40 public:
41   SyntheticChildrenFrontEnd(ValueObject &backend)
42       : m_backend(backend), m_valid(true) {}
43
44   virtual ~SyntheticChildrenFrontEnd() = default;
45
46   virtual size_t CalculateNumChildren() = 0;
47
48   virtual size_t CalculateNumChildren(uint32_t max) {
49     auto count = CalculateNumChildren();
50     return count <= max ? count : max;
51   }
52
53   virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx) = 0;
54
55   virtual size_t GetIndexOfChildWithName(const ConstString &name) = 0;
56
57   // this function is assumed to always succeed and it if fails, the front-end
58   // should know to deal with it in the correct way (most probably, by refusing
59   // to return any children) the return value of Update() should actually be
60   // interpreted as "ValueObjectSyntheticFilter cache is good/bad" if =true,
61   // ValueObjectSyntheticFilter is allowed to use the children it fetched
62   // previously and cached if =false, ValueObjectSyntheticFilter must throw
63   // away its cache, and query again for children
64   virtual bool Update() = 0;
65
66   // if this function returns false, then CalculateNumChildren() MUST return 0
67   // since UI frontends might validly decide not to inquire for children given
68   // a false return value from this call if it returns true, then
69   // CalculateNumChildren() can return any number >= 0 (0 being valid) it
70   // should if at all possible be more efficient than CalculateNumChildren()
71   virtual bool MightHaveChildren() = 0;
72
73   // if this function returns a non-null ValueObject, then the returned
74   // ValueObject will stand for this ValueObject whenever a "value" request is
75   // made to this ValueObject
76   virtual lldb::ValueObjectSP GetSyntheticValue() { return nullptr; }
77
78   // if this function returns a non-empty ConstString, then clients are
79   // expected to use the return as the name of the type of this ValueObject for
80   // display purposes
81   virtual ConstString GetSyntheticTypeName() { return ConstString(); }
82
83   typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
84   typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
85
86 protected:
87   lldb::ValueObjectSP
88   CreateValueObjectFromExpression(llvm::StringRef name,
89                                   llvm::StringRef expression,
90                                   const ExecutionContext &exe_ctx);
91
92   lldb::ValueObjectSP
93   CreateValueObjectFromAddress(llvm::StringRef name, uint64_t address,
94                                const ExecutionContext &exe_ctx,
95                                CompilerType type);
96
97   lldb::ValueObjectSP CreateValueObjectFromData(llvm::StringRef name,
98                                                 const DataExtractor &data,
99                                                 const ExecutionContext &exe_ctx,
100                                                 CompilerType type);
101
102 private:
103   bool m_valid;
104   DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
105 };
106
107 class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd {
108 public:
109   SyntheticValueProviderFrontEnd(ValueObject &backend)
110       : SyntheticChildrenFrontEnd(backend) {}
111
112   ~SyntheticValueProviderFrontEnd() override = default;
113
114   size_t CalculateNumChildren() override { return 0; }
115
116   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { return nullptr; }
117
118   size_t GetIndexOfChildWithName(const ConstString &name) override {
119     return UINT32_MAX;
120   }
121
122   bool Update() override { return false; }
123
124   bool MightHaveChildren() override { return false; }
125
126   lldb::ValueObjectSP GetSyntheticValue() override = 0;
127
128 private:
129   DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd);
130 };
131
132 class SyntheticChildren {
133 public:
134   class Flags {
135   public:
136     Flags() : m_flags(lldb::eTypeOptionCascade) {}
137
138     Flags(const Flags &other) : m_flags(other.m_flags) {}
139
140     Flags(uint32_t value) : m_flags(value) {}
141
142     Flags &operator=(const Flags &rhs) {
143       if (&rhs != this)
144         m_flags = rhs.m_flags;
145
146       return *this;
147     }
148
149     Flags &operator=(const uint32_t &rhs) {
150       m_flags = rhs;
151       return *this;
152     }
153
154     Flags &Clear() {
155       m_flags = 0;
156       return *this;
157     }
158
159     bool GetCascades() const {
160       return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
161     }
162
163     Flags &SetCascades(bool value = true) {
164       if (value)
165         m_flags |= lldb::eTypeOptionCascade;
166       else
167         m_flags &= ~lldb::eTypeOptionCascade;
168       return *this;
169     }
170
171     bool GetSkipPointers() const {
172       return (m_flags & lldb::eTypeOptionSkipPointers) ==
173              lldb::eTypeOptionSkipPointers;
174     }
175
176     Flags &SetSkipPointers(bool value = true) {
177       if (value)
178         m_flags |= lldb::eTypeOptionSkipPointers;
179       else
180         m_flags &= ~lldb::eTypeOptionSkipPointers;
181       return *this;
182     }
183
184     bool GetSkipReferences() const {
185       return (m_flags & lldb::eTypeOptionSkipReferences) ==
186              lldb::eTypeOptionSkipReferences;
187     }
188
189     Flags &SetSkipReferences(bool value = true) {
190       if (value)
191         m_flags |= lldb::eTypeOptionSkipReferences;
192       else
193         m_flags &= ~lldb::eTypeOptionSkipReferences;
194       return *this;
195     }
196
197     bool GetNonCacheable() const {
198       return (m_flags & lldb::eTypeOptionNonCacheable) ==
199              lldb::eTypeOptionNonCacheable;
200     }
201
202     Flags &SetNonCacheable(bool value = true) {
203       if (value)
204         m_flags |= lldb::eTypeOptionNonCacheable;
205       else
206         m_flags &= ~lldb::eTypeOptionNonCacheable;
207       return *this;
208     }
209
210     bool GetFrontEndWantsDereference() const {
211       return (m_flags & lldb::eTypeOptionFrontEndWantsDereference) ==
212              lldb::eTypeOptionFrontEndWantsDereference;
213     }
214
215     Flags &SetFrontEndWantsDereference(bool value = true) {
216       if (value)
217         m_flags |= lldb::eTypeOptionFrontEndWantsDereference;
218       else
219         m_flags &= ~lldb::eTypeOptionFrontEndWantsDereference;
220       return *this;
221     }
222
223     uint32_t GetValue() { return m_flags; }
224
225     void SetValue(uint32_t value) { m_flags = value; }
226
227   private:
228     uint32_t m_flags;
229   };
230
231   SyntheticChildren(const Flags &flags) : m_flags(flags) {}
232
233   virtual ~SyntheticChildren() = default;
234
235   bool Cascades() const { return m_flags.GetCascades(); }
236
237   bool SkipsPointers() const { return m_flags.GetSkipPointers(); }
238
239   bool SkipsReferences() const { return m_flags.GetSkipReferences(); }
240
241   bool NonCacheable() const { return m_flags.GetNonCacheable(); }
242   
243   bool WantsDereference() const { return m_flags.GetFrontEndWantsDereference();} 
244
245   void SetCascades(bool value) { m_flags.SetCascades(value); }
246
247   void SetSkipsPointers(bool value) { m_flags.SetSkipPointers(value); }
248
249   void SetSkipsReferences(bool value) { m_flags.SetSkipReferences(value); }
250
251   void SetNonCacheable(bool value) { m_flags.SetNonCacheable(value); }
252
253   uint32_t GetOptions() { return m_flags.GetValue(); }
254
255   void SetOptions(uint32_t value) { m_flags.SetValue(value); }
256
257   virtual bool IsScripted() = 0;
258
259   virtual std::string GetDescription() = 0;
260
261   virtual SyntheticChildrenFrontEnd::AutoPointer
262   GetFrontEnd(ValueObject &backend) = 0;
263
264   typedef std::shared_ptr<SyntheticChildren> SharedPointer;
265
266   uint32_t &GetRevision() { return m_my_revision; }
267
268 protected:
269   uint32_t m_my_revision;
270   Flags m_flags;
271
272 private:
273   DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
274 };
275
276 class TypeFilterImpl : public SyntheticChildren {
277   std::vector<std::string> m_expression_paths;
278
279 public:
280   TypeFilterImpl(const SyntheticChildren::Flags &flags)
281       : SyntheticChildren(flags), m_expression_paths() {}
282
283   TypeFilterImpl(const SyntheticChildren::Flags &flags,
284                  const std::initializer_list<const char *> items)
285       : SyntheticChildren(flags), m_expression_paths() {
286     for (auto path : items)
287       AddExpressionPath(path);
288   }
289
290   void AddExpressionPath(const char *path) {
291     AddExpressionPath(std::string(path));
292   }
293
294   void Clear() { m_expression_paths.clear(); }
295
296   size_t GetCount() const { return m_expression_paths.size(); }
297
298   const char *GetExpressionPathAtIndex(size_t i) const {
299     return m_expression_paths[i].c_str();
300   }
301
302   bool SetExpressionPathAtIndex(size_t i, const char *path) {
303     return SetExpressionPathAtIndex(i, std::string(path));
304   }
305
306   void AddExpressionPath(const std::string &path);
307
308   bool SetExpressionPathAtIndex(size_t i, const std::string &path);
309
310   bool IsScripted() override { return false; }
311
312   std::string GetDescription() override;
313
314   class FrontEnd : public SyntheticChildrenFrontEnd {
315   public:
316     FrontEnd(TypeFilterImpl *flt, ValueObject &backend)
317         : SyntheticChildrenFrontEnd(backend), filter(flt) {}
318
319     ~FrontEnd() override = default;
320
321     size_t CalculateNumChildren() override { return filter->GetCount(); }
322
323     lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
324       if (idx >= filter->GetCount())
325         return lldb::ValueObjectSP();
326       return m_backend.GetSyntheticExpressionPathChild(
327           filter->GetExpressionPathAtIndex(idx), true);
328     }
329
330     bool Update() override { return false; }
331
332     bool MightHaveChildren() override { return filter->GetCount() > 0; }
333
334     size_t GetIndexOfChildWithName(const ConstString &name) override;
335
336     typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
337
338   private:
339     TypeFilterImpl *filter;
340
341     DISALLOW_COPY_AND_ASSIGN(FrontEnd);
342   };
343
344   SyntheticChildrenFrontEnd::AutoPointer
345   GetFrontEnd(ValueObject &backend) override {
346     return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
347   }
348
349   typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
350
351 private:
352   DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
353 };
354
355 class CXXSyntheticChildren : public SyntheticChildren {
356 public:
357   typedef std::function<SyntheticChildrenFrontEnd *(CXXSyntheticChildren *,
358                                                     lldb::ValueObjectSP)>
359       CreateFrontEndCallback;
360   CXXSyntheticChildren(const SyntheticChildren::Flags &flags,
361                        const char *description, CreateFrontEndCallback callback)
362       : SyntheticChildren(flags), m_create_callback(callback),
363         m_description(description ? description : "") {}
364
365   bool IsScripted() override { return false; }
366
367   std::string GetDescription() override;
368
369   SyntheticChildrenFrontEnd::AutoPointer
370   GetFrontEnd(ValueObject &backend) override {
371     return SyntheticChildrenFrontEnd::AutoPointer(
372         m_create_callback(this, backend.GetSP()));
373   }
374
375 protected:
376   CreateFrontEndCallback m_create_callback;
377   std::string m_description;
378
379 private:
380   DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
381 };
382
383 #ifndef LLDB_DISABLE_PYTHON
384
385 class ScriptedSyntheticChildren : public SyntheticChildren {
386   std::string m_python_class;
387   std::string m_python_code;
388
389 public:
390   ScriptedSyntheticChildren(const SyntheticChildren::Flags &flags,
391                             const char *pclass, const char *pcode = nullptr)
392       : SyntheticChildren(flags), m_python_class(), m_python_code() {
393     if (pclass)
394       m_python_class = pclass;
395     if (pcode)
396       m_python_code = pcode;
397   }
398
399   const char *GetPythonClassName() { return m_python_class.c_str(); }
400
401   const char *GetPythonCode() { return m_python_code.c_str(); }
402
403   void SetPythonClassName(const char *fname) {
404     m_python_class.assign(fname);
405     m_python_code.clear();
406   }
407
408   void SetPythonCode(const char *script) { m_python_code.assign(script); }
409
410   std::string GetDescription() override;
411
412   bool IsScripted() override { return true; }
413
414   class FrontEnd : public SyntheticChildrenFrontEnd {
415   public:
416     FrontEnd(std::string pclass, ValueObject &backend);
417
418     ~FrontEnd() override;
419
420     bool IsValid();
421
422     size_t CalculateNumChildren() override;
423
424     size_t CalculateNumChildren(uint32_t max) override;
425
426     lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
427
428     bool Update() override;
429
430     bool MightHaveChildren() override;
431
432     size_t GetIndexOfChildWithName(const ConstString &name) override;
433
434     lldb::ValueObjectSP GetSyntheticValue() override;
435
436     ConstString GetSyntheticTypeName() override;
437
438     typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
439
440   private:
441     std::string m_python_class;
442     StructuredData::ObjectSP m_wrapper_sp;
443     ScriptInterpreter *m_interpreter;
444
445     DISALLOW_COPY_AND_ASSIGN(FrontEnd);
446   };
447
448   SyntheticChildrenFrontEnd::AutoPointer
449   GetFrontEnd(ValueObject &backend) override {
450     auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(
451         new FrontEnd(m_python_class, backend));
452     if (synth_ptr && ((FrontEnd *)synth_ptr.get())->IsValid())
453       return synth_ptr;
454     return nullptr;
455   }
456
457 private:
458   DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
459 };
460 #endif
461 } // namespace lldb_private
462
463 #endif // lldb_TypeSynthetic_h_