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_
16 // Other libraries and framework includes
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/Type.h"
19 #include "clang/AST/DeclObjC.h"
22 #include "lldb/lldb-public.h"
24 #include "lldb/Core/Log.h"
25 #include "lldb/Core/RegularExpression.h"
26 #include "lldb/Core/ValueObject.h"
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"
34 #include "lldb/Symbol/ClangASTContext.h"
35 #include "lldb/Symbol/ClangASTType.h"
37 #include "lldb/Target/ObjCLanguageRuntime.h"
38 #include "lldb/Target/Process.h"
39 #include "lldb/Target/StackFrame.h"
40 #include "lldb/Target/TargetList.h"
42 #include "lldb/Utility/StringLexer.h"
44 namespace lldb_private {
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
57 ~IFormatChangeListener () {}
60 GetCurrentRevision () = 0;
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)
74 std::string type_cstr(type.AsCString());
75 lldb_utility::StringLexer type_lexer(type_cstr);
77 type_lexer.AdvanceIf("class ");
78 type_lexer.AdvanceIf("enum ");
79 type_lexer.AdvanceIf("struct ");
80 type_lexer.AdvanceIf("union ");
82 while (type_lexer.NextIf({' ','\t','\v','\f'}).first)
85 return ConstString(type_lexer.GetUnlexed());
88 template<typename KeyType, typename ValueType>
89 class FormattersContainer;
91 template<typename KeyType, typename ValueType>
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&);
101 FormatMap(IFormatChangeListener* lst) :
103 m_map_mutex(Mutex::eMutexTypeRecursive),
110 const ValueSP& entry)
113 entry->GetRevision() = listener->GetCurrentRevision();
115 entry->GetRevision() = 0;
117 Mutex::Locker locker(m_map_mutex);
124 Delete (KeyType name)
126 Mutex::Locker locker(m_map_mutex);
127 MapIterator iter = m_map.find(name);
128 if (iter == m_map.end())
139 Mutex::Locker locker(m_map_mutex);
149 Mutex::Locker locker(m_map_mutex);
150 MapIterator iter = m_map.find(name);
151 if (iter == m_map.end())
153 entry = iter->second;
158 LoopThrough (CallbackType callback, void* param)
162 Mutex::Locker locker(m_map_mutex);
163 MapIterator pos, end = m_map.end();
164 for (pos = m_map.begin(); pos != end; pos++)
166 KeyType type = pos->first;
167 if (!callback(param, type, pos->second))
180 GetValueAtIndex (size_t index)
182 Mutex::Locker locker(m_map_mutex);
183 MapIterator iter = m_map.begin();
184 MapIterator end = m_map.end();
196 GetKeyAtIndex (size_t index)
198 Mutex::Locker locker(m_map_mutex);
199 MapIterator iter = m_map.begin();
200 MapIterator end = m_map.end();
214 IFormatChangeListener* listener;
228 friend class FormattersContainer<KeyType, ValueType>;
229 friend class FormatManager;
233 template<typename KeyType, typename ValueType>
234 class FormattersContainer
237 typedef FormatMap<KeyType,ValueType> BackEndType;
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;
247 friend class TypeCategoryImpl;
249 FormattersContainer(std::string name,
250 IFormatChangeListener* lst) :
257 Add (const MapKeyType &type, const MapValueType& entry)
259 Add_Impl(type, entry, (KeyType*)NULL);
263 Delete (ConstString type)
265 return Delete_Impl(type, (KeyType*)NULL);
269 Get(ValueObject& valobj,
271 lldb::DynamicValueType use_dynamic,
272 uint32_t* why = NULL)
274 uint32_t value = lldb_private::eFormatterChoiceCriterionDirectChoice;
275 ClangASTType ast_type(valobj.GetClangType());
276 bool ret = Get(valobj, ast_type, entry, use_dynamic, value);
278 entry = MapValueType(entry);
280 entry = MapValueType();
287 Get (ConstString type, MapValueType& entry)
289 return Get_Impl(type, entry, (KeyType*)NULL);
293 GetExact (ConstString type, MapValueType& entry)
295 return GetExact_Impl(type, entry, (KeyType*)NULL);
299 GetAtIndex (size_t index)
301 return m_format_map.GetValueAtIndex(index);
304 lldb::TypeNameSpecifierImplSP
305 GetTypeNameSpecifierAtIndex (size_t index)
307 return GetTypeNameSpecifierAtIndex_Impl(index, (KeyType*)NULL);
313 m_format_map.Clear();
317 LoopThrough (CallbackType callback, void* param)
319 m_format_map.LoopThrough(callback,param);
325 return m_format_map.GetCount();
329 BackEndType m_format_map;
332 DISALLOW_COPY_AND_ASSIGN(FormattersContainer);
335 Add_Impl (const MapKeyType &type, const MapValueType& entry, lldb::RegularExpressionSP *dummy)
337 m_format_map.Add(type,entry);
340 void Add_Impl (const ConstString &type, const MapValueType& entry, ConstString *dummy)
342 m_format_map.Add(GetValidTypeName_Impl(type), entry);
346 Delete_Impl (ConstString type, ConstString *dummy)
348 return m_format_map.Delete(type);
352 Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
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++)
359 lldb::RegularExpressionSP regex = pos->first;
360 if ( ::strcmp(type.AsCString(),regex->GetText()) == 0)
362 m_format_map.map().erase(pos);
363 if (m_format_map.listener)
364 m_format_map.listener->Changed();
372 Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
374 return m_format_map.Get(type, entry);
378 GetExact_Impl (ConstString type, MapValueType& entry, ConstString *dummy)
380 return Get_Impl(type,entry, (KeyType*)0);
383 lldb::TypeNameSpecifierImplSP
384 GetTypeNameSpecifierAtIndex_Impl (size_t index, ConstString *dummy)
386 ConstString key = m_format_map.GetKeyAtIndex(index);
388 return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(key.AsCString(),
391 return lldb::TypeNameSpecifierImplSP();
394 lldb::TypeNameSpecifierImplSP
395 GetTypeNameSpecifierAtIndex_Impl (size_t index, lldb::RegularExpressionSP *dummy)
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(),
405 Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
407 const char* key_cstr = key.AsCString();
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++)
415 lldb::RegularExpressionSP regex = pos->first;
416 if (regex->Execute(key_cstr))
426 GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
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++)
433 lldb::RegularExpressionSP regex = pos->first;
434 if (strcmp(regex->GetText(),key.AsCString()) == 0)
444 Get (const FormattersMatchVector& candidates,
448 for (const FormattersMatchCandidate& candidate : candidates)
450 // FIXME: could we do the IsMatch() check first?
451 if (Get(candidate.GetTypeName(),entry))
453 if (candidate.IsMatch(entry) == false)
461 *reason = candidate.GetReason();
470 } // namespace lldb_private
472 #endif // lldb_FormattersContainer_h_