Skip to content

Commit 8be798a

Browse files
committed
refactor(_dwarf): document bindings, drop as_referenced_die polyfill
- Add Google-style docstrings derived from the LLVM DWARF headers, only where LLVM documents the API (nothing invented). - Replace the as_referenced_die body with LLVM 22 DWARFDie:: getAttributeValueAsReferencedDie (verified identical to the old inline pre-LLVM-20 polyfill).
1 parent 14ff038 commit 8be798a

1 file changed

Lines changed: 56 additions & 36 deletions

File tree

‎src/dwarf2cpp/_dwarf.cpp‎

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -133,25 +133,35 @@ NB_MODULE(_dwarf, m) {
133133
.value("DECLARED_NOT_INLINED", llvm::dwarf::DW_INL_declared_not_inlined)
134134
.value("DECLARED_INLINED", llvm::dwarf::DW_INL_declared_inlined);
135135

136-
nb::class_<PyDWARFContext>(m, "DWARFContext")
136+
nb::class_<PyDWARFContext>(
137+
m, "DWARFContext",
138+
"Top-level entity that deals with DWARF debug information parsing.")
137139
.def(nb::init<const std::string &>(), nb::arg("path"))
138140
.def_prop_ro("info_section_units",
139141
&PyDWARFContext::info_section_units,
140-
nb::rv_policy::reference_internal)
142+
nb::rv_policy::reference_internal,
143+
"Get units from .debug_info in this context.")
141144
.def_prop_ro("types_section_units",
142145
&PyDWARFContext::types_section_units,
143-
nb::rv_policy::reference_internal)
146+
nb::rv_policy::reference_internal,
147+
"Get units from .debug_types in this context.")
144148
.def_prop_ro("compile_units",
145149
&PyDWARFContext::compile_units,
146-
nb::rv_policy::reference_internal)
147-
.def_prop_ro("num_compile_units", &PyDWARFContext::getNumCompileUnits)
148-
.def_prop_ro("num_type_units", &PyDWARFContext::getNumTypeUnits)
149-
.def_prop_ro("num_dwo_compile_units", &PyDWARFContext::getNumDWOCompileUnits)
150-
.def_prop_ro("num_dwo_type_units", &PyDWARFContext::getNumDWOTypeUnits)
150+
nb::rv_policy::reference_internal,
151+
"Get compile units in this context.")
152+
.def_prop_ro("num_compile_units", &PyDWARFContext::getNumCompileUnits,
153+
"Get the number of compile units in this context.")
154+
.def_prop_ro("num_type_units", &PyDWARFContext::getNumTypeUnits,
155+
"Get the number of type units in this context.")
156+
.def_prop_ro("num_dwo_compile_units", &PyDWARFContext::getNumDWOCompileUnits,
157+
"Get the number of compile units in the DWO context.")
158+
.def_prop_ro("num_dwo_type_units", &PyDWARFContext::getNumDWOTypeUnits,
159+
"Get the number of type units in the DWO context.")
151160
.def_prop_ro("max_version", &PyDWARFContext::getMaxVersion)
152161
.def_prop_ro("max_dwo_version", &PyDWARFContext::getMaxDWOVersion)
153162
.def_prop_ro("is_little_endian", &PyDWARFContext::isLittleEndian)
154-
.def_prop_ro("cu_addr_size", &PyDWARFContext::getCUAddrSize);
163+
.def_prop_ro("cu_addr_size", &PyDWARFContext::getCUAddrSize,
164+
"Get address size from CUs.");
155165

156166
nb::class_<llvm::DWARFUnit>(m, "DWARFUnit")
157167
.def_prop_ro("offset", &llvm::DWARFUnit::getOffset)
@@ -166,9 +176,13 @@ NB_MODULE(_dwarf, m) {
166176
})
167177
.def_prop_ro("compilation_dir", &llvm::DWARFUnit::getCompilationDir);
168178

169-
nb::class_<llvm::DWARFDie>(m, "DWARFDie")
179+
nb::class_<llvm::DWARFDie>(
180+
m, "DWARFDie",
181+
"Utility class that carries the DWARF compile/type unit and the debug "
182+
"info entry in an object.")
170183
.def_prop_ro("unit", &llvm::DWARFDie::getDwarfUnit)
171-
.def_prop_ro("offset", &llvm::DWARFDie::getOffset)
184+
.def_prop_ro("offset", &llvm::DWARFDie::getOffset,
185+
"Get the absolute offset into the debug info or types section.")
172186
.def_prop_ro(
173187
"tag", [](const llvm::DWARFDie &self) { return TagString(self.getTag()).str(); })
174188
.def_prop_ro("parent",
@@ -177,7 +191,8 @@ NB_MODULE(_dwarf, m) {
177191
return parent;
178192
}
179193
return std::nullopt;
180-
})
194+
},
195+
"Get the parent of this DIE object, or None if it has no parent.")
181196
.def_prop_ro("short_name",
182197
[](const llvm::DWARFDie &self) {
183198
return llvm::dwarf::toString(
@@ -210,7 +225,8 @@ NB_MODULE(_dwarf, m) {
210225
attrs.emplace_back(attr);
211226
}
212227
return attrs;
213-
})
228+
},
229+
"Get all attributes in the current DIE only.")
214230
.def_prop_ro("children",
215231
[](const llvm::DWARFDie &self) {
216232
std::vector<llvm::DWARFDie> children;
@@ -228,11 +244,19 @@ NB_MODULE(_dwarf, m) {
228244
self.dump(os);
229245
os.flush();
230246
return result;
231-
})
247+
},
248+
"Dump the DIE and all of its attributes.")
232249
.def("find",
233250
[](const llvm::DWARFDie &self, const std::string &attribute) {
234251
return self.find(ToAttribute(attribute));
235-
})
252+
},
253+
R"doc(Extract the specified attribute from this DIE.
254+
255+
Extracts the attribute value from this DIE only; it does not look for the value
256+
in any DW_AT_specification or DW_AT_abstract_origin referenced DIEs.
257+
258+
Returns:
259+
The form value if the attribute was successfully extracted, otherwise None.)doc")
236260
.def("resolve_type_unit_reference",
237261
[](const llvm::DWARFDie &self) -> std::optional<llvm::DWARFDie> {
238262
auto die = self.resolveTypeUnitReference();
@@ -244,12 +268,18 @@ NB_MODULE(_dwarf, m) {
244268
.def("__hash__", &llvm::DWARFDie::getOffset)
245269
.def(nb::self == nb::self);
246270

247-
nb::class_<llvm::DWARFAttribute>(m, "DWARFAttribute")
248-
.def_ro("offset", &llvm::DWARFAttribute::Offset)
249-
.def_ro("byte_size", &llvm::DWARFAttribute::ByteSize)
271+
nb::class_<llvm::DWARFAttribute>(
272+
m, "DWARFAttribute",
273+
"Encapsulates a DWARF attribute value and all of the data required to "
274+
"describe the attribute value.")
275+
.def_ro("offset", &llvm::DWARFAttribute::Offset,
276+
"The debug info/types offset for this attribute.")
277+
.def_ro("byte_size", &llvm::DWARFAttribute::ByteSize,
278+
"The debug info/types section byte size of the data for this attribute.")
250279
.def_prop_ro("name",
251280
[](const llvm::DWARFAttribute &self) { return ToString(self.Attr); })
252-
.def_ro("value", &llvm::DWARFAttribute::Value);
281+
.def_ro("value", &llvm::DWARFAttribute::Value,
282+
"The form and value for this attribute.");
253283

254284
nb::class_<llvm::DWARFFormValue>(m, "DWARFFormValue")
255285
.def_prop_ro("form",
@@ -258,22 +288,11 @@ NB_MODULE(_dwarf, m) {
258288
})
259289
.def("as_referenced_die",
260290
[](const llvm::DWARFFormValue &self) -> std::optional<llvm::DWARFDie> {
261-
llvm::DWARFDie result;
262-
auto &V = self;
263-
auto *U = self.getUnit();
264-
if (std::optional<uint64_t> offset = V.getAsRelativeReference()) {
265-
result = const_cast<llvm::DWARFUnit *>(V.getUnit())
266-
->getDIEForOffset(V.getUnit()->getOffset() + offset.value());
267-
} else if (offset = V.getAsDebugInfoReference(); offset) {
268-
if (llvm::DWARFUnit *spec_unit
269-
= U->getUnitVector().getUnitForOffset(offset.value()))
270-
result = spec_unit->getDIEForOffset(*offset);
271-
} else if (std::optional<uint64_t> sig = V.getAsSignatureReference()) {
272-
if (llvm::DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash(
273-
sig.value(), U->isDWOUnit()))
274-
result = TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset());
275-
}
276-
291+
// getAttributeValueAsReferencedDie resolves using the form value's unit,
292+
// so any DIE of that unit (here the unit DIE) yields the same result.
293+
llvm::DWARFDie result = const_cast<llvm::DWARFUnit *>(self.getUnit())
294+
->getUnitDIE()
295+
.getAttributeValueAsReferencedDie(self);
277296
if (result.isValid()) {
278297
return result;
279298
}
@@ -302,7 +321,8 @@ NB_MODULE(_dwarf, m) {
302321
.def(nb::init())
303322
.def("append_qualified_name", &PyDWARFTypePrinter::appendQualifiedName)
304323
.def("append_qualified_name_before", &PyDWARFTypePrinter::appendQualifiedNameBefore)
305-
.def("append_unqualified_name", &PyDWARFTypePrinter::appendUnqualifiedName)
324+
.def("append_unqualified_name", &PyDWARFTypePrinter::appendUnqualifiedName,
325+
"Recursively append the DIE type name when applicable.")
306326
.def("append_unqualified_name_before", &PyDWARFTypePrinter::appendUnqualifiedNameBefore)
307327
.def("append_unqualified_name_after", &PyDWARFTypePrinter::appendUnqualifiedNameAfter)
308328
.def("append_scopes", &PyDWARFTypePrinter::appendScopes)

0 commit comments

Comments
 (0)