Skip to content

Commit 3da6095

Browse files
authored
Merge pull request #10005 from augusto2112/swap-order-expr-eval
[lldb] Run generic expression evaluator first
2 parents aeb1272 + 7b1bb14 commit 3da6095

File tree

7 files changed

+82
-48
lines changed

7 files changed

+82
-48
lines changed

lldb/include/lldb/Interpreter/CommandOptionArgumentTable.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,9 @@ static constexpr OptionEnumValueElement g_bind_gen_type_params[] = {
160160
{
161161
lldb::eBindAuto,
162162
"auto",
163-
"Attempt to run the expression with bound generic parameters first, "
164-
"fallback to unbound generic parameters if binding the type parameters "
163+
"Attempt to run the expression with unbound generic parameters first, "
164+
"fallback to binding the generic parameters if the expression with "
165+
"unbound generic type parameters "
165166
"fails",
166167
},
167168
{lldb::eBind, "true", "Bind generic type parameters."},

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ swift::FuncDecl *SwiftASTManipulator::GetFunctionToInjectVariableInto(
878878
// When not binding generic type parameters, we want to inject the metadata
879879
// pointers in the wrapper, so we can pass them as opaque pointers in the
880880
// trampoline function later on.
881-
if (m_bind_generic_types == lldb::eDontBind &&
881+
if (!ShouldBindGenericTypes(m_bind_generic_types) &&
882882
(variable.IsMetadataPointer() || variable.IsPackCount() ||
883883
variable.IsUnboundPack()))
884884
return m_entrypoint_decl;
@@ -896,7 +896,8 @@ llvm::Expected<swift::Type> SwiftASTManipulator::GetSwiftTypeForVariable(
896896

897897
// When injecting a value pack or pack count into the outer
898898
// lldb_expr function, treat it as an opaque raw pointer.
899-
if (m_bind_generic_types == lldb::eDontBind && variable.IsUnboundPack()) {
899+
if (!ShouldBindGenericTypes(m_bind_generic_types) &&
900+
variable.IsUnboundPack()) {
900901
auto swift_ast_ctx = type_system_swift->GetSwiftASTContext(m_sc);
901902
if (!swift_ast_ctx)
902903
return llvm::createStringError("no typesystem for variable " +

lldb/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,12 @@ class SwiftASTManipulator : public SwiftASTManipulatorBase {
284284
const EvaluateExpressionOptions &options,
285285
std::string &expr_source_path);
286286

287+
// By default expression evaluation should not try to bind the generic types.
288+
static bool
289+
ShouldBindGenericTypes(lldb::BindGenericTypes bind_generic_types) {
290+
return bind_generic_types == lldb::eBind;
291+
}
292+
287293
swift::FuncDecl *GetEntrypointDecl() const {
288294
return m_entrypoint_decl;
289295
}

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

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ static CompilerType GetSwiftTypeForVariableValueObject(
448448
CompilerType result = valobj_sp->GetCompilerType();
449449
if (!result)
450450
return {};
451-
if (bind_generic_types != lldb::eDontBind)
451+
if (SwiftASTManipulator::ShouldBindGenericTypes(bind_generic_types))
452452
result = runtime->BindGenericTypeParameters(*stack_frame_sp, result);
453453
if (!result)
454454
return {};
@@ -489,7 +489,8 @@ CompilerType SwiftExpressionParser::ResolveVariable(
489489
// though, as we don't bind the generic parameters in that case.
490490
if (swift_type_system->IsMeaninglessWithoutDynamicResolution(
491491
var_type.GetOpaqueQualType()) &&
492-
bind_generic_types != lldb::eDontBind && use_dynamic_value) {
492+
SwiftASTManipulator::ShouldBindGenericTypes(bind_generic_types) &&
493+
use_dynamic_value) {
493494
var_type = GetSwiftTypeForVariableValueObject(
494495
valobj_sp->GetDynamicValue(use_dynamic), stack_frame_sp, runtime,
495496
bind_generic_types);
@@ -583,7 +584,7 @@ AddRequiredAliases(Block *block, lldb::StackFrameSP &stack_frame_sp,
583584
"self type from an import isn't valid.");
584585

585586
auto *stack_frame = stack_frame_sp.get();
586-
if (bind_generic_types != lldb::eDontBind) {
587+
if (SwiftASTManipulator::ShouldBindGenericTypes(bind_generic_types)) {
587588
imported_self_type = swift_runtime->BindGenericTypeParameters(
588589
*stack_frame, imported_self_type);
589590
if (!imported_self_type)
@@ -1710,6 +1711,11 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
17101711
auto expr_diagnostics = m_swift_ast_ctx.getScopedDiagnosticConsumer();
17111712
m_swift_ast_ctx.GetDiagnosticEngine().resetHadAnyError();
17121713

1714+
// The result in case parsing the expression fails. If the option is auto
1715+
// expression evaluation should retry by binding the generic types.
1716+
auto parse_result_failure = m_options.GetBindGenericTypes() == lldb::eBindAuto
1717+
? ParseResult::retry_bind_generic_params
1718+
: ParseResult::unrecoverable_error;
17131719
// Helper function to diagnose errors in m_swift_scratch_context.
17141720
unsigned buffer_id = UINT32_MAX;
17151721
auto DiagnoseSwiftASTContextError = [&]() {
@@ -1726,7 +1732,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
17261732
const bool playground = m_options.GetPlaygroundTransformEnabled();
17271733

17281734
if (!m_exe_scope)
1729-
return ParseResult::unrecoverable_error;
1735+
return parse_result_failure;
17301736

17311737
// Parse the expression and import all nececssary swift modules.
17321738
auto parsed_expr = ParseAndImport(*expr_diagnostics, variable_map, buffer_id,
@@ -1767,7 +1773,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
17671773
return ParseResult::retry_fresh_context;
17681774

17691775
// Unrecoverable error.
1770-
return ParseResult::unrecoverable_error;
1776+
return parse_result_failure;
17711777
}
17721778

17731779
// If any generics are present, this expression is not parseable.
@@ -1809,11 +1815,11 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
18091815
"Missing type debug information for variable \"%s\": %s",
18101816
var.GetName().str().str().c_str(),
18111817
llvm::toString(std::move(error)).c_str());
1812-
return ParseResult::unrecoverable_error;
1818+
return parse_result_failure;
18131819
}
18141820
// Otherwise print the diagnostics from the Swift compiler.
18151821
DiagnoseSwiftASTContextError();
1816-
return ParseResult::unrecoverable_error;
1822+
return parse_result_failure;
18171823
}
18181824

18191825
if (repl)
@@ -1826,7 +1832,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
18261832
if (error) {
18271833
diagnostic_manager.PutString(eSeverityError,
18281834
llvm::toString(std::move(error)));
1829-
return ParseResult::unrecoverable_error;
1835+
return parse_result_failure;
18301836
}
18311837
} else {
18321838
swift::performPlaygroundTransform(
@@ -1842,7 +1848,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
18421848
diagnostic_manager.PutString(
18431849
eSeverityError,
18441850
"Cannot evaluate an expression that results in a ~Copyable type");
1845-
return ParseResult::unrecoverable_error;
1851+
return parse_result_failure;
18461852
}
18471853

18481854
// FIXME: We now should have to do the name binding and type
@@ -1965,10 +1971,9 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
19651971
if (!var_info) {
19661972
auto error_string = llvm::toString(var_info.takeError());
19671973
LLDB_LOG(log, "Variable info failzed to materialize with error: {0}",
1968-
error_string);
1969-
1974+
error_string);
19701975

1971-
return ParseResult::unrecoverable_error;
1976+
return parse_result_failure;
19721977
}
19731978

19741979
const char *name = ConstString(variable.GetName().get()).GetCString();
@@ -2001,7 +2006,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
20012006

20022007
if (expr_diagnostics->HasErrors()) {
20032008
DiagnoseSwiftASTContextError();
2004-
return ParseResult::unrecoverable_error;
2009+
return parse_result_failure;
20052010
}
20062011

20072012
if (log) {
@@ -2025,7 +2030,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
20252030

20262031
if (expr_diagnostics->HasErrors()) {
20272032
DiagnoseSwiftASTContextError();
2028-
return ParseResult::unrecoverable_error;
2033+
return parse_result_failure;
20292034
}
20302035

20312036
{
@@ -2063,14 +2068,14 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
20632068
diagnostic_manager.PutString(
20642069
eSeverityInfo, "couldn't IRGen expression: Clang importer error");
20652070
DiagnoseSwiftASTContextError();
2066-
return ParseResult::unrecoverable_error;
2071+
return parse_result_failure;
20672072
}
20682073

20692074
if (error_kind == ErrorKind::swift) {
20702075
diagnostic_manager.PutString(eSeverityInfo,
20712076
"couldn't IRGen expression: Swift error");
20722077
DiagnoseSwiftASTContextError();
2073-
return ParseResult::unrecoverable_error;
2078+
return parse_result_failure;
20742079
}
20752080

20762081
if (!m_module) {
@@ -2079,7 +2084,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
20792084
"couldn't IRGen expression. Please enable the expression log by "
20802085
"running \"log enable lldb expr\", then run the failing expression "
20812086
"again, and file a bug report with the log output.");
2082-
return ParseResult::unrecoverable_error;
2087+
return parse_result_failure;
20832088
}
20842089

20852090
if (log) {
@@ -2091,7 +2096,8 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
20912096
}
20922097

20932098
if (ThreadSafeASTContext ast_ctx = m_swift_ast_ctx.GetASTContext()) {
2094-
if (m_options.GetBindGenericTypes() == lldb::eDontBind &&
2099+
if (!SwiftASTManipulator::ShouldBindGenericTypes(
2100+
m_options.GetBindGenericTypes()) &&
20952101
!RedirectCallFromSinkToTrampolineFunction(
20962102
*m_module.get(), *parsed_expr->code_manipulator.get(), **ast_ctx)) {
20972103
diagnostic_manager.Printf(
@@ -2100,7 +2106,7 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
21002106
"expression log by running \"log enable lldb "
21012107
"expr\", then run the failing expression again, and file a "
21022108
"bugreport with the log output.");
2103-
return ParseResult::unrecoverable_error;
2109+
return parse_result_failure;
21042110
}
21052111
}
21062112

@@ -2120,14 +2126,14 @@ SwiftExpressionParser::Parse(DiagnosticManager &diagnostic_manager,
21202126
LLVMReturnStatusAction, nullptr);
21212127
if (has_errors) {
21222128
diagnostic_manager.PutString(eSeverityInfo, "LLVM verification error");
2123-
return ParseResult::unrecoverable_error;
2129+
return parse_result_failure;
21242130
}
21252131
}
21262132

21272133
if (expr_diagnostics->HasErrors()) {
21282134
diagnostic_manager.PutString(eSeverityInfo, "post-IRGen error");
21292135
DiagnoseSwiftASTContextError();
2130-
return ParseResult::unrecoverable_error;
2136+
return parse_result_failure;
21312137
}
21322138

21332139
// The Parse succeeded! Now put this module into the context's list

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ class SwiftExpressionParser : public ExpressionParser {
5151
enum class ParseResult {
5252
success,
5353
retry_fresh_context,
54-
retry_no_bind_generic_params,
54+
retry_bind_generic_params,
55+
// Retry by binding the generic parameters because the generic expression
56+
// evaluator does not support running this expression.
57+
retry_bind_generic_params_not_supported,
5558
unrecoverable_error
5659
};
5760
//------------------------------------------------------------------

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ do {
408408
weak_self ? "Swift.Optional where Wrapped == " : "";
409409

410410
// The expression text is inserted into the body of $__lldb_user_expr_%u.
411-
if (options.GetBindGenericTypes() == lldb::eDontBind) {
411+
if (!SwiftASTManipulator::ShouldBindGenericTypes(
412+
options.GetBindGenericTypes())) {
412413
// A Swift program can't have types with non-bound generic type parameters
413414
// inside a non generic function. For example, the following program would
414415
// not compile as T is not part of foo's signature.
@@ -511,7 +512,8 @@ func $__lldb_expr(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
511512
wrapped_expr_text.GetData(), availability.c_str(),
512513
current_counter);
513514
}
514-
} else if (options.GetBindGenericTypes() == lldb::eDontBind) {
515+
} else if (!SwiftASTManipulator::ShouldBindGenericTypes(
516+
options.GetBindGenericTypes())) {
515517
auto c = MakeGenericSignaturesAndCalls(local_variables, generic_sig,
516518
needs_object_ptr);
517519
if (!c) {

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

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -322,16 +322,18 @@ static llvm::Error AddVariableInfo(
322322
return llvm::Error::success();
323323

324324
CompilerType target_type;
325+
bool should_not_bind_generic_types =
326+
!SwiftASTManipulator::ShouldBindGenericTypes(bind_generic_types);
325327
bool is_unbound_pack =
326-
bind_generic_types == lldb::eDontBind &&
328+
should_not_bind_generic_types &&
327329
(variable_sp->GetType()->GetForwardCompilerType().GetTypeInfo() &
328330
lldb::eTypeIsPack);
329331

330332
// If we're not binding the generic types, we need to set the self type as an
331333
// opaque pointer type. This is necessary because we don't bind the generic
332334
// parameters, and we can't have a type with unbound generics in a non-generic
333335
// function.
334-
if (bind_generic_types == lldb::eDontBind && is_self)
336+
if (should_not_bind_generic_types && is_self)
335337
target_type = ast_context.GetBuiltinRawPointerType();
336338
else if (is_unbound_pack)
337339
target_type = variable_sp->GetType()->GetForwardCompilerType();
@@ -623,7 +625,7 @@ SwiftUserExpression::GetTextAndSetExpressionParser(
623625
lldb::eSeverityError,
624626
"Couldn't realize Swift AST type of self. Hint: using `v` to "
625627
"directly inspect variables and fields may still work.");
626-
return ParseResult::retry_no_bind_generic_params;
628+
return ParseResult::retry_bind_generic_params;
627629
}
628630

629631
auto ts = m_swift_ast_ctx->GetTypeSystemSwiftTypeRef();
@@ -636,14 +638,15 @@ SwiftUserExpression::GetTextAndSetExpressionParser(
636638
func_name.GetStringRef(), *ts);
637639
}
638640

639-
if (m_options.GetBindGenericTypes() == lldb::eDontBind &&
641+
if (!SwiftASTManipulator::ShouldBindGenericTypes(
642+
m_options.GetBindGenericTypes()) &&
640643
!CanEvaluateExpressionWithoutBindingGenericParams(
641644
local_variables, m_generic_signature, *m_swift_ast_ctx, sc.block,
642645
*stack_frame.get())) {
643646
diagnostic_manager.PutString(
644647
lldb::eSeverityError,
645648
"Could not evaluate the expression without binding generic types.");
646-
return ParseResult::unrecoverable_error;
649+
return ParseResult::retry_bind_generic_params_not_supported;
647650
}
648651

649652
uint32_t first_body_line = 0;
@@ -807,44 +810,56 @@ bool SwiftUserExpression::Parse(DiagnosticManager &diagnostic_manager,
807810
DiagnosticManager second_try_diagnostic_manager;
808811

809812
bool retry = false;
813+
bool first_expression_not_supported = false;
810814
while (true) {
811815
SwiftExpressionParser::ParseResult parse_result;
812816
if (!retry) {
813817
parse_result = GetTextAndSetExpressionParser(
814818
first_try_diagnostic_manager, source_code, exe_ctx, exe_scope);
815-
if (parse_result != SwiftExpressionParser::ParseResult::
816-
retry_no_bind_generic_params ||
819+
if ((parse_result !=
820+
SwiftExpressionParser::ParseResult::retry_bind_generic_params &&
821+
parse_result != SwiftExpressionParser::ParseResult::
822+
retry_bind_generic_params_not_supported) ||
817823
m_options.GetBindGenericTypes() != lldb::eBindAuto)
818824
// If we're not retrying, just copy the diagnostics over.
819825
diagnostic_manager.Consume(std::move(first_try_diagnostic_manager));
820826
} else {
821827
parse_result = GetTextAndSetExpressionParser(
822828
second_try_diagnostic_manager, source_code, exe_ctx, exe_scope);
823-
if (parse_result == SwiftExpressionParser::ParseResult::success)
824-
// If we succeeded the second time around, copy any diagnostics we
825-
// produced in the success case over, and ignore the first attempt's
826-
// failures.
829+
827830
diagnostic_manager.Consume(std::move(second_try_diagnostic_manager));
828-
else
829-
// If we failed though, copy the diagnostics of the first attempt, and
830-
// silently ignore any errors produced by the retry, as the retry was
831-
// not what the user asked, and any diagnostics produced by it will
832-
// most likely confuse the user.
833-
diagnostic_manager.Consume(std::move(first_try_diagnostic_manager));
831+
if (parse_result == SwiftExpressionParser::ParseResult::success ||
832+
first_expression_not_supported)
833+
// If we succeeded the second time around, copy any diagnostics we
834+
// produced in the success case over, and ignore the first attempt's
835+
// failures.
836+
// If the generic expression evaluator failed because it doesn't
837+
// support the expression the error message won't be very useful, so
838+
// print the regular expression evaluator's error instead.
839+
diagnostic_manager.Consume(std::move(second_try_diagnostic_manager));
840+
else
841+
// If we failed though, copy the diagnostics of the first attempt, and
842+
// silently ignore any errors produced by the retry, as the retry was
843+
// not what the user asked, and any diagnostics produced by it will
844+
// most likely confuse the user.
845+
diagnostic_manager.Consume(std::move(first_try_diagnostic_manager));
834846
}
835847

836848
if (parse_result == SwiftExpressionParser::ParseResult::success)
837849
break;
838850

839851
switch (parse_result) {
840-
case ParseResult::retry_no_bind_generic_params:
852+
case ParseResult::retry_bind_generic_params_not_supported:
853+
first_expression_not_supported = true;
854+
LLVM_FALLTHROUGH;
855+
case ParseResult::retry_bind_generic_params:
841856
// Retry running the expression without binding the generic types if
842857
// BindGenericTypes was in the auto setting, give up otherwise.
843858
if (m_options.GetBindGenericTypes() != lldb::eBindAuto)
844859
return false;
845-
// Retry without binding generic parameters, this is the only
860+
// Retry binding generic parameters, this is the only
846861
// case that will loop.
847-
m_options.SetBindGenericTypes(lldb::eDontBind);
862+
m_options.SetBindGenericTypes(lldb::eBind);
848863
retry = true;
849864
break;
850865

0 commit comments

Comments
 (0)