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