Skip to content

Commit

Permalink
[lldb] Fix offset calculation when printing diagnostics in multiple r…
Browse files Browse the repository at this point in the history
…anges (llvm#112466)

depends on llvm#112451
  • Loading branch information
adrian-prantl authored Oct 16, 2024
1 parent 889e6ad commit 8046f15
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 17 deletions.
38 changes: 21 additions & 17 deletions lldb/source/Utility/DiagnosticsRendering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,17 +112,21 @@ void RenderDiagnosticDetails(Stream &stream,
// Print a line with caret indicator(s) below the lldb prompt + command.
const size_t padding = *offset_in_command;
stream << std::string(padding, ' ');
size_t offset = 1;
for (const DiagnosticDetail &detail : remaining_details) {
auto &loc = *detail.source_location;

if (offset > loc.column)
continue;

stream << std::string(loc.column - offset, ' ') << cursor;
for (unsigned i = 0; i + 1 < loc.length; ++i)
stream << underline;
offset = loc.column + 1;
{
size_t x_pos = 1;
for (const DiagnosticDetail &detail : remaining_details) {
auto &loc = *detail.source_location;

if (x_pos > loc.column)
continue;

stream << std::string(loc.column - x_pos, ' ') << cursor;
++x_pos;
for (unsigned i = 0; i + 1 < loc.length; ++i) {
stream << underline;
++x_pos;
}
}
}
stream << '\n';

Expand All @@ -134,19 +138,19 @@ void RenderDiagnosticDetails(Stream &stream,
// Get the information to print this detail and remove it from the stack.
// Print all the lines for all the other messages first.
stream << std::string(padding, ' ');
size_t offset = 1;
size_t x_pos = 1;
for (auto &remaining_detail :
llvm::ArrayRef(remaining_details).drop_back(1)) {
uint16_t column = remaining_detail.source_location->column;
if (offset <= column)
stream << std::string(column - offset, ' ') << vbar;
offset = column + 1;
if (x_pos <= column)
stream << std::string(column - x_pos, ' ') << vbar;
x_pos = column + 1;
}

// Print the line connecting the ^ with the error message.
uint16_t column = detail->source_location->column;
if (offset <= column)
stream << std::string(column - offset, ' ') << joint << hbar << spacer;
if (x_pos <= column)
stream << std::string(column - x_pos, ' ') << joint << hbar << spacer;

// Print a colorized string based on the message's severity type.
PrintSeverity(stream, detail->severity);
Expand Down
18 changes: 18 additions & 0 deletions lldb/unittests/Utility/DiagnosticsRenderingTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,22 @@ TEST_F(ErrorDisplayTest, RenderStatus) {
DiagnosticDetail{loc1, eSeverityError, "Y", "Y"}});
ASSERT_LT(StringRef(result).find("Y"), StringRef(result).find("X"));
}
{
// Test that range diagnostics are emitted correctly.
SourceLocation loc1 = {FileSpec{"a.c"}, 1, 1, 3, false, true};
SourceLocation loc2 = {FileSpec{"a.c"}, 1, 5, 3, false, true};
std::string result =
Render({DiagnosticDetail{loc1, eSeverityError, "X", "X"},
DiagnosticDetail{loc2, eSeverityError, "Y", "Y"}});
auto lines = StringRef(result).split('\n');
auto line1 = lines.first;
lines = lines.second.split('\n');
auto line2 = lines.first;
lines = lines.second.split('\n');
auto line3 = lines.first;
// 1234567
ASSERT_EQ(line1, "^~~ ^~~");
ASSERT_EQ(line2, "| error: Y");
ASSERT_EQ(line3, "error: X");
}
}

0 comments on commit 8046f15

Please sign in to comment.