64 while (!strToProcess.
empty()) {
66 size_t regexIt = strToProcess.
find(
"{{");
72 strToProcess = strToProcess.
drop_front(regexIt + 2);
75 size_t regexEndIt = strToProcess.
find(
"}}");
77 return emitError(os, mgr,
"found start of regex with no end '}}'");
81 std::string regexError;
83 return emitError(os, mgr,
"invalid regex: " + regexError);
85 regexOS <<
'(' << regexBlock <<
')';
86 strToProcess = strToProcess.
drop_front(regexEndIt + 2);
93 assert(!prefixes.
empty() &&
"Diagnostic verifier needs at least one prefix");
94 std::string pattern =
"(^|[^[:alnum:]_-])(";
98 assert(!prefix.
empty() &&
"Diagnostic verifier prefix cannot be empty");
101 [&] { pattern +=
'|'; });
102 pattern +=
")-(error|note|remark|warning)(-re)?"
103 "( *@([+-][0-9]+|above|below|unknown))?(:([0-9]+))?"
105 return Regex(pattern);
122 unsigned lastNonDesignatorLine = 0;
130 for (
unsigned lineNo = 0, e = lines.
size(); lineNo < e; ++lineNo) {
132 if (!expected.match(lines[lineNo].rtrim(), &matches)) {
134 if (!designatorsForNextLine.
empty()) {
135 for (
unsigned diagIndex : designatorsForNextLine)
136 expectedDiags[diagIndex].lineNo = lineNo + 1;
137 designatorsForNextLine.clear();
139 lastNonDesignatorLine = lineNo;
147 if (matches[3] ==
"error")
149 else if (matches[3] ==
"warning")
151 else if (matches[3] ==
"remark")
154 assert(matches[3] ==
"note");
157 ExpectedDiag record(kind, lineNo + 1, expectedStart, matches[9]);
160 if (!matches[4].empty() && !record.
computeRegex(os, mgr)) {
165 if (!matches[8].empty() &&
166 (matches[8].getAsInteger(10, record.
colNo) || record.
colNo == 0)) {
167 record.
emitError(os, mgr,
"invalid column '" + matches[7] +
"'");
173 if (!offsetMatch.
empty()) {
175 if (offsetMatch[0] ==
'+' || offsetMatch[0] ==
'-') {
179 if (offsetMatch.
front() ==
'+')
184 if (record.
colNo != 0) {
185 record.
emitError(os, mgr,
"cannot specify a column with '@unknown'");
191 expectedUnknownLocDiags.emplace_back(std::move(record));
196 record.
lineNo = lastNonDesignatorLine + 1;
201 designatorsForNextLine.
push_back(expectedDiags.size());
210 return expectedDiags;
213std::optional<MutableArrayRef<SourceMgrDiagnosticVerifier::ExpectedDiag>>
215 auto expectedDiags = expectedDiagsPerFile.find(bufName);
216 if (expectedDiags != expectedDiagsPerFile.end())
224 bool reportUnexpected) {
236 diags = expectedUnknownLocDiags;
244 for (
auto &e : diags) {
246 if (
hasLoc && e.lineNo != lineNo)
248 if (
hasLoc && e.colNo != 0 && e.colNo != colNo)
250 if (e.match(message)) {
251 if (e.kind == kind) {
262 if (!reportUnexpected)
271 "' diagnostic emitted when expecting a '" +
282 diag.emitError(os, mgr,
284 diag.substring +
"\" was not produced");
288 for (
auto &expectedDiagsPair : expectedDiagsPerFile)
289 for (
auto &diag : expectedDiagsPair.second)
290 checkExpectedDiags(diag);
291 for (
auto &diag : expectedUnknownLocDiags)
292 checkExpectedDiags(diag);
293 expectedDiagsPerFile.clear();
294 expectedUnknownLocDiags.clear();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
bool hasLoc(const Instruction &I)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
static Regex buildExpectedRegex(ArrayRef< StringRef > prefixes)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
Check if the array is empty.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
virtual StringRef getBufferIdentifier() const
Return an identifier for this buffer, typically the filename it was read from.
StringRef getBuffer() const
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
static LLVM_ABI std::string escape(StringRef String)
Turn String into a regex by escaping its special characters.
LLVM_ABI void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true, bool ShowLocation=true) const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
Represents a range in source code.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MatchResult
The result of matching a single actual diagnostic against the expected diagnostics recorded for its l...
@ Matched
The diagnostic matched an expected diagnostic (kind and text).
@ Unexpected
The diagnostic did not match any expected diagnostic.
@ Ignored
The diagnostic did not match, but reportUnexpected was false, so nothing was printed and nothing need...
@ NearMiss
The diagnostic's text matched an expected diagnostic, but its kind didn't; a message about this has a...
bool verify(raw_ostream &os, SourceMgr &mgr)
Reports (through mgr) any expected diagnostic that was never matched by a call to process.
MutableArrayRef< ExpectedDiag > computeExpectedDiags(raw_ostream &os, SourceMgr &mgr, const MemoryBuffer *buf)
Computes and caches the list of expected diagnostics for buf, if not already cached.
std::optional< MutableArrayRef< ExpectedDiag > > getExpectedDiags(StringRef bufName)
Returns the cached expected diagnostics for the buffer named bufName, or std::nullopt if computeExpec...
static void printMessage(raw_ostream &os, const SourceMgr &mgr, SMLoc loc, const Twine &msg, ArrayRef< SMRange > ranges={})
Prints an error to os without going through mgr's diagnostic handler, which may be the one feeding th...
MatchResult process(raw_ostream &os, SourceMgr &mgr, SourceMgr::DiagKind kind, bool hasLoc, const MemoryBuffer *buf, unsigned lineNo, unsigned colNo, StringRef message, bool reportUnexpected=true)
Matches a single actual diagnostic against the expected diagnostics recorded for buf / lineNo / colNo...
static StringRef getDiagKindStr(SourceMgr::DiagKind kind)
Given a diagnostic kind, return a human readable string for it.
SourceMgrDiagnosticVerifier(ArrayRef< StringRef > prefixes={ "expected"})
Recognizes directives starting with any of prefixes (e.g.
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling.
LLVM_ABI void printIncludeStackForDiagnostic(SMLoc Loc, raw_ostream &OS) const
Prints the include stack of a buffer unless it is a macro instantiation buffer.
LLVM_ABI SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg, ArrayRef< SMRange > Ranges={}, ArrayRef< SMFixIt > FixIts={}) const
Return an SMDiagnostic at the specified location with the specified string.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
char front() const
Get the first character in the string.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
void interleave(ForwardIterator begin, ForwardIterator end, UnaryFunctor each_fn, NullaryFunctor between_fn)
An STL-style algorithm similar to std::for_each that applies a second functor between every pair of e...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
A single diagnostic expected via an 'expected-<kind>' comment.
std::optional< Regex > substringRegex
An optional regex matcher, if the expected diagnostic substring was a regex string.
StringRef substring
The substring that is expected to be within the diagnostic.
LLVM_ABI bool computeRegex(raw_ostream &os, SourceMgr &mgr)
Computes the regex matcher for a '-re' diagnostic's substring.
SourceMgr::DiagKind kind
The severity of the diagnostic expected.
SMLoc fileLoc
The location of the expected diagnostic within the input file.
LLVM_ABI bool match(StringRef str) const
Returns true if this diagnostic matches the given message.
unsigned lineNo
The line number the expected diagnostic should be on.
LLVM_ABI bool emitError(raw_ostream &os, SourceMgr &mgr, const Twine &msg) const
Prints msg at this diagnostic's location and returns false, for use as return emitError(....
unsigned colNo
The column the expected diagnostic should be at, or 0 if any column matches.