[Lldb-commits] [lldb] [LLDB] Add optional callback function to `TypeMatcher` (PR #143748)
via lldb-commits
lldb-commits at lists.llvm.org
Wed Jun 11 14:45:43 PDT 2025
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/143748
>From fc36d220f6e21b0a49e6f86b7972d1029813e4fc Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at 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;
}
More information about the lldb-commits
mailing list