]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersContainer.h
Update LLDB snapshot to upstream r225923 (git 2b588ecd)
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / include / lldb / DataFormatters / FormattersContainer.h
1 //===-- FormattersContainer.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_FormattersContainer_h_
11 #define lldb_FormattersContainer_h_
12
13 // C Includes
14 // C++ Includes
15
16 // Other libraries and framework includes
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Type.h"
19 #include "clang/AST/DeclObjC.h"
20
21 // Project includes
22 #include "lldb/lldb-public.h"
23
24 #include "lldb/Core/Log.h"
25 #include "lldb/Core/RegularExpression.h"
26 #include "lldb/Core/ValueObject.h"
27
28 #include "lldb/DataFormatters/FormatClasses.h"
29 #include "lldb/DataFormatters/TypeFormat.h"
30 #include "lldb/DataFormatters/TypeSummary.h"
31 #include "lldb/DataFormatters/TypeSynthetic.h"
32 #include "lldb/DataFormatters/TypeValidator.h"
33
34 #include "lldb/Symbol/ClangASTContext.h"
35 #include "lldb/Symbol/ClangASTType.h"
36
37 #include "lldb/Target/ObjCLanguageRuntime.h"
38 #include "lldb/Target/Process.h"
39 #include "lldb/Target/StackFrame.h"
40 #include "lldb/Target/TargetList.h"
41
42 #include "lldb/Utility/StringLexer.h"
43
44 namespace lldb_private {
45     
46 // this file (and its. cpp) contain the low-level implementation of LLDB Data Visualization
47 // class DataVisualization is the high-level front-end of this feature
48 // clients should refer to that class as the entry-point into the data formatters
49 // unless they have a good reason to bypass it and prefer to use this file's objects directly
50 class IFormatChangeListener
51 {
52 public:
53     virtual void
54     Changed () = 0;
55     
56     virtual
57     ~IFormatChangeListener () {}
58     
59     virtual uint32_t
60     GetCurrentRevision () = 0;
61     
62 };
63     
64 // if the user tries to add formatters for, say, "struct Foo"
65 // those will not match any type because of the way we strip qualifiers from typenames
66 // this method looks for the case where the user is adding a "class","struct","enum" or "union" Foo
67 // and strips the unnecessary qualifier
68 static inline ConstString
69 GetValidTypeName_Impl (const ConstString& type)
70 {
71     if (type.IsEmpty())
72         return type;
73     
74     std::string type_cstr(type.AsCString());
75     lldb_utility::StringLexer type_lexer(type_cstr);
76     
77     type_lexer.AdvanceIf("class ");
78     type_lexer.AdvanceIf("enum ");
79     type_lexer.AdvanceIf("struct ");
80     type_lexer.AdvanceIf("union ");
81     
82     while (type_lexer.NextIf({' ','\t','\v','\f'}).first)
83         ;
84     
85     return ConstString(type_lexer.GetUnlexed());
86 }
87
88 template<typename KeyType, typename ValueType>
89 class FormattersContainer;
90
91 template<typename KeyType, typename ValueType>
92 class FormatMap
93 {
94 public:
95
96     typedef typename ValueType::SharedPointer ValueSP;
97     typedef std::map<KeyType, ValueSP> MapType;
98     typedef typename MapType::iterator MapIterator;
99     typedef bool(*CallbackType)(void*, KeyType, const ValueSP&);
100     
101     FormatMap(IFormatChangeListener* lst) :
102     m_map(),
103     m_map_mutex(Mutex::eMutexTypeRecursive),
104     listener(lst)
105     {
106     }
107     
108     void
109     Add(KeyType name,
110         const ValueSP& entry)
111     {
112         if (listener)
113             entry->GetRevision() = listener->GetCurrentRevision();
114         else
115             entry->GetRevision() = 0;
116
117         Mutex::Locker locker(m_map_mutex);
118         m_map[name] = entry;
119         if (listener)
120             listener->Changed();
121     }
122     
123     bool
124     Delete (KeyType name)
125     {
126         Mutex::Locker locker(m_map_mutex);
127         MapIterator iter = m_map.find(name);
128         if (iter == m_map.end())
129             return false;
130         m_map.erase(name);
131         if (listener)
132             listener->Changed();
133         return true;
134     }
135     
136     void
137     Clear ()
138     {
139         Mutex::Locker locker(m_map_mutex);
140         m_map.clear();
141         if (listener)
142             listener->Changed();
143     }
144     
145     bool
146     Get(KeyType name,
147         ValueSP& entry)
148     {
149         Mutex::Locker locker(m_map_mutex);
150         MapIterator iter = m_map.find(name);
151         if (iter == m_map.end())
152             return false;
153         entry = iter->second;
154         return true;
155     }
156     
157     void
158     LoopThrough (CallbackType callback, void* param)
159     {
160         if (callback)
161         {
162             Mutex::Locker locker(m_map_mutex);
163             MapIterator pos, end = m_map.end();
164             for (pos = m_map.begin(); pos != end; pos++)
165             {
166                 KeyType type = pos->first;
167                 if (!callback(param, type, pos->second))
168                     break;
169             }
170         }
171     }
172     
173     uint32_t
174     GetCount ()
175     {
176         return m_map.size();
177     }
178     
179     ValueSP
180     GetValueAtIndex (size_t index)
181     {
182         Mutex::Locker locker(m_map_mutex);
183         MapIterator iter = m_map.begin();
184         MapIterator end = m_map.end();
185         while (index > 0)
186         {
187             iter++;
188             index--;
189             if (end == iter)
190                 return ValueSP();
191         }
192         return iter->second;
193     }
194     
195     KeyType
196     GetKeyAtIndex (size_t index)
197     {
198         Mutex::Locker locker(m_map_mutex);
199         MapIterator iter = m_map.begin();
200         MapIterator end = m_map.end();
201         while (index > 0)
202         {
203             iter++;
204             index--;
205             if (end == iter)
206                 return KeyType();
207         }
208         return iter->first;
209     }
210     
211 protected:
212     MapType m_map;    
213     Mutex m_map_mutex;
214     IFormatChangeListener* listener;
215     
216     MapType&
217     map ()
218     {
219         return m_map;
220     }
221     
222     Mutex&
223     mutex ()
224     {
225         return m_map_mutex;
226     }
227     
228     friend class FormattersContainer<KeyType, ValueType>;
229     friend class FormatManager;
230     
231 };
232     
233 template<typename KeyType, typename ValueType>
234 class FormattersContainer
235 {
236 protected:
237     typedef FormatMap<KeyType,ValueType> BackEndType;
238     
239 public:
240     typedef typename BackEndType::MapType MapType;
241     typedef typename MapType::iterator MapIterator;
242     typedef typename MapType::key_type MapKeyType;
243     typedef typename MapType::mapped_type MapValueType;
244     typedef typename BackEndType::CallbackType CallbackType;
245     typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType> > SharedPointer;
246     
247     friend class TypeCategoryImpl;
248
249     FormattersContainer(std::string name,
250                     IFormatChangeListener* lst) :
251     m_format_map(lst),
252     m_name(name)
253     {
254     }
255     
256     void
257     Add (const MapKeyType &type, const MapValueType& entry)
258     {
259         Add_Impl(type, entry, (KeyType*)NULL);
260     }
261     
262     bool
263     Delete (ConstString type)
264     {
265         return Delete_Impl(type, (KeyType*)NULL);
266     }
267         
268     bool
269     Get(ValueObject& valobj,
270         MapValueType& entry,
271         lldb::DynamicValueType use_dynamic,
272         uint32_t* why = NULL)
273     {
274         uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
275         ClangASTType ast_type(valobj.GetClangType());
276         bool ret = Get(valobj, ast_type, entry, use_dynamic, value);
277         if (ret)
278             entry = MapValueType(entry);
279         else
280             entry = MapValueType();        
281         if (why)
282             *why = value;
283         return ret;
284     }
285     
286     bool
287     Get (ConstString type, MapValueType& entry)
288     {
289         return Get_Impl(type, entry, (KeyType*)NULL);
290     }
291     
292     bool
293     GetExact (ConstString type, MapValueType& entry)
294     {
295         return GetExact_Impl(type, entry, (KeyType*)NULL);
296     }
297     
298     MapValueType
299     GetAtIndex (size_t index)
300     {
301         return m_format_map.GetValueAtIndex(index);
302     }
303     
304     lldb::TypeNameSpecifierImplSP
305     GetTypeNameSpecifierAtIndex (size_t index)
306     {
307         return GetTypeNameSpecifierAtIndex_Impl(index, (KeyType*)NULL);
308     }
309     
310     void
311     Clear ()
312     {
313         m_format_map.Clear();
314     }
315     
316     void
317     LoopThrough (CallbackType callback, void* param)
318     {
319         m_format_map.LoopThrough(callback,param);
320     }
321     
322     uint32_t
323     GetCount ()
324     {
325         return m_format_map.GetCount();
326     }
327     
328 protected:
329     BackEndType m_format_map;
330     std::string m_name;
331     
332     DISALLOW_COPY_AND_ASSIGN(FormattersContainer);
333     
334     void
335     Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy)
336     {
337        m_format_map.Add(type,entry);
338     }
339
340     void Add_Impl (const ConstString &type, const MapValueType& entry, ConstString *dummy)
341     {
342        m_format_map.Add(GetValidTypeName_Impl(type), entry);
343     }
344
345     bool
346     Delete_Impl (ConstString type, ConstString *dummy)
347     {
348        return m_format_map.Delete(type);
349     }
350
351     bool
352     Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
353     {
354        Mutex& x_mutex = m_format_map.mutex();
355         lldb_private::Mutex::Locker locker(x_mutex);
356        MapIterator pos, end = m_format_map.map().end();
357        for (pos = m_format_map.map().begin(); pos != end; pos++)
358        {
359            lldb::RegularExpressionSP regex = pos->first;
360            if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
361            {
362                m_format_map.map().erase(pos);
363                if (m_format_map.listener)
364                    m_format_map.listener->Changed();
365                return true;
366            }
367        }
368        return false;
369     }    
370
371     bool
372     Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
373     {
374        return m_format_map.Get(type, entry);
375     }
376
377     bool
378     GetExact_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
379     {
380         return Get_Impl(type,entry, (KeyType*)0);
381     }
382     
383     lldb::TypeNameSpecifierImplSP
384     GetTypeNameSpecifierAtIndex_Impl (size_t index, ConstString *dummy)
385     {
386         ConstString key = m_format_map.GetKeyAtIndex(index);
387         if (key)
388             return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(key.AsCString(),
389                                                                            false));
390         else
391             return lldb::TypeNameSpecifierImplSP();
392     }
393     
394     lldb::TypeNameSpecifierImplSP
395     GetTypeNameSpecifierAtIndex_Impl (size_t index, lldb::RegularExpressionSP *dummy)
396     {
397         lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index);
398         if (regex.get() == NULL)
399             return lldb::TypeNameSpecifierImplSP();
400         return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(regex->GetText(),
401                                                                        true));
402     }
403
404     bool
405     Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
406     {
407        const char* key_cstr = key.AsCString();
408        if (!key_cstr)
409            return false;
410        Mutex& x_mutex = m_format_map.mutex();
411        lldb_private::Mutex::Locker locker(x_mutex);
412        MapIterator pos, end = m_format_map.map().end();
413        for (pos = m_format_map.map().begin(); pos != end; pos++)
414        {
415            lldb::RegularExpressionSP regex = pos->first;
416            if (regex->Execute(key_cstr))
417            {
418                value = pos->second;
419                return true;
420            }
421        }
422        return false;
423     }
424     
425     bool
426     GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
427     {
428         Mutex& x_mutex = m_format_map.mutex();
429         lldb_private::Mutex::Locker locker(x_mutex);
430         MapIterator pos, end = m_format_map.map().end();
431         for (pos = m_format_map.map().begin(); pos != end; pos++)
432         {
433             lldb::RegularExpressionSP regex = pos->first;
434             if (strcmp(regex->GetText(),key.AsCString()) == 0)
435             {
436                 value = pos->second;
437                 return true;
438             }
439         }
440         return false;
441     }
442
443     bool
444     Get (const FormattersMatchVector& candidates,
445          MapValueType& entry,
446          uint32_t *reason)
447     {
448         for (const FormattersMatchCandidate& candidate : candidates)
449         {
450             // FIXME: could we do the IsMatch() check first?
451             if (Get(candidate.GetTypeName(),entry))
452             {
453                 if (candidate.IsMatch(entry) == false)
454                 {
455                     entry.reset();
456                     continue;
457                 }
458                 else
459                 {
460                     if(reason)
461                         *reason = candidate.GetReason();
462                     return true;
463                 }
464             }
465         }
466         return false;
467     }
468 };
469
470 } // namespace lldb_private
471
472 #endif  // lldb_FormattersContainer_h_