Skip to content

Commit 3a2547c

Browse files
committed
[Diagnostics][NFC] Allow column specification in -verify mode
To check the column a diagnostic is emitted at, use expected-error@+x:y, or expected-error@:y to specify a column without a line offset
1 parent 4126215 commit 3a2547c

File tree

1 file changed

+48
-14
lines changed

1 file changed

+48
-14
lines changed

lib/Frontend/DiagnosticVerifier.cpp

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/Basic/SourceManager.h"
1919
#include "swift/Parse/Lexer.h"
2020
#include "llvm/Support/FileSystem.h"
21+
#include "llvm/Support/FormatVariadic.h"
2122
#include "llvm/Support/MemoryBuffer.h"
2223
#include "llvm/Support/raw_ostream.h"
2324

@@ -52,7 +53,8 @@ namespace {
5253
// This is the message string with escapes expanded.
5354
std::string MessageStr;
5455
unsigned LineNo = ~0U;
55-
56+
Optional<unsigned> ColumnNo;
57+
5658
std::vector<ExpectedFixIt> Fixits;
5759

5860
ExpectedDiagnosticInfo(const char *ExpectedStart,
@@ -127,6 +129,12 @@ DiagnosticVerifier::findDiagnostic(const ExpectedDiagnosticInfo &Expected,
127129
I->getFilename() != BufferName)
128130
continue;
129131

132+
// If a specific column was expected, verify it. Add one to the captured
133+
// index so expected column numbers correspond to printed output.
134+
if (Expected.ColumnNo.hasValue() &&
135+
I->getColumnNo() + 1 != (int)*Expected.ColumnNo)
136+
continue;
137+
130138
// Verify the classification and string.
131139
if (I->getKind() != Expected.Classification ||
132140
I->getMessage().find(Expected.MessageStr) == StringRef::npos)
@@ -262,10 +270,14 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID,
262270
continue;
263271
}
264272

273+
ExpectedDiagnosticInfo Expected(DiagnosticLoc, ExpectedClassification);
265274
int LineOffset = 0;
275+
266276
if (TextStartIdx > 0 && MatchStart[0] == '@') {
267-
if (MatchStart[1] != '+' && MatchStart[1] != '-') {
268-
addError(MatchStart.data(), "expected '+'/'-' for line offset");
277+
if (MatchStart[1] != '+' && MatchStart[1] != '-' &&
278+
MatchStart[1] != ':') {
279+
addError(MatchStart.data(),
280+
"expected '+'/'-' for line offset, or ':' for column");
269281
continue;
270282
}
271283
StringRef Offs;
@@ -285,13 +297,27 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID,
285297
TextStartIdx = 0;
286298
}
287299

288-
if (Offs.getAsInteger(10, LineOffset)) {
289-
addError(MatchStart.data(), "expected line offset before '{{'");
290-
continue;
300+
size_t ColonIndex = Offs.find(':');
301+
// Check whether a line offset was provided
302+
if (ColonIndex != 0) {
303+
StringRef LineOffs = Offs.slice(0, ColonIndex);
304+
if (LineOffs.getAsInteger(10, LineOffset)) {
305+
addError(MatchStart.data(), "expected line offset before '{{'");
306+
continue;
307+
}
291308
}
292-
}
293309

294-
ExpectedDiagnosticInfo Expected(DiagnosticLoc, ExpectedClassification);
310+
// Check whether a column was provided
311+
if (ColonIndex != StringRef::npos) {
312+
Offs = Offs.slice(ColonIndex + 1, Offs.size());
313+
int Column = 0;
314+
if (Offs.getAsInteger(10, Column)) {
315+
addError(MatchStart.data(), "expected column before '{{'");
316+
continue;
317+
}
318+
Expected.ColumnNo = Column;
319+
}
320+
}
295321

296322
unsigned Count = 1;
297323
if (TextStartIdx > 0) {
@@ -532,12 +558,20 @@ bool DiagnosticVerifier::verifyFile(unsigned BufferID,
532558
}
533559

534560
if (I == CapturedDiagnostics.end()) continue;
535-
536-
auto StartLoc = SMLoc::getFromPointer(expected.MessageRange.begin());
537-
auto EndLoc = SMLoc::getFromPointer(expected.MessageRange.end());
538-
539-
llvm::SMFixIt fixIt(llvm::SMRange{ StartLoc, EndLoc }, I->getMessage());
540-
addError(expected.MessageRange.begin(), "incorrect message found", fixIt);
561+
562+
if (I->getMessage().find(expected.MessageStr) == StringRef::npos) {
563+
auto StartLoc = SMLoc::getFromPointer(expected.MessageRange.begin());
564+
auto EndLoc = SMLoc::getFromPointer(expected.MessageRange.end());
565+
566+
llvm::SMFixIt fixIt(llvm::SMRange{StartLoc, EndLoc}, I->getMessage());
567+
addError(expected.MessageRange.begin(), "incorrect message found", fixIt);
568+
} else {
569+
// The difference must be only in the column
570+
addError(expected.MessageRange.begin(),
571+
llvm::formatv("message found at column {0} but was expected to "
572+
"appear at column {1}",
573+
I->getColumnNo() + 1, *expected.ColumnNo));
574+
}
541575
CapturedDiagnostics.erase(I);
542576
ExpectedDiagnostics.erase(ExpectedDiagnostics.begin()+i);
543577
}

0 commit comments

Comments
 (0)