Skip to content

[LLDB] Add optional callback function to TypeMatcher #143748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions lldb/include/lldb/DataFormatters/FormatCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <map>
#include <mutex>

#include "lldb/DataFormatters/FormatClasses.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-public.h"

Expand All @@ -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();
Expand All @@ -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);
Expand Down
7 changes: 5 additions & 2 deletions lldb/include/lldb/DataFormatters/FormatClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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.
Expand All @@ -200,6 +202,7 @@ class TypeNameSpecifierImpl {
CompilerType m_compiler_type;
};
TypeOrName m_type;
uint32_t m_tag = 0;

TypeNameSpecifierImpl(const TypeNameSpecifierImpl &) = delete;
const TypeNameSpecifierImpl &
Expand Down
11 changes: 9 additions & 2 deletions lldb/include/lldb/DataFormatters/FormattersContainer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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());
}
Expand Down Expand Up @@ -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;
}
};

Expand Down Expand Up @@ -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;
}
Expand Down
4 changes: 4 additions & 0 deletions lldb/include/lldb/DataFormatters/TypeFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions lldb/include/lldb/DataFormatters/TypeSummary.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <memory>
#include <string>

#include "lldb/DataFormatters/TypeValidator.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"

Expand Down Expand Up @@ -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:
Expand All @@ -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;
};
Expand Down
5 changes: 5 additions & 0 deletions lldb/include/lldb/DataFormatters/TypeSynthetic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down
20 changes: 20 additions & 0 deletions lldb/include/lldb/DataFormatters/TypeValidator.h
Original file line number Diff line number Diff line change
@@ -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
43 changes: 31 additions & 12 deletions lldb/source/DataFormatters/FormatCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 &);
/// \}

Expand Down
2 changes: 1 addition & 1 deletion lldb/source/DataFormatters/FormatManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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}",
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/DataFormatters/LanguageCategory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
Loading