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