Implement diagnostic range as per clang_formatDiagnostic

This commit is contained in:
Fangrui Song 2017-12-10 18:13:25 -08:00 committed by Jacob Dufault
parent 177e4cd224
commit 86cc50e27f

View File

@ -20,30 +20,46 @@ lsRange GetLsRangeForFixIt(const CXSourceRange& range) {
} // namespace } // namespace
// See clang_formatDiagnostic
optional<lsDiagnostic> BuildAndDisposeDiagnostic(CXDiagnostic diagnostic, optional<lsDiagnostic> BuildAndDisposeDiagnostic(CXDiagnostic diagnostic,
const std::string& path) { const std::string& path) {
// Get diagnostic location. // Get diagnostic location.
CXFile file; CXFile file;
unsigned int line, column; unsigned start_line, start_column;
clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file, clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic),
&line, &column, nullptr); &file, &start_line, &start_column, nullptr);
// Only report diagnostics in the same file. Using if (file && path != FileName(file)) {
// clang_Location_isInSystemHeader causes crashes for some reason.
if (path != FileName(file)) {
clang_disposeDiagnostic(diagnostic); clang_disposeDiagnostic(diagnostic);
return nullopt; return nullopt;
} }
unsigned end_line = start_line, end_column = start_column,
num_ranges = clang_getDiagnosticNumRanges(diagnostic);
for (unsigned i = 0; i < num_ranges; i++) {
CXFile file0, file1;
unsigned line0, column0, line1, column1;
CXSourceRange range = clang_getDiagnosticRange(diagnostic, i);
clang_getSpellingLocation(clang_getRangeStart(range), &file0, &line0,
&column0, nullptr);
clang_getSpellingLocation(clang_getRangeEnd(range), &file1, &line1,
&column1, nullptr);
if (file0 != file1 || file0 != file)
continue;
if (line0 < start_line || (line0 == start_line && column0 < start_column)) {
start_line = line0;
start_column = column0;
}
if (line1 > end_line || (line1 == end_line && column1 > end_column)) {
end_line = line1;
end_column = column1;
}
}
// Build diagnostic. // Build diagnostic.
lsDiagnostic ls_diagnostic; lsDiagnostic ls_diagnostic;
ls_diagnostic.range = lsRange(lsPosition(start_line - 1, start_column - 1),
// TODO: consider using clang_getDiagnosticRange lsPosition(end_line - 1, end_column - 1));
// TODO: ls_diagnostic.range is lsRange, we have Range. We should only be
// storing Range types when inside the indexer so that index <-> buffer
// remapping logic is applied.
ls_diagnostic.range =
lsRange(lsPosition(line - 1, column), lsPosition(line - 1, column));
ls_diagnostic.message = ToString(clang_getDiagnosticSpelling(diagnostic)); ls_diagnostic.message = ToString(clang_getDiagnosticSpelling(diagnostic));
@ -57,6 +73,8 @@ optional<lsDiagnostic> BuildAndDisposeDiagnostic(CXDiagnostic diagnostic,
switch (clang_getDiagnosticSeverity(diagnostic)) { switch (clang_getDiagnosticSeverity(diagnostic)) {
case CXDiagnostic_Ignored: case CXDiagnostic_Ignored:
// llvm_unreachable
break;
case CXDiagnostic_Note: case CXDiagnostic_Note:
ls_diagnostic.severity = lsDiagnosticSeverity::Information; ls_diagnostic.severity = lsDiagnosticSeverity::Information;
break; break;