Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1600,16 +1600,38 @@ std::string SwiftLanguageRuntime::GetParentNameIfClosure(Function &func) {
swift_demangle::GetFirstChildOfKind(closure_node, function_kinds);
if (!parent_func_node)
return "";
swift_demangle::ReplaceChildWith(*node, *closure_node, *parent_func_node);

ManglingErrorOr<std::string> mangled = swift::Demangle::mangleNode(node);
NodeFactory factory;
Node *new_global = factory.createNode(Kind::Global);
if (!new_global)
return "";
// For a given function-like node, async information is a sibling - not a
// child - of the node in the demangling tree. Bring that over as well.
// Don't bring all children, however, as the closure number of `closure_node`
// is also a child of `closure_node`, i.e., it is not related to
// `parent_func_node`.
//
// node (Global)
// |
// |- closure_node
// |- parent_func_node (any function_kind)
// |- async info for parent_func_node
// |- closure number for closure_node
for (auto *child : *closure_node)
if (child->getKind() == Kind::AsyncAwaitResumePartialFunction ||
child->getKind() == Kind::AsyncSuspendResumePartialFunction)
new_global->addChild(child, factory);
new_global->addChild(parent_func_node, factory);

ManglingErrorOr<std::string> mangled =
swift::Demangle::mangleNode(new_global);
if (!mangled.isSuccess())
return "";

if (parent_func_node->getKind() == Kind::Constructor)
if (Module *module = func.CalculateSymbolContextModule().get())
return HandleCtorAndAllocatorVariants(mangled.result(), *module, *node,
*parent_func_node);
return HandleCtorAndAllocatorVariants(mangled.result(), *module,
*new_global, *parent_func_node);
return mangled.result();
}
} // namespace lldb_private
5 changes: 3 additions & 2 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftDemangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ inline NodePointer GetFirstChildOfKind(NodePointer node,
inline void ReplaceChildWith(Node &parent, Node &to_replace, Node &new_child) {
for (unsigned idx = 0; idx < parent.getNumChildren(); idx++) {
auto *child = parent.getChild(idx);
if (child == &to_replace)
if (child == &to_replace) {
parent.replaceChild(idx, &new_child);
return;
return;
}
}
llvm_unreachable("invalid child passed to replaceChildWith");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ def test_async_closure(self):
)
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me")

@swiftTest
# Async variable inspection on Linux/Windows are still problematic.
@skipIf(oslist=["windows", "linux"])
def test_task_inside_non_async_func(self):
self.build()
(target, process, thread) = self.get_to_bkpt(
"break_task_inside_non_async_function"
)
check_not_captured_error(
self, thread.frames[0], "x", "task_inside_non_async_function()"
)

@swiftTest
def test_ctor_class_closure(self):
self.build()
Expand Down
13 changes: 13 additions & 0 deletions lldb/test/API/lang/swift/closures_var_not_captured/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,18 @@ enum MY_ENUM {
}
}

func async_foo() async {}

func task_inside_non_async_function() -> Task<Void, Never> {
var x = 10;
var task = Task {
await async_foo()
print("break_task_inside_non_async_function")
}

return task
}

func_1(arg: 42)
func_2(arg: 42)
await func_3(arg: 42)
Expand All @@ -227,3 +239,4 @@ my_struct.struct_computed_property = 10
my_struct.struct_computed_property_didset = 10
let _ = MY_ENUM(input: [1,2])
MY_ENUM.static_func(input_static: [42])
await task_inside_non_async_function().getResult()