22#include <system_error>
32 (UseGlobs ?
"glob" :
"regex") +
" was blank");
37 for (
size_t pos = 0; (pos = Regexp.find(
'*', pos)) != std::string::npos;
38 pos += strlen(
".*")) {
39 Regexp.replace(pos, strlen(
"*"),
".*");
45 Regex CheckRE(Regexp);
50 RegExes.emplace_back(std::make_pair(
51 std::make_unique<Regex>(std::move(CheckRE)), LineNumber));
61 auto &Pair = It->getValue();
63 .moveInto(Pair.first))
65 Pair.second = LineNumber;
71 for (
const auto &[
Pattern, Pair] : Globs)
72 if (Pair.first.match(Query))
74 for (
const auto &[
Regex, LineNumber] : RegExes)
81std::unique_ptr<SpecialCaseList>
85 if (SCL->createInternal(Paths, FS,
Error))
93 if (SCL->createInternal(MB,
Error))
98std::unique_ptr<SpecialCaseList>
109 for (
const auto &Path : Paths) {
112 if (std::error_code EC = FileOrErr.
getError()) {
113 Error = (
Twine(
"can't open file '") + Path +
"': " + EC.message()).str();
116 std::string ParseError;
117 if (!
parse(FileOrErr.
get().get(), ParseError)) {
118 Error = (
Twine(
"error parsing file '") + Path +
"': " + ParseError).str();
126 std::string &
Error) {
135 auto [It, DidEmplace] =
Sections.try_emplace(SectionStr);
136 auto &
Section = It->getValue();
140 "malformed section at line " +
Twine(LineNo) +
148 if (
auto Err =
addSection(
"*", 1).moveInto(CurrentSection)) {
162 unsigned LineNo = LineIt.line_number();
168 if (Line.starts_with(
"[")) {
169 if (!Line.ends_with(
"]")) {
171 (
"malformed section header on line " +
Twine(LineNo) +
": " + Line)
176 if (
auto Err =
addSection(Line.drop_front().drop_back(), LineNo, UseGlobs)
177 .moveInto(CurrentSection)) {
185 auto [Prefix, Postfix] = Line.split(
":");
186 if (Postfix.empty()) {
188 Error = (
"malformed line " +
Twine(LineNo) +
": '" + Line +
"'").str();
192 auto [
Pattern, Category] = Postfix.split(
"=");
193 auto &Entry = CurrentSection->
Entries[Prefix][Category];
194 if (
auto Err = Entry.insert(
Pattern, LineNo, UseGlobs)) {
196 (
Twine(
"malformed ") + (UseGlobs ?
"glob" :
"regex") +
" in line " +
216 const auto &S = It.getValue();
217 if (S.SectionMatcher->match(
Section)) {
218 unsigned Blame =
inSectionBlame(S.Entries, Prefix, Query, Category);
230 if (
I == Entries.end())
return 0;
232 if (
II ==
I->second.end())
return 0;
234 return II->getValue().match(Query);
uint64_t IntrinsicInst * II
Defines the virtual file system interface vfs::FileSystem.
Represents either an error or a value T.
std::error_code getError() const
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
static Expected< GlobPattern > create(StringRef Pat, std::optional< size_t > MaxSubPatterns={})
This interface provides simple read-only access to a block of memory, and provides simple methods for...
StringRef getBuffer() const
bool isValid(std::string &Error) const
isValid - returns the error encountered during regex compilation, if any.
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
std::vector< std::pair< std::unique_ptr< Regex >, unsigned > > RegExes
StringMap< std::pair< GlobPattern, unsigned > > Globs
unsigned match(StringRef Query) const
Error insert(StringRef Pattern, unsigned LineNumber, bool UseRegex)
bool createInternal(const std::vector< std::string > &Paths, vfs::FileSystem &VFS, std::string &Error)
static std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
static std::unique_ptr< SpecialCaseList > create(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS, std::string &Error)
Parses the special case list entries from files.
StringMap< Section > Sections
SpecialCaseList()=default
unsigned inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category=StringRef()) const
Returns the line number corresponding to the special case list entry if the special case list contain...
Expected< Section * > addSection(StringRef SectionStr, unsigned LineNo, bool UseGlobs=true)
bool inSection(StringRef Section, StringRef Prefix, StringRef Query, StringRef Category=StringRef()) const
Returns true, if special case list contains a line.
bool parse(const MemoryBuffer *MB, std::string &Error)
Parses just-constructed SpecialCaseList entries from a memory buffer.
StringRef - Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A forward iterator which reads text lines from a buffer.
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
The virtual file system interface.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > getBufferForFile(const Twine &Name, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false, bool IsText=true)
This is a convenience method that opens a file, gets its content and then closes the file.
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
const char * toString(DWARFSectionKind Kind)
std::unique_ptr< Matcher > SectionMatcher