Skip to content

Commit afbe6ca

Browse files
committed
[NFC][SpecialCaseList] Replace callback with return value
This commit introduces `SpecialCaseList::Match`, a small struct to hold the matched rule and its line number. This simplifies the `match` methods by allowing them to return a single value instead of using a callback. Pull Request: llvm#165943
1 parent a8a0ffb commit afbe6ca

File tree

2 files changed

+45
-50
lines changed

2 files changed

+45
-50
lines changed

llvm/include/llvm/Support/SpecialCaseList.h

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,16 @@ class SpecialCaseList {
126126
SpecialCaseList &operator=(SpecialCaseList const &) = delete;
127127

128128
private:
129+
using Match = std::pair<StringRef, unsigned>;
130+
static constexpr Match NotMatched = {"", 0};
131+
129132
// Lagacy v1 matcher.
130133
class RegexMatcher {
131134
public:
132135
LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber);
133136
LLVM_ABI void preprocess(bool BySize);
134137

135-
LLVM_ABI void
136-
match(StringRef Query,
137-
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
138+
LLVM_ABI Match match(StringRef Query) const;
138139

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

155-
LLVM_ABI void
156-
match(StringRef Query,
157-
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
156+
LLVM_ABI Match match(StringRef Query) const;
158157

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

169168
RadixTree<iterator_range<StringRef::const_iterator>,
170169
RadixTree<iterator_range<StringRef::const_reverse_iterator>,
171-
SmallVector<const GlobMatcher::Glob *, 1>>>
170+
SmallVector<int, 1>>>
172171
PrefixSuffixToGlob;
173172

174-
RadixTree<iterator_range<StringRef::const_iterator>,
175-
SmallVector<const GlobMatcher::Glob *, 1>>
173+
RadixTree<iterator_range<StringRef::const_iterator>, SmallVector<int, 1>>
176174
SubstrToGlob;
177175
};
178176

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

187-
LLVM_ABI void
188-
match(StringRef Query,
189-
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const;
185+
LLVM_ABI Match match(StringRef Query) const;
190186

191187
LLVM_ABI bool matchAny(StringRef Query) const {
192-
bool R = false;
193-
match(Query, [&](StringRef, unsigned) { R = true; });
194-
return R;
188+
return match(Query) != NotMatched;
195189
}
196190

197191
std::variant<RegexMatcher, GlobMatcher> M;

llvm/lib/Support/SpecialCaseList.cpp

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515

1616
#include "llvm/Support/SpecialCaseList.h"
1717
#include "llvm/ADT/STLExtras.h"
18+
#include "llvm/ADT/SetVector.h"
1819
#include "llvm/ADT/StringExtras.h"
1920
#include "llvm/ADT/StringRef.h"
2021
#include "llvm/Support/LineIterator.h"
2122
#include "llvm/Support/MemoryBuffer.h"
2223
#include "llvm/Support/VirtualFileSystem.h"
24+
#include "llvm/Support/raw_ostream.h"
2325
#include <algorithm>
2426
#include <limits>
2527
#include <memory>
@@ -63,12 +65,12 @@ void SpecialCaseList::RegexMatcher::preprocess(bool BySize) {
6365
}
6466
}
6567

66-
void SpecialCaseList::RegexMatcher::match(
67-
StringRef Query,
68-
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
68+
SpecialCaseList::Match
69+
SpecialCaseList::RegexMatcher::match(StringRef Query) const {
6970
for (const auto &R : reverse(RegExes))
7071
if (R.Rg.match(Query))
71-
return Cb(R.Name, R.LineNo);
72+
return {R.Name, R.LineNo};
73+
return NotMatched;
7274
}
7375

7476
Error SpecialCaseList::GlobMatcher::insert(StringRef Pattern,
@@ -90,7 +92,7 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
9092
});
9193
}
9294

93-
for (const auto &G : reverse(Globs)) {
95+
for (const auto &[Idx, G] : enumerate(Globs)) {
9496
StringRef Prefix = G.Pattern.prefix();
9597
StringRef Suffix = G.Pattern.suffix();
9698

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

110112
auto &SToGlob = PrefixSuffixToGlob.emplace(Prefix).first->second;
111113
auto &V = SToGlob.emplace(reverse(Suffix)).first->second;
112-
V.emplace_back(&G);
114+
V.emplace_back(Idx);
113115
}
114116
}
115117

116-
void SpecialCaseList::GlobMatcher::match(
117-
StringRef Query,
118-
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
118+
SpecialCaseList::Match
119+
SpecialCaseList::GlobMatcher::match(StringRef Query) const {
120+
int Best = -1;
119121
if (!PrefixSuffixToGlob.empty()) {
120122
for (const auto &[_, SToGlob] : PrefixSuffixToGlob.find_prefixes(Query)) {
121123
for (const auto &[_, V] : SToGlob.find_prefixes(reverse(Query))) {
122-
for (const auto *G : V) {
123-
if (G->Pattern.match(Query)) {
124-
Cb(G->Name, G->LineNo);
124+
for (int Idx : reverse(V)) {
125+
if (Best > Idx)
126+
break;
127+
const GlobMatcher::Glob &G = Globs[Idx];
128+
if (G.Pattern.match(Query)) {
129+
Best = Idx;
125130
// As soon as we find a match in the vector, we can break for this
126131
// vector, since the globs are already sorted by priority within the
127132
// prefix group. However, we continue searching other prefix groups
@@ -138,9 +143,12 @@ void SpecialCaseList::GlobMatcher::match(
138143
// possibilities. In most cases search will fail on first characters.
139144
for (StringRef Q = Query; !Q.empty(); Q = Q.drop_front()) {
140145
for (const auto &[_, V] : SubstrToGlob.find_prefixes(Q)) {
141-
for (const auto *G : V) {
142-
if (G->Pattern.match(Query)) {
143-
Cb(G->Name, G->LineNo);
146+
for (int Idx : reverse(V)) {
147+
if (Best > Idx)
148+
break;
149+
const GlobMatcher::Glob &G = Globs[Idx];
150+
if (G.Pattern.match(Query)) {
151+
Best = Idx;
144152
// As soon as we find a match in the vector, we can break for this
145153
// vector, since the globs are already sorted by priority within the
146154
// prefix group. However, we continue searching other prefix groups
@@ -151,6 +159,9 @@ void SpecialCaseList::GlobMatcher::match(
151159
}
152160
}
153161
}
162+
if (Best < 0)
163+
return NotMatched;
164+
return {Globs[Best].Name, Globs[Best].LineNo};
154165
}
155166

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

172-
void SpecialCaseList::Matcher::match(
173-
StringRef Query,
174-
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
183+
SpecialCaseList::Match SpecialCaseList::Matcher::match(StringRef Query) const {
175184
if (RemoveDotSlash)
176185
Query = llvm::sys::path::remove_leading_dotslash(Query);
177-
return std::visit([&](auto &V) { return V.match(Query, Cb); }, M);
186+
return std::visit(
187+
[&](auto &V) -> SpecialCaseList::Match { return V.match(Query); }, M);
178188
}
179189

180190
// TODO: Refactor this to return Expected<...>
@@ -371,26 +381,17 @@ LLVM_ABI void SpecialCaseList::Section::preprocess(bool OrderBySize) {
371381
unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix,
372382
StringRef Query,
373383
StringRef Category) const {
374-
unsigned LastLine = 0;
375-
if (const Matcher *M = findMatcher(Prefix, Category)) {
376-
M->match(Query, [&](StringRef, unsigned LineNo) {
377-
LastLine = std::max(LastLine, LineNo);
378-
});
379-
}
380-
return LastLine;
384+
if (const Matcher *M = findMatcher(Prefix, Category))
385+
return M->match(Query).second;
386+
return 0;
381387
}
382388

383389
StringRef SpecialCaseList::Section::getLongestMatch(StringRef Prefix,
384390
StringRef Query,
385391
StringRef Category) const {
386-
StringRef LongestRule;
387-
if (const Matcher *M = findMatcher(Prefix, Category)) {
388-
M->match(Query, [&](StringRef Rule, unsigned) {
389-
if (LongestRule.size() < Rule.size())
390-
LongestRule = Rule;
391-
});
392-
}
393-
return LongestRule;
392+
if (const Matcher *M = findMatcher(Prefix, Category))
393+
return M->match(Query).first;
394+
return {};
394395
}
395396

396397
} // namespace llvm

0 commit comments

Comments
 (0)