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