diff --git a/lldb/bindings/interface/SBTypeNameSpecifier.i b/lldb/bindings/interface/SBTypeNameSpecifier.i --- a/lldb/bindings/interface/SBTypeNameSpecifier.i +++ b/lldb/bindings/interface/SBTypeNameSpecifier.i @@ -20,6 +20,9 @@ SBTypeNameSpecifier (const char* name, bool is_regex = false); + SBTypeNameSpecifier (const char* name, + lldb::FormatterMatchType match_type); + SBTypeNameSpecifier (SBType type); SBTypeNameSpecifier (const lldb::SBTypeNameSpecifier &rhs); @@ -40,6 +43,9 @@ lldb::SBType GetType (); + lldb::FormatterMatchType + GetMatchType(); + bool IsRegex(); diff --git a/lldb/include/lldb/API/SBTypeNameSpecifier.h b/lldb/include/lldb/API/SBTypeNameSpecifier.h --- a/lldb/include/lldb/API/SBTypeNameSpecifier.h +++ b/lldb/include/lldb/API/SBTypeNameSpecifier.h @@ -20,6 +20,9 @@ SBTypeNameSpecifier(const char *name, bool is_regex = false); + SBTypeNameSpecifier(const char *name, + lldb::FormatterMatchType match_type); + SBTypeNameSpecifier(SBType type); SBTypeNameSpecifier(const lldb::SBTypeNameSpecifier &rhs); @@ -34,6 +37,8 @@ SBType GetType(); + lldb::FormatterMatchType GetMatchType(); + bool IsRegex(); bool GetDescription(lldb::SBStream &description, diff --git a/lldb/include/lldb/DataFormatters/FormatClasses.h b/lldb/include/lldb/DataFormatters/FormatClasses.h --- a/lldb/include/lldb/DataFormatters/FormatClasses.h +++ b/lldb/include/lldb/DataFormatters/FormatClasses.h @@ -133,21 +133,23 @@ public: TypeNameSpecifierImpl() = default; - TypeNameSpecifierImpl(llvm::StringRef name, bool is_regex) - : m_is_regex(is_regex) { + TypeNameSpecifierImpl(llvm::StringRef name, + lldb::FormatterMatchType match_type) + : m_match_type(match_type) { m_type.m_type_name = std::string(name); } - // if constructing with a given type, is_regex cannot be true since we are - // giving an exact type to match - TypeNameSpecifierImpl(lldb::TypeSP type) : m_is_regex(false) { + // if constructing with a given type, we consider that a case of exact match. + TypeNameSpecifierImpl(lldb::TypeSP type) + : m_match_type(lldb::eFormatterMatchExact) { if (type) { m_type.m_type_name = std::string(type->GetName().GetStringRef()); m_type.m_compiler_type = type->GetForwardCompilerType(); } } - TypeNameSpecifierImpl(CompilerType type) : m_is_regex(false) { + TypeNameSpecifierImpl(CompilerType type) + : m_match_type(lldb::eFormatterMatchExact) { if (type.IsValid()) { m_type.m_type_name.assign(type.GetTypeName().GetCString()); m_type.m_compiler_type = type; @@ -166,10 +168,12 @@ return CompilerType(); } - bool IsRegex() { return m_is_regex; } + lldb::FormatterMatchType GetMatchType() { return m_match_type; } + + bool IsRegex() { return m_match_type == lldb::eFormatterMatchRegex; } private: - bool m_is_regex = false; + lldb::FormatterMatchType m_match_type = lldb::eFormatterMatchExact; // TODO: Replace this with TypeAndOrName. struct TypeOrName { std::string m_type_name; diff --git a/lldb/include/lldb/DataFormatters/FormattersContainer.h b/lldb/include/lldb/DataFormatters/FormattersContainer.h --- a/lldb/include/lldb/DataFormatters/FormattersContainer.h +++ b/lldb/include/lldb/DataFormatters/FormattersContainer.h @@ -41,9 +41,11 @@ 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; + /// Indicates what kind of matching strategy should be used: + /// - eFormatterMatchExact: match the exact type name in m_type_name. + /// - eFormatterMatchRegex: match using the RegularExpression object + /// `m_type_name_regex` instead. + lldb::FormatterMatchType m_match_type; // 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 @@ -71,22 +73,25 @@ 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) {} + : m_type_name(type_name), m_match_type(lldb::eFormatterMatchExact) {} /// 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) {} + : m_type_name_regex(std::move(regex)), + m_match_type(lldb::eFormatterMatchRegex) {} /// True iff this matches the given type name. bool Matches(ConstString type_name) const { - if (m_is_regex) + if (m_match_type == lldb::eFormatterMatchRegex) return m_type_name_regex.Execute(type_name.GetStringRef()); return m_type_name == type_name || StripTypeName(m_type_name) == StripTypeName(type_name); } + lldb::FormatterMatchType GetMatchType() const { return m_match_type; } + /// Returns the underlying match string for this TypeMatcher. ConstString GetMatchString() const { - if (m_is_regex) + if (m_match_type == lldb::eFormatterMatchRegex) return ConstString(m_type_name_regex.GetText()); return StripTypeName(m_type_name); } @@ -176,7 +181,8 @@ return lldb::TypeNameSpecifierImplSP(); TypeMatcher type_matcher = m_map[index].first; return std::make_shared( - type_matcher.GetMatchString().GetStringRef(), true); + type_matcher.GetMatchString().GetStringRef(), + type_matcher.GetMatchType()); } void Clear() { diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -832,6 +832,15 @@ eTemplateArgumentKindNullPtr, }; +/// Type of match to be performed when looking for a formatter for a data type. +/// Used by classes like SBTypeNameSpecifier or lldb_private::TypeMatcher. +enum FormatterMatchType { + eFormatterMatchExact, + eFormatterMatchRegex, + + eLastFormatterMatchType = eFormatterMatchRegex, +}; + /// Options that can be set for a formatter to alter its behavior. Not /// all of these are applicable to all formatter types. FLAGS_ENUM(TypeOptions){eTypeOptionNone = (0u), diff --git a/lldb/source/API/SBTypeNameSpecifier.cpp b/lldb/source/API/SBTypeNameSpecifier.cpp --- a/lldb/source/API/SBTypeNameSpecifier.cpp +++ b/lldb/source/API/SBTypeNameSpecifier.cpp @@ -20,8 +20,15 @@ SBTypeNameSpecifier::SBTypeNameSpecifier() { LLDB_INSTRUMENT_VA(this); } SBTypeNameSpecifier::SBTypeNameSpecifier(const char *name, bool is_regex) - : m_opaque_sp(new TypeNameSpecifierImpl(name, is_regex)) { + : SBTypeNameSpecifier(name, is_regex ? eFormatterMatchRegex + : eFormatterMatchExact) { LLDB_INSTRUMENT_VA(this, name, is_regex); +} + +SBTypeNameSpecifier::SBTypeNameSpecifier(const char *name, + FormatterMatchType match_type) + : m_opaque_sp(new TypeNameSpecifierImpl(name, match_type)) { + LLDB_INSTRUMENT_VA(this, name, match_type); if (name == nullptr || (*name) == 0) m_opaque_sp.reset(); @@ -72,13 +79,20 @@ return SBType(); } +FormatterMatchType SBTypeNameSpecifier::GetMatchType() { + LLDB_INSTRUMENT_VA(this); + if (!IsValid()) + return eFormatterMatchExact; + return m_opaque_sp->GetMatchType(); +} + bool SBTypeNameSpecifier::IsRegex() { LLDB_INSTRUMENT_VA(this); if (!IsValid()) return false; - return m_opaque_sp->IsRegex(); + return m_opaque_sp->GetMatchType() == eFormatterMatchRegex; } bool SBTypeNameSpecifier::GetDescription( @@ -116,7 +130,7 @@ if (!IsValid()) return !rhs.IsValid(); - if (IsRegex() != rhs.IsRegex()) + if (GetMatchType() != rhs.GetMatchType()) return false; if (GetName() == nullptr || rhs.GetName() == nullptr) return false; diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -825,7 +825,7 @@ bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize()); auto type_sp = std::make_shared( - bitfield_name.GetString(), false); + bitfield_name.GetString(), lldb::eFormatterMatchExact); if (val_obj_display == ValueObject::eValueObjectRepresentationStyleSummary && !DataVisualization::GetSummaryForType(type_sp))