8000 Merge pull request #10938 from felipepiovezan/felipe/task_cherry_pick… · swiftlang/llvm-project@00e141f · GitHub
[go: up one dir, main page]

Skip to content

Commit 00e141f

Browse files
Merge pull request #10938 from felipepiovezan/felipe/task_cherry_picksGetParentIfClosure
🍒 [lldb][swift] Fix GetParentIfClosure for Struct/Enum constructors
2 parents 6278ee1 + b64d466 commit 00e141f

File tree

8 files changed

+169
-18
lines changed

8 files changed

+169
-18
lines changed

lldb/include/lldb/Target/Language.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,7 @@ class Language : public PluginInterface {
513513
/// returns the name of the parent function where the input closure was
514514
/// defined. Returns an empty string if there is no such parent, or if the
515515
/// query does not make sense for this language.
516-
virtual std::string
517-
GetParentNameIfClosure(llvm::StringRef mangled_name) const {
516+
virtual std::string GetParentNameIfClosure(Function &function) const {
518517
return "";
519518
}
520519

lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,9 +2193,8 @@ SwiftLanguage::GetFunctionNameInfo(ConstString name) const {
21932193
return {func_name_type, ConstString(basename)};
21942194
}
21952195

2196-
std::string
2197-
SwiftLanguage::GetParentNameIfClosure(llvm::StringRef mangled_name) const {
2198-
return SwiftLanguageRuntime::GetParentNameIfClosure(mangled_name);
2196+
std::string SwiftLanguage::GetParentNameIfClosure(Function &func) const {
2197+
return SwiftLanguageRuntime::GetParentNameIfClosure(func);
21992198
}
22002199
//------------------------------------------------------------------
22012200
// Static Functions

lldb/source/Plugins/Language/Swift/SwiftLanguage.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ class SwiftLanguage : public Language {
116116
std::pair<lldb::FunctionNameType, std::optional<ConstString>>
117117
GetFunctionNameInfo(ConstString name) const override;
118118

119-
std::string
120-
GetParentNameIfClosure(llvm::StringRef mangled_name) const override;
119+
std::string GetParentNameIfClosure(Function &func) const override;
121120
//------------------------------------------------------------------
122121
// Static Functions
123122
//------------------------------------------------------------------

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ class SwiftLanguageRuntime : public LanguageRuntime {
204204
const SymbolContext *sc = nullptr,
205205
const ExecutionContext *exe_ctx = nullptr);
206206

207-
static std::string GetParentNameIfClosure(llvm::StringRef mangled_name);
207+
static std::string GetParentNameIfClosure(Function &func);
208208

209209
/// Demangle a symbol to a swift::Demangle node tree.
210210
///

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

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,9 +1499,52 @@ SwiftLanguageRuntime::GetGenericSignature(llvm::StringRef function_name,
14991499
return signature;
15001500
}
15011501

1502-
std::string SwiftLanguageRuntime::GetParentNameIfClosure(StringRef name) {
1502+
/// Returns true if a function called `symbol_name` exists in `module`.
1503+
static bool SymbolExists(StringRef symbol_name, Module &module) {
1504+
SymbolContextList sc_list;
1505+
Module::LookupInfo lookup_info(ConstString(symbol_name),
1506+
lldb::FunctionNameType::eFunctionNameTypeFull,
1507+
lldb::eLanguageTypeSw B41A ift);
1508+
module.FindFunctions(lookup_info, CompilerDeclContext(),
1509+
ModuleFunctionSearchOptions(), sc_list);
1510+
return !sc_list.IsEmpty();
1511+
}
1512+
1513+
/// There are two possible variants of constructors: allocating
1514+
/// (Kind::Allocator) and initializing (Kind::Constructor). When mangling a
1515+
/// closure, the "context" is arbitrarily chosen to be the Kind::Constructor
1516+
/// variant. This function checks for the existence of the Kind::Constructor,
1517+
/// given by the symbol `ctor_kind_mangled_name` in the module. If it exists,
1518+
/// `ctor_kind_mangled_name` is returned. Otherwise, creates and returns the
1519+
/// symbol name for the `Kind::Allocating` variant.
1520+
static std::string
1521+
HandleCtorAndAllocatorVariants(StringRef ctor_kind_mangled_name, Module &module,
1522+
Node &top_level_node, Node &ctor_node) {
1523+
if (SymbolExists(ctor_kind_mangled_name, module))
1524+
return ctor_kind_mangled_name.str();
1525+
1526+
using Kind = Node::Kind;
1527+
NodeFactory factory;
1528+
1529+
// Create a kind::Allocator node with all the children of the
1530+
// kind::Constructor node.
1531+
Node *allocating_ctor = factory.createNode(Kind::Allocator);
1532+
if (!allocating_ctor)
1533+
return "";
1534+
for (auto *child : ctor_node)
1535+
allocating_ctor->addChild(child, factory);
1536+
swift_demangle::ReplaceChildWith(top_level_node, ctor_node, *allocating_ctor);
1537+
1538+
if (auto mangled = swift::Demangle::mangleNode(&top_level_node);
1539+
mangled.isSuccess())
1540+
return std::move(mangled.result());
1541+
return "";
1542+
}
1543+
1544+
std::string SwiftLanguageRuntime::GetParentNameIfClosure(Function &func) {
15031545
using Kind = Node::Kind;
15041546
swift::Demangle::Context ctx;
1547+
ConstString name = func.GetMangled().GetMangledName();
15051548
auto *node = SwiftLanguageRuntime::DemangleSymbolAsNode(name, ctx);
15061549
if (!node || node->getKind() != Node::Kind::Global)
15071550
return "";
@@ -1521,9 +1564,14 @@ std::string SwiftLanguageRuntime::GetParentNameIfClosure(StringRef name) {
15211564
return "";
15221565
swift_demangle::ReplaceChildWith(*node, *closure_node, *parent_func_node);
15231566

1524-
if (ManglingErrorOr<std::string> mangled = swift::Demangle::mangleNode(node);
1525-
mangled.isSuccess())
1526-
return mangled.result();
1527-
return "";
1567+
ManglingErrorOr<std::string> mangled = swift::Demangle::mangleNode(node);
1568+
if (!mangled.isSuccess())
1569+
return "";
1570+
1571+
if (parent_func_node->getKind() == Kind::Constructor)
1572+
if (Module *module = func.CalculateSymbolContextModule().get())
1573+
return HandleCtorAndAllocatorVariants(mangled.result(), *module, *node,
1574+
*parent_func_node);
1575+
return mangled.result();
15281576
}
15291577
} // namespace lldb_private

lldb/source/Target/Language.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,8 +601,7 @@ GetParentFunctionsWhileClosure(const SymbolContext &sc,
601601

602602
parents.push_back(root);
603603
for (int idx = 0; idx < upper_limit; idx++) {
604-
ConstString mangled = root->GetMangled().GetMangledName();
605-
std::string parent = language.GetParentNameIfClosure(mangled);
604+
std::string parent = language.GetParentNameIfClosure(*root);
606605
if (parent.empty())
607606
break;
608607

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

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,35 @@ def test_async_closure(self):
110110
def test_ctor_class_closure(self):
111111
self.build()
112112
(target, process, thread) = self.get_to_bkpt("break_ctor_class")
113+
check_not_captured_error(
114+
self, thread.frames[0], "input", "MY_CLASS.init(input:)"
115+
)
116+
check_not_captured_error(
117+
self, thread.frames[0], "find_me", "MY_CLASS.init(input:)"
118+
)
119+
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me")
120+
121+
lldbutil.continue_to_source_breakpoint(
122+
self, process, "break_static_member_class", lldb.SBFileSpec("main.swift")
123+
)
124+
check_not_captured_error(
125+
self,
126+
thread.frames[0],
127+
"input_static",
128+
"static MY_CLASS.static_func(input_static:)",
129+
)
130+
check_not_captured_error(
131+
self,
132+
thread.frames[0],
133+
"find_me_static",
134+
"static MY_CLASS.static_func(input_static:)",
135+
)
136+
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me_static")
137+
138+
@swiftTest
139+
def test_ctor_struct_closure(self):
140+
self.build()
141+
(target, process, thread) = self.get_to_bkpt("break_ctor_struct")
113142
check_not_captured_error(
114143
self, thread.frames[0], "input", "MY_STRUCT.init(input:)"
115144
)
@@ -119,7 +148,7 @@ def test_ctor_class_closure(self):
119148
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me")
120149

121150
lldbutil.continue_to_source_breakpoint(
122-
self, process, "break_static_member", lldb.SBFileSpec("main.swift")
151+
self, process, "break_static_member_struct", lldb.SBFileSpec("main.swift")
123152
)
124153
check_not_captured_error(
125154
self,
@@ -134,3 +163,32 @@ def test_ctor_class_closure(self):
134163
"static MY_STRUCT.static_func(input_static:)",
135164
)
136165
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me_static")
166+
167+
@swiftTest
168+
def test_ctor_enum_closure(self):
169+
self.build()
170+
(target, process, thread) = self.get_to_bkpt("break_ctor_enum")
171+
check_not_captured_error(
172+
self, thread.frames[0], "input", "MY_ENUM.init(input:)"
173+
)
174+
check_not_captured_error(
175+
self, thread.frames[0], "find_me", "MY_ENUM.init(input:)"
176+
)
177+
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me")
178+
179+
lldbutil.continue_to_source_breakpoint(
180+
self, process, "break_static_member_enum", lldb.SBFileSpec("main.swift")
181+
)
182+
check_not_captured_error(
183+
self,
184+
thread.frames[0],
185+
"input_static",
186+
"static MY_ENUM.static_func(input_static:)",
187+
)
188+
check_not_captured_error(
189+
self,
190+
thread.frames[0],
191+
"find_me_static",
192+
"static MY_ENUM.static_func(input_static:)",
193+
)
194+
check_no_enhanced_diagnostic(self, thread.frames[0], "dont_find_me_static")
2851

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

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ func func_3(arg: Int) async {
8787
print(dont_find_me)
8888
}
8989

90-
class MY_STRUCT {
90+
class MY_CLASS {
9191
init(input: [Int]) {
9292
let find_me = "hello"
9393
let _ = input.map {
@@ -99,7 +99,52 @@ class MY_STRUCT {
9999
static func static_func(input_static: [Int]) {
100100
let find_me_static = "hello"
101101
let _ = input_static.map {
102-
return $0 // break_static_member
102+
return $0 // break_static_member_class
103+
}
104+
let dont_find_me_static = "hello"
105+
}
106+
}
107+
108+
struct MY_STRUCT {
109+
init(input: [Int]) {
110+
let find_me = "hello"
111+
let _ = input.map {
112+
print("break_ctor_struct")
113+
return $0
114+
}
115+
let dont_find_me = "hello"
116+
}
117+
118+
static func static_func(input_static: [Int]) {
119+
let find_me_static = "hello"
120+
let _ = input_static.map {
121+
print("break_static_member_struct")
122+
return $0
123+
}
124+
let dont_find_me_static = "hello"
125+
}
126+
}
127+
128+
enum MY_ENUM {
129+
case case1(Double)
130+
case case2(Double)
131+
132+
init(input: [Int]) {
133+
let find_me = "hello"
134+
let _ = input.map {
135+
print("break_ctor_enum")
136+
return $0
137+
}
138+
139+
let dont_find_me = "hello"
140+
self = .case1(42.0)
141+
}
142+
143+
static func static_func(input_static: [Int]) {
144+
let find_me_static = "hello"
145+
let _ = input_static.map {
146+
print("break_static_member_enum")
147+
return $0
103148
}
104149
let dont_find_me_static = "hello"
105150
}
@@ -108,5 +153,9 @@ class MY_STRUCT {
108153
func_1(arg: 42)
109154
func_2(arg: 42)
110155
await func_3(arg: 42)
156+
let _ = MY_CLASS(input: [1, 2])
157+
MY_CLASS.static_func(input_static: [42])
111158
let _ = MY_STRUCT(input: [1, 2])
112159
MY_STRUCT.static_func(input_static: [42])
160+
let _ = MY_ENUM(input: [1,2])
161+
MY_ENUM.static_func(input_static: [42])

0 commit comments

Comments
 (0)
0