1 //===-- FormattersContainer.h -----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef lldb_FormattersContainer_h_
11 #define lldb_FormattersContainer_h_
20 // Other libraries and framework includes
22 #include "lldb/lldb-public.h"
24 #include "lldb/Core/RegularExpression.h"
25 #include "lldb/Core/ValueObject.h"
26 #include "lldb/DataFormatters/FormatClasses.h"
27 #include "lldb/DataFormatters/TypeFormat.h"
28 #include "lldb/DataFormatters/TypeSummary.h"
29 #include "lldb/DataFormatters/TypeSynthetic.h"
30 #include "lldb/DataFormatters/TypeValidator.h"
31 #include "lldb/Symbol/CompilerType.h"
32 #include "lldb/Utility/StringLexer.h"
34 namespace lldb_private {
36 class IFormatChangeListener
40 ~IFormatChangeListener() = default;
46 GetCurrentRevision () = 0;
49 // if the user tries to add formatters for, say, "struct Foo"
50 // those will not match any type because of the way we strip qualifiers from typenames
51 // this method looks for the case where the user is adding a "class","struct","enum" or "union" Foo
52 // and strips the unnecessary qualifier
53 static inline ConstString
54 GetValidTypeName_Impl (const ConstString& type)
59 std::string type_cstr(type.AsCString());
60 lldb_utility::StringLexer type_lexer(type_cstr);
62 type_lexer.AdvanceIf("class ");
63 type_lexer.AdvanceIf("enum ");
64 type_lexer.AdvanceIf("struct ");
65 type_lexer.AdvanceIf("union ");
67 while (type_lexer.NextIf({' ','\t','\v','\f'}).first)
70 return ConstString(type_lexer.GetUnlexed());
73 template<typename KeyType, typename ValueType>
74 class FormattersContainer;
76 template<typename KeyType, typename ValueType>
80 typedef typename ValueType::SharedPointer ValueSP;
81 typedef std::map<KeyType, ValueSP> MapType;
82 typedef typename MapType::iterator MapIterator;
83 typedef std::function<bool(KeyType, const ValueSP&)> ForEachCallback;
85 FormatMap(IFormatChangeListener* lst) :
87 m_map_mutex(Mutex::eMutexTypeRecursive),
97 entry->GetRevision() = listener->GetCurrentRevision();
99 entry->GetRevision() = 0;
101 Mutex::Locker locker(m_map_mutex);
108 Delete (KeyType name)
110 Mutex::Locker locker(m_map_mutex);
111 MapIterator iter = m_map.find(name);
112 if (iter == m_map.end())
123 Mutex::Locker locker(m_map_mutex);
133 Mutex::Locker locker(m_map_mutex);
134 MapIterator iter = m_map.find(name);
135 if (iter == m_map.end())
137 entry = iter->second;
142 ForEach (ForEachCallback callback)
146 Mutex::Locker locker(m_map_mutex);
147 MapIterator pos, end = m_map.end();
148 for (pos = m_map.begin(); pos != end; pos++)
150 KeyType type = pos->first;
151 if (!callback(type, pos->second))
164 GetValueAtIndex (size_t index)
166 Mutex::Locker locker(m_map_mutex);
167 MapIterator iter = m_map.begin();
168 MapIterator end = m_map.end();
180 GetKeyAtIndex (size_t index)
182 Mutex::Locker locker(m_map_mutex);
183 MapIterator iter = m_map.begin();
184 MapIterator end = m_map.end();
198 IFormatChangeListener* listener;
212 friend class FormattersContainer<KeyType, ValueType>;
213 friend class FormatManager;
216 template<typename KeyType, typename ValueType>
217 class FormattersContainer
220 typedef FormatMap<KeyType,ValueType> BackEndType;
223 typedef typename BackEndType::MapType MapType;
224 typedef typename MapType::iterator MapIterator;
225 typedef typename MapType::key_type MapKeyType;
226 typedef typename MapType::mapped_type MapValueType;
227 typedef typename BackEndType::ForEachCallback ForEachCallback;
228 typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType> > SharedPointer;
230 friend class TypeCategoryImpl;
232 FormattersContainer(std::string name,
233 IFormatChangeListener* lst) :
240 Add (const MapKeyType &type, const MapValueType& entry)
242 Add_Impl(type, entry, static_cast<KeyType*>(nullptr));
246 Delete (ConstString type)
248 return Delete_Impl(type, static_cast<KeyType*>(nullptr));
252 Get(ValueObject& valobj,
254 lldb::DynamicValueType use_dynamic,
255 uint32_t* why = nullptr)
257 uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
258 CompilerType ast_type(valobj.GetCompilerType());
259 bool ret = Get(valobj, ast_type, entry, use_dynamic, value);
261 entry = MapValueType(entry);
263 entry = MapValueType();
270 Get (ConstString type, MapValueType& entry)
272 return Get_Impl(type, entry, static_cast<KeyType*>(nullptr));
276 GetExact (ConstString type, MapValueType& entry)
278 return GetExact_Impl(type, entry, static_cast<KeyType*>(nullptr));
282 GetAtIndex (size_t index)
284 return m_format_map.GetValueAtIndex(index);
287 lldb::TypeNameSpecifierImplSP
288 GetTypeNameSpecifierAtIndex (size_t index)
290 return GetTypeNameSpecifierAtIndex_Impl(index, static_cast<KeyType*>(nullptr));
296 m_format_map.Clear();
300 ForEach (ForEachCallback callback)
302 m_format_map.ForEach(callback);
308 return m_format_map.GetCount();
312 BackEndType m_format_map;
315 DISALLOW_COPY_AND_ASSIGN(FormattersContainer);
318 Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy)
320 m_format_map.Add(type,entry);
323 void Add_Impl (const ConstString &type, const MapValueType& entry, ConstString *dummy)
325 m_format_map.Add(GetValidTypeName_Impl(type), entry);
329 Delete_Impl (ConstString type, ConstString *dummy)
331 return m_format_map.Delete(type);
335 Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
337 Mutex& x_mutex = m_format_map.mutex();
338 lldb_private::Mutex::Locker locker(x_mutex);
339 MapIterator pos, end = m_format_map.map().end();
340 for (pos = m_format_map.map().begin(); pos != end; pos++)
342 lldb::RegularExpressionSP regex = pos->first;
343 if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
345 m_format_map.map().erase(pos);
346 if (m_format_map.listener)
347 m_format_map.listener->Changed();
355 Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
357 return m_format_map.Get(type, entry);
361 GetExact_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
363 return Get_Impl(type, entry, static_cast<KeyType*>(nullptr));
366 lldb::TypeNameSpecifierImplSP
367 GetTypeNameSpecifierAtIndex_Impl (size_t index, ConstString *dummy)
369 ConstString key = m_format_map.GetKeyAtIndex(index);
371 return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(key.AsCString(),
374 return lldb::TypeNameSpecifierImplSP();
377 lldb::TypeNameSpecifierImplSP
378 GetTypeNameSpecifierAtIndex_Impl (size_t index, lldb::RegularExpressionSP *dummy)
380 lldb::RegularExpressionSP regex = m_format_map.GetKeyAtIndex(index);
381 if (regex.get() == nullptr)
382 return lldb::TypeNameSpecifierImplSP();
383 return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(regex->GetText(),
388 Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
390 const char* key_cstr = key.AsCString();
393 Mutex& x_mutex = m_format_map.mutex();
394 lldb_private::Mutex::Locker locker(x_mutex);
395 MapIterator pos, end = m_format_map.map().end();
396 for (pos = m_format_map.map().begin(); pos != end; pos++)
398 lldb::RegularExpressionSP regex = pos->first;
399 if (regex->Execute(key_cstr))
409 GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
411 Mutex& x_mutex = m_format_map.mutex();
412 lldb_private::Mutex::Locker locker(x_mutex);
413 MapIterator pos, end = m_format_map.map().end();
414 for (pos = m_format_map.map().begin(); pos != end; pos++)
416 lldb::RegularExpressionSP regex = pos->first;
417 if (strcmp(regex->GetText(),key.AsCString()) == 0)
427 Get (const FormattersMatchVector& candidates,
431 for (const FormattersMatchCandidate& candidate : candidates)
433 if (Get(candidate.GetTypeName(),entry))
435 if (candidate.IsMatch(entry) == false)
443 *reason = candidate.GetReason();
452 } // namespace lldb_private
454 #endif // lldb_FormattersContainer_h_