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

Reply via email to