Skip to content
Merged
7 changes: 7 additions & 0 deletions llvm/include/llvm/Support/SpecialCaseList.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
#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"
Expand Down Expand Up @@ -162,6 +165,10 @@ class SpecialCaseList {
};

std::vector<GlobMatcher::Glob> Globs;

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

/// Represents a set of patterns and their line numbers
Expand Down
25 changes: 22 additions & 3 deletions llvm/lib/Support/SpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,33 @@ void SpecialCaseList::GlobMatcher::preprocess(bool BySize) {
return A.Name.size() < B.Name.size();
});
}

for (const auto &G : reverse(Globs)) {
StringRef Prefix = G.Pattern.prefix();

auto &V = PrefixToGlob.emplace(Prefix).first->second;
V.emplace_back(&G);
}
}

void SpecialCaseList::GlobMatcher::match(
StringRef Query,
llvm::function_ref<void(StringRef Rule, unsigned LineNo)> Cb) const {
for (const auto &G : reverse(Globs))
if (G.Pattern.match(Query))
return Cb(G.Name, G.LineNo);
if (!PrefixToGlob.empty()) {
for (const auto &[_, V] : PrefixToGlob.find_prefixes(Query)) {
for (const auto *G : V) {
// Each value of the map is a vector of globs sorted as from best to
// worst.
if (G->Pattern.match(Query)) {
Cb(G->Name, G->LineNo);
// As soon as we find a match in the vector we can break for the vector,
// but we still need to continue for other values in the map, as they
// may contain a better match.
break;
}
}
}
}
}

SpecialCaseList::Matcher::Matcher(bool UseGlobs, bool RemoveDotSlash)
Expand Down
Loading