Skip to content

Commit d650ab4

Browse files
authored
Merge pull request llvm#8472 from augusto2112/cp-257d4606bc
[lldb] Support frame variable for generic types in embedded Swift
2 parents b178534 + d19cafd commit d650ab4

File tree

3 files changed

+112
-0
lines changed

3 files changed

+112
-0
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserSwiftDescriptorFinder.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,29 @@ using namespace lldb_private;
3232
using namespace lldb_private::dwarf;
3333
using namespace lldb_private::plugin::dwarf;
3434

35+
/// Given a die to a substituted generic Swift type, return the analogous
36+
/// unsubstituted version.
37+
///
38+
/// Given a generic type (for example, a generic Pair), the compiler will emit
39+
/// full debug information for the unsubstituted type (Pair<T, U>), and opaque
40+
/// debug information for each every specialization (for example, Pair<Int,
41+
/// Double>), with a link back to the unsubstituted type. When looking up one of
42+
/// the specialized generics, return the unsubstituted version instead.
43+
static std::optional<std::pair<CompilerType, DWARFDIE>>
44+
findUnsubstitutedGenericTypeAndDie(TypeSystemSwiftTypeRef &ts,
45+
const DWARFDIE &die) {
46+
auto specified_die =
47+
die.GetAttributeValueAsReferenceDIE(llvm::dwarf::DW_AT_specification);
48+
if (!specified_die)
49+
return {};
50+
51+
const auto *mangled_name = specified_die.GetAttributeValueAsString(
52+
llvm::dwarf::DW_AT_linkage_name, nullptr);
53+
assert(mangled_name);
54+
auto specified_type =
55+
ts.GetTypeFromMangledTypename(ConstString(mangled_name));
56+
return {{specified_type, specified_die}};
57+
}
3558
/// Given a type system and a typeref, return the compiler type and die of the
3659
/// type that matches that mangled name, looking up the in the type system's
3760
/// module's debug information.
@@ -62,6 +85,10 @@ getTypeAndDie(TypeSystemSwiftTypeRef &ts,
6285
return {};
6386
}
6487
auto die = dwarf->GetDIE(lldb_type->GetID());
88+
89+
if (auto unsubstituted_pair = findUnsubstitutedGenericTypeAndDie(ts, die))
90+
return unsubstituted_pair;
91+
6592
return {{type, die}};
6693
}
6794

lldb/test/API/lang/swift/embedded/frame_variable/TestSwiftEmbeddedFrameVariable.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,61 @@ def test(self):
129129
"subSubField = (field = 4.2000000000000002)",
130130
],
131131
)
132+
133+
self.expect(
134+
"frame variable gsp",
135+
substrs=[
136+
"GenericStructPair<Int, Double>) gsp =",
137+
"(t = 42, u = 94.299999999999997)",
138+
],
139+
)
140+
141+
self.expect(
142+
"frame variable gsp2",
143+
substrs=[
144+
"a.GenericStructPair<a.Sup, a.B>) gsp2 = {",
145+
"t = ",
146+
"(supField = 42)",
147+
"u = {",
148+
"a = (field = 4.2000000000000002)",
149+
"b = 123456",
150+
],
151+
)
152+
153+
self.expect(
154+
"frame variable gsp3",
155+
substrs=[
156+
"(a.GenericStructPair<a.BigFullMultipayloadEnum,",
157+
"a.SmallMultipayloadEnum>) gsp3 = {",
158+
"t = one {",
159+
"one = (0 = 209, 1 = 315)",
160+
"u = two {",
161+
],
162+
)
163+
164+
self.expect(
165+
"frame variable gcp",
166+
substrs=[
167+
"GenericClassPair<Double, Int>) gcp =",
168+
"(t = 43.799999999999997, u = 9348)",
169+
],
170+
)
171+
172+
self.expect(
173+
"frame variable either",
174+
substrs=["(a.Either<Int, Double>) either =", "left (left = 1234)"],
175+
)
176+
177+
self.expect(
178+
"frame variable either2",
179+
substrs=[
180+
"(a.Either<a.Sup, a.GenericStructPair<a.BigFullMultipayloadEnum,",
181+
"a.SmallMultipayloadEnum>>)",
182+
"either2 = right {",
183+
"right = {",
184+
"t = one {",
185+
"one = (0 = 209, 1 = 315)",
186+
"u = two {",
187+
"two = one",
188+
],
189+
)

lldb/test/API/lang/swift/embedded/frame_variable/main.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,27 @@ class SubSub: Sub {
6262
var subSubField = A()
6363
}
6464

65+
66+
struct GenericStructPair<T, U> {
67+
let t: T
68+
let u: U
69+
}
70+
71+
class GenericClassPair<T, U> {
72+
let t: T
73+
let u: U
74+
75+
init(t: T, u: U) {
76+
self.t = t
77+
self.u = u
78+
}
79+
}
80+
81+
enum Either<Left, Right> {
82+
case left(Left)
83+
case right(Right)
84+
}
85+
6586
let varB = B()
6687
let tuple = (A(), B())
6788
let trivial = TrivialEnum.theCase
@@ -85,6 +106,12 @@ let sup = Sup()
85106
let sub = Sub()
86107
let subSub = SubSub()
87108
let sup2: Sup = SubSub()
109+
let gsp = GenericStructPair(t: 42, u: 94.3)
110+
let gsp2 = GenericStructPair(t: Sup(), u: B())
111+
let gsp3 = GenericStructPair(t: bigFullMultipayloadEnum1, u: smallMultipayloadEnum2)
112+
let gcp = GenericClassPair(t: 43.8, u: 9348)
113+
let either = Either<Int, Double>.left(1234)
114+
let either2 = Either<Sup, _>.right(gsp3)
88115

89116
// Dummy statement to set breakpoint print can't be used in embedded Swift for now.
90117
let dummy = A() // break here

0 commit comments

Comments
 (0)