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
31namespace lldb_private {
32
33    class TypeSummaryImpl
34    {
35    public:
36        class Flags
37        {
38        public:
39
40            Flags () :
41            m_flags (lldb::eTypeOptionCascade)
42            {}
43
44            Flags (const Flags& other) :
45            m_flags (other.m_flags)
46            {}
47
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&
69            Clear()
70            {
71                m_flags = 0;
72                return *this;
73            }
74
75            bool
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
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
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
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
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
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
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
188            GetValue ()
189            {
190                return m_flags;
191            }
192
193            void
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
214        Cascades () const
215        {
216            return m_flags.GetCascades();
217        }
218        bool
219        SkipsPointers () const
220        {
221            return m_flags.GetSkipPointers();
222        }
223        bool
224        SkipsReferences () const
225        {
226            return m_flags.GetSkipReferences();
227        }
228
229        bool
230        DoesPrintChildren () const
231        {
232            return !m_flags.GetDontShowChildren();
233        }
234
235        bool
236        DoesPrintValue () const
237        {
238            return !m_flags.GetDontShowValue();
239        }
240
241        bool
242        IsOneliner () const
243        {
244            return m_flags.GetShowMembersOneLiner();
245        }
246
247        bool
248        HideNames () const
249        {
250            return m_flags.GetHideItemNames();
251        }
252
253        void
254        SetCascades (bool value)
255        {
256            m_flags.SetCascades(value);
257        }
258
259        void
260        SetSkipsPointers (bool value)
261        {
262            m_flags.SetSkipPointers(value);
263        }
264
265        void
266        SetSkipsReferences (bool value)
267        {
268            m_flags.SetSkipReferences(value);
269        }
270
271        void
272        SetDoesPrintChildren (bool value)
273        {
274            m_flags.SetDontShowChildren(!value);
275        }
276
277        void
278        SetDoesPrintValue (bool value)
279        {
280            m_flags.SetDontShowValue(!value);
281        }
282
283        void
284        SetIsOneliner (bool value)
285        {
286            m_flags.SetShowMembersOneLiner(value);
287        }
288
289        void
290        SetHideNames (bool value)
291        {
292            m_flags.SetHideItemNames(value);
293        }
294
295        uint32_t
296        GetOptions ()
297        {
298            return m_flags.GetValue();
299        }
300
301        void
302        SetOptions (uint32_t value)
303        {
304            m_flags.SetValue(value);
305        }
306
307        virtual
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&
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*
355        GetSummaryString () const
356        {
357            return m_format.c_str();
358        }
359
360        void
361        SetSummaryString (const char* data)
362        {
363            if (data)
364                m_format.assign(data);
365            else
366                m_format.clear();
367        }
368
369        virtual
370        ~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
382        IsScripted ()
383        {
384            return false;
385        }
386
387
388        virtual Type
389        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
414        GetBackendFunction () const
415        {
416            return m_impl;
417        }
418
419        const char*
420        GetTextualInfo () const
421        {
422            return m_description.c_str();
423        }
424
425        void
426        SetBackendFunction (Callback cb_func)
427        {
428            m_impl = cb_func;
429        }
430
431        void
432        SetTextualInfo (const char* descr)
433        {
434            if (descr)
435                m_description.assign(descr);
436            else
437                m_description.clear();
438        }
439
440        virtual
441        ~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
453        IsScripted ()
454        {
455            return false;
456        }
457
458        virtual Type
459        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*
484        GetFunctionName () const
485        {
486            return m_function_name.c_str();
487        }
488
489        const char*
490        GetPythonScript () const
491        {
492            return m_python_script.c_str();
493        }
494
495        void
496        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
506        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
515        ~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
527        IsScripted ()
528        {
529            return true;
530        }
531
532        virtual Type
533        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