Skip to content

Commit 2848fe7

Browse files
Merge pull request #2919 from adrian-prantl/better-diagnostics
Improve diagnostics for import failures
2 parents a376547 + 2ce057c commit 2848fe7

File tree

7 files changed

+83
-48
lines changed

7 files changed

+83
-48
lines changed

lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1479,11 +1479,7 @@ unsigned SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
14791479
retry = true;
14801480
},
14811481
[&](const SwiftASTContextError &SACE) {
1482-
if (swift_ast_ctx->GetClangImporter())
1483-
DiagnoseSwiftASTContextError();
1484-
else
1485-
// Discard the shared scratch context and retry.
1486-
retry = true;
1482+
DiagnoseSwiftASTContextError();
14871483
},
14881484
[&](const StringError &SE) {
14891485
diagnostic_manager.PutString(eDiagnosticSeverityError,

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 42 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2869,52 +2869,51 @@ class StoringDiagnosticConsumer : public swift::DiagnosticConsumer {
28692869
const DiagnosticSeverity severity = SeverityForKind(diagnostic.kind);
28702870
const DiagnosticOrigin origin = eDiagnosticOriginSwift;
28712871

2872-
if (first_line > 0 && bufferID != UINT32_MAX &&
2873-
diagnostic.bufferID == bufferID && !diagnostic.bufferName.empty()) {
2874-
// Make sure the error line is in range.
2875-
if (diagnostic.line >= first_line && diagnostic.line <= last_line) {
2876-
// Need to remap the error/warning to a different line.
2877-
StreamString match;
2878-
match.Printf("%s:%u:", diagnostic.bufferName.str().c_str(),
2879-
diagnostic.line);
2880-
const size_t match_len = match.GetString().size();
2881-
size_t match_pos =
2882-
diagnostic.description.find(match.GetString().str());
2883-
if (match_pos != std::string::npos) {
2884-
// We have some <file>:<line>:" instances that need to be updated.
2885-
StreamString fixed_description;
2886-
size_t start_pos = 0;
2887-
do {
2888-
if (match_pos > start_pos)
2889-
fixed_description.Printf(
2890-
"%s", diagnostic.description.substr(start_pos, match_pos)
2891-
.c_str());
2892-
fixed_description.Printf(
2893-
"%s:%u:", diagnostic.bufferName.str().c_str(),
2894-
diagnostic.line - first_line + 1);
2895-
start_pos = match_pos + match_len;
2896-
match_pos = diagnostic.description.find(match.GetString().str(),
2897-
start_pos);
2898-
} while (match_pos != std::string::npos);
2899-
2900-
// Append any last remaining text.
2901-
if (start_pos < diagnostic.description.size())
2872+
if (first_line > 0 && bufferID != UINT32_MAX) {
2873+
// Make sure the error line is in range or in another file.
2874+
if (diagnostic.bufferID == bufferID && !diagnostic.bufferName.empty() &&
2875+
(diagnostic.line < first_line || diagnostic.line > last_line))
2876+
continue;
2877+
// Need to remap the error/warning to a different line.
2878+
StreamString match;
2879+
match.Printf("%s:%u:", diagnostic.bufferName.str().c_str(),
2880+
diagnostic.line);
2881+
const size_t match_len = match.GetString().size();
2882+
size_t match_pos = diagnostic.description.find(match.GetString().str());
2883+
if (match_pos != std::string::npos) {
2884+
// We have some <file>:<line>:" instances that need to be updated.
2885+
StreamString fixed_description;
2886+
size_t start_pos = 0;
2887+
do {
2888+
if (match_pos > start_pos)
29022889
fixed_description.Printf(
2903-
"%s", diagnostic.description
2904-
.substr(start_pos,
2905-
diagnostic.description.size() - start_pos)
2906-
.c_str());
2907-
2908-
auto new_diagnostic = std::make_unique<SwiftDiagnostic>(
2909-
fixed_description.GetData(), severity, origin, bufferID);
2910-
for (auto fixit : diagnostic.fixits)
2911-
new_diagnostic->AddFixIt(fixit);
2912-
2913-
diagnostic_manager.AddDiagnostic(std::move(new_diagnostic));
2890+
"%s",
2891+
diagnostic.description.substr(start_pos, match_pos).c_str());
2892+
fixed_description.Printf(
2893+
"%s:%u:", diagnostic.bufferName.str().c_str(),
2894+
diagnostic.line - first_line + 1);
2895+
start_pos = match_pos + match_len;
2896+
match_pos =
2897+
diagnostic.description.find(match.GetString().str(), start_pos);
2898+
} while (match_pos != std::string::npos);
2899+
2900+
// Append any last remaining text.
2901+
if (start_pos < diagnostic.description.size())
2902+
fixed_description.Printf(
2903+
"%s", diagnostic.description
2904+
.substr(start_pos,
2905+
diagnostic.description.size() - start_pos)
2906+
.c_str());
2907+
2908+
auto new_diagnostic = std::make_unique<SwiftDiagnostic>(
2909+
fixed_description.GetData(), severity, origin, bufferID);
2910+
for (auto fixit : diagnostic.fixits)
2911+
new_diagnostic->AddFixIt(fixit);
2912+
2913+
diagnostic_manager.AddDiagnostic(std::move(new_diagnostic));
2914+
if (diagnostic.kind == swift::DiagnosticKind::Error)
29142915
added_one_diagnostic = true;
29152916

2916-
continue;
2917-
}
29182917
}
29192918
}
29202919
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS = -Xcc -I$(SRCDIR)
3+
4+
include Makefile.rules
5+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import unittest2
6+
7+
class TestSwiftExprImport(TestBase):
8+
9+
mydir = TestBase.compute_mydir(__file__)
10+
11+
def setUp(self):
12+
TestBase.setUp(self)
13+
14+
# Don't run ClangImporter tests if Clangimporter is disabled.
15+
@skipIf(setting=('symbols.use-swift-clangimporter', 'false'))
16+
@swiftTest
17+
def test(self):
18+
"""Test error handling if the expression evaluator
19+
encounters a Clang import failure.
20+
"""
21+
self.build()
22+
23+
lldbutil.run_to_source_breakpoint(self, "break here",
24+
lldb.SBFileSpec('main.swift'))
25+
self.expect("expr -- import A", error=True,
26+
substrs=['SYNTAX_ERROR',
27+
'could', 'not', 'build', 'module'])
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
int i = SYNTAX_ERROR;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
func f() {}
2+
3+
print("break here")
4+
f()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module A {
2+
header "a.h"
3+
}

0 commit comments

Comments
 (0)