diff options
Diffstat (limited to 'contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h')
-rw-r--r-- | contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h | 329 |
1 files changed, 120 insertions, 209 deletions
diff --git a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h index d414882bae19..2f56218c43a7 100644 --- a/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h +++ b/contrib/llvm-project/lldb/include/lldb/DataFormatters/FormattersContainer.h @@ -37,57 +37,103 @@ public: virtual uint32_t GetCurrentRevision() = 0; }; -// if the user tries to add formatters for, say, "struct Foo" those will not -// match any type because of the way we strip qualifiers from typenames this -// method looks for the case where the user is adding a "class","struct","enum" -// or "union" Foo and strips the unnecessary qualifier -static inline ConstString GetValidTypeName_Impl(ConstString type) { - if (type.IsEmpty()) - return type; +/// Class for matching type names. +class TypeMatcher { + RegularExpression m_type_name_regex; + ConstString m_type_name; + /// False if m_type_name_regex should be used for matching. False if this is + /// just matching by comparing with m_type_name string. + bool m_is_regex; - std::string type_cstr(type.AsCString()); - StringLexer type_lexer(type_cstr); + // if the user tries to add formatters for, say, "struct Foo" those will not + // match any type because of the way we strip qualifiers from typenames this + // method looks for the case where the user is adding a + // "class","struct","enum" or "union" Foo and strips the unnecessary qualifier + static ConstString StripTypeName(ConstString type) { + if (type.IsEmpty()) + return type; - type_lexer.AdvanceIf("class "); - type_lexer.AdvanceIf("enum "); - type_lexer.AdvanceIf("struct "); - type_lexer.AdvanceIf("union "); + std::string type_cstr(type.AsCString()); + StringLexer type_lexer(type_cstr); - while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first) - ; + type_lexer.AdvanceIf("class "); + type_lexer.AdvanceIf("enum "); + type_lexer.AdvanceIf("struct "); + type_lexer.AdvanceIf("union "); - return ConstString(type_lexer.GetUnlexed()); -} + while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first) + ; -template <typename KeyType, typename ValueType> class FormattersContainer; + return ConstString(type_lexer.GetUnlexed()); + } -template <typename KeyType, typename ValueType> class FormatMap { public: - typedef typename ValueType::SharedPointer ValueSP; - typedef std::vector<std::pair<KeyType, ValueSP>> MapType; - typedef typename MapType::iterator MapIterator; - typedef std::function<bool(const KeyType &, const ValueSP &)> ForEachCallback; + TypeMatcher() = delete; + /// Creates a matcher that accepts any type with exactly the given type name. + TypeMatcher(ConstString type_name) + : m_type_name(type_name), m_is_regex(false) {} + /// Creates a matcher that accepts any type matching the given regex. + TypeMatcher(RegularExpression regex) + : m_type_name_regex(std::move(regex)), m_is_regex(true) {} + + /// True iff this matches the given type name. + bool Matches(ConstString type_name) const { + if (m_is_regex) + return m_type_name_regex.Execute(type_name.GetStringRef()); + return m_type_name == type_name || + StripTypeName(m_type_name) == StripTypeName(type_name); + } + + /// Returns the underlying match string for this TypeMatcher. + ConstString GetMatchString() const { + if (m_is_regex) + return ConstString(m_type_name_regex.GetText()); + return StripTypeName(m_type_name); + } + + /// Returns true if this TypeMatcher and the given one were most created by + /// the same match string. + /// The main purpose of this function is to find existing TypeMatcher + /// instances by the user input that created them. This is necessary as LLDB + /// allows referencing existing TypeMatchers in commands by the user input + /// that originally created them: + /// (lldb) type summary add --summary-string \"A\" -x TypeName + /// (lldb) type summary delete TypeName + bool CreatedBySameMatchString(TypeMatcher other) const { + return GetMatchString() == other.GetMatchString(); + } +}; + +template <typename ValueType> class FormattersContainer { +public: + typedef typename std::shared_ptr<ValueType> ValueSP; + typedef std::vector<std::pair<TypeMatcher, ValueSP>> MapType; + typedef std::function<bool(const TypeMatcher &, const ValueSP &)> + ForEachCallback; + typedef typename std::shared_ptr<FormattersContainer<ValueType>> + SharedPointer; + + friend class TypeCategoryImpl; - FormatMap(IFormatChangeListener *lst) - : m_map(), m_map_mutex(), listener(lst) {} + FormattersContainer(IFormatChangeListener *lst) : listener(lst) {} - void Add(KeyType name, const ValueSP &entry) { + void Add(TypeMatcher matcher, const ValueSP &entry) { if (listener) entry->GetRevision() = listener->GetCurrentRevision(); else entry->GetRevision() = 0; std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - Delete(name); - m_map.emplace_back(std::move(name), std::move(entry)); + Delete(matcher); + m_map.emplace_back(std::move(matcher), std::move(entry)); if (listener) listener->Changed(); } - bool Delete(const KeyType &name) { + bool Delete(TypeMatcher matcher) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter) - if (iter->first == name) { + for (auto iter = m_map.begin(); iter != m_map.end(); ++iter) + if (iter->first.CreatedBySameMatchString(matcher)) { m_map.erase(iter); if (listener) listener->Changed(); @@ -96,217 +142,78 @@ public: return false; } - void Clear() { + bool Get(ConstString type, ValueSP &entry) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - m_map.clear(); - if (listener) - listener->Changed(); + for (auto &formatter : llvm::reverse(m_map)) { + if (formatter.first.Matches(type)) { + entry = formatter.second; + return true; + } + } + return false; } - bool Get(const KeyType &name, ValueSP &entry) { + bool GetExact(TypeMatcher matcher, ValueSP &entry) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); for (const auto &pos : m_map) - if (pos.first == name) { + if (pos.first.CreatedBySameMatchString(matcher)) { entry = pos.second; return true; } return false; } - void ForEach(ForEachCallback callback) { - if (callback) { - std::lock_guard<std::recursive_mutex> guard(m_map_mutex); - for (const auto &pos : m_map) { - const KeyType &type = pos.first; - if (!callback(type, pos.second)) - break; - } - } - } - - uint32_t GetCount() { return m_map.size(); } - - ValueSP GetValueAtIndex(size_t index) { + ValueSP GetAtIndex(size_t index) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); if (index >= m_map.size()) return ValueSP(); return m_map[index].second; } - // If caller holds the mutex we could return a reference without copy ctor. - KeyType GetKeyAtIndex(size_t index) { + lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); if (index >= m_map.size()) - return {}; - return m_map[index].first; - } - -protected: - MapType m_map; - std::recursive_mutex m_map_mutex; - IFormatChangeListener *listener; - - MapType &map() { return m_map; } - - std::recursive_mutex &mutex() { return m_map_mutex; } - - friend class FormattersContainer<KeyType, ValueType>; - friend class FormatManager; -}; - -template <typename KeyType, typename ValueType> class FormattersContainer { -protected: - typedef FormatMap<KeyType, ValueType> BackEndType; - -public: - typedef typename BackEndType::MapType MapType; - typedef typename MapType::iterator MapIterator; - typedef KeyType MapKeyType; - typedef std::shared_ptr<ValueType> MapValueType; - typedef typename BackEndType::ForEachCallback ForEachCallback; - typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType>> - SharedPointer; - - friend class TypeCategoryImpl; - - FormattersContainer(std::string name, IFormatChangeListener *lst) - : m_format_map(lst), m_name(name) {} - - void Add(MapKeyType type, const MapValueType &entry) { - Add_Impl(std::move(type), entry, static_cast<KeyType *>(nullptr)); - } - - bool Delete(ConstString type) { - return Delete_Impl(type, static_cast<KeyType *>(nullptr)); - } - - bool Get(ValueObject &valobj, MapValueType &entry, - lldb::DynamicValueType use_dynamic) { - CompilerType ast_type(valobj.GetCompilerType()); - bool ret = Get(valobj, ast_type, entry, use_dynamic); - if (ret) - entry = MapValueType(entry); - else - entry = MapValueType(); - return ret; + return lldb::TypeNameSpecifierImplSP(); + TypeMatcher type_matcher = m_map[index].first; + return std::make_shared<TypeNameSpecifierImpl>( + type_matcher.GetMatchString().GetStringRef(), true); } - bool Get(ConstString type, MapValueType &entry) { - return Get_Impl(type, entry, static_cast<KeyType *>(nullptr)); + void Clear() { + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); + m_map.clear(); + if (listener) + listener->Changed(); } - bool GetExact(ConstString type, MapValueType &entry) { - return GetExact_Impl(type, entry, static_cast<KeyType *>(nullptr)); + void ForEach(ForEachCallback callback) { + if (callback) { + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); + for (const auto &pos : m_map) { + const TypeMatcher &type = pos.first; + if (!callback(type, pos.second)) + break; + } + } } - MapValueType GetAtIndex(size_t index) { - return m_format_map.GetValueAtIndex(index); + uint32_t GetCount() { + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); + return m_map.size(); } - lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) { - return GetTypeNameSpecifierAtIndex_Impl(index, - static_cast<KeyType *>(nullptr)); + void AutoComplete(CompletionRequest &request) { + ForEach([&request](const TypeMatcher &matcher, const ValueSP &value) { + request.TryCompleteCurrentArg(matcher.GetMatchString().GetStringRef()); + return true; + }); } - void Clear() { m_format_map.Clear(); } - - void ForEach(ForEachCallback callback) { m_format_map.ForEach(callback); } - - uint32_t GetCount() { return m_format_map.GetCount(); } - protected: - BackEndType m_format_map; - std::string m_name; - FormattersContainer(const FormattersContainer &) = delete; const FormattersContainer &operator=(const FormattersContainer &) = delete; - void Add_Impl(MapKeyType type, const MapValueType &entry, - RegularExpression *dummy) { - m_format_map.Add(std::move(type), entry); - } - - void Add_Impl(ConstString type, const MapValueType &entry, - ConstString *dummy) { - m_format_map.Add(GetValidTypeName_Impl(type), entry); - } - - bool Delete_Impl(ConstString type, ConstString *dummy) { - return m_format_map.Delete(type); - } - - bool Delete_Impl(ConstString type, RegularExpression *dummy) { - std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - MapIterator pos, end = m_format_map.map().end(); - for (pos = m_format_map.map().begin(); pos != end; pos++) { - const RegularExpression ®ex = pos->first; - if (type.GetStringRef() == regex.GetText()) { - m_format_map.map().erase(pos); - if (m_format_map.listener) - m_format_map.listener->Changed(); - return true; - } - } - return false; - } - - bool Get_Impl(ConstString type, MapValueType &entry, ConstString *dummy) { - return m_format_map.Get(type, entry); - } - - bool GetExact_Impl(ConstString type, MapValueType &entry, - ConstString *dummy) { - return Get_Impl(type, entry, static_cast<KeyType *>(nullptr)); - } - - lldb::TypeNameSpecifierImplSP - GetTypeNameSpecifierAtIndex_Impl(size_t index, ConstString *dummy) { - ConstString key = m_format_map.GetKeyAtIndex(index); - if (key) - return lldb::TypeNameSpecifierImplSP( - new TypeNameSpecifierImpl(key.GetStringRef(), false)); - else - return lldb::TypeNameSpecifierImplSP(); - } - - lldb::TypeNameSpecifierImplSP - GetTypeNameSpecifierAtIndex_Impl(size_t index, RegularExpression *dummy) { - RegularExpression regex = m_format_map.GetKeyAtIndex(index); - if (regex == RegularExpression()) - return lldb::TypeNameSpecifierImplSP(); - return lldb::TypeNameSpecifierImplSP( - new TypeNameSpecifierImpl(regex.GetText().str().c_str(), true)); - } - - bool Get_Impl(ConstString key, MapValueType &value, - RegularExpression *dummy) { - llvm::StringRef key_str = key.GetStringRef(); - std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - // Patterns are matched in reverse-chronological order. - for (const auto &pos : llvm::reverse(m_format_map.map())) { - const RegularExpression ®ex = pos.first; - if (regex.Execute(key_str)) { - value = pos.second; - return true; - } - } - return false; - } - - bool GetExact_Impl(ConstString key, MapValueType &value, - RegularExpression *dummy) { - std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); - for (const auto &pos : m_format_map.map()) { - const RegularExpression ®ex = pos.first; - if (regex.GetText() == key.GetStringRef()) { - value = pos.second; - return true; - } - } - return false; - } - - bool Get(const FormattersMatchVector &candidates, MapValueType &entry) { + bool Get(const FormattersMatchVector &candidates, ValueSP &entry) { for (const FormattersMatchCandidate &candidate : candidates) { if (Get(candidate.GetTypeName(), entry)) { if (candidate.IsMatch(entry) == false) { @@ -319,6 +226,10 @@ protected: } return false; } + + MapType m_map; + std::recursive_mutex m_map_mutex; + IFormatChangeListener *listener; }; } // namespace lldb_private |