Skip to content
Merged
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
24 changes: 9 additions & 15 deletions llvm/include/llvm/Support/SpecialCaseList.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,16 @@ class SpecialCaseList {
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 void
match(StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
LLVM_ABI Match match(StringRef Query) const;

struct Reg {
Reg(StringRef Name, unsigned LineNo, Regex &&Rg)
Expand All @@ -152,9 +153,7 @@ class SpecialCaseList {
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
LLVM_ABI void preprocess(bool BySize);

LLVM_ABI void
match(StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
LLVM_ABI Match match(StringRef Query) const;

struct Glob {
Glob(StringRef Name, unsigned LineNo, GlobPattern &&Pattern)
Expand All @@ -168,11 +167,10 @@ class SpecialCaseList {

RadixTree<iterator_range<StringRef::const_iterator>,
RadixTree<iterator_range<StringRef::const_reverse_iterator>,
SmallVector<const GlobMatcher::Glob *, 1>>>
SmallVector<int, 1>>>
PrefixSuffixToGlob;

RadixTree<iterator_range<StringRef::const_iterator>,
SmallVector<const GlobMatcher::Glob *, 1>>
RadixTree<iterator_range<StringRef::const_iterator>, SmallVector<int, 1>>
SubstrToGlob;
};

Expand All @@ -184,14 +182,10 @@ class SpecialCaseList {
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
LLVM_ABI void preprocess(bool BySize);

LLVM_ABI void
match(StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
LLVM_ABI Match match(StringRef Query) const;

LLVM_ABI bool matchAny(StringRef Query) const {
bool R = false;
match(Query, [&](StringRef, unsigned) { R = true; });
return R;
return match(Query) != NotMatched;
}

std::variant<RegexMatcher, GlobMatcher> M;
Expand Down
71 changes: 36 additions & 35 deletions llvm/lib/Support/SpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@

#include "llvm/Support/SpecialCaseList.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <limits>
#include <memory>
Expand Down Expand Up @@ -63,12 +65,12 @@ void SpecialCaseList::RegexMatcher::preprocess(bool BySize) {
}
}

void SpecialCaseList::RegexMatcher::match(
StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
SpecialCaseList::Match
SpecialCaseList::RegexMatcher::match(StringRef Query) const {
for (const auto &R : reverse(RegExes))
if (R.Rg.match(Query))
return Cb(R.Name, R.LineNo);
return {R.Name, R.LineNo};
return NotMatched;
}

Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern,
Expand All @@ -90,7 +92,7 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
});
}

for (const auto &G : reverse(Globs)) {
for (const auto &[Idx, G] : enumerate(Globs)) {
StringRef Prefix = G.Pattern.prefix();
StringRef Suffix = G.Pattern.suffix();

Expand All @@ -102,26 +104,29 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
// But only if substring is not empty. Searching this tree is more
// expensive.
auto &V = SubstrToGlob.emplace(Substr).first->second;
V.emplace_back(&G);
V.emplace_back(Idx);
continue;
}
}

auto &SToGlob = PrefixSuffixToGlob.emplace(Prefix).first->second;
auto &V = SToGlob.emplace(reverse(Suffix)).first->second;
V.emplace_back(&G);
V.emplace_back(Idx);
}
}

void SpecialCaseList::GlobMatcher::match(
StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
SpecialCaseList::Match
SpecialCaseList::GlobMatcher::match(StringRef Query) const {
int Best = -1;
if (!PrefixSuffixToGlob.empty()) {
for (const auto &[_, SToGlob] : PrefixSuffixToGlob.find_prefixes(Query)) {
for (const auto &[_, V] : SToGlob.find_prefixes(reverse(Query))) {
for (const auto *G : V) {
if (G->Pattern.match(Query)) {
Cb(G->Name, G->LineNo);
for (int Idx : reverse(V)) {
if (Best > Idx)
break;
const GlobMatcher::Glob &G = Globs[Idx];
if (G.Pattern.match(Query)) {
Best = Idx;
// As soon as we find a match in the vector, we can break for this
// vector, since the globs are already sorted by priority within the
// prefix group. However, we continue searching other prefix groups
Expand All @@ -138,9 +143,12 @@ void SpecialCaseList::GlobMatcher::match(
// possibilities. In most cases search will fail on first characters.
for (StringRef Q = Query; !Q.empty(); Q = Q.drop_front()) {
for (const auto &[_, V] : SubstrToGlob.find_prefixes(Q)) {
for (const auto *G : V) {
if (G->Pattern.match(Query)) {
Cb(G->Name, G->LineNo);
for (int Idx : reverse(V)) {
if (Best > Idx)
break;
const GlobMatcher::Glob &G = Globs[Idx];
if (G.Pattern.match(Query)) {
Best = Idx;
// As soon as we find a match in the vector, we can break for this
// vector, since the globs are already sorted by priority within the
// prefix group. However, we continue searching other prefix groups
Expand All @@ -151,6 +159,9 @@ void SpecialCaseList::GlobMatcher::match(
}
}
}
if (Best < 0)
return NotMatched;
return {Globs[Best].Name, Globs[Best].LineNo};
}

SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash)
Expand All @@ -169,12 +180,11 @@ void SpecialCaseList::Matcher::preprocess(bool BySize) {
return std::visit([&](auto &V) { return V.preprocess(BySize); }, M);
}

void SpecialCaseList::Matcher::match(
StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
SpecialCaseList::Match SpecialCaseList::Matcher::match(StringRef Query) const {
if (RemoveDotSlash)
Query = llvm::sys::path::remove_leading_dotslash(Query);
return std::visit([&](auto &V) { return V.match(Query, Cb); }, M);
return std::visit(
[&](auto &V) -> SpecialCaseList::Match { return V.match(Query); }, M);
}

// TODO: Refactor this to return Expected<...>
Expand Down Expand Up @@ -375,26 +385,17 @@ LLVM_ABI void SpecialCaseList::Section::preprocess(bool OrderBySize) {
unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix,
StringRef Query,
StringRef Category) const {
unsigned LastLine = 0;
if (const Matcher *M = findMatcher(Prefix, Category)) {
M->match(Query, [&](StringRef, unsigned LineNo) {
LastLine = std::max(LastLine, LineNo);
});
}
return LastLine;
if (const Matcher *M = findMatcher(Prefix, Category))
return M->match(Query).second;
return 0;
}

StringRef SpecialCaseList::Section::getLongestMatch(StringRef Prefix,
StringRef Query,
StringRef Category) const {
StringRef LongestRule;
if (const Matcher *M = findMatcher(Prefix, Category)) {
M->match(Query, [&](StringRef Rule, unsigned) {
if (LongestRule.size() < Rule.size())
LongestRule = Rule;
});
}
return LongestRule;
if (const Matcher *M = findMatcher(Prefix, Category))
return M->match(Query).first;
return {};
}

bool SpecialCaseList::Section::hasPrefix(StringRef Prefix) const {
Expand Down
Loading