1 //===-- TypeSummary.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_TypeSummary_h_
11 #define lldb_TypeSummary_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 
33     class TypeSummaryImpl
34     {
35     public:
36         class Flags
37         {
38         public:
39 
Flags()40             Flags () :
41             m_flags (lldb::eTypeOptionCascade)
42             {}
43 
Flags(const Flags & other)44             Flags (const Flags& other) :
45             m_flags (other.m_flags)
46             {}
47 
Flags(uint32_t value)48             Flags (uint32_t value) :
49             m_flags (value)
50             {}
51 
52             Flags&
53             operator = (const Flags& rhs)
54             {
55                 if (&rhs != this)
56                     m_flags = rhs.m_flags;
57 
58                 return *this;
59             }
60 
61             Flags&
62             operator = (const uint32_t& rhs)
63             {
64                 m_flags = rhs;
65                 return *this;
66             }
67 
68             Flags&
Clear()69             Clear()
70             {
71                 m_flags = 0;
72                 return *this;
73             }
74 
75             bool
GetCascades()76             GetCascades () const
77             {
78                 return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
79             }
80 
81             Flags&
82             SetCascades (bool value = true)
83             {
84                 if (value)
85                     m_flags |= lldb::eTypeOptionCascade;
86                 else
87                     m_flags &= ~lldb::eTypeOptionCascade;
88                 return *this;
89             }
90 
91             bool
GetSkipPointers()92             GetSkipPointers () const
93             {
94                 return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
95             }
96 
97             Flags&
98             SetSkipPointers (bool value = true)
99             {
100                 if (value)
101                     m_flags |= lldb::eTypeOptionSkipPointers;
102                 else
103                     m_flags &= ~lldb::eTypeOptionSkipPointers;
104                 return *this;
105             }
106 
107             bool
GetSkipReferences()108             GetSkipReferences () const
109             {
110                 return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
111             }
112 
113             Flags&
114             SetSkipReferences (bool value = true)
115             {
116                 if (value)
117                     m_flags |= lldb::eTypeOptionSkipReferences;
118                 else
119                     m_flags &= ~lldb::eTypeOptionSkipReferences;
120                 return *this;
121             }
122 
123             bool
GetDontShowChildren()124             GetDontShowChildren () const
125             {
126                 return (m_flags & lldb::eTypeOptionHideChildren) == lldb::eTypeOptionHideChildren;
127             }
128 
129             Flags&
130             SetDontShowChildren (bool value = true)
131             {
132                 if (value)
133                     m_flags |= lldb::eTypeOptionHideChildren;
134                 else
135                     m_flags &= ~lldb::eTypeOptionHideChildren;
136                 return *this;
137             }
138 
139             bool
GetDontShowValue()140             GetDontShowValue () const
141             {
142                 return (m_flags & lldb::eTypeOptionHideValue) == lldb::eTypeOptionHideValue;
143             }
144 
145             Flags&
146             SetDontShowValue (bool value = true)
147             {
148                 if (value)
149                     m_flags |= lldb::eTypeOptionHideValue;
150                 else
151                     m_flags &= ~lldb::eTypeOptionHideValue;
152                 return *this;
153             }
154 
155             bool
GetShowMembersOneLiner()156             GetShowMembersOneLiner () const
157             {
158                 return (m_flags & lldb::eTypeOptionShowOneLiner) == lldb::eTypeOptionShowOneLiner;
159             }
160 
161             Flags&
162             SetShowMembersOneLiner (bool value = true)
163             {
164                 if (value)
165                     m_flags |= lldb::eTypeOptionShowOneLiner;
166                 else
167                     m_flags &= ~lldb::eTypeOptionShowOneLiner;
168                 return *this;
169             }
170 
171             bool
GetHideItemNames()172             GetHideItemNames () const
173             {
174                 return (m_flags & lldb::eTypeOptionHideNames) == lldb::eTypeOptionHideNames;
175             }
176 
177             Flags&
178             SetHideItemNames (bool value = true)
179             {
180                 if (value)
181                     m_flags |= lldb::eTypeOptionHideNames;
182                 else
183                     m_flags &= ~lldb::eTypeOptionHideNames;
184                 return *this;
185             }
186 
187             uint32_t
GetValue()188             GetValue ()
189             {
190                 return m_flags;
191             }
192 
193             void
SetValue(uint32_t value)194             SetValue (uint32_t value)
195             {
196                 m_flags = value;
197             }
198 
199         private:
200             uint32_t m_flags;
201         };
202 
203         typedef enum Type
204         {
205             eTypeUnknown,
206             eTypeString,
207             eTypeScript,
208             eTypeCallback
209         } Type;
210 
211         TypeSummaryImpl (const TypeSummaryImpl::Flags& flags);
212 
213         bool
Cascades()214         Cascades () const
215         {
216             return m_flags.GetCascades();
217         }
218         bool
SkipsPointers()219         SkipsPointers () const
220         {
221             return m_flags.GetSkipPointers();
222         }
223         bool
SkipsReferences()224         SkipsReferences () const
225         {
226             return m_flags.GetSkipReferences();
227         }
228 
229         bool
DoesPrintChildren()230         DoesPrintChildren () const
231         {
232             return !m_flags.GetDontShowChildren();
233         }
234 
235         bool
DoesPrintValue()236         DoesPrintValue () const
237         {
238             return !m_flags.GetDontShowValue();
239         }
240 
241         bool
IsOneliner()242         IsOneliner () const
243         {
244             return m_flags.GetShowMembersOneLiner();
245         }
246 
247         bool
HideNames()248         HideNames () const
249         {
250             return m_flags.GetHideItemNames();
251         }
252 
253         void
SetCascades(bool value)254         SetCascades (bool value)
255         {
256             m_flags.SetCascades(value);
257         }
258 
259         void
SetSkipsPointers(bool value)260         SetSkipsPointers (bool value)
261         {
262             m_flags.SetSkipPointers(value);
263         }
264 
265         void
SetSkipsReferences(bool value)266         SetSkipsReferences (bool value)
267         {
268             m_flags.SetSkipReferences(value);
269         }
270 
271         void
SetDoesPrintChildren(bool value)272         SetDoesPrintChildren (bool value)
273         {
274             m_flags.SetDontShowChildren(!value);
275         }
276 
277         void
SetDoesPrintValue(bool value)278         SetDoesPrintValue (bool value)
279         {
280             m_flags.SetDontShowValue(!value);
281         }
282 
283         void
SetIsOneliner(bool value)284         SetIsOneliner (bool value)
285         {
286             m_flags.SetShowMembersOneLiner(value);
287         }
288 
289         void
SetHideNames(bool value)290         SetHideNames (bool value)
291         {
292             m_flags.SetHideItemNames(value);
293         }
294 
295         uint32_t
GetOptions()296         GetOptions ()
297         {
298             return m_flags.GetValue();
299         }
300 
301         void
SetOptions(uint32_t value)302         SetOptions (uint32_t value)
303         {
304             m_flags.SetValue(value);
305         }
306 
307         virtual
~TypeSummaryImpl()308         ~TypeSummaryImpl ()
309         {
310         }
311 
312         // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
313         // extended periods of time and we trust the ValueObject to stay around for as long as it is required
314         // for us to generate its summary
315         virtual bool
316         FormatObject (ValueObject *valobj,
317                       std::string& dest) = 0;
318 
319         virtual std::string
320         GetDescription () = 0;
321 
322         virtual bool
323         IsScripted () = 0;
324 
325         virtual Type
326         GetType () = 0;
327 
328         uint32_t&
GetRevision()329         GetRevision ()
330         {
331             return m_my_revision;
332         }
333 
334         typedef std::shared_ptr<TypeSummaryImpl> SharedPointer;
335         typedef bool(*SummaryCallback)(void*, ConstString, const lldb::TypeSummaryImplSP&);
336         typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const lldb::TypeSummaryImplSP&);
337 
338     protected:
339         uint32_t m_my_revision;
340         Flags m_flags;
341 
342     private:
343         DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl);
344     };
345 
346     // simple string-based summaries, using ${var to show data
347     struct StringSummaryFormat : public TypeSummaryImpl
348     {
349         std::string m_format;
350 
351         StringSummaryFormat(const TypeSummaryImpl::Flags& flags,
352                             const char* f);
353 
354         const char*
GetSummaryStringStringSummaryFormat355         GetSummaryString () const
356         {
357             return m_format.c_str();
358         }
359 
360         void
SetSummaryStringStringSummaryFormat361         SetSummaryString (const char* data)
362         {
363             if (data)
364                 m_format.assign(data);
365             else
366                 m_format.clear();
367         }
368 
369         virtual
~StringSummaryFormatStringSummaryFormat370         ~StringSummaryFormat()
371         {
372         }
373 
374         virtual bool
375         FormatObject(ValueObject *valobj,
376                      std::string& dest);
377 
378         virtual std::string
379         GetDescription();
380 
381         virtual bool
IsScriptedStringSummaryFormat382         IsScripted ()
383         {
384             return false;
385         }
386 
387 
388         virtual Type
GetTypeStringSummaryFormat389         GetType ()
390         {
391             return TypeSummaryImpl::eTypeString;
392         }
393 
394     private:
395         DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
396     };
397 
398     // summaries implemented via a C++ function
399     struct CXXFunctionSummaryFormat : public TypeSummaryImpl
400     {
401 
402         // we should convert these to SBValue and SBStream if we ever cross
403         // the boundary towards the external world
404         typedef bool (*Callback)(ValueObject& valobj, Stream& dest);
405 
406         Callback m_impl;
407         std::string m_description;
408 
409         CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
410                                   Callback impl,
411                                   const char* description);
412 
413         Callback
GetBackendFunctionCXXFunctionSummaryFormat414         GetBackendFunction () const
415         {
416             return m_impl;
417         }
418 
419         const char*
GetTextualInfoCXXFunctionSummaryFormat420         GetTextualInfo () const
421         {
422             return m_description.c_str();
423         }
424 
425         void
SetBackendFunctionCXXFunctionSummaryFormat426         SetBackendFunction (Callback cb_func)
427         {
428             m_impl = cb_func;
429         }
430 
431         void
SetTextualInfoCXXFunctionSummaryFormat432         SetTextualInfo (const char* descr)
433         {
434             if (descr)
435                 m_description.assign(descr);
436             else
437                 m_description.clear();
438         }
439 
440         virtual
~CXXFunctionSummaryFormatCXXFunctionSummaryFormat441         ~CXXFunctionSummaryFormat ()
442         {
443         }
444 
445         virtual bool
446         FormatObject (ValueObject *valobj,
447                       std::string& dest);
448 
449         virtual std::string
450         GetDescription ();
451 
452         virtual bool
IsScriptedCXXFunctionSummaryFormat453         IsScripted ()
454         {
455             return false;
456         }
457 
458         virtual Type
GetTypeCXXFunctionSummaryFormat459         GetType ()
460         {
461             return TypeSummaryImpl::eTypeCallback;
462         }
463 
464         typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer;
465 
466     private:
467         DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat);
468     };
469 
470 #ifndef LLDB_DISABLE_PYTHON
471 
472     // Python-based summaries, running script code to show data
473     struct ScriptSummaryFormat : public TypeSummaryImpl
474     {
475         std::string m_function_name;
476         std::string m_python_script;
477         lldb::ScriptInterpreterObjectSP m_script_function_sp;
478 
479         ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags,
480                             const char *function_name,
481                             const char* python_script = NULL);
482 
483         const char*
GetFunctionNameScriptSummaryFormat484         GetFunctionName () const
485         {
486             return m_function_name.c_str();
487         }
488 
489         const char*
GetPythonScriptScriptSummaryFormat490         GetPythonScript () const
491         {
492             return m_python_script.c_str();
493         }
494 
495         void
SetFunctionNameScriptSummaryFormat496         SetFunctionName (const char* function_name)
497         {
498             if (function_name)
499                 m_function_name.assign(function_name);
500             else
501                 m_function_name.clear();
502             m_python_script.clear();
503         }
504 
505         void
SetPythonScriptScriptSummaryFormat506         SetPythonScript (const char* script)
507         {
508             if (script)
509                 m_python_script.assign(script);
510             else
511                 m_python_script.clear();
512         }
513 
514         virtual
~ScriptSummaryFormatScriptSummaryFormat515         ~ScriptSummaryFormat ()
516         {
517         }
518 
519         virtual bool
520         FormatObject (ValueObject *valobj,
521                       std::string& dest);
522 
523         virtual std::string
524         GetDescription ();
525 
526         virtual bool
IsScriptedScriptSummaryFormat527         IsScripted ()
528         {
529             return true;
530         }
531 
532         virtual Type
GetTypeScriptSummaryFormat533         GetType ()
534         {
535             return TypeSummaryImpl::eTypeScript;
536         }
537 
538         typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer;
539 
540 
541     private:
542         DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat);
543     };
544 #endif
545 } // namespace lldb_private
546 
547 #endif	// lldb_TypeSummary_h_
548