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
7476Error 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
156167SpecialCaseList::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) {
371381unsigned 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
383389StringRef 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