aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Support/SpecialCaseList.h95
-rw-r--r--llvm/lib/Support/SpecialCaseList.cpp156
2 files changed, 128 insertions, 123 deletions
diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h
index e92aeef..5a012cf 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 @@ protected:
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();
// Returns name of the section, its entire string in [].
StringRef name() const { return Name; }
@@ -227,14 +147,11 @@ protected:
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; }
diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp
index 42c8933..91f98cf 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,34 @@ 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 {
+public:
+ void preprocess(bool OrderBySize);
+ const Matcher *findMatcher(StringRef Prefix, StringRef Category) const;
+
+ using SectionEntries = StringMap<StringMap<Matcher>>;
+
+ explicit SectionImpl(bool UseGlobs)
+ : SectionMatcher(UseGlobs, /*RemoveDotSlash=*/false) {}
+
+ Matcher SectionMatcher;
+ SectionEntries Entries;
+};
// TODO: Refactor this to return Expected<...>
std::unique_ptr<SpecialCaseList>
@@ -247,7 +326,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 +358,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 +386,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 +399,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 +413,7 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
}
for (Section &S : Sections)
- S.preprocess(OrderBySize);
+ S.Impl->preprocess(OrderBySize);
return true;
}
@@ -351,7 +430,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 +439,22 @@ 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>(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 +465,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 +475,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 +483,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