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