forked from OSchip/llvm-project
Revert "[lldb] Unify type name matching in FormattersContainer"
This reverts commit 5b0de5756c
.
Apparently that caused some test to get stuck on Linuxx. Reverting for now.
This commit is contained in:
parent
4fe912f186
commit
e031eda08d
|
@ -69,9 +69,9 @@ public:
|
||||||
|
|
||||||
static void Clear();
|
static void Clear();
|
||||||
|
|
||||||
static void ForEach(std::function<bool(const TypeMatcher &,
|
static void
|
||||||
const lldb::TypeSummaryImplSP &)>
|
ForEach(std::function<bool(ConstString, const lldb::TypeSummaryImplSP &)>
|
||||||
callback);
|
callback);
|
||||||
|
|
||||||
static uint32_t GetCount();
|
static uint32_t GetCount();
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace lldb_private {
|
||||||
// this file's objects directly
|
// this file's objects directly
|
||||||
|
|
||||||
class FormatManager : public IFormatChangeListener {
|
class FormatManager : public IFormatChangeListener {
|
||||||
typedef FormatMap<TypeSummaryImpl> NamedSummariesMap;
|
typedef FormatMap<ConstString, TypeSummaryImpl> NamedSummariesMap;
|
||||||
typedef TypeCategoryMap::MapType::iterator CategoryMapIterator;
|
typedef TypeCategoryMap::MapType::iterator CategoryMapIterator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -144,6 +144,13 @@ public:
|
||||||
|
|
||||||
static const char *GetFormatAsCString(lldb::Format format);
|
static const char *GetFormatAsCString(lldb::Format format);
|
||||||
|
|
||||||
|
// 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
|
||||||
|
// method looks for the case where the user is adding a
|
||||||
|
// "class","struct","enum" or "union" Foo and strips the unnecessary
|
||||||
|
// qualifier
|
||||||
|
static ConstString GetValidTypeName(ConstString type);
|
||||||
|
|
||||||
// when DataExtractor dumps a vectorOfT, it uses a predefined format for each
|
// when DataExtractor dumps a vectorOfT, it uses a predefined format for each
|
||||||
// item this method returns it, or eFormatInvalid if vector_format is not a
|
// item this method returns it, or eFormatInvalid if vector_format is not a
|
||||||
// vectorOf
|
// vectorOf
|
||||||
|
|
|
@ -37,113 +37,57 @@ public:
|
||||||
virtual uint32_t GetCurrentRevision() = 0;
|
virtual uint32_t GetCurrentRevision() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Class for matching type names.
|
// if the user tries to add formatters for, say, "struct Foo" those will not
|
||||||
class TypeMatcher {
|
// match any type because of the way we strip qualifiers from typenames this
|
||||||
RegularExpression m_type_name_regex;
|
// method looks for the case where the user is adding a "class","struct","enum"
|
||||||
ConstString m_type_name;
|
// or "union" Foo and strips the unnecessary qualifier
|
||||||
/// False if m_type_name_regex should be used for matching. False if this is
|
static inline ConstString GetValidTypeName_Impl(ConstString type) {
|
||||||
/// just matching by comparing with m_type_name string.
|
if (type.IsEmpty())
|
||||||
bool m_is_regex;
|
return type;
|
||||||
/// True iff this TypeMatcher is invalid and shouldn't be used for any
|
|
||||||
/// type matching logic.
|
|
||||||
bool m_valid = true;
|
|
||||||
|
|
||||||
// if the user tries to add formatters for, say, "struct Foo" those will not
|
std::string type_cstr(type.AsCString());
|
||||||
// match any type because of the way we strip qualifiers from typenames this
|
StringLexer type_lexer(type_cstr);
|
||||||
// method looks for the case where the user is adding a
|
|
||||||
// "class","struct","enum" or "union" Foo and strips the unnecessary qualifier
|
|
||||||
static ConstString StripTypeName(ConstString type) {
|
|
||||||
if (type.IsEmpty())
|
|
||||||
return type;
|
|
||||||
|
|
||||||
std::string type_cstr(type.AsCString());
|
type_lexer.AdvanceIf("class ");
|
||||||
StringLexer type_lexer(type_cstr);
|
type_lexer.AdvanceIf("enum ");
|
||||||
|
type_lexer.AdvanceIf("struct ");
|
||||||
|
type_lexer.AdvanceIf("union ");
|
||||||
|
|
||||||
type_lexer.AdvanceIf("class ");
|
while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first)
|
||||||
type_lexer.AdvanceIf("enum ");
|
;
|
||||||
type_lexer.AdvanceIf("struct ");
|
|
||||||
type_lexer.AdvanceIf("union ");
|
|
||||||
|
|
||||||
while (type_lexer.NextIf({' ', '\t', '\v', '\f'}).first)
|
return ConstString(type_lexer.GetUnlexed());
|
||||||
;
|
}
|
||||||
|
|
||||||
return ConstString(type_lexer.GetUnlexed());
|
template <typename KeyType, typename ValueType> class FormattersContainer;
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
template <typename KeyType, typename ValueType> class FormatMap {
|
||||||
/// Creates an invalid matcher that should not be used for any type matching.
|
|
||||||
TypeMatcher() : m_valid(false) {}
|
|
||||||
/// 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) {}
|
|
||||||
/// Creates a matcher that accepts any type matching the given regex.
|
|
||||||
TypeMatcher(RegularExpression regex)
|
|
||||||
: m_type_name_regex(regex), m_is_regex(true) {}
|
|
||||||
|
|
||||||
/// True iff this matches the given type name.
|
|
||||||
bool Matches(ConstString type_name) const {
|
|
||||||
assert(m_valid && "Using invalid TypeMatcher");
|
|
||||||
|
|
||||||
if (m_is_regex)
|
|
||||||
return m_type_name_regex.Execute(type_name.GetStringRef());
|
|
||||||
return m_type_name == type_name ||
|
|
||||||
StripTypeName(m_type_name) == StripTypeName(type_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the underlying match string for this TypeMatcher.
|
|
||||||
ConstString GetMatchString() const {
|
|
||||||
assert(m_valid && "Using invalid TypeMatcher");
|
|
||||||
|
|
||||||
if (m_is_regex)
|
|
||||||
return ConstString(m_type_name_regex.GetText());
|
|
||||||
return StripTypeName(m_type_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if this TypeMatcher and the given one were most created by
|
|
||||||
/// the same match string.
|
|
||||||
/// The main purpose of this function is to find existing TypeMatcher
|
|
||||||
/// instances by the user input that created them. This is necessary as LLDB
|
|
||||||
/// allows referencing existing TypeMatchers in commands by the user input
|
|
||||||
/// that originally created them:
|
|
||||||
/// (lldb) type summary add --summary-string \"A\" -x TypeName
|
|
||||||
/// (lldb) type summary delete TypeName
|
|
||||||
bool CreatedBySameMatchString(TypeMatcher other) const {
|
|
||||||
assert(m_valid && "Using invalid TypeMatcher");
|
|
||||||
|
|
||||||
return GetMatchString() == other.GetMatchString();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ValueType> class FormattersContainer;
|
|
||||||
|
|
||||||
template <typename ValueType> class FormatMap {
|
|
||||||
public:
|
public:
|
||||||
typedef typename ValueType::SharedPointer ValueSP;
|
typedef typename ValueType::SharedPointer ValueSP;
|
||||||
typedef std::vector<std::pair<TypeMatcher, ValueSP>> MapType;
|
typedef std::vector<std::pair<KeyType, ValueSP>> MapType;
|
||||||
typedef typename MapType::iterator MapIterator;
|
typedef typename MapType::iterator MapIterator;
|
||||||
typedef std::function<bool(const TypeMatcher &, const ValueSP &)>
|
typedef std::function<bool(const KeyType &, const ValueSP &)> ForEachCallback;
|
||||||
ForEachCallback;
|
|
||||||
|
|
||||||
FormatMap(IFormatChangeListener *lst)
|
FormatMap(IFormatChangeListener *lst)
|
||||||
: m_map(), m_map_mutex(), listener(lst) {}
|
: m_map(), m_map_mutex(), listener(lst) {}
|
||||||
|
|
||||||
void Add(TypeMatcher matcher, const ValueSP &entry) {
|
void Add(KeyType name, const ValueSP &entry) {
|
||||||
if (listener)
|
if (listener)
|
||||||
entry->GetRevision() = listener->GetCurrentRevision();
|
entry->GetRevision() = listener->GetCurrentRevision();
|
||||||
else
|
else
|
||||||
entry->GetRevision() = 0;
|
entry->GetRevision() = 0;
|
||||||
|
|
||||||
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
||||||
Delete(matcher);
|
Delete(name);
|
||||||
m_map.emplace_back(std::move(matcher), std::move(entry));
|
m_map.emplace_back(std::move(name), std::move(entry));
|
||||||
if (listener)
|
if (listener)
|
||||||
listener->Changed();
|
listener->Changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Delete(const TypeMatcher &matcher) {
|
bool Delete(const KeyType &name) {
|
||||||
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
||||||
for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter)
|
for (MapIterator iter = m_map.begin(); iter != m_map.end(); ++iter)
|
||||||
if (iter->first.CreatedBySameMatchString(matcher)) {
|
if (iter->first == name) {
|
||||||
m_map.erase(iter);
|
m_map.erase(iter);
|
||||||
if (listener)
|
if (listener)
|
||||||
listener->Changed();
|
listener->Changed();
|
||||||
|
@ -159,10 +103,10 @@ public:
|
||||||
listener->Changed();
|
listener->Changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Get(const TypeMatcher &matcher, ValueSP &entry) {
|
bool Get(const KeyType &name, ValueSP &entry) {
|
||||||
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
||||||
for (const auto &pos : m_map)
|
for (const auto &pos : m_map)
|
||||||
if (pos.first.CreatedBySameMatchString(matcher)) {
|
if (pos.first == name) {
|
||||||
entry = pos.second;
|
entry = pos.second;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +117,7 @@ public:
|
||||||
if (callback) {
|
if (callback) {
|
||||||
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
||||||
for (const auto &pos : m_map) {
|
for (const auto &pos : m_map) {
|
||||||
const TypeMatcher &type = pos.first;
|
const KeyType &type = pos.first;
|
||||||
if (!callback(type, pos.second))
|
if (!callback(type, pos.second))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -190,10 +134,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// If caller holds the mutex we could return a reference without copy ctor.
|
// If caller holds the mutex we could return a reference without copy ctor.
|
||||||
llvm::Optional<TypeMatcher> GetKeyAtIndex(size_t index) {
|
KeyType GetKeyAtIndex(size_t index) {
|
||||||
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
|
||||||
if (index >= m_map.size())
|
if (index >= m_map.size())
|
||||||
return llvm::None;
|
return {};
|
||||||
return m_map[index].first;
|
return m_map[index].first;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,43 +150,41 @@ protected:
|
||||||
|
|
||||||
std::recursive_mutex &mutex() { return m_map_mutex; }
|
std::recursive_mutex &mutex() { return m_map_mutex; }
|
||||||
|
|
||||||
friend class FormattersContainer<ValueType>;
|
friend class FormattersContainer<KeyType, ValueType>;
|
||||||
friend class FormatManager;
|
friend class FormatManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ValueType> class FormattersContainer {
|
template <typename KeyType, typename ValueType> class FormattersContainer {
|
||||||
protected:
|
protected:
|
||||||
typedef FormatMap<ValueType> BackEndType;
|
typedef FormatMap<KeyType, ValueType> BackEndType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
typedef typename BackEndType::MapType MapType;
|
||||||
|
typedef typename MapType::iterator MapIterator;
|
||||||
|
typedef KeyType MapKeyType;
|
||||||
typedef std::shared_ptr<ValueType> MapValueType;
|
typedef std::shared_ptr<ValueType> MapValueType;
|
||||||
typedef typename BackEndType::ForEachCallback ForEachCallback;
|
typedef typename BackEndType::ForEachCallback ForEachCallback;
|
||||||
typedef typename std::shared_ptr<FormattersContainer<ValueType>>
|
typedef typename std::shared_ptr<FormattersContainer<KeyType, ValueType>>
|
||||||
SharedPointer;
|
SharedPointer;
|
||||||
|
|
||||||
friend class TypeCategoryImpl;
|
friend class TypeCategoryImpl;
|
||||||
|
|
||||||
FormattersContainer(IFormatChangeListener *lst) : m_format_map(lst) {}
|
FormattersContainer(IFormatChangeListener *lst) : m_format_map(lst) {}
|
||||||
|
|
||||||
void Add(TypeMatcher type, const MapValueType &entry) {
|
void Add(MapKeyType type, const MapValueType &entry) {
|
||||||
m_format_map.Add(std::move(type), entry);
|
Add_Impl(std::move(type), entry, static_cast<KeyType *>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Delete(TypeMatcher type) { return m_format_map.Delete(type); }
|
bool Delete(ConstString type) {
|
||||||
|
return Delete_Impl(type, static_cast<KeyType *>(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
bool Get(ConstString type, MapValueType &entry) {
|
bool Get(ConstString type, MapValueType &entry) {
|
||||||
std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
|
return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
|
||||||
for (auto &formatter : llvm::reverse(m_format_map.map())) {
|
|
||||||
if (formatter.first.Matches(type)) {
|
|
||||||
entry = formatter.second;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetExact(ConstString type, MapValueType &entry) {
|
bool GetExact(ConstString type, MapValueType &entry) {
|
||||||
return m_format_map.Get(type, entry);
|
return GetExact_Impl(type, entry, static_cast<KeyType *>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
MapValueType GetAtIndex(size_t index) {
|
MapValueType GetAtIndex(size_t index) {
|
||||||
|
@ -250,12 +192,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) {
|
lldb::TypeNameSpecifierImplSP GetTypeNameSpecifierAtIndex(size_t index) {
|
||||||
llvm::Optional<TypeMatcher> type_matcher =
|
return GetTypeNameSpecifierAtIndex_Impl(index,
|
||||||
m_format_map.GetKeyAtIndex(index);
|
static_cast<KeyType *>(nullptr));
|
||||||
if (!type_matcher)
|
|
||||||
return lldb::TypeNameSpecifierImplSP();
|
|
||||||
return lldb::TypeNameSpecifierImplSP(new TypeNameSpecifierImpl(
|
|
||||||
type_matcher->GetMatchString().GetStringRef(), true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Clear() { m_format_map.Clear(); }
|
void Clear() { m_format_map.Clear(); }
|
||||||
|
@ -270,6 +208,91 @@ protected:
|
||||||
FormattersContainer(const FormattersContainer &) = delete;
|
FormattersContainer(const FormattersContainer &) = delete;
|
||||||
const FormattersContainer &operator=(const FormattersContainer &) = delete;
|
const FormattersContainer &operator=(const FormattersContainer &) = delete;
|
||||||
|
|
||||||
|
void Add_Impl(MapKeyType type, const MapValueType &entry,
|
||||||
|
RegularExpression *dummy) {
|
||||||
|
m_format_map.Add(std::move(type), entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add_Impl(ConstString type, const MapValueType &entry,
|
||||||
|
ConstString *dummy) {
|
||||||
|
m_format_map.Add(GetValidTypeName_Impl(type), entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Delete_Impl(ConstString type, ConstString *dummy) {
|
||||||
|
return m_format_map.Delete(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Delete_Impl(ConstString type, RegularExpression *dummy) {
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
|
||||||
|
MapIterator pos, end = m_format_map.map().end();
|
||||||
|
for (pos = m_format_map.map().begin(); pos != end; pos++) {
|
||||||
|
const RegularExpression ®ex = pos->first;
|
||||||
|
if (type.GetStringRef() == regex.GetText()) {
|
||||||
|
m_format_map.map().erase(pos);
|
||||||
|
if (m_format_map.listener)
|
||||||
|
m_format_map.listener->Changed();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Get_Impl(ConstString type, MapValueType &entry, ConstString *dummy) {
|
||||||
|
return m_format_map.Get(type, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetExact_Impl(ConstString type, MapValueType &entry,
|
||||||
|
ConstString *dummy) {
|
||||||
|
return Get_Impl(type, entry, static_cast<KeyType *>(nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::TypeNameSpecifierImplSP
|
||||||
|
GetTypeNameSpecifierAtIndex_Impl(size_t index, ConstString *dummy) {
|
||||||
|
ConstString key = m_format_map.GetKeyAtIndex(index);
|
||||||
|
if (key)
|
||||||
|
return lldb::TypeNameSpecifierImplSP(
|
||||||
|
new TypeNameSpecifierImpl(key.GetStringRef(), false));
|
||||||
|
else
|
||||||
|
return lldb::TypeNameSpecifierImplSP();
|
||||||
|
}
|
||||||
|
|
||||||
|
lldb::TypeNameSpecifierImplSP
|
||||||
|
GetTypeNameSpecifierAtIndex_Impl(size_t index, RegularExpression *dummy) {
|
||||||
|
RegularExpression regex = m_format_map.GetKeyAtIndex(index);
|
||||||
|
if (regex == RegularExpression())
|
||||||
|
return lldb::TypeNameSpecifierImplSP();
|
||||||
|
return lldb::TypeNameSpecifierImplSP(
|
||||||
|
new TypeNameSpecifierImpl(regex.GetText().str().c_str(), true));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Get_Impl(ConstString key, MapValueType &value,
|
||||||
|
RegularExpression *dummy) {
|
||||||
|
llvm::StringRef key_str = key.GetStringRef();
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
|
||||||
|
// Patterns are matched in reverse-chronological order.
|
||||||
|
for (const auto &pos : llvm::reverse(m_format_map.map())) {
|
||||||
|
const RegularExpression ®ex = pos.first;
|
||||||
|
if (regex.Execute(key_str)) {
|
||||||
|
value = pos.second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetExact_Impl(ConstString key, MapValueType &value,
|
||||||
|
RegularExpression *dummy) {
|
||||||
|
std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex());
|
||||||
|
for (const auto &pos : m_format_map.map()) {
|
||||||
|
const RegularExpression ®ex = pos.first;
|
||||||
|
if (regex.GetText() == key.GetStringRef()) {
|
||||||
|
value = pos.second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool Get(const FormattersMatchVector &candidates, MapValueType &entry) {
|
bool Get(const FormattersMatchVector &candidates, MapValueType &entry) {
|
||||||
for (const FormattersMatchCandidate &candidate : candidates) {
|
for (const FormattersMatchCandidate &candidate : candidates) {
|
||||||
if (Get(candidate.GetTypeName(), entry)) {
|
if (Get(candidate.GetTypeName(), entry)) {
|
||||||
|
|
|
@ -25,11 +25,12 @@ namespace lldb_private {
|
||||||
|
|
||||||
template <typename FormatterImpl> class FormatterContainerPair {
|
template <typename FormatterImpl> class FormatterContainerPair {
|
||||||
public:
|
public:
|
||||||
typedef FormattersContainer<FormatterImpl> ExactMatchContainer;
|
typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer;
|
||||||
typedef FormattersContainer<FormatterImpl> RegexMatchContainer;
|
typedef FormattersContainer<RegularExpression, FormatterImpl>
|
||||||
|
RegexMatchContainer;
|
||||||
|
|
||||||
typedef TypeMatcher ExactMatchMap;
|
typedef typename ExactMatchContainer::MapType ExactMatchMap;
|
||||||
typedef TypeMatcher RegexMatchMap;
|
typedef typename RegexMatchContainer::MapType RegexMatchMap;
|
||||||
|
|
||||||
typedef typename ExactMatchContainer::MapValueType MapValueType;
|
typedef typename ExactMatchContainer::MapValueType MapValueType;
|
||||||
|
|
||||||
|
@ -347,13 +348,19 @@ private:
|
||||||
friend class LanguageCategory;
|
friend class LanguageCategory;
|
||||||
friend class TypeCategoryMap;
|
friend class TypeCategoryMap;
|
||||||
|
|
||||||
friend class FormattersContainer<TypeFormatImpl>;
|
friend class FormattersContainer<ConstString, TypeFormatImpl>;
|
||||||
|
friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>;
|
||||||
|
|
||||||
friend class FormattersContainer<TypeSummaryImpl>;
|
friend class FormattersContainer<ConstString, TypeSummaryImpl>;
|
||||||
|
friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>;
|
||||||
|
|
||||||
friend class FormattersContainer<TypeFilterImpl>;
|
friend class FormattersContainer<ConstString, TypeFilterImpl>;
|
||||||
|
friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>;
|
||||||
|
|
||||||
|
friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>;
|
||||||
|
friend class FormattersContainer<lldb::RegularExpressionSP,
|
||||||
|
ScriptedSyntheticChildren>;
|
||||||
|
|
||||||
friend class FormattersContainer<ScriptedSyntheticChildren>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
|
@ -103,7 +103,7 @@ private:
|
||||||
|
|
||||||
std::recursive_mutex &mutex() { return m_map_mutex; }
|
std::recursive_mutex &mutex() { return m_map_mutex; }
|
||||||
|
|
||||||
friend class FormattersContainer<ValueType>;
|
friend class FormattersContainer<KeyType, ValueType>;
|
||||||
friend class FormatManager;
|
friend class FormatManager;
|
||||||
};
|
};
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
|
@ -1066,15 +1066,13 @@ protected:
|
||||||
TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
|
TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
|
||||||
foreach
|
foreach
|
||||||
.SetExact([&result, &formatter_regex, &any_printed](
|
.SetExact([&result, &formatter_regex, &any_printed](
|
||||||
const TypeMatcher &type_matcher,
|
ConstString name,
|
||||||
const FormatterSharedPointer &format_sp) -> bool {
|
const FormatterSharedPointer &format_sp) -> bool {
|
||||||
if (formatter_regex) {
|
if (formatter_regex) {
|
||||||
bool escape = true;
|
bool escape = true;
|
||||||
if (type_matcher.CreatedBySameMatchString(
|
if (name.GetStringRef() == formatter_regex->GetText()) {
|
||||||
ConstString(formatter_regex->GetText()))) {
|
|
||||||
escape = false;
|
escape = false;
|
||||||
} else if (formatter_regex->Execute(
|
} else if (formatter_regex->Execute(name.GetStringRef())) {
|
||||||
type_matcher.GetMatchString().GetStringRef())) {
|
|
||||||
escape = false;
|
escape = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1083,23 +1081,20 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
any_printed = true;
|
any_printed = true;
|
||||||
result.GetOutputStream().Printf(
|
result.GetOutputStream().Printf("%s: %s\n", name.AsCString(),
|
||||||
"%s: %s\n", type_matcher.GetMatchString().GetCString(),
|
format_sp->GetDescription().c_str());
|
||||||
format_sp->GetDescription().c_str());
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach
|
foreach
|
||||||
.SetWithRegex([&result, &formatter_regex, &any_printed](
|
.SetWithRegex([&result, &formatter_regex, &any_printed](
|
||||||
const TypeMatcher &type_matcher,
|
const RegularExpression ®ex,
|
||||||
const FormatterSharedPointer &format_sp) -> bool {
|
const FormatterSharedPointer &format_sp) -> bool {
|
||||||
if (formatter_regex) {
|
if (formatter_regex) {
|
||||||
bool escape = true;
|
bool escape = true;
|
||||||
if (type_matcher.CreatedBySameMatchString(
|
if (regex.GetText() == formatter_regex->GetText()) {
|
||||||
ConstString(formatter_regex->GetText()))) {
|
|
||||||
escape = false;
|
escape = false;
|
||||||
} else if (formatter_regex->Execute(
|
} else if (formatter_regex->Execute(regex.GetText())) {
|
||||||
type_matcher.GetMatchString().GetStringRef())) {
|
|
||||||
escape = false;
|
escape = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,9 +1103,9 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
any_printed = true;
|
any_printed = true;
|
||||||
result.GetOutputStream().Printf(
|
result.GetOutputStream().Printf("%s: %s\n",
|
||||||
"%s: %s\n", type_matcher.GetMatchString().GetCString(),
|
regex.GetText().str().c_str(),
|
||||||
format_sp->GetDescription().c_str());
|
format_sp->GetDescription().c_str());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1686,10 +1681,10 @@ protected:
|
||||||
if (DataVisualization::NamedSummaryFormats::GetCount() > 0) {
|
if (DataVisualization::NamedSummaryFormats::GetCount() > 0) {
|
||||||
result.GetOutputStream().Printf("Named summaries:\n");
|
result.GetOutputStream().Printf("Named summaries:\n");
|
||||||
DataVisualization::NamedSummaryFormats::ForEach(
|
DataVisualization::NamedSummaryFormats::ForEach(
|
||||||
[&result](const TypeMatcher &type_matcher,
|
[&result](ConstString name,
|
||||||
const TypeSummaryImplSP &summary_sp) -> bool {
|
const TypeSummaryImplSP &summary_sp) -> bool {
|
||||||
result.GetOutputStream().Printf(
|
result.GetOutputStream().Printf(
|
||||||
"%s: %s\n", type_matcher.GetMatchString().GetCString(),
|
"%s: %s\n", name.AsCString(),
|
||||||
summary_sp->GetDescription().c_str());
|
summary_sp->GetDescription().c_str());
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
|
@ -174,7 +174,8 @@ bool DataVisualization::NamedSummaryFormats::GetSummaryFormat(
|
||||||
|
|
||||||
void DataVisualization::NamedSummaryFormats::Add(
|
void DataVisualization::NamedSummaryFormats::Add(
|
||||||
ConstString type, const lldb::TypeSummaryImplSP &entry) {
|
ConstString type, const lldb::TypeSummaryImplSP &entry) {
|
||||||
GetFormatManager().GetNamedSummaryContainer().Add(type, entry);
|
GetFormatManager().GetNamedSummaryContainer().Add(
|
||||||
|
FormatManager::GetValidTypeName(type), entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DataVisualization::NamedSummaryFormats::Delete(ConstString type) {
|
bool DataVisualization::NamedSummaryFormats::Delete(ConstString type) {
|
||||||
|
@ -186,7 +187,7 @@ void DataVisualization::NamedSummaryFormats::Clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataVisualization::NamedSummaryFormats::ForEach(
|
void DataVisualization::NamedSummaryFormats::ForEach(
|
||||||
std::function<bool(const TypeMatcher &, const lldb::TypeSummaryImplSP &)>
|
std::function<bool(ConstString, const lldb::TypeSummaryImplSP &)>
|
||||||
callback) {
|
callback) {
|
||||||
GetFormatManager().GetNamedSummaryContainer().ForEach(callback);
|
GetFormatManager().GetNamedSummaryContainer().ForEach(callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -551,6 +551,10 @@ bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConstString FormatManager::GetValidTypeName(ConstString type) {
|
||||||
|
return ::GetValidTypeName_Impl(type);
|
||||||
|
}
|
||||||
|
|
||||||
ConstString FormatManager::GetTypeForCache(ValueObject &valobj,
|
ConstString FormatManager::GetTypeForCache(ValueObject &valobj,
|
||||||
lldb::DynamicValueType use_dynamic) {
|
lldb::DynamicValueType use_dynamic) {
|
||||||
ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(
|
ValueObjectSP valobj_sp = valobj.GetQualifiedRepresentationIfAvailable(
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
add_lldb_unittest(LLDBFormatterTests
|
add_lldb_unittest(LLDBFormatterTests
|
||||||
FormatManagerTests.cpp
|
FormatManagerTests.cpp
|
||||||
FormattersContainerTest.cpp
|
|
||||||
StringPrinterTests.cpp
|
StringPrinterTests.cpp
|
||||||
|
|
||||||
LINK_LIBS
|
LINK_LIBS
|
||||||
|
|
|
@ -1,159 +0,0 @@
|
||||||
//===-- FormattersContainerTests.cpp --------------------------------------===//
|
|
||||||
//
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
#include "lldb/DataFormatters/FormattersContainer.h"
|
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
using namespace lldb;
|
|
||||||
using namespace lldb_private;
|
|
||||||
|
|
||||||
// All the prefixes that the exact name matching will strip from the type.
|
|
||||||
static const std::vector<std::string> exact_name_prefixes = {
|
|
||||||
"", // no prefix.
|
|
||||||
"class ", "struct ", "union ", "enum ",
|
|
||||||
};
|
|
||||||
|
|
||||||
// TypeMatcher that uses a exact type name string that needs to be matched.
|
|
||||||
TEST(TypeMatcherTests, ExactName) {
|
|
||||||
for (const std::string &prefix : exact_name_prefixes) {
|
|
||||||
SCOPED_TRACE("Prefix: " + prefix);
|
|
||||||
|
|
||||||
TypeMatcher matcher(ConstString(prefix + "Name"));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("class Name")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("struct Name")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("union Name")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("enum Name")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("Name")));
|
|
||||||
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("Name ")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("ame")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("Nam")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("am")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("a")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString(" ")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("class N")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("class ")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("class")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypeMatcher that uses a regex to match a type name.
|
|
||||||
TEST(TypeMatcherTests, RegexName) {
|
|
||||||
TypeMatcher matcher(RegularExpression("^a[a-z]c$"));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("abc")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("azc")));
|
|
||||||
|
|
||||||
// FIXME: This isn't consistent with the 'exact' type name matches above.
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("class abc")));
|
|
||||||
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("abbc")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString(" abc")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("abc ")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString(" abc ")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("XabcX")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("ac")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("a[a-z]c")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("aAc")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("ABC")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TypeMatcher that only searches the type name.
|
|
||||||
TEST(TypeMatcherTests, RegexMatchPart) {
|
|
||||||
TypeMatcher matcher(RegularExpression("a[a-z]c"));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("class abc")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("abc")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString(" abc ")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("azc")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("abc ")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString(" abc ")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString(" abc")));
|
|
||||||
EXPECT_TRUE(matcher.Matches(ConstString("XabcX")));
|
|
||||||
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("abbc")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("ac")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("a[a-z]c")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("aAc")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("ABC")));
|
|
||||||
EXPECT_FALSE(matcher.Matches(ConstString("")));
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMatchString for exact type name matchers.
|
|
||||||
TEST(TypeMatcherTests, GetMatchStringExactName) {
|
|
||||||
EXPECT_EQ(TypeMatcher(ConstString("aa")).GetMatchString(), "aa");
|
|
||||||
EXPECT_EQ(TypeMatcher(ConstString("")).GetMatchString(), "");
|
|
||||||
EXPECT_EQ(TypeMatcher(ConstString("[a]")).GetMatchString(), "[a]");
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMatchString for regex matchers.
|
|
||||||
TEST(TypeMatcherTests, GetMatchStringRegex) {
|
|
||||||
EXPECT_EQ(TypeMatcher(RegularExpression("aa")).GetMatchString(), "aa");
|
|
||||||
EXPECT_EQ(TypeMatcher(RegularExpression("")).GetMatchString(), "");
|
|
||||||
EXPECT_EQ(TypeMatcher(RegularExpression("[a]")).GetMatchString(), "[a]");
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetMatchString for regex matchers.
|
|
||||||
TEST(TypeMatcherTests, CreatedBySameMatchString) {
|
|
||||||
TypeMatcher empty_str(ConstString(""));
|
|
||||||
TypeMatcher empty_regex(RegularExpression(""));
|
|
||||||
EXPECT_TRUE(empty_str.CreatedBySameMatchString(empty_str));
|
|
||||||
EXPECT_TRUE(empty_str.CreatedBySameMatchString(empty_regex));
|
|
||||||
|
|
||||||
TypeMatcher a_str(ConstString("a"));
|
|
||||||
TypeMatcher a_regex(RegularExpression("a"));
|
|
||||||
EXPECT_TRUE(a_str.CreatedBySameMatchString(a_str));
|
|
||||||
EXPECT_TRUE(a_str.CreatedBySameMatchString(a_regex));
|
|
||||||
|
|
||||||
TypeMatcher digit_str(ConstString("[0-9]"));
|
|
||||||
TypeMatcher digit_regex(RegularExpression("[0-9]"));
|
|
||||||
EXPECT_TRUE(digit_str.CreatedBySameMatchString(digit_str));
|
|
||||||
EXPECT_TRUE(digit_str.CreatedBySameMatchString(digit_regex));
|
|
||||||
|
|
||||||
EXPECT_FALSE(empty_str.CreatedBySameMatchString(a_str));
|
|
||||||
EXPECT_FALSE(empty_str.CreatedBySameMatchString(a_regex));
|
|
||||||
EXPECT_FALSE(empty_str.CreatedBySameMatchString(digit_str));
|
|
||||||
EXPECT_FALSE(empty_str.CreatedBySameMatchString(digit_regex));
|
|
||||||
|
|
||||||
EXPECT_FALSE(empty_regex.CreatedBySameMatchString(a_str));
|
|
||||||
EXPECT_FALSE(empty_regex.CreatedBySameMatchString(a_regex));
|
|
||||||
EXPECT_FALSE(empty_regex.CreatedBySameMatchString(digit_str));
|
|
||||||
EXPECT_FALSE(empty_regex.CreatedBySameMatchString(digit_regex));
|
|
||||||
|
|
||||||
EXPECT_FALSE(a_str.CreatedBySameMatchString(empty_str));
|
|
||||||
EXPECT_FALSE(a_str.CreatedBySameMatchString(empty_regex));
|
|
||||||
EXPECT_FALSE(a_str.CreatedBySameMatchString(digit_str));
|
|
||||||
EXPECT_FALSE(a_str.CreatedBySameMatchString(digit_regex));
|
|
||||||
|
|
||||||
EXPECT_FALSE(a_regex.CreatedBySameMatchString(empty_str));
|
|
||||||
EXPECT_FALSE(a_regex.CreatedBySameMatchString(empty_regex));
|
|
||||||
EXPECT_FALSE(a_regex.CreatedBySameMatchString(digit_str));
|
|
||||||
EXPECT_FALSE(a_regex.CreatedBySameMatchString(digit_regex));
|
|
||||||
|
|
||||||
EXPECT_FALSE(digit_str.CreatedBySameMatchString(empty_str));
|
|
||||||
EXPECT_FALSE(digit_str.CreatedBySameMatchString(empty_regex));
|
|
||||||
EXPECT_FALSE(digit_str.CreatedBySameMatchString(a_str));
|
|
||||||
EXPECT_FALSE(digit_str.CreatedBySameMatchString(a_regex));
|
|
||||||
|
|
||||||
EXPECT_FALSE(digit_regex.CreatedBySameMatchString(empty_str));
|
|
||||||
EXPECT_FALSE(digit_regex.CreatedBySameMatchString(empty_regex));
|
|
||||||
EXPECT_FALSE(digit_regex.CreatedBySameMatchString(a_str));
|
|
||||||
EXPECT_FALSE(digit_regex.CreatedBySameMatchString(a_regex));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test CreatedBySameMatchString with stripped exact name prefixes.
|
|
||||||
TEST(TypeMatcherTests, CreatedBySameMatchStringExactNamePrefixes) {
|
|
||||||
for (const std::string &prefix : exact_name_prefixes) {
|
|
||||||
SCOPED_TRACE("Prefix: " + prefix);
|
|
||||||
TypeMatcher with_prefix(ConstString(prefix + "Name"));
|
|
||||||
TypeMatcher without_prefix(RegularExpression(""));
|
|
||||||
|
|
||||||
EXPECT_TRUE(with_prefix.CreatedBySameMatchString(with_prefix));
|
|
||||||
EXPECT_TRUE(without_prefix.CreatedBySameMatchString(without_prefix));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue