llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-llvm-support Author: Vitaly Buka (vitalybuka) <details> <summary>Changes</summary> This commit moves the `RegexMatcher`, `GlobMatcher`, `Matcher` and `Section` classes into an anonymous namespace within `SpecialCaseList.cpp`. These classes are implementation details of `SpecialCaseList` and do not need to be exposed in the header. --- Full diff: https://github.com/llvm/llvm-project/pull/167280.diff 2 Files Affected: - (modified) llvm/include/llvm/Support/SpecialCaseList.h (+7-90) - (modified) llvm/lib/Support/SpecialCaseList.cpp (+136-34) ``````````diff diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index 8c4dc94ae54ce..5785dad7406df 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -12,19 +12,11 @@ #ifndef LLVM_SUPPORT_SPECIALCASELIST_H #define LLVM_SUPPORT_SPECIALCASELIST_H -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/RadixTree.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/GlobPattern.h" -#include "llvm/Support/Regex.h" +#include "llvm/Support/Error.h" #include <memory> #include <string> #include <utility> -#include <variant> #include <vector> namespace llvm { @@ -125,83 +117,11 @@ class SpecialCaseList { SpecialCaseList(SpecialCaseList const &) = delete; SpecialCaseList &operator=(SpecialCaseList const &) = delete; -private: - using Match = std::pair<StringRef, unsigned>; - static constexpr Match NotMatched = {"", 0}; - - // Lagacy v1 matcher. - class RegexMatcher { - public: - LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber); - LLVM_ABI void preprocess(bool BySize); - - LLVM_ABI Match match(StringRef Query) const; - - struct Reg { - Reg(StringRef Name, unsigned LineNo, Regex &&Rg) - : Name(Name), LineNo(LineNo), Rg(std::move(Rg)) {} - StringRef Name; - unsigned LineNo; - Regex Rg; - }; - - std::vector<Reg> RegExes; - }; - - class GlobMatcher { - public: - LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber); - LLVM_ABI void preprocess(bool BySize); - - LLVM_ABI Match match(StringRef Query) const; - - struct Glob { - Glob(StringRef Name, unsigned LineNo, GlobPattern &&Pattern) - : Name(Name), LineNo(LineNo), Pattern(std::move(Pattern)) {} - StringRef Name; - unsigned LineNo; - GlobPattern Pattern; - }; - - std::vector<GlobMatcher::Glob> Globs; - - RadixTree<iterator_range<StringRef::const_iterator>, - RadixTree<iterator_range<StringRef::const_reverse_iterator>, - SmallVector<int, 1>>> - PrefixSuffixToGlob; - - RadixTree<iterator_range<StringRef::const_iterator>, SmallVector<int, 1>> - SubstrToGlob; - }; - - /// Represents a set of patterns and their line numbers - class Matcher { - public: - LLVM_ABI Matcher(bool UseGlobs, bool RemoveDotSlash); - - LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber); - LLVM_ABI void preprocess(bool BySize); - - LLVM_ABI Match match(StringRef Query) const; - - LLVM_ABI bool matchAny(StringRef Query) const { - return match(Query) != NotMatched; - } - - std::variant<RegexMatcher, GlobMatcher> M; - bool RemoveDotSlash; - }; - - using SectionEntries = StringMap<StringMap<Matcher>>; - -protected: class Section { public: - Section(StringRef Name, unsigned FileIdx, bool UseGlobs) - : SectionMatcher(UseGlobs, /*RemoveDotSlash=*/false), Name(Name), - FileIdx(FileIdx) {} - - Section(Section &&) = default; + LLVM_ABI Section(StringRef Name, unsigned FileIdx, bool UseGlobs); + LLVM_ABI Section(Section &&); + LLVM_ABI ~Section(); // Return name of the section, it's entire string in []. StringRef name() const { return Name; } @@ -227,17 +147,14 @@ class SpecialCaseList { private: friend class SpecialCaseList; - LLVM_ABI void preprocess(bool OrderBySize); - LLVM_ABI const SpecialCaseList::Matcher * - findMatcher(StringRef Prefix, StringRef Category) const; + class SectionImpl; - Matcher SectionMatcher; StringRef Name; - SectionEntries Entries; unsigned FileIdx; + std::unique_ptr<SectionImpl> Impl; }; - ArrayRef<const Section> sections() const { return Sections; } + const std::vector<Section> §ions() const; private: BumpPtrAllocator StrAlloc; diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index 42c8933a43399..cf01f59fa37f6 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -14,26 +14,94 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/SpecialCaseList.h" +#include "llvm/ADT/RadixTree.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/GlobPattern.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Regex.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" -#include <algorithm> -#include <limits> #include <memory> #include <stdio.h> #include <string> #include <system_error> #include <utility> +#include <variant> +#include <vector> namespace llvm { -Error SpecialCaseList::RegexMatcher::insert(StringRef Pattern, - unsigned LineNumber) { +namespace { + +using Match = std::pair<StringRef, unsigned>; +static constexpr Match NotMatched = {"", 0}; + +// Lagacy v1 matcher. +class RegexMatcher { +public: + Error insert(StringRef Pattern, unsigned LineNumber); + void preprocess(bool BySize); + + Match match(StringRef Query) const; + + struct Reg { + Reg(StringRef Name, unsigned LineNo, Regex &&Rg) + : Name(Name), LineNo(LineNo), Rg(std::move(Rg)) {} + StringRef Name; + unsigned LineNo; + Regex Rg; + }; + + std::vector<Reg> RegExes; +}; + +class GlobMatcher { +public: + Error insert(StringRef Pattern, unsigned LineNumber); + void preprocess(bool BySize); + + Match match(StringRef Query) const; + + struct Glob { + Glob(StringRef Name, unsigned LineNo, GlobPattern &&Pattern) + : Name(Name), LineNo(LineNo), Pattern(std::move(Pattern)) {} + StringRef Name; + unsigned LineNo; + GlobPattern Pattern; + }; + + std::vector<GlobMatcher::Glob> Globs; + + RadixTree<iterator_range<StringRef::const_iterator>, + RadixTree<iterator_range<StringRef::const_reverse_iterator>, + SmallVector<int, 1>>> + PrefixSuffixToGlob; + + RadixTree<iterator_range<StringRef::const_iterator>, SmallVector<int, 1>> + SubstrToGlob; +}; + +/// Represents a set of patterns and their line numbers +class Matcher { +public: + Matcher(bool UseGlobs, bool RemoveDotSlash); + + Error insert(StringRef Pattern, unsigned LineNumber); + void preprocess(bool BySize); + Match match(StringRef Query) const; + + bool matchAny(StringRef Query) const { return match(Query).second > 0; } + + std::variant<RegexMatcher, GlobMatcher> M; + bool RemoveDotSlash; +}; + +Error RegexMatcher::insert(StringRef Pattern, unsigned LineNumber) { if (Pattern.empty()) return createStringError(errc::invalid_argument, "Supplied regex was blank"); @@ -57,7 +125,7 @@ Error SpecialCaseList::RegexMatcher::insert(StringRef Pattern, return Error::success(); } -void SpecialCaseList::RegexMatcher::preprocess(bool BySize) { +void RegexMatcher::preprocess(bool BySize) { if (BySize) { llvm::stable_sort(RegExes, [](const Reg &A, const Reg &B) { return A.Name.size() < B.Name.size(); @@ -65,16 +133,14 @@ void SpecialCaseList::RegexMatcher::preprocess(bool BySize) { } } -SpecialCaseList::Match -SpecialCaseList::RegexMatcher::match(StringRef Query) const { +Match RegexMatcher::match(StringRef Query) const { for (const auto &R : reverse(RegExes)) if (R.Rg.match(Query)) return {R.Name, R.LineNo}; return NotMatched; } -Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern, - unsigned LineNumber) { +Error GlobMatcher::insert(StringRef Pattern, unsigned LineNumber) { if (Pattern.empty()) return createStringError(errc::invalid_argument, "Supplied glob was blank"); @@ -85,7 +151,7 @@ Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern, return Error::success(); } -void SpecialCaseList::GlobMatcher::preprocess(bool BySize) { +void GlobMatcher::preprocess(bool BySize) { if (BySize) { llvm::stable_sort(Globs, [](const Glob &A, const Glob &B) { return A.Name.size() < B.Name.size(); @@ -115,8 +181,7 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) { } } -SpecialCaseList::Match -SpecialCaseList::GlobMatcher::match(StringRef Query) const { +Match GlobMatcher::match(StringRef Query) const { int Best = -1; if (!PrefixSuffixToGlob.empty()) { for (const auto &[_, SToGlob] : PrefixSuffixToGlob.find_prefixes(Query)) { @@ -164,7 +229,7 @@ SpecialCaseList::GlobMatcher::match(StringRef Query) const { return {Globs[Best].Name, Globs[Best].LineNo}; } -SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash) +Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash) : RemoveDotSlash(RemoveDotSlash) { if (UseGlobs) M.emplace<GlobMatcher>(); @@ -172,20 +237,45 @@ SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash) M.emplace<RegexMatcher>(); } -Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber) { +Error Matcher::insert(StringRef Pattern, unsigned LineNumber) { return std::visit([&](auto &V) { return V.insert(Pattern, LineNumber); }, M); } -void SpecialCaseList::Matcher::preprocess(bool BySize) { +void Matcher::preprocess(bool BySize) { return std::visit([&](auto &V) { return V.preprocess(BySize); }, M); } -SpecialCaseList::Match SpecialCaseList::Matcher::match(StringRef Query) const { +Match Matcher::match(StringRef Query) const { if (RemoveDotSlash) Query = llvm::sys::path::remove_leading_dotslash(Query); - return std::visit( - [&](auto &V) -> SpecialCaseList::Match { return V.match(Query); }, M); + return std::visit([&](auto &V) -> Match { return V.match(Query); }, M); } +} // namespace + +class SpecialCaseList::Section::SectionImpl { + friend class SpecialCaseList; + void preprocess(bool OrderBySize); + const Matcher *findMatcher(StringRef Prefix, StringRef Category) const; + +public: + using SectionEntries = StringMap<StringMap<Matcher>>; + + SectionImpl(StringRef Str, bool UseGlobs) + : SectionMatcher(UseGlobs, /*RemoveDotSlash=*/false) {} + + Matcher SectionMatcher; + SectionEntries Entries; + + // Helper method to search by Prefix, Query, and Category. Returns + // 1-based line number on which rule is defined, or 0 if there is no match. + unsigned getLastMatch(StringRef Prefix, StringRef Query, + StringRef Category) const; + + // Helper method to search by Prefix, Query, and Category. Returns + // matching rule, or empty string if there is no match. + StringRef getLongestMatch(StringRef Prefix, StringRef Query, + StringRef Category) const; +}; // TODO: Refactor this to return Expected<...> std::unique_ptr<SpecialCaseList> @@ -240,6 +330,10 @@ bool SpecialCaseList::createInternal(const MemoryBuffer *MB, std::string &Error, return true; } +const std::vector<SpecialCaseList::Section> &SpecialCaseList::sections() const { + return Sections; +} + Expected<SpecialCaseList::Section *> SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo, unsigned LineNo, bool UseGlobs) { @@ -247,7 +341,7 @@ SpecialCaseList::addSection(StringRef SectionStr, unsigned FileNo, Sections.emplace_back(SectionStr, FileNo, UseGlobs); auto &Section = Sections.back(); - if (auto Err = Section.SectionMatcher.insert(SectionStr, LineNo)) { + if (auto Err = Section.Impl->SectionMatcher.insert(SectionStr, LineNo)) { return createStringError(errc::invalid_argument, "malformed section at line " + Twine(LineNo) + ": '" + SectionStr + @@ -279,7 +373,7 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB, Error = toString(std::move(Err)); return false; } - Section *CurrentSection = ErrOrSection.get(); + Section::SectionImpl *CurrentImpl = ErrOrSection.get()->Impl.get(); // This is the current list of prefixes for all existing users matching file // path. We may need parametrization in constructor in future. @@ -307,7 +401,7 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB, Error = toString(std::move(Err)); return false; } - CurrentSection = ErrOrSection.get(); + CurrentImpl = ErrOrSection.get()->Impl.get(); continue; } @@ -320,7 +414,7 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB, } auto [Pattern, Category] = Postfix.split("="); - auto [It, _] = CurrentSection->Entries[Prefix].try_emplace( + auto [It, _] = CurrentImpl->Entries[Prefix].try_emplace( Category, UseGlobs, RemoveDotSlash && llvm::is_contained(PathPrefixes, Prefix)); Pattern = Pattern.copy(StrAlloc); @@ -334,7 +428,7 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB, } for (Section &S : Sections) - S.preprocess(OrderBySize); + S.Impl->preprocess(OrderBySize); return true; } @@ -351,7 +445,7 @@ std::pair<unsigned, unsigned> SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category) const { for (const auto &S : reverse(Sections)) { - if (S.SectionMatcher.matchAny(Section)) { + if (S.Impl->SectionMatcher.matchAny(Section)) { unsigned Blame = S.getLastMatch(Prefix, Query, Category); if (Blame) return {S.FileIdx, Blame}; @@ -360,13 +454,21 @@ SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix, return NotFound; } +SpecialCaseList::Section::Section(StringRef Str, unsigned FileIdx, + bool UseGlobs) + : Name(Str), FileIdx(FileIdx), + Impl(std::make_unique<SectionImpl>(Str, UseGlobs)) {} + +SpecialCaseList::Section::Section(Section &&) = default; +SpecialCaseList::Section::~Section() = default; + bool SpecialCaseList::Section::matchName(StringRef Name) const { - return SectionMatcher.matchAny(Name); + return Impl->SectionMatcher.matchAny(Name); } -const SpecialCaseList::Matcher * -SpecialCaseList::Section::findMatcher(StringRef Prefix, - StringRef Category) const { +const Matcher * +SpecialCaseList::Section::SectionImpl::findMatcher(StringRef Prefix, + StringRef Category) const { SectionEntries::const_iterator I = Entries.find(Prefix); if (I == Entries.end()) return nullptr; @@ -377,7 +479,7 @@ SpecialCaseList::Section::findMatcher(StringRef Prefix, return &II->second; } -LLVM_ABI void SpecialCaseList::Section::preprocess(bool OrderBySize) { +void SpecialCaseList::Section::SectionImpl::preprocess(bool OrderBySize) { SectionMatcher.preprocess(false); for (auto &[K1, E] : Entries) for (auto &[K2, M] : E) @@ -387,7 +489,7 @@ LLVM_ABI void SpecialCaseList::Section::preprocess(bool OrderBySize) { unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix, StringRef Query, StringRef Category) const { - if (const Matcher *M = findMatcher(Prefix, Category)) + if (const Matcher *M = Impl->findMatcher(Prefix, Category)) return M->match(Query).second; return 0; } @@ -395,13 +497,13 @@ unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix, StringRef SpecialCaseList::Section::getLongestMatch(StringRef Prefix, StringRef Query, StringRef Category) const { - if (const Matcher *M = findMatcher(Prefix, Category)) + if (const Matcher *M = Impl->findMatcher(Prefix, Category)) return M->match(Query).first; return {}; } bool SpecialCaseList::Section::hasPrefix(StringRef Prefix) const { - return Entries.find(Prefix) != Entries.end(); + return Impl->Entries.find(Prefix) != Impl->Entries.end(); } } // namespace llvm `````````` </details> https://github.com/llvm/llvm-project/pull/167280 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
