Skip to content

Commit a24a64c

Browse files
Merge pull request #12026 from felipepiovezan/felipe/fix_var_not_captured
[lldb] Fix GetParentIfClosure for async closures inside non-async functions
2 parents edf2964 + b9e473c commit a24a64c

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,16 +1600,38 @@ std::string SwiftLanguageRuntime::GetParentNameIfClosure(Function &func) {
16001600
swift_demangle::GetFirstChildOfKind(closure_node, function_kinds);
16011601
if (!parent_func_node)
16021602
return "";
1603-
swift_demangle::ReplaceChildWith(*node, *closure_node, *parent_func_node);
16041603

1605-
ManglingErrorOr<std::string> mangled = swift::Demangle::mangleNode(node);
1604+
NodeFactory factory;
1605+
Node *new_global = factory.createNode(Kind::Global);
1606+
if (!new_global)
1607+
return "";
1608+
// For a given function-like node, async information is a sibling - not a
1609+
// child - of the node in the demangling tree. Bring that over as well.
1610+
// Don't bring all children, however, as the closure number of `closure_node`
1611+
// is also a child of `closure_node`, i.e., it is not related to
1612+
// `parent_func_node`.
1613+
//
1614+
// node (Global)
1615+
// |
1616+
// |- closure_node
1617+
// |- parent_func_node (any function_kind)
1618+
// |- async info for parent_func_node
1619+
// |- closure number for closure_node
1620+
for (auto *child : *closure_node)
1621+
if (child->getKind() == Kind::AsyncAwaitResumePartialFunction ||
1622+
child->getKind() == Kind::AsyncSuspendResumePartialFunction)
1623+
new_global->addChild(child, factory);
1624+
new_global->addChild(parent_func_node, factory);
1625+
1626+
ManglingErrorOr<std::string> mangled =
1627+
swift::Demangle::mangleNode(new_global);
16061628
if (!mangled.isSuccess())
16071629
return "";
16081630

16091631
if (parent_func_node->getKind() == Kind::Constructor)
16101632
if (Module *module = func.CalculateSymbolContextModule().get())
1611-
return HandleCtorAndAllocatorVariants(mangled.result(), *module, *node,
1612-
*parent_func_node);
1633+
return HandleCtorAndAllocatorVariants(mangled.result(), *module,
1634+
*new_global, *parent_func_node);
16131635
return mangled.result();
16141636
}
16151637
} // namespace lldb_private

lldb/source/Plugins/TypeSystem/Swift/SwiftDemangle.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ inline NodePointer GetFirstChildOfKind(NodePointer node,
4141
inline void ReplaceChildWith(Node &parent, Node &to_replace, Node &new_child) {
4242
for (unsigned idx = 0; idx < parent.getNumChildren(); idx++) {
4343
auto *child = parent.getChild(idx);
44-
if (child == &to_replace)
44+
if (child == &to_replace) {
4545
parent.replaceChild(idx, &new_child);
46-
return;
46+
return;
47+
}
4748
}
4849
llvm_unreachable("invalid child passed to replaceChildWith");
4950
}

lldb/test/API/lang/swift/closures_var_not_captured/TestSwiftClosureVarNotCaptured.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ def test_async_closure(self):
106106
)
107107
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me")
108108

109+
@swiftTest
110+
# Async variable inspection on Linux/Windows are still problematic.
111+
@skipIf(oslist=["windows", "linux"])
112+
def test_task_inside_non_async_func(self):
113+
self.build()
114+
(target, process, thread) = self.get_to_bkpt(
115+
"break_task_inside_non_async_function"
116+
)
117+
check_not_captured_error(
118+
self, thread.frames[0], "x", "task_inside_non_async_function()"
119+
)
120+
109121
@swiftTest
110122
def test_ctor_class_closure(self):
111123
self.build()

lldb/test/API/lang/swift/closures_var_not_captured/main.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,18 @@ enum MY_ENUM {
212212
}
213213
}
214214

215+
func async_foo() async {}
216+
217+
func task_inside_non_async_function() -> Task<Void, Never> {
218+
var x = 10;
219+
var task = Task {
220+
await async_foo()
221+
print("break_task_inside_non_async_function")
222+
}
223+
224+
return task
225+
}
226+
215227
func_1(arg: 42)
216228
func_2(arg: 42)
217229
await func_3(arg: 42)
@@ -227,3 +239,4 @@ my_struct.struct_computed_property = 10
227239
my_struct.struct_computed_property_didset = 10
228240
let _ = MY_ENUM(input: [1,2])
229241
MY_ENUM.static_func(input_static: [42])
242+
await task_inside_non_async_function().getResult()

0 commit comments

Comments
 (0)