Skip to content

Commit e4eefe1

Browse files
authored
Merge pull request #7834 from augusto2112/fix-retry-message
[lldb] Handle diagnostics better around expression evaulation retries
2 parents 1f4accf + 5e4ece7 commit e4eefe1

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

lldb/include/lldb/Expression/DiagnosticManager.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@ class DiagnosticManager {
118118
m_diagnostics.push_back(std::move(diagnostic));
119119
}
120120

121+
/// Moves over the contents of a second diagnostic manager over. Leaves other
122+
/// diagnostic manager in an empty state.
123+
void Consume(DiagnosticManager &&other) {
124+
std::move(other.m_diagnostics.begin(), other.m_diagnostics.end(),
125+
std::back_inserter(m_diagnostics));
126+
m_fixed_expression = std::move(other.m_fixed_expression);
127+
other.Clear();
128+
}
129+
121130
size_t Printf(DiagnosticSeverity severity, const char *format, ...)
122131
__attribute__((format(printf, 3, 4)));
123132
void PutString(DiagnosticSeverity severity, llvm::StringRef str);

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

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,40 @@ exe_scope = exe_ctx.GetBestExecutionContextScope();
755755
m_options.SetGenerateDebugInfo(generate_debug_info);
756756

757757
using ParseResult = SwiftExpressionParser::ParseResult;
758-
758+
// Use a separate diagnostic manager instead of the main one, the reason we do
759+
// this is that on retries we would like to ignore diagnostics produced by
760+
// either the first or second try.
761+
DiagnosticManager first_try_diagnostic_manager;
762+
DiagnosticManager second_try_diagnostic_manager;
763+
764+
bool retry = false;
759765
while (true) {
760-
SwiftExpressionParser::ParseResult parse_result =
761-
GetTextAndSetExpressionParser(diagnostic_manager, source_code, exe_ctx,
762-
exe_scope);
766+
SwiftExpressionParser::ParseResult parse_result;
767+
if (!retry) {
768+
parse_result = GetTextAndSetExpressionParser(
769+
first_try_diagnostic_manager, source_code, exe_ctx, exe_scope);
770+
if (parse_result != SwiftExpressionParser::ParseResult::
771+
retry_no_bind_generic_params ||
772+
m_options.GetBindGenericTypes() != lldb::eBindAuto)
773+
// If we're not retrying, just copy the diagnostics over.
774+
diagnostic_manager.Consume(std::move(first_try_diagnostic_manager));
775+
} else {
776+
parse_result = GetTextAndSetExpressionParser(
777+
second_try_diagnostic_manager, source_code, exe_ctx, exe_scope);
778+
if (parse_result == SwiftExpressionParser::ParseResult::success)
779+
// If we succeeded the second time around, copy any diagnostics we
780+
// produced in the success case over, and ignore the first attempt's
781+
// failures.
782+
diagnostic_manager.Consume(std::move(second_try_diagnostic_manager));
783+
else
784+
// If we failed though, copy the diagnostics of the first attempt, and
785+
// silently ignore any errors produced by the retry, as the retry was
786+
// not what the user asked, and any diagnostics produced by it will
787+
// most likely confuse the user.
788+
diagnostic_manager.Consume(std::move(first_try_diagnostic_manager));
789+
}
763790

764-
if (parse_result == ParseResult::success)
791+
if (parse_result == SwiftExpressionParser::ParseResult::success)
765792
break;
766793

767794
switch (parse_result) {
@@ -770,13 +797,10 @@ exe_scope = exe_ctx.GetBestExecutionContextScope();
770797
// BindGenericTypes was in the auto setting, give up otherwise.
771798
if (m_options.GetBindGenericTypes() != lldb::eBindAuto)
772799
return false;
773-
diagnostic_manager.Clear();
774-
diagnostic_manager.PutString(eDiagnosticSeverityRemark,
775-
"Expression evaluation failed. Retrying "
776-
"without binding generic parameters");
777800
// Retry without binding generic parameters, this is the only
778801
// case that will loop.
779802
m_options.SetBindGenericTypes(lldb::eDontBind);
803+
retry = true;
780804
break;
781805

782806
case ParseResult::retry_fresh_context:

lldb/test/API/lang/swift/private_generic_type/TestSwiftPrivateGenericType.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,8 @@ def test_private_generic_type(self):
151151
substrs=["Could not evaluate the expression without binding generic types."],
152152
error=True)
153153

154+
# Check that if both binding and not binding the generic type parameters fail, we report
155+
# the "bind generic params" error message, as that's the default case that runs first.
156+
self.expect("e --bind-generic-types auto -- self",
157+
substrs=["Couldn't realize Swift AST type of self."],
158+
error=True)

0 commit comments

Comments
 (0)