Skip to content

Commit de7309d

Browse files
authored
Merge pull request #8267 from augusto2112/gen-types-dwarf
[lldb] Support frame variable for generic types in embedded Swift
2 parents 3bbc45d + 75a08e3 commit de7309d

File tree

3 files changed

+124
-12
lines changed

3 files changed

+124
-12
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 unsubstituted_die =
47+
die.GetAttributeValueAsReferenceDIE(llvm::dwarf::DW_AT_specification);
48+
if (!unsubstituted_die)
49+
return {};
50+
51+
const auto *mangled_name = unsubstituted_die.GetAttributeValueAsString(
52+
llvm::dwarf::DW_AT_linkage_name, nullptr);
53+
assert(mangled_name);
54+
auto unsubstituted_type =
55+
ts.GetTypeFromMangledTypename(ConstString(mangled_name));
56+
return {{unsubstituted_type, unsubstituted_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: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ def test(self):
1717

1818
self.expect(
1919
"frame variable varB",
20-
substrs=["varB = ", "a = (field = 4.2000000000000002)", "b = 123456"],
20+
substrs=["varB = ", "a = (field = 4.5)", "b = 123456"],
2121
)
2222
self.expect(
2323
"frame variable tuple",
2424
substrs=[
2525
"(a.A, a.B) tuple = {",
26-
"0 = (field = 4.2000000000000002)",
26+
"0 = (field = 4.5)",
2727
"1 = {",
28-
"a = (field = 4.2000000000000002)",
28+
"a = (field = 4.5)",
2929
"b = 123456",
3030
],
3131
)
@@ -41,7 +41,7 @@ def test(self):
4141
substrs=[
4242
"SinglePayloadEnum) singlePayload = ",
4343
"payload {",
44-
"a = (field = 4.2000000000000002)",
44+
"a = (field = 4.5)",
4545
"b = 123456",
4646
],
4747
)
@@ -85,7 +85,7 @@ def test(self):
8585
"frame variable fullMultipayloadEnum2",
8686
substrs=[
8787
"FullMultipayloadEnum) fullMultipayloadEnum2 = ",
88-
"(two = 9.2100000000000008)",
88+
"(two = 9.5)",
8989
],
9090
)
9191

@@ -100,7 +100,7 @@ def test(self):
100100
"frame variable bigFullMultipayloadEnum2",
101101
substrs=[
102102
"a.BigFullMultipayloadEnum) bigFullMultipayloadEnum2 = two {",
103-
"two = (0 = 452.19999999999999, 1 = 753.89999999999998)",
103+
"two = (0 = 452.5, 1 = 753.5)",
104104
],
105105
)
106106

@@ -112,7 +112,7 @@ def test(self):
112112
"Sup = {",
113113
"supField = 42",
114114
"subField = {",
115-
"a = (field = 4.2000000000000002",
115+
"a = (field = 4.5",
116116
"b = 123456",
117117
],
118118
)
@@ -124,8 +124,66 @@ def test(self):
124124
"a.Sup = {",
125125
"supField = 42",
126126
"subField = {",
127-
"a = (field = 4.2000000000000002",
127+
"a = (field = 4.5",
128128
"b = 123456",
129-
"subSubField = (field = 4.2000000000000002)",
129+
"subSubField = (field = 4.5)",
130+
],
131+
)
132+
133+
self.expect(
134+
"frame variable gsp",
135+
substrs=[
136+
"GenericStructPair<Int, Double>) gsp =",
137+
"(t = 42, u = 94.5)",
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.5)",
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",
130188
],
131189
)

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

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
struct A {
2-
let field = 4.2
2+
let field = 4.5
33
}
44

55
struct B {
@@ -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
@@ -78,13 +99,19 @@ let e3 = Sup()
7899
e3.supField = 44
79100
let bigMultipayloadEnum1 = BigMultipayloadEnum.one(e1, e2, e3)
80101
let fullMultipayloadEnum1 = FullMultipayloadEnum.one(120)
81-
let fullMultipayloadEnum2 = FullMultipayloadEnum.two(9.21)
102+
let fullMultipayloadEnum2 = FullMultipayloadEnum.two(9.5)
82103
let bigFullMultipayloadEnum1 = BigFullMultipayloadEnum.one(209, 315)
83-
let bigFullMultipayloadEnum2 = BigFullMultipayloadEnum.two(452.2, 753.9)
104+
let bigFullMultipayloadEnum2 = BigFullMultipayloadEnum.two(452.5, 753.5)
84105
let sup = Sup()
85106
let sub = Sub()
86107
let subSub = SubSub()
87108
let sup2: Sup = SubSub()
109+
let gsp = GenericStructPair(t: 42, u: 94.5)
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)