1254721Semaste//===-- TypeSummary.h --------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef lldb_TypeSummary_h_
11254721Semaste#define lldb_TypeSummary_h_
12254721Semaste
13254721Semaste// C Includes
14254721Semaste#include <stdint.h>
15254721Semaste#include <unistd.h>
16254721Semaste
17254721Semaste// C++ Includes
18254721Semaste#include <string>
19254721Semaste#include <vector>
20254721Semaste
21254721Semaste// Other libraries and framework includes
22254721Semaste
23254721Semaste// Project includes
24254721Semaste#include "lldb/lldb-public.h"
25254721Semaste#include "lldb/lldb-enumerations.h"
26254721Semaste
27254721Semaste#include "lldb/Core/ValueObject.h"
28254721Semaste#include "lldb/Interpreter/ScriptInterpreterPython.h"
29254721Semaste#include "lldb/Symbol/Type.h"
30254721Semaste
31254721Semastenamespace lldb_private {
32254721Semaste
33254721Semaste    class TypeSummaryImpl
34254721Semaste    {
35254721Semaste    public:
36254721Semaste        class Flags
37254721Semaste        {
38254721Semaste        public:
39254721Semaste
40254721Semaste            Flags () :
41254721Semaste            m_flags (lldb::eTypeOptionCascade)
42254721Semaste            {}
43254721Semaste
44254721Semaste            Flags (const Flags& other) :
45254721Semaste            m_flags (other.m_flags)
46254721Semaste            {}
47254721Semaste
48254721Semaste            Flags (uint32_t value) :
49254721Semaste            m_flags (value)
50254721Semaste            {}
51254721Semaste
52254721Semaste            Flags&
53254721Semaste            operator = (const Flags& rhs)
54254721Semaste            {
55254721Semaste                if (&rhs != this)
56254721Semaste                    m_flags = rhs.m_flags;
57254721Semaste
58254721Semaste                return *this;
59254721Semaste            }
60254721Semaste
61254721Semaste            Flags&
62254721Semaste            operator = (const uint32_t& rhs)
63254721Semaste            {
64254721Semaste                m_flags = rhs;
65254721Semaste                return *this;
66254721Semaste            }
67254721Semaste
68254721Semaste            Flags&
69254721Semaste            Clear()
70254721Semaste            {
71254721Semaste                m_flags = 0;
72254721Semaste                return *this;
73254721Semaste            }
74254721Semaste
75254721Semaste            bool
76254721Semaste            GetCascades () const
77254721Semaste            {
78254721Semaste                return (m_flags & lldb::eTypeOptionCascade) == lldb::eTypeOptionCascade;
79254721Semaste            }
80254721Semaste
81254721Semaste            Flags&
82254721Semaste            SetCascades (bool value = true)
83254721Semaste            {
84254721Semaste                if (value)
85254721Semaste                    m_flags |= lldb::eTypeOptionCascade;
86254721Semaste                else
87254721Semaste                    m_flags &= ~lldb::eTypeOptionCascade;
88254721Semaste                return *this;
89254721Semaste            }
90254721Semaste
91254721Semaste            bool
92254721Semaste            GetSkipPointers () const
93254721Semaste            {
94254721Semaste                return (m_flags & lldb::eTypeOptionSkipPointers) == lldb::eTypeOptionSkipPointers;
95254721Semaste            }
96254721Semaste
97254721Semaste            Flags&
98254721Semaste            SetSkipPointers (bool value = true)
99254721Semaste            {
100254721Semaste                if (value)
101254721Semaste                    m_flags |= lldb::eTypeOptionSkipPointers;
102254721Semaste                else
103254721Semaste                    m_flags &= ~lldb::eTypeOptionSkipPointers;
104254721Semaste                return *this;
105254721Semaste            }
106254721Semaste
107254721Semaste            bool
108254721Semaste            GetSkipReferences () const
109254721Semaste            {
110254721Semaste                return (m_flags & lldb::eTypeOptionSkipReferences) == lldb::eTypeOptionSkipReferences;
111254721Semaste            }
112254721Semaste
113254721Semaste            Flags&
114254721Semaste            SetSkipReferences (bool value = true)
115254721Semaste            {
116254721Semaste                if (value)
117254721Semaste                    m_flags |= lldb::eTypeOptionSkipReferences;
118254721Semaste                else
119254721Semaste                    m_flags &= ~lldb::eTypeOptionSkipReferences;
120254721Semaste                return *this;
121254721Semaste            }
122254721Semaste
123254721Semaste            bool
124254721Semaste            GetDontShowChildren () const
125254721Semaste            {
126254721Semaste                return (m_flags & lldb::eTypeOptionHideChildren) == lldb::eTypeOptionHideChildren;
127254721Semaste            }
128254721Semaste
129254721Semaste            Flags&
130254721Semaste            SetDontShowChildren (bool value = true)
131254721Semaste            {
132254721Semaste                if (value)
133254721Semaste                    m_flags |= lldb::eTypeOptionHideChildren;
134254721Semaste                else
135254721Semaste                    m_flags &= ~lldb::eTypeOptionHideChildren;
136254721Semaste                return *this;
137254721Semaste            }
138254721Semaste
139254721Semaste            bool
140254721Semaste            GetDontShowValue () const
141254721Semaste            {
142254721Semaste                return (m_flags & lldb::eTypeOptionHideValue) == lldb::eTypeOptionHideValue;
143254721Semaste            }
144254721Semaste
145254721Semaste            Flags&
146254721Semaste            SetDontShowValue (bool value = true)
147254721Semaste            {
148254721Semaste                if (value)
149254721Semaste                    m_flags |= lldb::eTypeOptionHideValue;
150254721Semaste                else
151254721Semaste                    m_flags &= ~lldb::eTypeOptionHideValue;
152254721Semaste                return *this;
153254721Semaste            }
154254721Semaste
155254721Semaste            bool
156254721Semaste            GetShowMembersOneLiner () const
157254721Semaste            {
158254721Semaste                return (m_flags & lldb::eTypeOptionShowOneLiner) == lldb::eTypeOptionShowOneLiner;
159254721Semaste            }
160254721Semaste
161254721Semaste            Flags&
162254721Semaste            SetShowMembersOneLiner (bool value = true)
163254721Semaste            {
164254721Semaste                if (value)
165254721Semaste                    m_flags |= lldb::eTypeOptionShowOneLiner;
166254721Semaste                else
167254721Semaste                    m_flags &= ~lldb::eTypeOptionShowOneLiner;
168254721Semaste                return *this;
169254721Semaste            }
170254721Semaste
171254721Semaste            bool
172254721Semaste            GetHideItemNames () const
173254721Semaste            {
174254721Semaste                return (m_flags & lldb::eTypeOptionHideNames) == lldb::eTypeOptionHideNames;
175254721Semaste            }
176254721Semaste
177254721Semaste            Flags&
178254721Semaste            SetHideItemNames (bool value = true)
179254721Semaste            {
180254721Semaste                if (value)
181254721Semaste                    m_flags |= lldb::eTypeOptionHideNames;
182254721Semaste                else
183254721Semaste                    m_flags &= ~lldb::eTypeOptionHideNames;
184254721Semaste                return *this;
185254721Semaste            }
186254721Semaste
187254721Semaste            uint32_t
188254721Semaste            GetValue ()
189254721Semaste            {
190254721Semaste                return m_flags;
191254721Semaste            }
192254721Semaste
193254721Semaste            void
194254721Semaste            SetValue (uint32_t value)
195254721Semaste            {
196254721Semaste                m_flags = value;
197254721Semaste            }
198254721Semaste
199254721Semaste        private:
200254721Semaste            uint32_t m_flags;
201254721Semaste        };
202254721Semaste
203254721Semaste        typedef enum Type
204254721Semaste        {
205254721Semaste            eTypeUnknown,
206254721Semaste            eTypeString,
207254721Semaste            eTypeScript,
208254721Semaste            eTypeCallback
209254721Semaste        } Type;
210254721Semaste
211254721Semaste        TypeSummaryImpl (const TypeSummaryImpl::Flags& flags);
212254721Semaste
213254721Semaste        bool
214254721Semaste        Cascades () const
215254721Semaste        {
216254721Semaste            return m_flags.GetCascades();
217254721Semaste        }
218254721Semaste        bool
219254721Semaste        SkipsPointers () const
220254721Semaste        {
221254721Semaste            return m_flags.GetSkipPointers();
222254721Semaste        }
223254721Semaste        bool
224254721Semaste        SkipsReferences () const
225254721Semaste        {
226254721Semaste            return m_flags.GetSkipReferences();
227254721Semaste        }
228254721Semaste
229254721Semaste        bool
230254721Semaste        DoesPrintChildren () const
231254721Semaste        {
232254721Semaste            return !m_flags.GetDontShowChildren();
233254721Semaste        }
234254721Semaste
235254721Semaste        bool
236254721Semaste        DoesPrintValue () const
237254721Semaste        {
238254721Semaste            return !m_flags.GetDontShowValue();
239254721Semaste        }
240254721Semaste
241254721Semaste        bool
242254721Semaste        IsOneliner () const
243254721Semaste        {
244254721Semaste            return m_flags.GetShowMembersOneLiner();
245254721Semaste        }
246254721Semaste
247254721Semaste        bool
248254721Semaste        HideNames () const
249254721Semaste        {
250254721Semaste            return m_flags.GetHideItemNames();
251254721Semaste        }
252254721Semaste
253254721Semaste        void
254254721Semaste        SetCascades (bool value)
255254721Semaste        {
256254721Semaste            m_flags.SetCascades(value);
257254721Semaste        }
258254721Semaste
259254721Semaste        void
260254721Semaste        SetSkipsPointers (bool value)
261254721Semaste        {
262254721Semaste            m_flags.SetSkipPointers(value);
263254721Semaste        }
264254721Semaste
265254721Semaste        void
266254721Semaste        SetSkipsReferences (bool value)
267254721Semaste        {
268254721Semaste            m_flags.SetSkipReferences(value);
269254721Semaste        }
270254721Semaste
271254721Semaste        void
272254721Semaste        SetDoesPrintChildren (bool value)
273254721Semaste        {
274254721Semaste            m_flags.SetDontShowChildren(!value);
275254721Semaste        }
276254721Semaste
277254721Semaste        void
278254721Semaste        SetDoesPrintValue (bool value)
279254721Semaste        {
280254721Semaste            m_flags.SetDontShowValue(!value);
281254721Semaste        }
282254721Semaste
283254721Semaste        void
284254721Semaste        SetIsOneliner (bool value)
285254721Semaste        {
286254721Semaste            m_flags.SetShowMembersOneLiner(value);
287254721Semaste        }
288254721Semaste
289254721Semaste        void
290254721Semaste        SetHideNames (bool value)
291254721Semaste        {
292254721Semaste            m_flags.SetHideItemNames(value);
293254721Semaste        }
294254721Semaste
295254721Semaste        uint32_t
296254721Semaste        GetOptions ()
297254721Semaste        {
298254721Semaste            return m_flags.GetValue();
299254721Semaste        }
300254721Semaste
301254721Semaste        void
302254721Semaste        SetOptions (uint32_t value)
303254721Semaste        {
304254721Semaste            m_flags.SetValue(value);
305254721Semaste        }
306254721Semaste
307254721Semaste        virtual
308254721Semaste        ~TypeSummaryImpl ()
309254721Semaste        {
310254721Semaste        }
311254721Semaste
312254721Semaste        // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
313254721Semaste        // extended periods of time and we trust the ValueObject to stay around for as long as it is required
314254721Semaste        // for us to generate its summary
315254721Semaste        virtual bool
316254721Semaste        FormatObject (ValueObject *valobj,
317254721Semaste                      std::string& dest) = 0;
318254721Semaste
319254721Semaste        virtual std::string
320254721Semaste        GetDescription () = 0;
321254721Semaste
322254721Semaste        virtual bool
323254721Semaste        IsScripted () = 0;
324254721Semaste
325254721Semaste        virtual Type
326254721Semaste        GetType () = 0;
327254721Semaste
328254721Semaste        uint32_t&
329254721Semaste        GetRevision ()
330254721Semaste        {
331254721Semaste            return m_my_revision;
332254721Semaste        }
333254721Semaste
334254721Semaste        typedef std::shared_ptr<TypeSummaryImpl> SharedPointer;
335254721Semaste        typedef bool(*SummaryCallback)(void*, ConstString, const lldb::TypeSummaryImplSP&);
336254721Semaste        typedef bool(*RegexSummaryCallback)(void*, lldb::RegularExpressionSP, const lldb::TypeSummaryImplSP&);
337254721Semaste
338254721Semaste    protected:
339254721Semaste        uint32_t m_my_revision;
340254721Semaste        Flags m_flags;
341254721Semaste
342254721Semaste    private:
343254721Semaste        DISALLOW_COPY_AND_ASSIGN(TypeSummaryImpl);
344254721Semaste    };
345254721Semaste
346254721Semaste    // simple string-based summaries, using ${var to show data
347254721Semaste    struct StringSummaryFormat : public TypeSummaryImpl
348254721Semaste    {
349254721Semaste        std::string m_format;
350254721Semaste
351254721Semaste        StringSummaryFormat(const TypeSummaryImpl::Flags& flags,
352254721Semaste                            const char* f);
353254721Semaste
354254721Semaste        const char*
355254721Semaste        GetSummaryString () const
356254721Semaste        {
357254721Semaste            return m_format.c_str();
358254721Semaste        }
359254721Semaste
360254721Semaste        void
361254721Semaste        SetSummaryString (const char* data)
362254721Semaste        {
363254721Semaste            if (data)
364254721Semaste                m_format.assign(data);
365254721Semaste            else
366254721Semaste                m_format.clear();
367254721Semaste        }
368254721Semaste
369254721Semaste        virtual
370254721Semaste        ~StringSummaryFormat()
371254721Semaste        {
372254721Semaste        }
373254721Semaste
374254721Semaste        virtual bool
375254721Semaste        FormatObject(ValueObject *valobj,
376254721Semaste                     std::string& dest);
377254721Semaste
378254721Semaste        virtual std::string
379254721Semaste        GetDescription();
380254721Semaste
381254721Semaste        virtual bool
382254721Semaste        IsScripted ()
383254721Semaste        {
384254721Semaste            return false;
385254721Semaste        }
386254721Semaste
387254721Semaste
388254721Semaste        virtual Type
389254721Semaste        GetType ()
390254721Semaste        {
391254721Semaste            return TypeSummaryImpl::eTypeString;
392254721Semaste        }
393254721Semaste
394254721Semaste    private:
395254721Semaste        DISALLOW_COPY_AND_ASSIGN(StringSummaryFormat);
396254721Semaste    };
397254721Semaste
398254721Semaste    // summaries implemented via a C++ function
399254721Semaste    struct CXXFunctionSummaryFormat : public TypeSummaryImpl
400254721Semaste    {
401254721Semaste
402254721Semaste        // we should convert these to SBValue and SBStream if we ever cross
403254721Semaste        // the boundary towards the external world
404254721Semaste        typedef bool (*Callback)(ValueObject& valobj, Stream& dest);
405254721Semaste
406254721Semaste        Callback m_impl;
407254721Semaste        std::string m_description;
408254721Semaste
409254721Semaste        CXXFunctionSummaryFormat (const TypeSummaryImpl::Flags& flags,
410254721Semaste                                  Callback impl,
411254721Semaste                                  const char* description);
412254721Semaste
413254721Semaste        Callback
414254721Semaste        GetBackendFunction () const
415254721Semaste        {
416254721Semaste            return m_impl;
417254721Semaste        }
418254721Semaste
419254721Semaste        const char*
420254721Semaste        GetTextualInfo () const
421254721Semaste        {
422254721Semaste            return m_description.c_str();
423254721Semaste        }
424254721Semaste
425254721Semaste        void
426254721Semaste        SetBackendFunction (Callback cb_func)
427254721Semaste        {
428254721Semaste            m_impl = cb_func;
429254721Semaste        }
430254721Semaste
431254721Semaste        void
432254721Semaste        SetTextualInfo (const char* descr)
433254721Semaste        {
434254721Semaste            if (descr)
435254721Semaste                m_description.assign(descr);
436254721Semaste            else
437254721Semaste                m_description.clear();
438254721Semaste        }
439254721Semaste
440254721Semaste        virtual
441254721Semaste        ~CXXFunctionSummaryFormat ()
442254721Semaste        {
443254721Semaste        }
444254721Semaste
445254721Semaste        virtual bool
446254721Semaste        FormatObject (ValueObject *valobj,
447254721Semaste                      std::string& dest);
448254721Semaste
449254721Semaste        virtual std::string
450254721Semaste        GetDescription ();
451254721Semaste
452254721Semaste        virtual bool
453254721Semaste        IsScripted ()
454254721Semaste        {
455254721Semaste            return false;
456254721Semaste        }
457254721Semaste
458254721Semaste        virtual Type
459254721Semaste        GetType ()
460254721Semaste        {
461254721Semaste            return TypeSummaryImpl::eTypeCallback;
462254721Semaste        }
463254721Semaste
464254721Semaste        typedef std::shared_ptr<CXXFunctionSummaryFormat> SharedPointer;
465254721Semaste
466254721Semaste    private:
467254721Semaste        DISALLOW_COPY_AND_ASSIGN(CXXFunctionSummaryFormat);
468254721Semaste    };
469254721Semaste
470254721Semaste#ifndef LLDB_DISABLE_PYTHON
471254721Semaste
472254721Semaste    // Python-based summaries, running script code to show data
473254721Semaste    struct ScriptSummaryFormat : public TypeSummaryImpl
474254721Semaste    {
475254721Semaste        std::string m_function_name;
476254721Semaste        std::string m_python_script;
477254721Semaste        lldb::ScriptInterpreterObjectSP m_script_function_sp;
478254721Semaste
479254721Semaste        ScriptSummaryFormat(const TypeSummaryImpl::Flags& flags,
480254721Semaste                            const char *function_name,
481254721Semaste                            const char* python_script = NULL);
482254721Semaste
483254721Semaste        const char*
484254721Semaste        GetFunctionName () const
485254721Semaste        {
486254721Semaste            return m_function_name.c_str();
487254721Semaste        }
488254721Semaste
489254721Semaste        const char*
490254721Semaste        GetPythonScript () const
491254721Semaste        {
492254721Semaste            return m_python_script.c_str();
493254721Semaste        }
494254721Semaste
495254721Semaste        void
496254721Semaste        SetFunctionName (const char* function_name)
497254721Semaste        {
498254721Semaste            if (function_name)
499254721Semaste                m_function_name.assign(function_name);
500254721Semaste            else
501254721Semaste                m_function_name.clear();
502254721Semaste            m_python_script.clear();
503254721Semaste        }
504254721Semaste
505254721Semaste        void
506254721Semaste        SetPythonScript (const char* script)
507254721Semaste        {
508254721Semaste            if (script)
509254721Semaste                m_python_script.assign(script);
510254721Semaste            else
511254721Semaste                m_python_script.clear();
512254721Semaste        }
513254721Semaste
514254721Semaste        virtual
515254721Semaste        ~ScriptSummaryFormat ()
516254721Semaste        {
517254721Semaste        }
518254721Semaste
519254721Semaste        virtual bool
520254721Semaste        FormatObject (ValueObject *valobj,
521254721Semaste                      std::string& dest);
522254721Semaste
523254721Semaste        virtual std::string
524254721Semaste        GetDescription ();
525254721Semaste
526254721Semaste        virtual bool
527254721Semaste        IsScripted ()
528254721Semaste        {
529254721Semaste            return true;
530254721Semaste        }
531254721Semaste
532254721Semaste        virtual Type
533254721Semaste        GetType ()
534254721Semaste        {
535254721Semaste            return TypeSummaryImpl::eTypeScript;
536254721Semaste        }
537254721Semaste
538254721Semaste        typedef std::shared_ptr<ScriptSummaryFormat> SharedPointer;
539254721Semaste
540254721Semaste
541254721Semaste    private:
542254721Semaste        DISALLOW_COPY_AND_ASSIGN(ScriptSummaryFormat);
543254721Semaste    };
544254721Semaste#endif
545254721Semaste} // namespace lldb_private
546254721Semaste
547254721Semaste#endif	// lldb_TypeSummary_h_
548