diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp index a1dc4a7ec99bf..792000b545fb8 100644 --- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -42,7 +42,7 @@ void SanitizerSpecialCaseList::createSanitizerSections() { SanitizerMask Mask; #define SANITIZER(NAME, ID) \ - if (S.SectionMatcher.match(NAME)) \ + if (S.SectionMatcher.matchAny(NAME)) \ Mask |= SanitizerKind::ID; #define SANITIZER_GROUP(NAME, ID, ALIAS) SANITIZER(NAME, ID) diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index 55d3d12dc3d5f..bb382f64b084f 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -123,9 +123,15 @@ class SpecialCaseList { public: LLVM_ABI Error insert(StringRef Pattern, unsigned LineNumber, bool UseRegex); - // Returns the line number in the source file that this query matches to. - // Returns zero if no match is found. - LLVM_ABI unsigned match(StringRef Query) const; + LLVM_ABI void + match(StringRef Query, + llvm::function_ref Cb) const; + + LLVM_ABI bool matchAny(StringRef Query) const { + bool R = false; + match(Query, [&](StringRef, unsigned) { R = true; }); + return R; + } struct Glob { std::string Name; @@ -158,6 +164,15 @@ class SpecialCaseList { // 1-based line number on which rule is defined, or 0 if there is no match. LLVM_ABI unsigned getLastMatch(StringRef Prefix, StringRef Query, StringRef Category) const; + + // Helper method to search by Prefix, Query, and Category. Returns + // matching rule, or empty string if there is no match. + LLVM_ABI StringRef getLongestMatch(StringRef Prefix, StringRef Query, + StringRef Category) const; + + private: + LLVM_ABI const SpecialCaseList::Matcher * + findMatcher(StringRef Prefix, StringRef Category) const; }; std::vector
Sections; diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index 04f092b1a7ba8..9a1b47faab3ed 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/VirtualFileSystem.h" +#include #include #include #include @@ -69,14 +70,15 @@ Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber, return Error::success(); } -unsigned SpecialCaseList::Matcher::match(StringRef Query) const { +void SpecialCaseList::Matcher::match( + StringRef Query, + llvm::function_ref Cb) const { for (const auto &Glob : reverse(Globs)) if (Glob->Pattern.match(Query)) - return Glob->LineNo; + Cb(Glob->Name, Glob->LineNo); for (const auto &[Regex, LineNumber] : reverse(RegExes)) if (Regex->match(Query)) - return LineNumber; - return 0; + Cb(/*FIXME: there is no users of this param yet */ "", LineNumber); } // TODO: Refactor this to return Expected<...> @@ -227,7 +229,7 @@ std::pair SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category) const { for (const auto &S : reverse(Sections)) { - if (S.SectionMatcher.match(Section)) { + if (S.SectionMatcher.matchAny(Section)) { unsigned Blame = S.getLastMatch(Prefix, Query, Category); if (Blame) return {S.FileIdx, Blame}; @@ -236,17 +238,29 @@ SpecialCaseList::inSectionBlame(StringRef Section, StringRef Prefix, return NotFound; } -unsigned SpecialCaseList::Section::getLastMatch(StringRef Prefix, - StringRef Query, - StringRef Category) const { +const SpecialCaseList::Matcher * +SpecialCaseList::Section::findMatcher(StringRef Prefix, + StringRef Category) const { SectionEntries::const_iterator I = Entries.find(Prefix); if (I == Entries.end()) - return 0; + return nullptr; StringMap::const_iterator II = I->second.find(Category); if (II == I->second.end()) - return 0; + return nullptr; + + return &II->second; +} - return II->getValue().match(Query); +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; } } // namespace llvm