diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp index 18f94d832a56c..37a46bf5766bb 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftUserExpression.cpp @@ -486,7 +486,7 @@ static bool CollectVariablesInScope(SymbolContext &sc, } /// Create a \c VariableInfo record for each visible variable. -static llvm::Error RegisterAllVariables( +static std::pair RegisterAllVariables( SymbolContext &sc, lldb::StackFrameSP &stack_frame_sp, SwiftASTContextForExpressions &ast_context, llvm::SmallVectorImpl &local_variables, @@ -504,13 +504,14 @@ static llvm::Error RegisterAllVariables( // Proceed from the innermost scope outwards, adding all variables // not already shadowed by an inner declaration. llvm::SmallDenseSet processed_names; - for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) - if (auto error = - AddVariableInfo({variables.GetVariableAtIndex(vi)}, stack_frame_sp, - ast_context, language_runtime, processed_names, - local_variables, use_dynamic, bind_generic_types)) - return error; - return llvm::Error::success(); + for (size_t vi = 0, ve = variables.GetSize(); vi != ve; ++vi) { + lldb::VariableSP var = variables.GetVariableAtIndex(vi); + if (auto error = AddVariableInfo( + {var}, stack_frame_sp, ast_context, language_runtime, + processed_names, local_variables, use_dynamic, bind_generic_types)) + return {std::move(error), var}; + } + return {llvm::Error::success(), nullptr}; } /// Check if we can evaluate the expression as generic. @@ -624,15 +625,17 @@ SwiftUserExpression::GetTextAndSetExpressionParser( llvm::SmallVector local_variables; - if (llvm::Error error = RegisterAllVariables( - sc, stack_frame, *m_swift_ast_ctx, local_variables, - m_options.GetUseDynamic(), m_options.GetBindGenericTypes())) { + auto [error, bad_var] = RegisterAllVariables( + sc, stack_frame, *m_swift_ast_ctx, local_variables, + m_options.GetUseDynamic(), m_options.GetBindGenericTypes()); + if (error) { diagnostic_manager.PutString(lldb::eSeverityInfo, llvm::toString(std::move(error))); - diagnostic_manager.PutString( - lldb::eSeverityError, - "Couldn't realize Swift AST type of self. Hint: using `v` to " - "directly inspect variables and fields may still work."); + std::string diag = llvm::formatv( + "Couldn't realize Swift AST type of variable '{0}'. Hint: using `v` to " + "directly inspect variables and fields may still work.", + bad_var->GetName()); + diagnostic_manager.PutString(lldb::eSeverityError, diag); return ParseResult::retry_bind_generic_params; } diff --git a/lldb/test/API/lang/swift/private_generic_type/TestSwiftPrivateGenericType.py b/lldb/test/API/lang/swift/private_generic_type/TestSwiftPrivateGenericType.py index 5c2283f22e202..241995cee9bbe 100644 --- a/lldb/test/API/lang/swift/private_generic_type/TestSwiftPrivateGenericType.py +++ b/lldb/test/API/lang/swift/private_generic_type/TestSwiftPrivateGenericType.py @@ -26,7 +26,8 @@ def test_private_generic_type(self): extra_images=['Public']) # Make sure this fails without generic expression evaluation. self.expect("expr --bind-generic-types true -- self", - substrs=["Couldn't realize Swift AST type of self."], + substrs=["note: type for self cannot be reconstructed", + "Couldn't realize Swift AST type of all variables."], error=True) # Test that not binding works. self.expect("expr --bind-generic-types false -- self", @@ -48,7 +49,8 @@ def test_private_generic_type(self): 'break here for class', lldb.SBFileSpec('Public.swift'), None) lldbutil.continue_to_breakpoint(process, breakpoint) self.expect("expr --bind-generic-types true -- self", - substrs=["Couldn't realize Swift AST type of self."], + substrs=["note: type for self cannot be reconstructed", + "Couldn't realize Swift AST type of all variables."], error=True) self.expect("expr --bind-generic-types false -- self", substrs=["Public.ClassWrapper", @@ -67,7 +69,8 @@ def test_private_generic_type(self): 'break here for two generic parameters', lldb.SBFileSpec('Public.swift'), None) lldbutil.continue_to_breakpoint(process, breakpoint) self.expect("expr --bind-generic-types true -- self", - substrs=["Couldn't realize Swift AST type of self."], + substrs=["note: type for self cannot be reconstructed", + "Couldn't realize Swift AST type of all variables."], error=True) self.expect("expr --bind-generic-types false -- self", substrs=["Public.TwoGenericParameters", @@ -96,7 +99,8 @@ def test_private_generic_type(self): 'break here for three generic parameters', lldb.SBFileSpec('Public.swift'), None) lldbutil.continue_to_breakpoint(process, breakpoint) self.expect("expr --bind-generic-types true -- self", - substrs=["Couldn't realize Swift AST type of self."], + substrs=["note: type for self cannot be reconstructed", + "Couldn't realize Swift AST type of all variables."], error=True) self.expect("expr --bind-generic-types false -- self", substrs=["Public.ThreeGenericParameters", @@ -124,7 +128,8 @@ def test_private_generic_type(self): 'break here for four generic parameters', lldb.SBFileSpec('Public.swift'), None) lldbutil.continue_to_breakpoint(process, breakpoint) self.expect("expr --bind-generic-types true -- self", - substrs=["Couldn't realize Swift AST type of self."], + substrs=["note: type for self cannot be reconstructed", + "Couldn't realize Swift AST type of all variables."], error=True) self.expect("expr --bind-generic-types false -- self", substrs=["Public.FourGenericParameters", @@ -168,5 +173,6 @@ def test_private_generic_type(self): # Check that if both binding and not binding the generic type parameters fail, we report # the "bind generic params" error message, as that's the default case that runs first. self.expect("expr --bind-generic-types auto -- self", - substrs=["Couldn't realize Swift AST type of self."], + substrs=["note: type for self cannot be reconstructed", + "Couldn't realize Swift AST type of all variables."], error=True)