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