]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/DataFormatters/TypeCategoryMap.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / tools / lldb / source / DataFormatters / TypeCategoryMap.cpp
1 //===-- TypeCategoryMap.cpp ----------------------------------------*- 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 #include "lldb/lldb-python.h"
11
12 #include "lldb/DataFormatters/TypeCategoryMap.h"
13
14 #include "lldb/DataFormatters/FormatClasses.h"
15 #include "lldb/DataFormatters/FormatManager.h"
16
17 // C Includes
18 // C++ Includes
19 // Other libraries and framework includes
20 // Project includes
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25 TypeCategoryMap::TypeCategoryMap (IFormatChangeListener* lst) :
26 m_map_mutex(Mutex::eMutexTypeRecursive),
27 listener(lst),
28 m_map(),
29 m_active_categories()
30 {
31     ConstString default_cs("default");
32     lldb::TypeCategoryImplSP default_sp = lldb::TypeCategoryImplSP(new TypeCategoryImpl(listener, default_cs));
33     Add(default_cs,default_sp);
34     Enable(default_cs,First);
35 }
36
37 void
38 TypeCategoryMap::Add (KeyType name, const ValueSP& entry)
39 {
40     Mutex::Locker locker(m_map_mutex);
41     m_map[name] = entry;
42     if (listener)
43         listener->Changed();
44 }
45
46 bool
47 TypeCategoryMap::Delete (KeyType name)
48 {
49     Mutex::Locker locker(m_map_mutex);
50     MapIterator iter = m_map.find(name);
51     if (iter == m_map.end())
52         return false;
53     m_map.erase(name);
54     Disable(name);
55     if (listener)
56         listener->Changed();
57     return true;
58 }
59
60 bool
61 TypeCategoryMap::Enable (KeyType category_name, Position pos)
62 {
63     Mutex::Locker locker(m_map_mutex);
64     ValueSP category;
65     if (!Get(category_name,category))
66         return false;
67     return Enable(category, pos);
68 }
69
70 bool
71 TypeCategoryMap::Disable (KeyType category_name)
72 {
73     Mutex::Locker locker(m_map_mutex);
74     ValueSP category;
75     if (!Get(category_name,category))
76         return false;
77     return Disable(category);
78 }
79
80 bool
81 TypeCategoryMap::Enable (ValueSP category, Position pos)
82 {
83     Mutex::Locker locker(m_map_mutex);
84     if (category.get())
85     {
86         Position pos_w = pos;
87         if (pos == First || m_active_categories.size() == 0)
88             m_active_categories.push_front(category);
89         else if (pos == Last || pos == m_active_categories.size())
90             m_active_categories.push_back(category);
91         else if (pos < m_active_categories.size())
92         {
93             ActiveCategoriesList::iterator iter = m_active_categories.begin();
94             while (pos_w)
95             {
96                 pos_w--,iter++;
97             }
98             m_active_categories.insert(iter,category);
99         }
100         else
101             return false;
102         category->Enable(true,
103                          pos);
104         return true;
105     }
106     return false;
107 }
108
109 bool
110 TypeCategoryMap::Disable (ValueSP category)
111 {
112     Mutex::Locker locker(m_map_mutex);
113     if (category.get())
114     {
115         m_active_categories.remove_if(delete_matching_categories(category));
116         category->Disable();
117         return true;
118     }
119     return false;
120 }
121
122 void
123 TypeCategoryMap::Clear ()
124 {
125     Mutex::Locker locker(m_map_mutex);
126     m_map.clear();
127     m_active_categories.clear();
128     if (listener)
129         listener->Changed();
130 }
131
132 bool
133 TypeCategoryMap::Get (KeyType name, ValueSP& entry)
134 {
135     Mutex::Locker locker(m_map_mutex);
136     MapIterator iter = m_map.find(name);
137     if (iter == m_map.end())
138         return false;
139     entry = iter->second;
140     return true;
141 }
142
143 bool
144 TypeCategoryMap::Get (uint32_t pos, ValueSP& entry)
145 {
146     Mutex::Locker locker(m_map_mutex);
147     MapIterator iter = m_map.begin();
148     MapIterator end = m_map.end();
149     while (pos > 0)
150     {
151         iter++;
152         pos--;
153         if (iter == end)
154             return false;
155     }
156     entry = iter->second;
157     return false;
158 }
159
160 bool
161 TypeCategoryMap::AnyMatches (ConstString type_name,
162                              TypeCategoryImpl::FormatCategoryItems items,
163                              bool only_enabled,
164                              const char** matching_category,
165                              TypeCategoryImpl::FormatCategoryItems* matching_type)
166 {
167     Mutex::Locker locker(m_map_mutex);
168     
169     MapIterator pos, end = m_map.end();
170     for (pos = m_map.begin(); pos != end; pos++)
171     {
172         if (pos->second->AnyMatches(type_name,
173                                     items,
174                                     only_enabled,
175                                     matching_category,
176                                     matching_type))
177             return true;
178     }
179     return false;
180 }
181
182 lldb::TypeFormatImplSP
183 TypeCategoryMap::GetFormat (ValueObject& valobj,
184                             lldb::DynamicValueType use_dynamic)
185 {
186     Mutex::Locker locker(m_map_mutex);
187     
188     uint32_t reason_why;
189     ActiveCategoriesIterator begin, end = m_active_categories.end();
190     
191     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
192     
193     FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic);
194     
195     for (begin = m_active_categories.begin(); begin != end; begin++)
196     {
197         lldb::TypeCategoryImplSP category_sp = *begin;
198         lldb::TypeFormatImplSP current_format;
199         if (log)
200             log->Printf("\n[TypeCategoryMap::GetFormat] Trying to use category %s", category_sp->GetName());
201         if (!category_sp->Get(valobj, matches, current_format, &reason_why))
202             continue;
203         return current_format;
204     }
205     if (log)
206         log->Printf("[TypeCategoryMap::GetFormat] nothing found - returning empty SP");
207     return lldb::TypeFormatImplSP();
208 }
209
210 lldb::TypeSummaryImplSP
211 TypeCategoryMap::GetSummaryFormat (ValueObject& valobj,
212                                    lldb::DynamicValueType use_dynamic)
213 {
214     Mutex::Locker locker(m_map_mutex);
215     
216     uint32_t reason_why;
217     ActiveCategoriesIterator begin, end = m_active_categories.end();
218     
219     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
220     
221     FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic);
222     
223     for (begin = m_active_categories.begin(); begin != end; begin++)
224     {
225         lldb::TypeCategoryImplSP category_sp = *begin;
226         lldb::TypeSummaryImplSP current_format;
227         if (log)
228             log->Printf("\n[CategoryMap::GetSummaryFormat] Trying to use category %s", category_sp->GetName());
229         if (!category_sp->Get(valobj, matches, current_format, &reason_why))
230             continue;
231         return current_format;
232     }
233     if (log)
234         log->Printf("[CategoryMap::GetSummaryFormat] nothing found - returning empty SP");
235     return lldb::TypeSummaryImplSP();
236 }
237
238 #ifndef LLDB_DISABLE_PYTHON
239 lldb::SyntheticChildrenSP
240 TypeCategoryMap::GetSyntheticChildren (ValueObject& valobj,
241                                        lldb::DynamicValueType use_dynamic)
242 {
243     Mutex::Locker locker(m_map_mutex);
244     
245     uint32_t reason_why;
246     
247     ActiveCategoriesIterator begin, end = m_active_categories.end();
248     
249     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
250     
251     FormattersMatchVector matches = FormatManager::GetPossibleMatches(valobj, use_dynamic);
252     
253     for (begin = m_active_categories.begin(); begin != end; begin++)
254     {
255         lldb::TypeCategoryImplSP category_sp = *begin;
256         lldb::SyntheticChildrenSP current_format;
257         if (log)
258             log->Printf("\n[CategoryMap::GetSyntheticChildren] Trying to use category %s", category_sp->GetName());
259         if (!category_sp->Get(valobj, matches, current_format, &reason_why))
260             continue;
261         return current_format;
262     }
263     if (log)
264         log->Printf("[CategoryMap::GetSyntheticChildren] nothing found - returning empty SP");
265     return lldb::SyntheticChildrenSP();
266 }
267 #endif
268
269 void
270 TypeCategoryMap::LoopThrough(CallbackType callback, void* param)
271 {
272     if (callback)
273     {
274         Mutex::Locker locker(m_map_mutex);
275         
276         // loop through enabled categories in respective order
277         {
278             ActiveCategoriesIterator begin, end = m_active_categories.end();
279             for (begin = m_active_categories.begin(); begin != end; begin++)
280             {
281                 lldb::TypeCategoryImplSP category = *begin;
282                 ConstString type = ConstString(category->GetName());
283                 if (!callback(param, category))
284                     break;
285             }
286         }
287         
288         // loop through disabled categories in just any order
289         {
290             MapIterator pos, end = m_map.end();
291             for (pos = m_map.begin(); pos != end; pos++)
292             {
293                 if (pos->second->IsEnabled())
294                     continue;
295                 KeyType type = pos->first;
296                 if (!callback(param, pos->second))
297                     break;
298             }
299         }
300     }
301 }
302
303 TypeCategoryImplSP
304 TypeCategoryMap::GetAtIndex (uint32_t index)
305 {
306     Mutex::Locker locker(m_map_mutex);
307     
308     if (index < m_map.size())
309     {
310         MapIterator pos, end = m_map.end();
311         for (pos = m_map.begin(); pos != end; pos++)
312         {
313             if (index == 0)
314                 return pos->second;
315             index--;
316         }
317     }
318     
319     return TypeCategoryImplSP();
320 }