Skip to content

Commit 44566d7

Browse files
Merge pull request #9422 from felipepiovezan/felipe/add_unittests_demangler
[lldb] Add unittests for SwiftLanguageRuntime demangling functions
2 parents bbdb7bd + 4dac4d3 commit 44566d7

File tree

3 files changed

+106
-16
lines changed

3 files changed

+106
-16
lines changed

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

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -83,24 +83,26 @@ static bool IsSwiftAsyncFunctionSymbol(swift::Demangle::NodePointer node) {
8383
return false;
8484
if (hasChild(node, Node::Kind::AsyncSuspendResumePartialFunction))
8585
return false;
86-
87-
// Peel off layers over top of Function nodes.
88-
switch (node->getFirstChild()->getKind()) {
89-
case Node::Kind::Static:
90-
case Node::Kind::ExplicitClosure:
86+
// Peel off a Static node. If it exists, there will be a single instance and a
87+
// top level node.
88+
if (node->getFirstChild()->getKind() == Node::Kind::Static)
9189
node = node->getFirstChild();
92-
break;
93-
default:
94-
break;
95-
}
9690

97-
return childAtPath(node,
98-
{Node::Kind::Function, Node::Kind::Type,
99-
Node::Kind::FunctionType, Node::Kind::AsyncAnnotation}) ||
100-
childAtPath(node,
101-
{Node::Kind::Function, Node::Kind::Type,
102-
Node::Kind::DependentGenericType, Node::Kind::Type,
103-
Node::Kind::FunctionType, Node::Kind::AsyncAnnotation});
91+
// Get the ExplicitClosure or Function node.
92+
// For nested closures in Swift, the demangle tree is inverted: the
93+
// inner-most closure is the top-most ExplicitClosure node.
94+
NodePointer func_node = [&] {
95+
if (NodePointer func = childAtPath(node, Node::Kind::Function))
96+
return func;
97+
return childAtPath(node, Node::Kind::ExplicitClosure);
98+
}();
99+
100+
return childAtPath(func_node, {Node::Kind::Type, Node::Kind::FunctionType,
101+
Node::Kind::AsyncAnnotation}) ||
102+
childAtPath(func_node,
103+
{Node::Kind::Type, Node::Kind::DependentGenericType,
104+
Node::Kind::Type, Node::Kind::FunctionType,
105+
Node::Kind::AsyncAnnotation});
104106
}
105107

106108
bool SwiftLanguageRuntime::IsSwiftAsyncFunctionSymbol(StringRef name) {

lldb/unittests/Symbol/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
set(SWIFT_SOURCES
22
TestSwiftASTContext.cpp
33
TestTypeSystemSwiftTypeRef.cpp
4+
TestSwiftDemangler.cpp
45
)
56
set(SWIFT_LIBS
67
lldbPluginTypeSystemSwift
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include "gtest/gtest.h"
2+
3+
#include "Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
4+
5+
using namespace lldb;
6+
using namespace lldb_private;
7+
using namespace llvm;
8+
static constexpr auto IsSwiftMangledName =
9+
SwiftLanguageRuntime::IsSwiftMangledName;
10+
static constexpr auto IsAnySwiftAsyncFunctionSymbol = [](StringRef name) {
11+
return SwiftLanguageRuntime::IsAnySwiftAsyncFunctionSymbol(name);
12+
};
13+
14+
TEST(TestSwiftDemangleAsyncNames, BasicAsync) {
15+
// "sayBasic" == a basic async function
16+
// "sayGeneric" == a generic async function
17+
SmallVector<StringRef> basic_funclets = {
18+
"$s1a8sayBasicyySSYaF",
19+
"$s1a8sayBasicyySSYaFTY0_",
20+
"$s1a8sayBasicyySSYaFTQ1_",
21+
"$s1a8sayBasicyySSYaFTY2_",
22+
};
23+
SmallVector<StringRef> generic_funclets = {
24+
"$s1a10sayGenericyyxYalF",
25+
"$s1a10sayGenericyyxYalFTY0_",
26+
"$s1a10sayGenericyyxYalFTQ1_",
27+
"$s1a10sayGenericyyxYalFTY2_",
28+
};
29+
for (StringRef async_name :
30+
llvm::concat<StringRef>(basic_funclets, generic_funclets)) {
31+
EXPECT_TRUE(IsSwiftMangledName(async_name)) << async_name;
32+
EXPECT_TRUE(IsAnySwiftAsyncFunctionSymbol(async_name)) << async_name;
33+
}
34+
}
35+
36+
TEST(TestSwiftDemangleAsyncNames, ClosureAsync) {
37+
// These are all async closures
38+
SmallVector<StringRef> nested1_funclets = {
39+
// Nesting level 1: a closure inside a function.
40+
"$s1a8sayHelloyyYaFyypYacfU_", "$s1a8sayHelloyyYaFyypYacfU_TY0_",
41+
"$s1a8sayHelloyyYaFyypYacfU_TQ1_", "$s1a8sayHelloyyYaFyypYacfU_TY2_",
42+
"$s1a8sayHelloyyYaFyypYacfU_TQ3_", "$s1a8sayHelloyyYaFyypYacfU_TY4_",
43+
"$s1a8sayHelloyyYaFyypYacfU_TQ5_", "$s1a8sayHelloyyYaFyypYacfU_TY6_"};
44+
SmallVector<StringRef> nested2_funclets1 = {
45+
// Nesting level 2: a closure inside a closure.
46+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU_",
47+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU_TY0_",
48+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU_TQ1_",
49+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU_TY2_",
50+
};
51+
SmallVector<StringRef> nested2_funclets2 = {
52+
// Nesting level 2: another closure, same level as the previous one.
53+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU0_",
54+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU0_TY0_",
55+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU0_TQ1_",
56+
"$s1a8sayHelloyyYaFyypYacfU_yypYacfU0_TY2_",
57+
};
58+
SmallVector<StringRef> nested2_funclets_top_not_async = {
59+
// Also nesting level 2: but this time, the top level function is _not_
60+
// async!
61+
"$s1a18myNonAsyncFunctionyyFyyYacfU_SiypYacfU_SSypYacfU0_",
62+
"$s1a18myNonAsyncFunctionyyFyyYacfU_SiypYacfU_SSypYacfU0_TY0_",
63+
"$s1a18myNonAsyncFunctionyyFyyYacfU_SiypYacfU_SSypYacfU0_TQ1_",
64+
"$s1a18myNonAsyncFunctionyyFyyYacfU_SiypYacfU_SSypYacfU0_TY2_"};
65+
66+
for (StringRef async_name : llvm::concat<StringRef>(
67+
nested1_funclets, nested2_funclets1, nested2_funclets2,
68+
nested2_funclets_top_not_async)) {
69+
EXPECT_TRUE(IsSwiftMangledName(async_name)) << async_name;
70+
EXPECT_TRUE(IsAnySwiftAsyncFunctionSymbol(async_name)) << async_name;
71+
}
72+
}
73+
74+
TEST(TestSwiftDemangleAsyncNames, StaticAsync) {
75+
// static async functions
76+
SmallVector<StringRef> async_names = {
77+
"$s1a6StructV9sayStaticyySSYaFZ"
78+
"$s1a6StructV9sayStaticyySSYaFZTY0_",
79+
"$s1a6StructV9sayStaticyySSYaFZTQ1_",
80+
"$s1a6StructV9sayStaticyySSYaFZTY2_",
81+
};
82+
83+
for (StringRef async_name : async_names) {
84+
EXPECT_TRUE(IsSwiftMangledName(async_name)) << async_name;
85+
EXPECT_TRUE(IsAnySwiftAsyncFunctionSymbol(async_name)) << async_name;
86+
}
87+
}

0 commit comments

Comments
 (0)