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