aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r--llvm/lib/Support/SpecialCaseList.cpp91
1 files changed, 51 insertions, 40 deletions
diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp
index 246d90c..beec8b8 100644
--- a/llvm/lib/Support/SpecialCaseList.cpp
+++ b/llvm/lib/Support/SpecialCaseList.cpp
@@ -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>
@@ -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,
@@ -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();
@@ -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
@@ -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
@@ -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)
@@ -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<...>
@@ -264,11 +274,12 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
bool RemoveDotSlash = Version > 2;
- Section *CurrentSection;
- if (auto Err = addSection("*", FileIdx, 1, true).moveInto(CurrentSection)) {
+ auto ErrOrSection = addSection("*", FileIdx, 1, true);
+ if (auto Err = ErrOrSection.takeError()) {
Error = toString(std::move(Err));
return false;
}
+ Section *CurrentSection = ErrOrSection.get();
// This is the current list of prefixes for all existing users matching file
// path. We may need parametrization in constructor in future.
@@ -290,12 +301,13 @@ bool SpecialCaseList::parse(unsigned FileIdx, const MemoryBuffer *MB,
return false;
}
- if (auto Err = addSection(Line.drop_front().drop_back(), FileIdx, LineNo,
- UseGlobs)
- .moveInto(CurrentSection)) {
+ auto ErrOrSection =
+ addSection(Line.drop_front().drop_back(), FileIdx, LineNo, UseGlobs);
+ if (auto Err = ErrOrSection.takeError()) {
Error = toString(std::move(Err));
return false;
}
+ CurrentSection = ErrOrSection.get();
continue;
}
@@ -348,6 +360,10 @@ SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix,
return NotFound;
}
+bool SpecialCaseList::Section::matchName(StringRef Name) const {
+ return SectionMatcher.matchAny(Name);
+}
+
const SpecialCaseList::Matcher *
SpecialCaseList::Section::findMatcher(StringRef Prefix,
StringRef Category) const {
@@ -371,26 +387,21 @@ 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 {
+ return Entries.find(Prefix) != Entries.end();
}
} // namespace llvm