Skip to content

Commit a5a7ef3

Browse files
Merge pull request #10289 from adrian-prantl/146326633-lldb
[lldb] Add a heuristic for handling DW_AT_specification
2 parents 5e6f4c4 + 2c05201 commit a5a7ef3

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

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

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
7777

7878
if (num_attributes > 0) {
7979
uint32_t i;
80+
bool has_specification_of = false;
8081
for (i = 0; i < num_attributes; ++i) {
8182
const dw_attr_t attr = attributes.AttributeAtIndex(i);
8283
DWARFFormValue form_value;
@@ -95,9 +96,38 @@ lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
9596
case DW_AT_name:
9697
name.SetCString(form_value.AsCString());
9798
break;
99+
case DW_AT_specification:
100+
has_specification_of = true;
101+
break;
98102
case DW_AT_linkage_name:
99-
case DW_AT_MIPS_linkage_name:
103+
case DW_AT_MIPS_linkage_name: {
100104
mangled_name.SetCString(form_value.AsCString());
105+
auto HasSpecificationOf = [&](){
106+
if (has_specification_of)
107+
return true;
108+
for (uint32_t j = i+1; j < num_attributes; ++j)
109+
if (attributes.AttributeAtIndex(j) == DW_AT_specification)
110+
return true;
111+
return false;
112+
};
113+
// Is this a sized container with a specification? If yes,
114+
// the linkage name we just got is the one of the
115+
// specification die, which would be the unsubsituted
116+
// type. The child contains the linkage name of the
117+
// specialized type. We should define appropriate DWARF for
118+
// this instead of relying on this heuristic.
119+
if (die.Tag() == DW_TAG_structure_type && die.HasChildren() &&
120+
HasSpecificationOf()) {
121+
DWARFDIE member_die = die.GetFirstChild();
122+
if (member_die.Tag() != DW_TAG_member || member_die.GetName())
123+
break;
124+
if (DWARFDIE inner_type_die =
125+
member_die.GetAttributeValueAsReferenceDIE(DW_AT_type))
126+
if (const char *s = inner_type_die.GetAttributeValueAsString(
127+
DW_AT_name, nullptr))
128+
mangled_name.SetCString(s);
129+
}
130+
}
101131
break;
102132
case DW_AT_byte_size:
103133
dwarf_byte_size = form_value.Unsigned();
@@ -106,7 +136,7 @@ lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
106136
if (die.Tag() == DW_TAG_const_type)
107137
// This is how let bindings are represented. This doesn't
108138
// change the underlying Swift type.
109-
return ParseTypeFromDWARF(sc, die.GetReferencedDIE(attr),
139+
return ParseTypeFromDWARF(sc, form_value.Reference(),
110140
type_is_new_ptr);
111141
break;
112142
default:

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ def implementation(self):
2727
)
2828
frame = thread.frames[0]
2929
self.assertTrue(frame, "Frame 0 is valid.")
30+
if self.TraceOn():
31+
self.expect("frame variable")
3032

3133
varB = frame.FindVariable("varB")
3234
field = varB.GetChildMemberWithName("a").GetChildMemberWithName("field")

0 commit comments

Comments
 (0)