https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/143748
>From fc36d220f6e21b0a49e6f86b7972d1029813e4fc Mon Sep 17 00:00:00 2001 From: Nerixyz <nerix...@outlook.de> Date: Wed, 11 Jun 2025 18:11:20 +0200 Subject: [PATCH] [LLDB] Add optional callback function to `TypeMatcher` --- .../include/lldb/DataFormatters/FormatCache.h | 6 ++- .../lldb/DataFormatters/FormatClasses.h | 7 ++- .../lldb/DataFormatters/FormattersContainer.h | 11 ++++- lldb/include/lldb/DataFormatters/TypeFormat.h | 4 ++ .../include/lldb/DataFormatters/TypeSummary.h | 5 +++ .../lldb/DataFormatters/TypeSynthetic.h | 5 +++ .../lldb/DataFormatters/TypeValidator.h | 20 +++++++++ lldb/source/DataFormatters/FormatCache.cpp | 43 +++++++++++++------ lldb/source/DataFormatters/FormatManager.cpp | 2 +- .../DataFormatters/LanguageCategory.cpp | 2 +- 10 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 lldb/include/lldb/DataFormatters/TypeValidator.h diff --git a/lldb/include/lldb/DataFormatters/FormatCache.h b/lldb/include/lldb/DataFormatters/FormatCache.h index 3f1baa26a5a54..889a555f2c4c6 100644 --- a/lldb/include/lldb/DataFormatters/FormatCache.h +++ b/lldb/include/lldb/DataFormatters/FormatCache.h @@ -13,6 +13,7 @@ #include <map> #include <mutex> +#include "lldb/DataFormatters/FormatClasses.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-public.h" @@ -32,7 +33,7 @@ class FormatCache { public: Entry(); - template<typename ImplSP> bool IsCached(); + template <typename ImplSP> bool IsCached(FormattersMatchData &match_data); bool IsFormatCached(); bool IsSummaryCached(); bool IsSyntheticCached(); @@ -54,7 +55,8 @@ class FormatCache { public: FormatCache() = default; - template <typename ImplSP> bool Get(ConstString type, ImplSP &format_impl_sp); + template <typename ImplSP> + bool Get(FormattersMatchData &match_data, ImplSP &format_impl_sp); void Set(ConstString type, lldb::TypeFormatImplSP &format_sp); void Set(ConstString type, lldb::TypeSummaryImplSP &summary_sp); void Set(ConstString type, lldb::SyntheticChildrenSP &synthetic_sp); diff --git a/lldb/include/lldb/DataFormatters/FormatClasses.h b/lldb/include/lldb/DataFormatters/FormatClasses.h index 89d74649ecc64..9131a8919ec57 100644 --- a/lldb/include/lldb/DataFormatters/FormatClasses.h +++ b/lldb/include/lldb/DataFormatters/FormatClasses.h @@ -154,8 +154,8 @@ class TypeNameSpecifierImpl { TypeNameSpecifierImpl() = default; TypeNameSpecifierImpl(llvm::StringRef name, - lldb::FormatterMatchType match_type) - : m_match_type(match_type) { + lldb::FormatterMatchType match_type, uint32_t tag = 0) + : m_match_type(match_type), m_tag(tag) { m_type.m_type_name = std::string(name); } @@ -192,6 +192,8 @@ class TypeNameSpecifierImpl { bool IsRegex() { return m_match_type == lldb::eFormatterMatchRegex; } + uint32_t GetTag() const { return m_tag; } + private: lldb::FormatterMatchType m_match_type = lldb::eFormatterMatchExact; // TODO: Replace this with TypeAndOrName. @@ -200,6 +202,7 @@ class TypeNameSpecifierImpl { CompilerType m_compiler_type; }; TypeOrName m_type; + uint32_t m_tag = 0; TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete; const TypeNameSpecifierImpl & diff --git a/lldb/include/lldb/DataFormatters/FormattersContainer.h b/lldb/include/lldb/DataFormatters/FormattersContainer.h index f7465fc65538d..cec48cf508fb3 100644 --- a/lldb/include/lldb/DataFormatters/FormattersContainer.h +++ b/lldb/include/lldb/DataFormatters/FormattersContainer.h @@ -50,6 +50,7 @@ class TypeMatcher { /// - eFormatterMatchCallback: run the function in m_name to decide if a type /// matches or not. lldb::FormatterMatchType m_match_type; + uint32_t m_tag = 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 @@ -86,7 +87,8 @@ class TypeMatcher { /// name specifier. TypeMatcher(lldb::TypeNameSpecifierImplSP type_specifier) : m_name(type_specifier->GetName()), - m_match_type(type_specifier->GetMatchType()) { + m_match_type(type_specifier->GetMatchType()), + m_tag(type_specifier->GetTag()) { if (m_match_type == lldb::eFormatterMatchRegex) m_type_name_regex = RegularExpression(type_specifier->GetName()); } @@ -134,7 +136,7 @@ class TypeMatcher { /// (lldb) type summary add --summary-string \"A\" -x TypeName /// (lldb) type summary delete TypeName bool CreatedBySameMatchString(TypeMatcher other) const { - return GetMatchString() == other.GetMatchString(); + return GetMatchString() == other.GetMatchString() && m_tag == other.m_tag; } }; @@ -181,6 +183,11 @@ template <typename ValueType> class FormattersContainer { std::lock_guard<std::recursive_mutex> guard(m_map_mutex); for (auto &formatter : llvm::reverse(m_map)) { if (formatter.first.Matches(candidate)) { + if (formatter.second && formatter.second->GetTypeValidator() && + !formatter.second->GetTypeValidator()( + candidate.GetType().GetCompilerType(false))) + continue; + entry = formatter.second; return true; } diff --git a/lldb/include/lldb/DataFormatters/TypeFormat.h b/lldb/include/lldb/DataFormatters/TypeFormat.h index d242f9083d608..ec2b9afcdc9dc 100644 --- a/lldb/include/lldb/DataFormatters/TypeFormat.h +++ b/lldb/include/lldb/DataFormatters/TypeFormat.h @@ -151,10 +151,14 @@ class TypeFormatImpl { virtual std::string GetDescription() = 0; + CxxTypeValidatorFn *GetTypeValidator() const { return m_validator_fn; } + void SetTypeValidator(CxxTypeValidatorFn *value) { m_validator_fn = value; } + protected: Flags m_flags; uint32_t m_my_revision = 0; uint32_t m_ptr_match_depth = 1; + CxxTypeValidatorFn *m_validator_fn = nullptr; private: TypeFormatImpl(const TypeFormatImpl &) = delete; diff --git a/lldb/include/lldb/DataFormatters/TypeSummary.h b/lldb/include/lldb/DataFormatters/TypeSummary.h index 589f68c2ce314..14b4a2c797871 100644 --- a/lldb/include/lldb/DataFormatters/TypeSummary.h +++ b/lldb/include/lldb/DataFormatters/TypeSummary.h @@ -15,6 +15,7 @@ #include <memory> #include <string> +#include "lldb/DataFormatters/TypeValidator.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" @@ -276,6 +277,9 @@ class TypeSummaryImpl { uint32_t &GetRevision() { return m_my_revision; } + CxxTypeValidatorFn *GetTypeValidator() const { return m_validator_fn; } + void SetTypeValidator(CxxTypeValidatorFn *value) { m_validator_fn = value; } + typedef std::shared_ptr<TypeSummaryImpl> SharedPointer; protected: @@ -288,6 +292,7 @@ class TypeSummaryImpl { private: Kind m_kind; uint32_t m_ptr_match_depth = 1; + CxxTypeValidatorFn *m_validator_fn = nullptr; TypeSummaryImpl(const TypeSummaryImpl &) = delete; const TypeSummaryImpl &operator=(const TypeSummaryImpl &) = delete; }; diff --git a/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/lldb/include/lldb/DataFormatters/TypeSynthetic.h index 11a4ca2cd8330..a6856efce7df8 100644 --- a/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -277,12 +277,17 @@ class SyntheticChildren { void SetPtrMatchDepth(uint32_t value) { m_ptr_match_depth = value; } + CxxTypeValidatorFn *GetTypeValidator() const { return m_validator_fn; } + void SetTypeValidator(CxxTypeValidatorFn *value) { m_validator_fn = value; } + protected: uint32_t m_my_revision = 0; Flags m_flags; uint32_t m_ptr_match_depth = 1; private: + CxxTypeValidatorFn *m_validator_fn = nullptr; + SyntheticChildren(const SyntheticChildren &) = delete; const SyntheticChildren &operator=(const SyntheticChildren &) = delete; }; diff --git a/lldb/include/lldb/DataFormatters/TypeValidator.h b/lldb/include/lldb/DataFormatters/TypeValidator.h new file mode 100644 index 0000000000000..0981b7452ffca --- /dev/null +++ b/lldb/include/lldb/DataFormatters/TypeValidator.h @@ -0,0 +1,20 @@ +//===-- TypeValidator.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_DATAFORMATTERS_TYPEVALIDATOR_H +#define LLDB_DATAFORMATTERS_TYPEVALIDATOR_H + +#include "lldb/Symbol/CompilerType.h" + +namespace lldb_private { + +using CxxTypeValidatorFn = bool(const CompilerType &); + +} // namespace lldb_private + +#endif // LLDB_DATAFORMATTERS_TYPEVALIDATOR_H diff --git a/lldb/source/DataFormatters/FormatCache.cpp b/lldb/source/DataFormatters/FormatCache.cpp index 6c83b36e79dea..3f9160702afe4 100644 --- a/lldb/source/DataFormatters/FormatCache.cpp +++ b/lldb/source/DataFormatters/FormatCache.cpp @@ -53,23 +53,41 @@ void FormatCache::Entry::Set(lldb::SyntheticChildrenSP synthetic_sp) { namespace lldb_private { -template<> bool FormatCache::Entry::IsCached<lldb::TypeFormatImplSP>() { - return IsFormatCached(); +template <typename ImplSP> +static bool passesValidator(const ImplSP &impl_sp, + FormattersMatchData &match_data) { + if (!impl_sp || !impl_sp->GetTypeValidator()) + return true; + + ValueObject &valobj = match_data.GetValueObject(); + lldb::ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable( + match_data.GetDynamicValueType(), valobj.IsSynthetic()); + return valobj_sp && impl_sp->GetTypeValidator()(valobj_sp->GetCompilerType()); +} + +template <> +bool FormatCache::Entry::IsCached<lldb::TypeFormatImplSP>( + FormattersMatchData &match_data) { + return IsFormatCached() && passesValidator(m_format_sp, match_data); } -template<> bool FormatCache::Entry::IsCached<lldb::TypeSummaryImplSP> () { - return IsSummaryCached(); +template <> +bool FormatCache::Entry::IsCached<lldb::TypeSummaryImplSP>( + FormattersMatchData &match_data) { + return IsSummaryCached() && passesValidator(m_summary_sp, match_data); } -template<> bool FormatCache::Entry::IsCached<lldb::SyntheticChildrenSP>() { - return IsSyntheticCached(); +template <> +bool FormatCache::Entry::IsCached<lldb::SyntheticChildrenSP>( + FormattersMatchData &match_data) { + return IsSyntheticCached() && passesValidator(m_synthetic_sp, match_data); } } // namespace lldb_private template <typename ImplSP> -bool FormatCache::Get(ConstString type, ImplSP &format_impl_sp) { +bool FormatCache::Get(FormattersMatchData &match_data, ImplSP &format_impl_sp) { std::lock_guard<std::recursive_mutex> guard(m_mutex); - auto entry = m_entries[type]; - if (entry.IsCached<ImplSP>()) { + auto entry = m_entries[match_data.GetTypeForCache()]; + if (entry.IsCached<ImplSP>(match_data)) { m_cache_hits++; entry.Get(format_impl_sp); return true; @@ -82,12 +100,13 @@ bool FormatCache::Get(ConstString type, ImplSP &format_impl_sp) { /// Explicit instantiations for the three types. /// \{ template bool -FormatCache::Get<lldb::TypeFormatImplSP>(ConstString, lldb::TypeFormatImplSP &); +FormatCache::Get<lldb::TypeFormatImplSP>(FormattersMatchData &, + lldb::TypeFormatImplSP &); template bool -FormatCache::Get<lldb::TypeSummaryImplSP>(ConstString, +FormatCache::Get<lldb::TypeSummaryImplSP>(FormattersMatchData &, lldb::TypeSummaryImplSP &); template bool -FormatCache::Get<lldb::SyntheticChildrenSP>(ConstString, +FormatCache::Get<lldb::SyntheticChildrenSP>(FormattersMatchData &, lldb::SyntheticChildrenSP &); /// \} diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index 122f2304ead24..baec64cfb9c2d 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -657,7 +657,7 @@ ImplSP FormatManager::GetCached(FormattersMatchData &match_data) { if (match_data.GetTypeForCache()) { LLDB_LOGF(log, "\n\n" FORMAT_LOG("Looking into cache for type %s"), match_data.GetTypeForCache().AsCString("<invalid>")); - if (m_format_cache.Get(match_data.GetTypeForCache(), retval_sp)) { + if (m_format_cache.Get(match_data, retval_sp)) { if (log) { LLDB_LOGF(log, FORMAT_LOG("Cache search success. Returning.")); LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}", diff --git a/lldb/source/DataFormatters/LanguageCategory.cpp b/lldb/source/DataFormatters/LanguageCategory.cpp index 4794186ce9aec..4b6bc294fd711 100644 --- a/lldb/source/DataFormatters/LanguageCategory.cpp +++ b/lldb/source/DataFormatters/LanguageCategory.cpp @@ -40,7 +40,7 @@ bool LanguageCategory::Get(FormattersMatchData &match_data, return false; if (match_data.GetTypeForCache()) { - if (m_format_cache.Get(match_data.GetTypeForCache(), retval_sp)) + if (m_format_cache.Get(match_data, retval_sp)) return (bool)retval_sp; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits