]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/lldb/DataFormatters/TypeSynthetic.h
Vendor import of lldb release_39 branch r276489:
[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 <initializer_list>
18 #include <functional>
19 #include <memory>
20 #include <string>
21 #include <vector>
22
23 // Other libraries and framework includes
24 // Project includes
25 #include "lldb/lldb-public.h"
26 #include "lldb/lldb-enumerations.h"
27
28 #include "lldb/Core/StructuredData.h"
29 #include "lldb/Core/ValueObject.h"
30
31 namespace lldb_private {
32     class SyntheticChildrenFrontEnd
33     {
34     protected:
35         ValueObject &m_backend;
36         
37         void
38         SetValid (bool valid)
39         {
40             m_valid = valid;
41         }
42         
43         bool
44         IsValid ()
45         {
46             return m_valid;
47         }
48         
49     public:
50         SyntheticChildrenFrontEnd (ValueObject &backend) :
51         m_backend(backend),
52         m_valid(true)
53         {}
54
55         virtual
56         ~SyntheticChildrenFrontEnd() = default;
57
58         virtual size_t
59         CalculateNumChildren () = 0;
60
61         virtual size_t
62         CalculateNumChildren (uint32_t max)
63         {
64             auto count = CalculateNumChildren ();
65             return count <= max ? count : max;
66         }
67         
68         virtual lldb::ValueObjectSP
69         GetChildAtIndex (size_t idx) = 0;
70
71         virtual size_t
72         GetIndexOfChildWithName (const ConstString &name) = 0;
73         
74         // this function is assumed to always succeed and it if fails, the front-end should know to deal
75         // with it in the correct way (most probably, by refusing to return any children)
76         // the return value of Update() should actually be interpreted as "ValueObjectSyntheticFilter cache is good/bad"
77         // if =true, ValueObjectSyntheticFilter is allowed to use the children it fetched previously and cached
78         // if =false, ValueObjectSyntheticFilter must throw away its cache, and query again for children
79         virtual bool
80         Update () = 0;
81         
82         // if this function returns false, then CalculateNumChildren() MUST return 0 since UI frontends
83         // might validly decide not to inquire for children given a false return value from this call
84         // if it returns true, then CalculateNumChildren() can return any number >= 0 (0 being valid)
85         // it should if at all possible be more efficient than CalculateNumChildren()
86         virtual bool
87         MightHaveChildren () = 0;
88         
89         // if this function returns a non-null ValueObject, then the returned ValueObject will stand
90         // for this ValueObject whenever a "value" request is made to this ValueObject
91         virtual lldb::ValueObjectSP
92         GetSyntheticValue () { return nullptr; }
93         
94         // if this function returns a non-empty ConstString, then clients are expected to use the return
95         // as the name of the type of this ValueObject for display purposes
96         virtual ConstString
97         GetSyntheticTypeName () { return ConstString(); }
98         
99         typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
100         typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer;
101         
102     protected:
103         lldb::ValueObjectSP
104         CreateValueObjectFromExpression (const char* name,
105                                          const char* expression,
106                                          const ExecutionContext& exe_ctx);
107         
108         lldb::ValueObjectSP
109         CreateValueObjectFromAddress (const char* name,
110                                       uint64_t address,
111                                       const ExecutionContext& exe_ctx,
112                                       CompilerType type);
113         
114         lldb::ValueObjectSP
115         CreateValueObjectFromData (const char* name,
116                                    const DataExtractor& data,
117                                    const ExecutionContext& exe_ctx,
118                                    CompilerType type);
119         
120     private:
121         bool m_valid;
122         DISALLOW_COPY_AND_ASSIGN(SyntheticChildrenFrontEnd);
123     };
124     
125     class SyntheticValueProviderFrontEnd : public SyntheticChildrenFrontEnd
126     {
127     public:
128         SyntheticValueProviderFrontEnd (ValueObject &backend) :
129         SyntheticChildrenFrontEnd(backend)
130         {}
131
132         ~SyntheticValueProviderFrontEnd() override = default;
133
134         size_t
135         CalculateNumChildren() override { return 0; }
136         
137         lldb::ValueObjectSP
138         GetChildAtIndex(size_t idx) override { return nullptr; }
139         
140         size_t
141         GetIndexOfChildWithName(const ConstString &name) override { return UINT32_MAX; }
142         
143         bool
144         Update() override { return false; }
145         
146         bool
147         MightHaveChildren () override { return false; }
148         
149         lldb::ValueObjectSP
150         GetSyntheticValue() override = 0;
151         
152     private:
153         DISALLOW_COPY_AND_ASSIGN(SyntheticValueProviderFrontEnd);
154     };
155     
156     class SyntheticChildren
157     {
158     public:
159         class Flags
160         {
161         public:
162             
163             Flags () :
164             m_flags (lldb::eTypeOptionCascade)
165             {}
166             
167             Flags (const Flags& other) :
168             m_flags (other.m_flags)
169             {}
170             
171             Flags (uint32_t value) :
172             m_flags (value)
173             {}
174             
175             Flags&
176             operator = (const Flags& rhs)
177             {
178                 if (&rhs != this)
179                     m_flags = rhs.m_flags;
180                 
181                 return *this;
182             }
183             
184             Flags&
185             operator = (const uint32_t& rhs)
186             {
187                 m_flags = rhs;
188                 return *this;
189             }
190             
191             Flags&
192             Clear()
193             {
194                 m_flags = 0;
195                 return *this;
196             }
197             
198             bool
199             GetCascades () const
200             {
201                 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
202             }
203             
204             Flags&
205             SetCascades (bool value = true)
206             {
207                 if (value)
208                     m_flags |= lldb::eTypeOptionCascade;
209                 else
210                     m_flags &= ~lldb::eTypeOptionCascade;
211                 return *this;
212             }
213             
214             bool
215             GetSkipPointers () const
216             {
217                 return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
218             }
219             
220             Flags&
221             SetSkipPointers (bool value = true)
222             {
223                 if (value)
224                     m_flags |= lldb::eTypeOptionSkipPointers;
225                 else
226                     m_flags &= ~lldb::eTypeOptionSkipPointers;
227                 return *this;
228             }
229             
230             bool
231             GetSkipReferences () const
232             {
233                 return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
234             }
235             
236             Flags&
237             SetSkipReferences (bool value = true)
238             {
239                 if (value)
240                     m_flags |= lldb::eTypeOptionSkipReferences;
241                 else
242                     m_flags &= ~lldb::eTypeOptionSkipReferences;
243                 return *this;
244             }
245             
246             bool
247             GetNonCacheable () const
248             {
249                 return (m_flags & lldb::eTypeOptionNonCacheable) == lldb::eTypeOptionNonCacheable;
250             }
251             
252             Flags&
253             SetNonCacheable (bool value = true)
254             {
255                 if (value)
256                     m_flags |= lldb::eTypeOptionNonCacheable;
257                 else
258                     m_flags &= ~lldb::eTypeOptionNonCacheable;
259                 return *this;
260             }
261             
262             uint32_t
263             GetValue ()
264             {
265                 return m_flags;
266             }
267             
268             void
269             SetValue (uint32_t value)
270             {
271                 m_flags = value;
272             }
273             
274         private:
275             uint32_t m_flags;
276         };
277         
278         SyntheticChildren (const Flags& flags) :
279         m_flags(flags)
280         {
281         }
282
283         virtual
284         ~SyntheticChildren() = default;
285
286         bool
287         Cascades () const
288         {
289             return m_flags.GetCascades();
290         }
291
292         bool
293         SkipsPointers () const
294         {
295             return m_flags.GetSkipPointers();
296         }
297
298         bool
299         SkipsReferences () const
300         {
301             return m_flags.GetSkipReferences();
302         }
303
304         bool
305         NonCacheable () const
306         {
307             return m_flags.GetNonCacheable();
308         }
309         
310         void
311         SetCascades (bool value)
312         {
313             m_flags.SetCascades(value);
314         }
315         
316         void
317         SetSkipsPointers (bool value)
318         {
319             m_flags.SetSkipPointers(value);
320         }
321         
322         void
323         SetSkipsReferences (bool value)
324         {
325             m_flags.SetSkipReferences(value);
326         }
327         
328         void
329         SetNonCacheable (bool value)
330         {
331             m_flags.SetNonCacheable(value);
332         }
333         
334         uint32_t
335         GetOptions ()
336         {
337             return m_flags.GetValue();
338         }
339         
340         void
341         SetOptions (uint32_t value)
342         {
343             m_flags.SetValue(value);
344         }
345         
346         virtual bool
347         IsScripted () = 0;
348         
349         virtual std::string
350         GetDescription () = 0;
351         
352         virtual SyntheticChildrenFrontEnd::AutoPointer
353         GetFrontEnd (ValueObject &backend) = 0;
354         
355         typedef std::shared_ptr<SyntheticChildren> SharedPointer;
356         
357         uint32_t&
358         GetRevision ()
359         {
360             return m_my_revision;
361         }
362         
363     protected:
364         uint32_t m_my_revision;
365         Flags m_flags;
366         
367     private:
368         DISALLOW_COPY_AND_ASSIGN(SyntheticChildren);
369     };
370     
371     class TypeFilterImpl : public SyntheticChildren
372     {
373         std::vector<std::string> m_expression_paths;
374     public:
375         TypeFilterImpl(const SyntheticChildren::Flags& flags) :
376         SyntheticChildren(flags),
377         m_expression_paths()
378         {
379         }
380
381         TypeFilterImpl(const SyntheticChildren::Flags& flags,
382                        const std::initializer_list<const char*> items) :
383         SyntheticChildren(flags),
384         m_expression_paths()
385         {
386             for (auto path : items)
387                 AddExpressionPath (path);
388         }
389         
390         void
391         AddExpressionPath (const char* path)
392         {
393             AddExpressionPath(std::string(path));
394         }
395         
396         void
397         Clear()
398         {
399             m_expression_paths.clear();
400         }
401         
402         size_t
403         GetCount() const
404         {
405             return m_expression_paths.size();
406         }
407         
408         const char*
409         GetExpressionPathAtIndex(size_t i) const
410         {
411             return m_expression_paths[i].c_str();
412         }
413         
414         bool
415         SetExpressionPathAtIndex (size_t i, const char* path)
416         {
417             return SetExpressionPathAtIndex(i, std::string(path));
418         }
419         
420         void
421         AddExpressionPath (const std::string& path);
422         
423         bool
424         SetExpressionPathAtIndex (size_t i, const std::string& path);
425         
426         bool
427         IsScripted() override
428         {
429             return false;
430         }
431         
432         std::string
433         GetDescription() override;
434         
435         class FrontEnd : public SyntheticChildrenFrontEnd
436         {
437         public:
438             FrontEnd(TypeFilterImpl* flt,
439                      ValueObject &backend) :
440             SyntheticChildrenFrontEnd(backend),
441             filter(flt)
442             {}
443
444             ~FrontEnd() override = default;
445
446             size_t
447             CalculateNumChildren() override
448             {
449                 return filter->GetCount();
450             }
451             
452             lldb::ValueObjectSP
453             GetChildAtIndex(size_t idx) override
454             {
455                 if (idx >= filter->GetCount())
456                     return lldb::ValueObjectSP();
457                 return m_backend.GetSyntheticExpressionPathChild(filter->GetExpressionPathAtIndex(idx), true);
458             }
459
460             bool
461             Update() override { return false; }
462             
463             bool
464             MightHaveChildren() override
465             {
466                 return filter->GetCount() > 0;
467             }
468             
469             size_t
470             GetIndexOfChildWithName(const ConstString &name) override;
471             
472             typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
473             
474         private:
475             TypeFilterImpl* filter;
476
477             DISALLOW_COPY_AND_ASSIGN(FrontEnd);
478         };
479         
480         SyntheticChildrenFrontEnd::AutoPointer
481         GetFrontEnd(ValueObject &backend) override
482         {
483             return SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(this, backend));
484         }
485         
486         typedef std::shared_ptr<TypeFilterImpl> SharedPointer;
487         
488     private:
489         DISALLOW_COPY_AND_ASSIGN(TypeFilterImpl);
490     };
491     
492     class CXXSyntheticChildren : public SyntheticChildren
493     {
494     public:
495         typedef std::function<SyntheticChildrenFrontEnd*(CXXSyntheticChildren*, lldb::ValueObjectSP)> CreateFrontEndCallback;
496         CXXSyntheticChildren (const SyntheticChildren::Flags& flags,
497                               const char* description,
498                               CreateFrontEndCallback callback) :
499         SyntheticChildren(flags),
500         m_create_callback(callback),
501         m_description(description ? description : "")
502         {
503         }
504         
505         bool
506         IsScripted() override
507         {
508             return false;
509         }
510         
511         std::string
512         GetDescription() override;
513         
514         SyntheticChildrenFrontEnd::AutoPointer
515         GetFrontEnd(ValueObject &backend) override
516         {
517             return SyntheticChildrenFrontEnd::AutoPointer(m_create_callback(this, backend.GetSP()));
518         }
519         
520     protected:
521         CreateFrontEndCallback m_create_callback;
522         std::string m_description;
523
524     private:
525         DISALLOW_COPY_AND_ASSIGN(CXXSyntheticChildren);
526     };
527     
528 #ifndef LLDB_DISABLE_PYTHON
529     
530     class ScriptedSyntheticChildren : public SyntheticChildren
531     {
532         std::string m_python_class;
533         std::string m_python_code;
534     public:
535         
536         ScriptedSyntheticChildren(const SyntheticChildren::Flags& flags,
537                                   const char* pclass,
538                                   const char* pcode = nullptr) :
539         SyntheticChildren(flags),
540         m_python_class(),
541         m_python_code()
542         {
543             if (pclass)
544                 m_python_class = pclass;
545             if (pcode)
546                 m_python_code = pcode;
547         }
548         
549         const char*
550         GetPythonClassName ()
551         {
552             return m_python_class.c_str();
553         }
554         
555         const char*
556         GetPythonCode ()
557         {
558             return m_python_code.c_str();
559         }
560         
561         void
562         SetPythonClassName (const char* fname)
563         {
564             m_python_class.assign(fname);
565             m_python_code.clear();
566         }
567         
568         void
569         SetPythonCode (const char* script)
570         {
571             m_python_code.assign(script);
572         }
573         
574         std::string
575         GetDescription() override;
576         
577         bool
578         IsScripted() override
579         {
580             return true;
581         }
582         
583         class FrontEnd : public SyntheticChildrenFrontEnd
584         {
585         public:
586             FrontEnd (std::string pclass,
587                       ValueObject &backend);
588             
589             ~FrontEnd() override;
590
591             bool
592             IsValid ();
593             
594             size_t
595             CalculateNumChildren() override;
596
597             size_t
598             CalculateNumChildren(uint32_t max) override;
599             
600             lldb::ValueObjectSP
601             GetChildAtIndex(size_t idx) override;
602
603             bool
604             Update() override;
605             
606             bool
607             MightHaveChildren() override;
608             
609             size_t
610             GetIndexOfChildWithName(const ConstString &name) override;
611             
612             lldb::ValueObjectSP
613             GetSyntheticValue() override;
614             
615             ConstString
616             GetSyntheticTypeName () override;
617
618             typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer;
619             
620         private:
621             std::string m_python_class;
622             StructuredData::ObjectSP m_wrapper_sp;
623             ScriptInterpreter *m_interpreter;
624
625             DISALLOW_COPY_AND_ASSIGN(FrontEnd);
626         };
627         
628         SyntheticChildrenFrontEnd::AutoPointer
629         GetFrontEnd(ValueObject &backend) override
630         {
631             auto synth_ptr = SyntheticChildrenFrontEnd::AutoPointer(new FrontEnd(m_python_class, backend));
632             if (synth_ptr && ((FrontEnd*)synth_ptr.get())->IsValid())
633                 return synth_ptr;
634             return nullptr;
635         }
636         
637     private:
638         DISALLOW_COPY_AND_ASSIGN(ScriptedSyntheticChildren);
639     };
640 #endif
641 } // namespace lldb_private
642
643 #endif // lldb_TypeSynthetic_h_