|
|
|
@@ -28,6 +28,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
using namespace swift;
|
|
|
|
using namespace swift;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const DiagnosticKind DiagnosticKindExpansion = DiagnosticKind((int)DiagnosticKind::Note + 1);
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
|
|
struct ExpectedCheckMatchStartParser {
|
|
|
|
struct ExpectedCheckMatchStartParser {
|
|
|
|
@@ -67,6 +69,13 @@ struct ExpectedCheckMatchStartParser {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (MatchStart.starts_with("expansion")) {
|
|
|
|
|
|
|
|
ClassificationStartLoc = MatchStart.data();
|
|
|
|
|
|
|
|
ExpectedClassification = DiagnosticKindExpansion;
|
|
|
|
|
|
|
|
MatchStart = MatchStart.substr(strlen("expansion"));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -221,6 +230,8 @@ struct ExpectedDiagnosticInfo {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
std::optional<ExpectedDocumentationFile> DocumentationFile;
|
|
|
|
std::optional<ExpectedDocumentationFile> DocumentationFile;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<ExpectedDiagnosticInfo> NestedDiags = {};
|
|
|
|
|
|
|
|
|
|
|
|
ExpectedDiagnosticInfo(const char *ExpectedStart,
|
|
|
|
ExpectedDiagnosticInfo(const char *ExpectedStart,
|
|
|
|
const char *ClassificationStart,
|
|
|
|
const char *ClassificationStart,
|
|
|
|
const char *ClassificationEnd,
|
|
|
|
const char *ClassificationEnd,
|
|
|
|
@@ -239,6 +250,8 @@ static std::string getDiagKindString(DiagnosticKind Kind) {
|
|
|
|
return "note";
|
|
|
|
return "note";
|
|
|
|
case DiagnosticKind::Remark:
|
|
|
|
case DiagnosticKind::Remark:
|
|
|
|
return "remark";
|
|
|
|
return "remark";
|
|
|
|
|
|
|
|
case DiagnosticKindExpansion:
|
|
|
|
|
|
|
|
return "expansion";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
llvm_unreachable("Unhandled DiagKind in switch.");
|
|
|
|
llvm_unreachable("Unhandled DiagKind in switch.");
|
|
|
|
@@ -259,7 +272,7 @@ renderDocumentationFile(const std::string &documentationFile) {
|
|
|
|
/// Otherwise return \c CapturedDiagnostics.end() with \c false.
|
|
|
|
/// Otherwise return \c CapturedDiagnostics.end() with \c false.
|
|
|
|
static std::tuple<std::vector<CapturedDiagnosticInfo>::iterator, bool>
|
|
|
|
static std::tuple<std::vector<CapturedDiagnosticInfo>::iterator, bool>
|
|
|
|
findDiagnostic(std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics,
|
|
|
|
findDiagnostic(std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics,
|
|
|
|
const ExpectedDiagnosticInfo &Expected, unsigned BufferID) {
|
|
|
|
const ExpectedDiagnosticInfo &Expected, unsigned BufferID, SourceManager &SM) {
|
|
|
|
auto fallbackI = CapturedDiagnostics.end();
|
|
|
|
auto fallbackI = CapturedDiagnostics.end();
|
|
|
|
|
|
|
|
|
|
|
|
for (auto I = CapturedDiagnostics.begin(), E = CapturedDiagnostics.end();
|
|
|
|
for (auto I = CapturedDiagnostics.begin(), E = CapturedDiagnostics.end();
|
|
|
|
@@ -418,7 +431,20 @@ void DiagnosticVerifier::printDiagnostic(const llvm::SMDiagnostic &Diag) const {
|
|
|
|
raw_ostream &stream = llvm::errs();
|
|
|
|
raw_ostream &stream = llvm::errs();
|
|
|
|
ColoredStream coloredStream{stream};
|
|
|
|
ColoredStream coloredStream{stream};
|
|
|
|
raw_ostream &out = UseColor ? coloredStream : stream;
|
|
|
|
raw_ostream &out = UseColor ? coloredStream : stream;
|
|
|
|
SM.getLLVMSourceMgr().PrintMessage(out, Diag);
|
|
|
|
llvm::SourceMgr &Underlying = SM.getLLVMSourceMgr();
|
|
|
|
|
|
|
|
Underlying.PrintMessage(out, Diag);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SourceLoc Loc = SourceLoc::getFromPointer(Diag.getLoc().getPointer());
|
|
|
|
|
|
|
|
if (Loc.isInvalid())
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
unsigned BufferID = SM.findBufferContainingLoc(Loc);
|
|
|
|
|
|
|
|
if (const GeneratedSourceInfo *GSI = SM.getGeneratedSourceInfo(BufferID)) {
|
|
|
|
|
|
|
|
SourceLoc ParentLoc = GSI->originalSourceRange.getStart();
|
|
|
|
|
|
|
|
if (ParentLoc.isInvalid())
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
printDiagnostic(SM.GetMessage(ParentLoc, llvm::SourceMgr::DK_Note,
|
|
|
|
|
|
|
|
"in expansion from here", {}, {}));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string
|
|
|
|
std::string
|
|
|
|
@@ -465,9 +491,9 @@ DiagnosticVerifier::renderFixits(ArrayRef<CapturedFixItInfo> ActualFixIts,
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// \param DiagnosticLineNo The line number of the associated expected
|
|
|
|
/// \param DiagnosticLineNo The line number of the associated expected
|
|
|
|
/// diagnostic; used to turn line offsets into line numbers.
|
|
|
|
/// diagnostic; used to turn line offsets into line numbers.
|
|
|
|
static std::optional<LineColumnRange> parseExpectedFixItRange(
|
|
|
|
std::optional<LineColumnRange>
|
|
|
|
StringRef &Str, unsigned DiagnosticLineNo,
|
|
|
|
DiagnosticVerifier::parseExpectedFixItRange(StringRef &Str,
|
|
|
|
llvm::function_ref<void(const char *, const Twine &)> diagnoseError) {
|
|
|
|
unsigned DiagnosticLineNo) {
|
|
|
|
assert(!Str.empty());
|
|
|
|
assert(!Str.empty());
|
|
|
|
|
|
|
|
|
|
|
|
struct ParsedLineAndColumn {
|
|
|
|
struct ParsedLineAndColumn {
|
|
|
|
@@ -497,10 +523,10 @@ static std::optional<LineColumnRange> parseExpectedFixItRange(
|
|
|
|
unsigned FirstVal = 0;
|
|
|
|
unsigned FirstVal = 0;
|
|
|
|
if (Str.consumeInteger(10, FirstVal)) {
|
|
|
|
if (Str.consumeInteger(10, FirstVal)) {
|
|
|
|
if (LineOffsetKind == OffsetKind::None) {
|
|
|
|
if (LineOffsetKind == OffsetKind::None) {
|
|
|
|
diagnoseError(Str.data(),
|
|
|
|
addError(Str.data(),
|
|
|
|
"expected line or column number in fix-it verification");
|
|
|
|
"expected line or column number in fix-it verification");
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
diagnoseError(Str.data(),
|
|
|
|
addError(Str.data(),
|
|
|
|
"expected line offset after leading '+' or '-' in fix-it "
|
|
|
|
"expected line offset after leading '+' or '-' in fix-it "
|
|
|
|
"verification");
|
|
|
|
"verification");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -514,7 +540,7 @@ static std::optional<LineColumnRange> parseExpectedFixItRange(
|
|
|
|
return ParsedLineAndColumn{std::nullopt, FirstVal};
|
|
|
|
return ParsedLineAndColumn{std::nullopt, FirstVal};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
diagnoseError(Str.data(),
|
|
|
|
addError(Str.data(),
|
|
|
|
"expected colon-separated column number after line offset "
|
|
|
|
"expected colon-separated column number after line offset "
|
|
|
|
"in fix-it verification");
|
|
|
|
"in fix-it verification");
|
|
|
|
return std::nullopt;
|
|
|
|
return std::nullopt;
|
|
|
|
@@ -523,7 +549,7 @@ static std::optional<LineColumnRange> parseExpectedFixItRange(
|
|
|
|
unsigned Column = 0;
|
|
|
|
unsigned Column = 0;
|
|
|
|
Str = Str.drop_front();
|
|
|
|
Str = Str.drop_front();
|
|
|
|
if (Str.consumeInteger(10, Column)) {
|
|
|
|
if (Str.consumeInteger(10, Column)) {
|
|
|
|
diagnoseError(Str.data(),
|
|
|
|
addError(Str.data(),
|
|
|
|
"expected column number after ':' in fix-it verification");
|
|
|
|
"expected column number after ':' in fix-it verification");
|
|
|
|
return std::nullopt;
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -556,7 +582,7 @@ static std::optional<LineColumnRange> parseExpectedFixItRange(
|
|
|
|
if (!Str.empty() && Str.front() == '-') {
|
|
|
|
if (!Str.empty() && Str.front() == '-') {
|
|
|
|
Str = Str.drop_front();
|
|
|
|
Str = Str.drop_front();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
diagnoseError(Str.data(),
|
|
|
|
addError(Str.data(),
|
|
|
|
"expected '-' range separator in fix-it verification");
|
|
|
|
"expected '-' range separator in fix-it verification");
|
|
|
|
return std::nullopt;
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -607,20 +633,13 @@ static bool parseTargetBufferName(StringRef &MatchStart, StringRef &Out, size_t
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
unsigned BufferID, StringRef MatchStart,
|
|
|
|
unsigned BufferID, StringRef MatchStartIn,
|
|
|
|
std::vector<llvm::SMDiagnostic> &Errors,
|
|
|
|
|
|
|
|
unsigned &PrevExpectedContinuationLine,
|
|
|
|
unsigned &PrevExpectedContinuationLine,
|
|
|
|
ExpectedDiagnosticInfo &Expected) const {
|
|
|
|
ExpectedDiagnosticInfo &Expected) {
|
|
|
|
auto addError = [&](const char *Loc, const Twine &message,
|
|
|
|
|
|
|
|
ArrayRef<llvm::SMFixIt> FixIts = {}) {
|
|
|
|
|
|
|
|
auto loc = SourceLoc::getFromPointer(Loc);
|
|
|
|
|
|
|
|
auto diag = SM.GetMessage(loc, llvm::SourceMgr::DK_Error, message,
|
|
|
|
|
|
|
|
{}, FixIts);
|
|
|
|
|
|
|
|
Errors.push_back(diag);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const SourceLoc BufferStartLoc = SM.getLocForBufferStart(BufferID);
|
|
|
|
const SourceLoc BufferStartLoc = SM.getLocForBufferStart(BufferID);
|
|
|
|
StringRef InputFile = SM.getEntireTextForBuffer(BufferID);
|
|
|
|
StringRef InputFile = SM.getEntireTextForBuffer(BufferID);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StringRef MatchStart = MatchStartIn;
|
|
|
|
const char *DiagnosticLoc = MatchStart.data();
|
|
|
|
const char *DiagnosticLoc = MatchStart.data();
|
|
|
|
MatchStart = MatchStart.substr(strlen("expected-"));
|
|
|
|
MatchStart = MatchStart.substr(strlen("expected-"));
|
|
|
|
|
|
|
|
|
|
|
|
@@ -654,9 +673,10 @@ unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
/*ClassificationEndLoc=*/MatchStart.data(),
|
|
|
|
/*ClassificationEndLoc=*/MatchStart.data(),
|
|
|
|
*ExpectedClassification);
|
|
|
|
*ExpectedClassification);
|
|
|
|
int LineOffset = 0;
|
|
|
|
int LineOffset = 0;
|
|
|
|
|
|
|
|
bool AbsoluteLine = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (TextStartIdx > 0 && MatchStart[0] == '@') {
|
|
|
|
if (TextStartIdx > 0 && MatchStart[0] == '@') {
|
|
|
|
if (MatchStart[1] != '+' && MatchStart[1] != '-' && MatchStart[1] != ':') {
|
|
|
|
if (MatchStart[1] != '+' && MatchStart[1] != '-' && MatchStart[1] != ':' && (MatchStart[1] < '0' || MatchStart[1] > '9')) {
|
|
|
|
StringRef TargetBufferName;
|
|
|
|
StringRef TargetBufferName;
|
|
|
|
if (!parseTargetBufferName(MatchStart, TargetBufferName, TextStartIdx)) {
|
|
|
|
if (!parseTargetBufferName(MatchStart, TargetBufferName, TextStartIdx)) {
|
|
|
|
addError(MatchStart.data(), "expected '+'/'-' for line offset, ':' "
|
|
|
|
addError(MatchStart.data(), "expected '+'/'-' for line offset, ':' "
|
|
|
|
@@ -669,12 +689,20 @@ unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
"no buffer with name '" + TargetBufferName + "' found");
|
|
|
|
"no buffer with name '" + TargetBufferName + "' found");
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MatchStart[0] != ':' || MatchStart[1] < '0' || MatchStart[1] > '9') {
|
|
|
|
|
|
|
|
addError(MatchStart.data(),
|
|
|
|
|
|
|
|
"expected absolute line number for diagnostic in other buffer");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
StringRef Offs;
|
|
|
|
StringRef Offs;
|
|
|
|
if (MatchStart[1] == '+')
|
|
|
|
if (MatchStart[1] == '+')
|
|
|
|
Offs = MatchStart.slice(2, TextStartIdx).rtrim();
|
|
|
|
Offs = MatchStart.slice(2, TextStartIdx).rtrim();
|
|
|
|
else
|
|
|
|
else {
|
|
|
|
Offs = MatchStart.slice(1, TextStartIdx).rtrim();
|
|
|
|
Offs = MatchStart.slice(1, TextStartIdx).rtrim();
|
|
|
|
|
|
|
|
if (Offs[0] != '-')
|
|
|
|
|
|
|
|
AbsoluteLine = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t SpaceIndex = Offs.find(' ');
|
|
|
|
size_t SpaceIndex = Offs.find(' ');
|
|
|
|
if (SpaceIndex != StringRef::npos && SpaceIndex < TextStartIdx) {
|
|
|
|
if (SpaceIndex != StringRef::npos && SpaceIndex < TextStartIdx) {
|
|
|
|
@@ -709,6 +737,11 @@ unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Expected.Classification == DiagnosticKindExpansion && !Expected.ColumnNo.has_value()) {
|
|
|
|
|
|
|
|
addError(DiagnosticLoc, "expected-expansion requires column location");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned Count = 1;
|
|
|
|
unsigned Count = 1;
|
|
|
|
if (TextStartIdx > 0) {
|
|
|
|
if (TextStartIdx > 0) {
|
|
|
|
StringRef CountStr = MatchStart.substr(0, TextStartIdx).trim(" \t");
|
|
|
|
StringRef CountStr = MatchStart.substr(0, TextStartIdx).trim(" \t");
|
|
|
|
@@ -730,19 +763,62 @@ unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
MatchStart = MatchStart.substr(TextStartIdx);
|
|
|
|
MatchStart = MatchStart.substr(TextStartIdx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size_t End = MatchStart.find("}}");
|
|
|
|
size_t End = StringRef::npos;
|
|
|
|
if (End == StringRef::npos) {
|
|
|
|
if (Expected.Classification == DiagnosticKindExpansion) {
|
|
|
|
addError(
|
|
|
|
size_t NestedMatch = MatchStart.find("expected-");
|
|
|
|
MatchStart.data(),
|
|
|
|
// Scan the memory buffer looking for expected-note/warning/error.
|
|
|
|
"didn't find '}}' to match '{{' in expected-warning/note/error line");
|
|
|
|
while (NestedMatch != StringRef::npos) {
|
|
|
|
return 0;
|
|
|
|
StringRef NestedMatchStart = MatchStart.substr(NestedMatch);
|
|
|
|
|
|
|
|
ExpectedDiagnosticInfo NestedExpected(nullptr, nullptr, nullptr,
|
|
|
|
|
|
|
|
DiagnosticKind(-1));
|
|
|
|
|
|
|
|
unsigned NestedCount =
|
|
|
|
|
|
|
|
parseExpectedDiagInfo(BufferID, NestedMatchStart,
|
|
|
|
|
|
|
|
PrevExpectedContinuationLine, NestedExpected);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t PrevMatchEnd = NestedMatch + 1;
|
|
|
|
|
|
|
|
if (NestedCount > 0) {
|
|
|
|
|
|
|
|
// Add the diagnostic the expected number of times.
|
|
|
|
|
|
|
|
for (; NestedCount; --NestedCount)
|
|
|
|
|
|
|
|
Expected.NestedDiags.push_back(NestedExpected);
|
|
|
|
|
|
|
|
size_t NestedMatchEnd =
|
|
|
|
|
|
|
|
NestedExpected.ExpectedEnd - NestedMatchStart.data();
|
|
|
|
|
|
|
|
assert(NestedMatchEnd > 0);
|
|
|
|
|
|
|
|
PrevMatchEnd = NestedMatch + NestedMatchEnd;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
size_t NextEnd = MatchStart.find("}}", PrevMatchEnd);
|
|
|
|
|
|
|
|
NestedMatch = MatchStart.find("expected-", PrevMatchEnd);
|
|
|
|
|
|
|
|
if (NextEnd < NestedMatch) {
|
|
|
|
|
|
|
|
End = NextEnd;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (End == StringRef::npos) {
|
|
|
|
|
|
|
|
addError(
|
|
|
|
|
|
|
|
DiagnosticLoc,
|
|
|
|
|
|
|
|
"didn't find '}}' to match '{{' in expected-expansion");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Expected.NestedDiags.size() == 0) {
|
|
|
|
|
|
|
|
addError(DiagnosticLoc, "expected-expansion block is empty");
|
|
|
|
|
|
|
|
// Keep going
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
End = MatchStart.find("}}");
|
|
|
|
|
|
|
|
if (End == StringRef::npos) {
|
|
|
|
|
|
|
|
addError(
|
|
|
|
|
|
|
|
MatchStart.data(),
|
|
|
|
|
|
|
|
"didn't find '}}' to match '{{' in expected-warning/note/error line");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
llvm::SmallString<256> Buf;
|
|
|
|
llvm::SmallString<256> Buf;
|
|
|
|
Expected.MessageRange = MatchStart.slice(2, End);
|
|
|
|
Expected.MessageRange = MatchStart.slice(2, End);
|
|
|
|
Expected.MessageStr =
|
|
|
|
Expected.MessageStr =
|
|
|
|
Lexer::getEncodedStringSegment(Expected.MessageRange, Buf).str();
|
|
|
|
Lexer::getEncodedStringSegment(Expected.MessageRange, Buf).str();
|
|
|
|
if (Expected.TargetBufferID)
|
|
|
|
if (AbsoluteLine)
|
|
|
|
Expected.LineNo = 0;
|
|
|
|
Expected.LineNo = 0;
|
|
|
|
else if (PrevExpectedContinuationLine)
|
|
|
|
else if (PrevExpectedContinuationLine)
|
|
|
|
Expected.LineNo = PrevExpectedContinuationLine;
|
|
|
|
Expected.LineNo = PrevExpectedContinuationLine;
|
|
|
|
@@ -861,7 +937,7 @@ unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
FixIt.EndLoc = CloseLoc;
|
|
|
|
FixIt.EndLoc = CloseLoc;
|
|
|
|
|
|
|
|
|
|
|
|
if (const auto range =
|
|
|
|
if (const auto range =
|
|
|
|
parseExpectedFixItRange(CheckStr, Expected.LineNo, addError)) {
|
|
|
|
parseExpectedFixItRange(CheckStr, Expected.LineNo)) {
|
|
|
|
FixIt.Range = range.value();
|
|
|
|
FixIt.Range = range.value();
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
@@ -893,6 +969,9 @@ unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Expected.Classification == DiagnosticKindExpansion) {
|
|
|
|
|
|
|
|
addError(OpenLoc, "expected-expansion cannot have fixits");
|
|
|
|
|
|
|
|
}
|
|
|
|
Expected.Fixits.back().push_back(FixIt);
|
|
|
|
Expected.Fixits.back().push_back(FixIt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -909,50 +988,7 @@ unsigned DiagnosticVerifier::parseExpectedDiagInfo(
|
|
|
|
return Count;
|
|
|
|
return Count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// After the file has been processed, check to see if we got all of
|
|
|
|
void DiagnosticVerifier::verifyDiagnostics(std::vector<ExpectedDiagnosticInfo> &ExpectedDiagnostics, unsigned BufferID) {
|
|
|
|
/// the expected diagnostics and check to see if there were any unexpected
|
|
|
|
|
|
|
|
/// ones.
|
|
|
|
|
|
|
|
DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
|
|
|
|
using llvm::SMLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StringRef InputFile = SM.getEntireTextForBuffer(BufferID);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Queue up all of the diagnostics, allowing us to sort them and emit them in
|
|
|
|
|
|
|
|
// file order.
|
|
|
|
|
|
|
|
std::vector<llvm::SMDiagnostic> Errors;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned PrevExpectedContinuationLine = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<ExpectedDiagnosticInfo> ExpectedDiagnostics;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto addError = [&](const char *Loc, const Twine &message,
|
|
|
|
|
|
|
|
ArrayRef<llvm::SMFixIt> FixIts = {}) {
|
|
|
|
|
|
|
|
auto loc = SourceLoc::getFromPointer(Loc);
|
|
|
|
|
|
|
|
auto diag = SM.GetMessage(loc, llvm::SourceMgr::DK_Error, message,
|
|
|
|
|
|
|
|
{}, FixIts);
|
|
|
|
|
|
|
|
Errors.push_back(diag);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Validate that earlier prefixes are not prefixes of alter
|
|
|
|
|
|
|
|
// prefixes... otherwise, we will never pattern match the later prefix.
|
|
|
|
|
|
|
|
validatePrefixList(AdditionalExpectedPrefixes);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Scan the memory buffer looking for expected-note/warning/error.
|
|
|
|
|
|
|
|
for (size_t Match = InputFile.find("expected-");
|
|
|
|
|
|
|
|
Match != StringRef::npos; Match = InputFile.find("expected-", Match+1)) {
|
|
|
|
|
|
|
|
// Process this potential match. If we fail to process it, just move on to
|
|
|
|
|
|
|
|
// the next match.
|
|
|
|
|
|
|
|
StringRef MatchStart = InputFile.substr(Match);
|
|
|
|
|
|
|
|
ExpectedDiagnosticInfo Expected(nullptr, nullptr, nullptr, DiagnosticKind(-1));
|
|
|
|
|
|
|
|
unsigned Count = parseExpectedDiagInfo(BufferID, MatchStart, Errors, PrevExpectedContinuationLine, Expected);
|
|
|
|
|
|
|
|
if (Count < 1)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add the diagnostic the expected number of times.
|
|
|
|
|
|
|
|
for (; Count; --Count)
|
|
|
|
|
|
|
|
ExpectedDiagnostics.push_back(Expected);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure all the expected diagnostics appeared.
|
|
|
|
// Make sure all the expected diagnostics appeared.
|
|
|
|
std::reverse(ExpectedDiagnostics.begin(), ExpectedDiagnostics.end());
|
|
|
|
std::reverse(ExpectedDiagnostics.begin(), ExpectedDiagnostics.end());
|
|
|
|
|
|
|
|
|
|
|
|
@@ -962,8 +998,22 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
|
|
|
|
|
|
|
|
unsigned ID = expected.TargetBufferID.value_or(BufferID);
|
|
|
|
unsigned ID = expected.TargetBufferID.value_or(BufferID);
|
|
|
|
// Check to see if we had this expected diagnostic.
|
|
|
|
// Check to see if we had this expected diagnostic.
|
|
|
|
|
|
|
|
if (expected.Classification == DiagnosticKindExpansion) {
|
|
|
|
|
|
|
|
SourceLoc Loc = SM.getLocForLineCol(BufferID, expected.LineNo, *expected.ColumnNo);
|
|
|
|
|
|
|
|
if (Expansions.count(Loc) == 0) {
|
|
|
|
|
|
|
|
addError(expected.ExpectedStart,
|
|
|
|
|
|
|
|
"no expansion with diagnostics starting at " +
|
|
|
|
|
|
|
|
std::to_string(expected.LineNo) + ":" + std::to_string(*expected.ColumnNo));
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned ExpansionBufferID = Expansions[Loc];
|
|
|
|
|
|
|
|
verifyDiagnostics(expected.NestedDiags, ExpansionBufferID);
|
|
|
|
|
|
|
|
if (expected.NestedDiags.empty())
|
|
|
|
|
|
|
|
ExpectedDiagnostics.erase(ExpectedDiagnostics.begin()+i);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
auto FoundDiagnosticInfo =
|
|
|
|
auto FoundDiagnosticInfo =
|
|
|
|
findDiagnostic(CapturedDiagnostics, expected, ID);
|
|
|
|
findDiagnostic(CapturedDiagnostics, expected, ID, SM);
|
|
|
|
auto FoundDiagnosticIter = std::get<0>(FoundDiagnosticInfo);
|
|
|
|
auto FoundDiagnosticIter = std::get<0>(FoundDiagnosticInfo);
|
|
|
|
if (FoundDiagnosticIter == CapturedDiagnostics.end()) {
|
|
|
|
if (FoundDiagnosticIter == CapturedDiagnostics.end()) {
|
|
|
|
// Diagnostic didn't exist. If this is a 'mayAppear' diagnostic, then
|
|
|
|
// Diagnostic didn't exist. If this is a 'mayAppear' diagnostic, then
|
|
|
|
@@ -976,8 +1026,8 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
auto emitFixItsError = [&](const char *location, const Twine &message,
|
|
|
|
auto emitFixItsError = [&](const char *location, const Twine &message,
|
|
|
|
const char *replStartLoc, const char *replEndLoc,
|
|
|
|
const char *replStartLoc, const char *replEndLoc,
|
|
|
|
const std::string &replStr) {
|
|
|
|
const std::string &replStr) {
|
|
|
|
llvm::SMFixIt fix(llvm::SMRange(SMLoc::getFromPointer(replStartLoc),
|
|
|
|
llvm::SMFixIt fix(llvm::SMRange(llvm::SMLoc::getFromPointer(replStartLoc),
|
|
|
|
SMLoc::getFromPointer(replEndLoc)),
|
|
|
|
llvm::SMLoc::getFromPointer(replEndLoc)),
|
|
|
|
replStr);
|
|
|
|
replStr);
|
|
|
|
addError(location, message, fix);
|
|
|
|
addError(location, message, fix);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
@@ -1118,8 +1168,8 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
// produce a fixit of our own.
|
|
|
|
// produce a fixit of our own.
|
|
|
|
auto actual =
|
|
|
|
auto actual =
|
|
|
|
renderDocumentationFile(FoundDiagnostic.CategoryDocFile);
|
|
|
|
renderDocumentationFile(FoundDiagnostic.CategoryDocFile);
|
|
|
|
auto replStartLoc = SMLoc::getFromPointer(expectedDocFile->StartLoc);
|
|
|
|
auto replStartLoc = llvm::SMLoc::getFromPointer(expectedDocFile->StartLoc);
|
|
|
|
auto replEndLoc = SMLoc::getFromPointer(expectedDocFile->EndLoc);
|
|
|
|
auto replEndLoc = llvm::SMLoc::getFromPointer(expectedDocFile->EndLoc);
|
|
|
|
|
|
|
|
|
|
|
|
llvm::SMFixIt fix(llvm::SMRange(replStartLoc, replEndLoc), actual);
|
|
|
|
llvm::SMFixIt fix(llvm::SMRange(replStartLoc, replEndLoc), actual);
|
|
|
|
addError(expectedDocFile->StartLoc,
|
|
|
|
addError(expectedDocFile->StartLoc,
|
|
|
|
@@ -1141,7 +1191,115 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
else
|
|
|
|
else
|
|
|
|
ExpectedDiagnostics.erase(ExpectedDiagnostics.begin()+i);
|
|
|
|
ExpectedDiagnostics.erase(ExpectedDiagnostics.begin()+i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void DiagnosticVerifier::verifyRemaining(
|
|
|
|
|
|
|
|
std::vector<ExpectedDiagnosticInfo> &ExpectedDiagnostics,
|
|
|
|
|
|
|
|
const char *FileStart) {
|
|
|
|
|
|
|
|
std::reverse(ExpectedDiagnostics.begin(), ExpectedDiagnostics.end());
|
|
|
|
|
|
|
|
for (auto &expected : ExpectedDiagnostics) {
|
|
|
|
|
|
|
|
if (expected.Classification == DiagnosticKindExpansion) {
|
|
|
|
|
|
|
|
verifyRemaining(expected.NestedDiags, FileStart);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string message = "expected "+getDiagKindString(expected.Classification)
|
|
|
|
|
|
|
|
+ " not produced";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get the range of the expected-foo{{}} diagnostic specifier.
|
|
|
|
|
|
|
|
auto StartLoc = expected.ExpectedStart;
|
|
|
|
|
|
|
|
auto EndLoc = expected.ExpectedEnd;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// A very common case if for the specifier to be the last thing on the line.
|
|
|
|
|
|
|
|
// In this case, eat any trailing whitespace.
|
|
|
|
|
|
|
|
while (isspace(*EndLoc) && *EndLoc != '\n' && *EndLoc != '\r')
|
|
|
|
|
|
|
|
++EndLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we found the end of the line, we can do great things. Otherwise,
|
|
|
|
|
|
|
|
// avoid nuking whitespace that might be zapped through other means.
|
|
|
|
|
|
|
|
if (*EndLoc != '\n' && *EndLoc != '\r') {
|
|
|
|
|
|
|
|
EndLoc = expected.ExpectedEnd;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// If we hit the end of line, then zap whitespace leading up to it.
|
|
|
|
|
|
|
|
while (StartLoc-1 != FileStart && isspace(StartLoc[-1]) &&
|
|
|
|
|
|
|
|
StartLoc[-1] != '\n' && StartLoc[-1] != '\r')
|
|
|
|
|
|
|
|
--StartLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we got to the end of the line, and the thing before this diagnostic
|
|
|
|
|
|
|
|
// is a "//" then we can remove it too.
|
|
|
|
|
|
|
|
if (StartLoc-2 >= FileStart && StartLoc[-1] == '/' && StartLoc[-2] == '/')
|
|
|
|
|
|
|
|
StartLoc -= 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Perform another round of general whitespace nuking to cleanup
|
|
|
|
|
|
|
|
// whitespace before the //.
|
|
|
|
|
|
|
|
while (StartLoc-1 != FileStart && isspace(StartLoc[-1]) &&
|
|
|
|
|
|
|
|
StartLoc[-1] != '\n' && StartLoc[-1] != '\r')
|
|
|
|
|
|
|
|
--StartLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we found a \n, then we can nuke the entire line.
|
|
|
|
|
|
|
|
if (StartLoc-1 != FileStart &&
|
|
|
|
|
|
|
|
(StartLoc[-1] == '\n' || StartLoc[-1] == '\r'))
|
|
|
|
|
|
|
|
--StartLoc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Remove the expected-foo{{}} as a fixit.
|
|
|
|
|
|
|
|
llvm::SMFixIt fixIt(llvm::SMRange{
|
|
|
|
|
|
|
|
llvm::SMLoc::getFromPointer(StartLoc),
|
|
|
|
|
|
|
|
llvm::SMLoc::getFromPointer(EndLoc)
|
|
|
|
|
|
|
|
}, "");
|
|
|
|
|
|
|
|
addError(expected.ExpectedStart, message, fixIt);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void DiagnosticVerifier::addError(const char *Loc, const Twine &message,
|
|
|
|
|
|
|
|
ArrayRef<llvm::SMFixIt> FixIts) {
|
|
|
|
|
|
|
|
auto loc = SourceLoc::getFromPointer(Loc);
|
|
|
|
|
|
|
|
auto diag =
|
|
|
|
|
|
|
|
SM.GetMessage(loc, llvm::SourceMgr::DK_Error, message, {}, FixIts);
|
|
|
|
|
|
|
|
Errors.push_back(diag);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// After the file has been processed, check to see if we got all of
|
|
|
|
|
|
|
|
/// the expected diagnostics and check to see if there were any unexpected
|
|
|
|
|
|
|
|
/// ones.
|
|
|
|
|
|
|
|
DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
|
|
|
|
Errors.clear();
|
|
|
|
|
|
|
|
using llvm::SMLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StringRef InputFile = SM.getEntireTextForBuffer(BufferID);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Queue up all of the diagnostics, allowing us to sort them and emit them in
|
|
|
|
|
|
|
|
// file order.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned PrevExpectedContinuationLine = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<ExpectedDiagnosticInfo> ExpectedDiagnostics;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Validate that earlier prefixes are not prefixes of alter
|
|
|
|
|
|
|
|
// prefixes... otherwise, we will never pattern match the later prefix.
|
|
|
|
|
|
|
|
validatePrefixList(AdditionalExpectedPrefixes);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const char *PrevMatchEnd = InputFile.data();
|
|
|
|
|
|
|
|
// Scan the memory buffer looking for expected-note/warning/error.
|
|
|
|
|
|
|
|
for (size_t Match = InputFile.find("expected-");
|
|
|
|
|
|
|
|
Match != StringRef::npos; Match = InputFile.find("expected-", Match+1)) {
|
|
|
|
|
|
|
|
// Process this potential match. If we fail to process it, just move on to
|
|
|
|
|
|
|
|
// the next match.
|
|
|
|
|
|
|
|
StringRef MatchStart = InputFile.substr(Match);
|
|
|
|
|
|
|
|
if (MatchStart.data() < PrevMatchEnd)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ExpectedDiagnosticInfo Expected(nullptr, nullptr, nullptr, DiagnosticKind(-1));
|
|
|
|
|
|
|
|
unsigned Count = parseExpectedDiagInfo(BufferID, MatchStart, PrevExpectedContinuationLine, Expected);
|
|
|
|
|
|
|
|
if (Count < 1)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add the diagnostic the expected number of times.
|
|
|
|
|
|
|
|
for (; Count; --Count)
|
|
|
|
|
|
|
|
ExpectedDiagnostics.push_back(Expected);
|
|
|
|
|
|
|
|
PrevMatchEnd = Expected.ExpectedEnd;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
verifyDiagnostics(ExpectedDiagnostics, BufferID);
|
|
|
|
|
|
|
|
|
|
|
|
// Check to see if we have any incorrect diagnostics. If so, diagnose them as
|
|
|
|
// Check to see if we have any incorrect diagnostics. If so, diagnose them as
|
|
|
|
// such.
|
|
|
|
// such.
|
|
|
|
auto expectedDiagIter = ExpectedDiagnostics.begin();
|
|
|
|
auto expectedDiagIter = ExpectedDiagnostics.begin();
|
|
|
|
@@ -1154,7 +1312,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
if (I->Line != expectedDiagIter->LineNo || I->SourceBufferID != BufferID
|
|
|
|
if (I->Line != expectedDiagIter->LineNo || I->SourceBufferID != BufferID
|
|
|
|
|| I->Classification != expectedDiagIter->Classification)
|
|
|
|
|| I->Classification != expectedDiagIter->Classification)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
// Otherwise, we found it, break out.
|
|
|
|
// Otherwise, we found it, break out.
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -1186,55 +1344,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Diagnose expected diagnostics that didn't appear.
|
|
|
|
// Diagnose expected diagnostics that didn't appear.
|
|
|
|
std::reverse(ExpectedDiagnostics.begin(), ExpectedDiagnostics.end());
|
|
|
|
verifyRemaining(ExpectedDiagnostics, InputFile.data());
|
|
|
|
for (auto const &expected : ExpectedDiagnostics) {
|
|
|
|
|
|
|
|
std::string message = "expected "+getDiagKindString(expected.Classification)
|
|
|
|
|
|
|
|
+ " not produced";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get the range of the expected-foo{{}} diagnostic specifier.
|
|
|
|
|
|
|
|
auto StartLoc = expected.ExpectedStart;
|
|
|
|
|
|
|
|
auto EndLoc = expected.ExpectedEnd;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// A very common case if for the specifier to be the last thing on the line.
|
|
|
|
|
|
|
|
// In this case, eat any trailing whitespace.
|
|
|
|
|
|
|
|
while (isspace(*EndLoc) && *EndLoc != '\n' && *EndLoc != '\r')
|
|
|
|
|
|
|
|
++EndLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we found the end of the line, we can do great things. Otherwise,
|
|
|
|
|
|
|
|
// avoid nuking whitespace that might be zapped through other means.
|
|
|
|
|
|
|
|
if (*EndLoc != '\n' && *EndLoc != '\r') {
|
|
|
|
|
|
|
|
EndLoc = expected.ExpectedEnd;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// If we hit the end of line, then zap whitespace leading up to it.
|
|
|
|
|
|
|
|
auto FileStart = InputFile.data();
|
|
|
|
|
|
|
|
while (StartLoc-1 != FileStart && isspace(StartLoc[-1]) &&
|
|
|
|
|
|
|
|
StartLoc[-1] != '\n' && StartLoc[-1] != '\r')
|
|
|
|
|
|
|
|
--StartLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we got to the end of the line, and the thing before this diagnostic
|
|
|
|
|
|
|
|
// is a "//" then we can remove it too.
|
|
|
|
|
|
|
|
if (StartLoc-2 >= FileStart && StartLoc[-1] == '/' && StartLoc[-2] == '/')
|
|
|
|
|
|
|
|
StartLoc -= 2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Perform another round of general whitespace nuking to cleanup
|
|
|
|
|
|
|
|
// whitespace before the //.
|
|
|
|
|
|
|
|
while (StartLoc-1 != FileStart && isspace(StartLoc[-1]) &&
|
|
|
|
|
|
|
|
StartLoc[-1] != '\n' && StartLoc[-1] != '\r')
|
|
|
|
|
|
|
|
--StartLoc;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If we found a \n, then we can nuke the entire line.
|
|
|
|
|
|
|
|
if (StartLoc-1 != FileStart &&
|
|
|
|
|
|
|
|
(StartLoc[-1] == '\n' || StartLoc[-1] == '\r'))
|
|
|
|
|
|
|
|
--StartLoc;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Remove the expected-foo{{}} as a fixit.
|
|
|
|
|
|
|
|
llvm::SMFixIt fixIt(llvm::SMRange{
|
|
|
|
|
|
|
|
SMLoc::getFromPointer(StartLoc),
|
|
|
|
|
|
|
|
SMLoc::getFromPointer(EndLoc)
|
|
|
|
|
|
|
|
}, "");
|
|
|
|
|
|
|
|
addError(expected.ExpectedStart, message, fixIt);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Verify that there are no diagnostics (in MemoryBuffer) left in the list.
|
|
|
|
// Verify that there are no diagnostics (in MemoryBuffer) left in the list.
|
|
|
|
bool HadUnexpectedDiag = false;
|
|
|
|
bool HadUnexpectedDiag = false;
|
|
|
|
@@ -1250,7 +1360,7 @@ DiagnosticVerifier::Result DiagnosticVerifier::verifyFile(unsigned BufferID) {
|
|
|
|
// buffer also count as part of this buffer for this purpose.
|
|
|
|
// buffer also count as part of this buffer for this purpose.
|
|
|
|
const GeneratedSourceInfo *GSI =
|
|
|
|
const GeneratedSourceInfo *GSI =
|
|
|
|
SM.getGeneratedSourceInfo(CapturedDiagIter->SourceBufferID.value());
|
|
|
|
SM.getGeneratedSourceInfo(CapturedDiagIter->SourceBufferID.value());
|
|
|
|
if (!GSI || !llvm::find(GSI->ancestors, BufferID)) {
|
|
|
|
if (!GSI || llvm::find(GSI->ancestors, BufferID) == GSI->ancestors.end()) {
|
|
|
|
++CapturedDiagIter;
|
|
|
|
++CapturedDiagIter;
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -1314,6 +1424,27 @@ void DiagnosticVerifier::printRemainingDiagnostics() const {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
|
|
processExpansions(SourceManager &SM, llvm::DenseMap<SourceLoc, unsigned> &Expansions,
|
|
|
|
|
|
|
|
std::vector<CapturedDiagnosticInfo> &CapturedDiagnostics) {
|
|
|
|
|
|
|
|
for (auto &diag : CapturedDiagnostics) {
|
|
|
|
|
|
|
|
if (!diag.SourceBufferID.has_value())
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
const GeneratedSourceInfo *GSI =
|
|
|
|
|
|
|
|
SM.getGeneratedSourceInfo(diag.SourceBufferID.value());
|
|
|
|
|
|
|
|
if (!GSI)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
SourceLoc ExpansionStart = GSI->originalSourceRange.getStart();
|
|
|
|
|
|
|
|
if (ExpansionStart.isInvalid())
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (Expansions.count(ExpansionStart)) {
|
|
|
|
|
|
|
|
ASSERT(Expansions[ExpansionStart] == diag.SourceBufferID.value());
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Expansions.insert(std::make_pair(ExpansionStart, diag.SourceBufferID.value()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Main entrypoints
|
|
|
|
// Main entrypoints
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
@@ -1368,6 +1499,8 @@ bool DiagnosticVerifier::finishProcessing() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
processExpansions(SM, Expansions, CapturedDiagnostics);
|
|
|
|
|
|
|
|
|
|
|
|
ArrayRef<unsigned> BufferIDLists[2] = { BufferIDs, additionalBufferIDs };
|
|
|
|
ArrayRef<unsigned> BufferIDLists[2] = { BufferIDs, additionalBufferIDs };
|
|
|
|
for (ArrayRef<unsigned> BufferIDList : BufferIDLists)
|
|
|
|
for (ArrayRef<unsigned> BufferIDList : BufferIDLists)
|
|
|
|
for (auto &BufferID : BufferIDList) {
|
|
|
|
for (auto &BufferID : BufferIDList) {
|
|
|
|
|