FormatNavigator.h revision 3e11c7ec050648ba865f1d451f8cb46fd39072a8
1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//===-- FormatNavigator.h ----------------------------------------*- C++ -*-===//
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//                     The LLVM Compiler Infrastructure
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// This file is distributed under the University of Illinois Open Source
6fab50875b98e8274ac8ee44b38ba42521bbbf1f9Adam Lesinski// License. See LICENSE.TXT for details.
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski//
82c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski//===----------------------------------------------------------------------===//
92c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifndef lldb_FormatNavigator_h_
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define lldb_FormatNavigator_h_
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// C Includes
142c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski// C++ Includes
152c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
162c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski// Other libraries and framework includes
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "clang/AST/DeclCXX.h"
182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#include "clang/AST/Type.h"
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "clang/AST/DeclObjC.h"
202c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Project includes
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/lldb-public.h"
232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Core/Log.h"
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Core/RegularExpression.h"
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Core/ValueObject.h"
27ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski
28ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski#include "lldb/DataFormatters/FormatClasses.h"
29ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski
30ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski#include "lldb/Symbol/ClangASTContext.h"
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Symbol/ClangASTType.h"
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Target/ObjCLanguageRuntime.h"
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Target/Process.h"
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Target/StackFrame.h"
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "lldb/Target/TargetList.h"
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskinamespace lldb_private {
39ad751224401564dcc8338df3d5c4c5de7722be8fAdam Lesinski
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// this file (and its. cpp) contain the low-level implementation of LLDB Data Visualization
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// class DataVisualization is the high-level front-end of this feature
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// clients should refer to that class as the entry-point into the data formatters
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// unless they have a good reason to bypass it and prefer to use this file's objects directly
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass IFormatChangeListener
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic:
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual void
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Changed () = 0;
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ~IFormatChangeListener () {}
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    virtual uint32_t
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetCurrentRevision () = 0;
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic inline bool
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiIsWhitespace (char c)
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return ( (c == ' ') || (c == '\t') || (c == '\v') || (c == '\f') );
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic inline bool
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiHasPrefix (const char* str1, const char* str2)
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return ( ::strstr(str1, str2) == str1 );
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// if the user tries to add formatters for, say, "struct Foo"
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// those will not match any type because of the way we strip qualifiers from typenames
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// this method looks for the case where the user is adding a "class","struct","enum" or "union" Foo
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// and strips the unnecessary qualifier
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic inline ConstString
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiGetValidTypeName_Impl (const ConstString& type)
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int strip_len = 0;
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (type == false)
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return type;
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    const char* type_cstr = type.AsCString();
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if ( HasPrefix(type_cstr, "class ") )
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        strip_len = 6;
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    else if ( HasPrefix(type_cstr, "enum ") )
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        strip_len = 5;
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    else if ( HasPrefix(type_cstr, "struct ") )
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        strip_len = 7;
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    else if ( HasPrefix(type_cstr, "union ") )
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        strip_len = 6;
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    if (strip_len == 0)
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return type;
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    type_cstr += strip_len;
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    while (IsWhitespace(*type_cstr) && ++type_cstr)
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ;
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return ConstString(type_cstr);
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskitemplate<typename KeyType, typename ValueType>
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass FormatNavigator;
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskitemplate<typename KeyType, typename ValueType>
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass FormatMap
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic:
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename ValueType::SharedPointer ValueSP;
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef std::map<KeyType, ValueSP> MapType;
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename MapType::iterator MapIterator;
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef bool(*CallbackType)(void*, KeyType, const ValueSP&);
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FormatMap(IFormatChangeListener* lst) :
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    m_map(),
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    m_map_mutex(Mutex::eMutexTypeRecursive),
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    listener(lst)
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Add(KeyType name,
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        const ValueSP& entry)
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (listener)
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            entry->GetRevision() = listener->GetCurrentRevision();
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            entry->GetRevision() = 0;
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Locker locker(m_map_mutex);
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        m_map[name] = entry;
134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (listener)
135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            listener->Changed();
136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Delete (KeyType name)
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Locker locker(m_map_mutex);
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapIterator iter = m_map.find(name);
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (iter == m_map.end())
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        m_map.erase(name);
146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (listener)
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            listener->Changed();
148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Clear ()
153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Locker locker(m_map_mutex);
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        m_map.clear();
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (listener)
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            listener->Changed();
158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Get(KeyType name,
162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ValueSP& entry)
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Locker locker(m_map_mutex);
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapIterator iter = m_map.find(name);
166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (iter == m_map.end())
167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        entry = iter->second;
169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return true;
170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void
173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LoopThrough (CallbackType callback, void* param)
174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (callback)
176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Mutex::Locker locker(m_map_mutex);
178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            MapIterator pos, end = m_map.end();
179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            for (pos = m_map.begin(); pos != end; pos++)
180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            {
181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                KeyType type = pos->first;
182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (!callback(param, type, pos->second))
183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    break;
184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    uint32_t
189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetCount ()
190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return m_map.size();
192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ValueSP
195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetValueAtIndex (size_t index)
196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Locker locker(m_map_mutex);
198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapIterator iter = m_map.begin();
199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapIterator end = m_map.end();
200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        while (index > 0)
201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iter++;
203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            index--;
204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (end == iter)
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return ValueSP();
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return iter->second;
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    KeyType
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetKeyAtIndex (size_t index)
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Mutex::Locker locker(m_map_mutex);
214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapIterator iter = m_map.begin();
215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapIterator end = m_map.end();
216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        while (index > 0)
217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            iter++;
219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            index--;
220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (end == iter)
221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return KeyType();
222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return iter->first;
224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprotected:
227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    MapType m_map;
228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex m_map_mutex;
229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    IFormatChangeListener* listener;
230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    MapType&
232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    map ()
233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return m_map;
235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Mutex&
238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    mutex ()
239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return m_map_mutex;
241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    friend class FormatNavigator<KeyType, ValueType>;
244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    friend class FormatManager;
245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskitemplate<typename KeyType, typename ValueType>
249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass FormatNavigator
250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprotected:
252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef FormatMap<KeyType,ValueType> BackEndType;
253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic:
255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename BackEndType::MapType MapType;
256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename MapType::iterator MapIterator;
257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename MapType::key_type MapKeyType;
258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename MapType::mapped_type MapValueType;
259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename BackEndType::CallbackType CallbackType;
260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    typedef typename std::shared_ptr<FormatNavigator<KeyType, ValueType> > SharedPointer;
261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    friend class TypeCategoryImpl;
263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    FormatNavigator(std::string name,
265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    IFormatChangeListener* lst) :
266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    m_format_map(lst),
267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    m_name(name),
268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    m_id_cs(ConstString("id"))
269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void
273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Add (const MapKeyType &type, const MapValueType& entry)
274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Add_Impl(type, entry, (KeyType*)NULL);
276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Delete (ConstString type)
280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return Delete_Impl(type, (KeyType*)NULL);
282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Get(ValueObject& valobj,
286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapValueType& entry,
287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        lldb::DynamicValueType use_dynamic,
288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        uint32_t* why = NULL)
289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        clang::QualType type = clang::QualType::getFromOpaquePtr(valobj.GetClangType());
292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        bool ret = Get(valobj, type, entry, use_dynamic, value);
293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (ret)
294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            entry = MapValueType(entry);
295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else
296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            entry = MapValueType();
297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (why)
298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            *why = value;
299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return ret;
300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Get (ConstString type, MapValueType& entry)
304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return Get_Impl(type, entry, (KeyType*)NULL);
306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetExact (ConstString type, MapValueType& entry)
310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return GetExact_Impl(type, entry, (KeyType*)NULL);
312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    MapValueType
315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetAtIndex (size_t index)
316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return m_format_map.GetValueAtIndex(index);
318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    lldb::TypeNameSpecifierImplSP
321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetTypeNameSpecifierAtIndex (size_t index)
322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return GetTypeNameSpecifierAtIndex_Impl(index, (KeyType*)NULL);
324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void
327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Clear ()
328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        m_format_map.Clear();
330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void
333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    LoopThrough (CallbackType callback, void* param)
334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        m_format_map.LoopThrough(callback,param);
336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    uint32_t
339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetCount ()
340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return m_format_map.GetCount();
342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprotected:
345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    BackEndType m_format_map;
347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    std::string m_name;
349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    DISALLOW_COPY_AND_ASSIGN(FormatNavigator);
351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ConstString m_id_cs;
353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void
355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy)
356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       m_format_map.Add(type,entry);
358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void Add_Impl (const ConstString &type, const MapValueType& entry, ConstString *dummy)
361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       m_format_map.Add(GetValidTypeName_Impl(type), entry);
363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Delete_Impl (ConstString type, ConstString *dummy)
367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       return m_format_map.Delete(type);
369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       Mutex& x_mutex = m_format_map.mutex();
375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        lldb_private::Mutex::Locker locker(x_mutex);
376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       MapIterator pos, end = m_format_map.map().end();
377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       for (pos = m_format_map.map().begin(); pos != end; pos++)
378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       {
379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           lldb::RegularExpressionSP regex = pos->first;
380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           {
382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski               m_format_map.map().erase(pos);
383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski               if (m_format_map.listener)
384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                   m_format_map.listener->Changed();
385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski               return true;
386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           }
387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       }
388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       return false;
38976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    }
39076327314d2238e105f8b94909f9c0cf85caca318Maurice Chu
39176327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    bool
39276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
39376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    {
39476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu       return m_format_map.Get(type, entry);
39576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    }
39676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu
39776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    bool
39876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    GetExact_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
39976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    {
4002675f769673f69b0661ddee346292f25cb30a296Maurice Chu        return Get_Impl(type,entry, (KeyType*)0);
4012675f769673f69b0661ddee346292f25cb30a296Maurice Chu    }
40276327314d2238e105f8b94909f9c0cf85caca318Maurice Chu
40376327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    lldb::TypeNameSpecifierImplSP
40476327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    GetTypeNameSpecifierAtIndex_Impl (size_t index, ConstString *dummy)
40576327314d2238e105f8b94909f9c0cf85caca318Maurice Chu    {
40676327314d2238e105f8b94909f9c0cf85caca318Maurice Chu        ConstString key = m_format_map.GetKeyAtIndex(index);
40776327314d2238e105f8b94909f9c0cf85caca318Maurice Chu        if (key)
40876327314d2238e105f8b94909f9c0cf85caca318Maurice Chu            return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(key.AsCString(),
40976327314d2238e105f8b94909f9c0cf85caca318Maurice Chu                                                                           false));
410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else
411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return lldb::TypeNameSpecifierImplSP();
412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    lldb::TypeNameSpecifierImplSP
415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetTypeNameSpecifierAtIndex_Impl (size_t index, lldb::RegularExpressionSP *dummy)
416a5018c900f126ee8424c82497f32983873db741bAdam Lesinski    {
4179d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski        lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index);
4189d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski        if (regex.get() == NULL)
41994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            return lldb::TypeNameSpecifierImplSP();
420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(regex->GetText(),
421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                                                       true));
422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       const char* key_cstr = key.AsCString();
428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       if (!key_cstr)
429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           return false;
430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       Mutex& x_mutex = m_format_map.mutex();
431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       lldb_private::Mutex::Locker locker(x_mutex);
432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       MapIterator pos, end = m_format_map.map().end();
433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       for (pos = m_format_map.map().begin(); pos != end; pos++)
434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       {
435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           lldb::RegularExpressionSP regex = pos->first;
436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           if (regex->Execute(key_cstr))
437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           {
438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski               value = pos->second;
439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski               return true;
440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski           }
441caf797c84a6a2829662872e0df93fcd61da78d51Adam Lesinski       }
442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski       return false;
443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool
446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
44894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        Mutex& x_mutex = m_format_map.mutex();
4490a5a5d6996e54a927af750e122a1275d64f77ee5Tim Kilbourn        lldb_private::Mutex::Locker locker(x_mutex);
450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        MapIterator pos, end = m_format_map.map().end();
451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        for (pos = m_format_map.map().begin(); pos != end; pos++)
4522675f769673f69b0661ddee346292f25cb30a296Maurice Chu        {
453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            lldb::RegularExpressionSP regex = pos->first;
454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (strcmp(regex->GetText(),key.AsCString()) == 0)
455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            {
456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                value = pos->second;
457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return true;
458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return false;
4612675f769673f69b0661ddee346292f25cb30a296Maurice Chu    }
462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
4632675f769673f69b0661ddee346292f25cb30a296Maurice Chu    bool
464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    Get_BitfieldMatch (ValueObject& valobj,
465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                       ConstString typeName,
4669cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski                       MapValueType& entry,
467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                       uint32_t& reason)
468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // for bitfields, append size to the typename so one can custom format them
471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        StreamString sstring;
472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        sstring.Printf("%s:%d",typeName.AsCString(),valobj.GetBitfieldBitSize());
473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ConstString bitfieldname = ConstString(sstring.GetData());
474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (log)
475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            log->Printf("[Get_BitfieldMatch] appended bitfield info, final result is %s", bitfieldname.GetCString());
476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (Get(bitfieldname, entry))
477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (log)
479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                log->Printf("[Get_BitfieldMatch] bitfield direct match found, returning");
480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return true;
481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        else
483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
4849cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski            reason |= lldb_private::eFormatterChoiceCriterionStrippedBitField;
4859cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski            if (log)
4869cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski                log->Printf("[Get_BitfieldMatch] no bitfield direct match");
4879cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski            return false;
4889cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski        }
4899cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski    }
490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    bool Get_ObjC (ValueObject& valobj,
492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                   MapValueType& entry)
493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    {
494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        lldb::ProcessSP process_sp = valobj.GetProcessSP();
496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime();
497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (runtime == NULL)
498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (log)
500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                log->Printf("[Get_ObjC] no valid ObjC runtime, skipping dynamic");
501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return false;
502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj));
504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (!objc_class_sp)
505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        {
506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (log)
50758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski                log->Printf("[Get_ObjC] invalid ISA, skipping dynamic");
50858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski            return false;
50958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        }
51058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        ConstString name (objc_class_sp->GetClassName());
51158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        if (log)
51258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski            log->Printf("[Get_ObjC] dynamic type inferred is %s - looking for direct dynamic match", name.GetCString());
51358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        if (Get(name, entry))
51458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        {
51558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski            if (log)
51658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski                log->Printf("[Get_ObjC] direct dynamic match found, returning");
51758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski            return true;
51858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        }
51958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        if (log)
52058f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski            log->Printf("[Get_ObjC] no dynamic match");
52158f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski        return false;
52258f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski    }
52358f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski
52458f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski    bool
52558f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski    Get_Impl (ValueObject& valobj,
52658f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski              clang::QualType type,
52758f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski              MapValueType& entry,
52858f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski              lldb::DynamicValueType use_dynamic,
52958f1f3617cb6d96e3f3cf3d5c99004a362f0a61eAdam Lesinski              uint32_t& reason)
53094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski    {
53194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
53294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski
53394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        if (type.isNull())
53494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        {
53594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (log)
53694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                log->Printf("[Get_Impl] type is NULL, returning");
53794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            return false;
53894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        }
53994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski
54094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        type.removeLocalConst(); type.removeLocalVolatile(); type.removeLocalRestrict();
54194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        const clang::Type* typePtr = type.getTypePtrOrNull();
54294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        if (!typePtr)
54394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        {
54494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (log)
54594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                log->Printf("[Get_Impl] type is NULL, returning");
54694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            return false;
54794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        }
54894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        ConstString typeName(ClangASTType::GetTypeNameForQualType(valobj.GetClangAST(), type).c_str());
54994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski
55094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        if (valobj.GetBitfieldBitSize() > 0)
55194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        {
55294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (Get_BitfieldMatch(valobj, typeName, entry, reason))
55394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                return true;
5549cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski        }
5559cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski
5569cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski        if (log)
5579cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski            log->Printf("[Get_Impl] trying to get %s for VO name %s of type %s",
5589cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski                        m_name.c_str(),
5599cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski                        valobj.GetName().AsCString(),
56094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                        typeName.AsCString());
56194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski
56294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        if (Get(typeName, entry))
56394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        {
56494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (log)
56594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                log->Printf("[Get] direct match found, returning");
56694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            return true;
5679cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski        }
5689cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski        if (log)
5699cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski            log->Printf("[Get_Impl] no direct match");
5709cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski
5719cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski        // strip pointers and references and see if that helps
5729cb2c68fafce55d43aacb2202deb882b986fa237Adam Lesinski        if (typePtr->isReferenceType())
57394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        {
57494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (log)
57594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                log->Printf("[Get_Impl] stripping reference");
57694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (Get_Impl(valobj,type.getNonReferenceType(),entry, use_dynamic, reason) && !entry->SkipsReferences())
57794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            {
57894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
57994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                return true;
58094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            }
58194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        }
58294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        else if (typePtr->isPointerType())
58394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        {
58494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (log)
58594fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                log->Printf("[Get_Impl] stripping pointer");
58694fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            clang::QualType pointee = typePtr->getPointeeType();
58794fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
58894fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            {
58994fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
59094fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski                return true;
59194fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski            }
59294fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        }
59394fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski
59494fc9124f51f0a101cc11e4563f9c647980fe2aaAdam Lesinski        bool canBeObjCDynamic = ClangASTContext::IsPossibleDynamicType (valobj.GetClangAST(),
5959d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski                                                                        type.getAsOpaquePtr(),
5969d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski                                                                        NULL,
5979d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski                                                                        false, // no C++
5989d5b08ea8c1eef6658418b33090a6a8142d75208Adam Lesinski                                                                        true); // yes ObjC
5992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
6002c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        if (canBeObjCDynamic)
6012c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        {
6022c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (use_dynamic != lldb::eNoDynamicValues)
6032c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            {
6042c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (log)
6052c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    log->Printf("[Get_Impl] allowed to figure out dynamic ObjC type");
6062c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (Get_ObjC(valobj,entry))
6072c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                {
6082c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    reason |= lldb_private::eFormatterChoiceCriterionDynamicObjCDiscovery;
6092c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    return true;
6102c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                }
6112c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            }
6122c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (log)
6132c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                log->Printf("[Get_Impl] dynamic disabled or failed - stripping ObjC pointer");
6142c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            clang::QualType pointee = typePtr->getPointeeType();
6152c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (Get_Impl(valobj, pointee, entry, use_dynamic, reason) && !entry->SkipsPointers())
6162c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            {
6172c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                reason |= lldb_private::eFormatterChoiceCriterionStrippedPointerReference;
6182c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                return true;
619d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski            }
620d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski        }
6212c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
6222c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        // try to strip typedef chains
6232c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        const clang::TypedefType* type_tdef = type->getAs<clang::TypedefType>();
6242c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        if (type_tdef)
6252c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        {
6262c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (log)
6272c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                log->Printf("[Get_Impl] stripping typedef");
6282c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if ((Get_Impl(valobj, type_tdef->getDecl()->getUnderlyingType(), entry, use_dynamic, reason)) && entry->Cascades())
6292c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            {
630d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski                reason |= lldb_private::eFormatterChoiceCriterionNavigatedTypedefs;
631d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski                return true;
632d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski            }
633d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski        }
634d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski
6352c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        // out of luck here
6362c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        return false;
6372c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski    }
6382c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
6392c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski    // we are separately passing in valobj and type because the valobj is fixed (and is used for ObjC discovery and bitfield size)
6402c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski    // but the type can change (e.g. stripping pointers, ...)
6412c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski    bool Get (ValueObject& valobj,
6422c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski              clang::QualType type,
6432c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski              MapValueType& entry,
6442c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski              lldb::DynamicValueType use_dynamic,
6452c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski              uint32_t& reason)
6462c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski    {
6472c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
6482c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
6492c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        if (Get_Impl (valobj,type,entry,use_dynamic,reason))
6502c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            return true;
6512c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
652d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski        // try going to the unqualified type
653d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski        do {
654d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski            if (log)
655d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski                log->Printf("[Get] trying the unqualified type");
6562c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            lldb::clang_type_t opaque_type = type.getAsOpaquePtr();
6572c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (!opaque_type)
6582c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            {
6592c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (log)
6602c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    log->Printf("[Get] could not get the opaque_type");
6612c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                break;
6622c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            }
6632c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            ClangASTType unqual_clang_ast_type = ClangASTType::GetFullyUnqualifiedType(valobj.GetClangAST(),opaque_type);
6642c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (!unqual_clang_ast_type.IsValid())
6652c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            {
6662c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (log)
6672c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    log->Printf("[Get] could not get the unqual_clang_ast_type");
6682c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                break;
6692c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            }
6702c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            clang::QualType unqualified_qual_type = clang::QualType::getFromOpaquePtr(unqual_clang_ast_type.GetOpaqueQualType());
6712c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (unqualified_qual_type.getTypePtrOrNull() != type.getTypePtrOrNull())
6722c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            {
6732c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (log)
6742c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    log->Printf("[Get] unqualified type is there and is not the same, let's try");
6752c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (Get_Impl (valobj,unqualified_qual_type,entry,use_dynamic,reason))
6762c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    return true;
6772c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            }
6782c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            else if (log)
6792c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                log->Printf("[Get] unqualified type same as original type");
6802c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        } while(false);
6812c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
6822c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        // if all else fails, go to static type
6832c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        if (valobj.IsDynamic())
6842c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        {
6852c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (log)
6862c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                log->Printf("[Get] going to static value");
6872c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            lldb::ValueObjectSP static_value_sp(valobj.GetStaticValue());
6882c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            if (static_value_sp)
6892c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            {
6902c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (log)
6912c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    log->Printf("[Get] has a static value - actually use it");
6922c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                if (Get(*static_value_sp.get(), clang::QualType::getFromOpaquePtr(static_value_sp->GetClangType()) , entry, use_dynamic, reason))
6932c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                {
6942c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    reason |= lldb_private::eFormatterChoiceCriterionWentToStaticValue;
6952c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                    return true;
6962c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski                }
6972c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski            }
6982c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        }
6992c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
7002c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski        return false;
7012c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski    }
7022c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski};
7032c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
7042c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski} // namespace lldb_private
7052c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski
7062c72b6822debb08fe997926eedc110f62d287d34Adam Lesinski#endif	// lldb_FormatNavigator_h_
707d7a94da476e9b783acf0673ed938cc3fc2cc6ba5Adam Lesinski