Skip to content

Commit d4b8fcd

Browse files
committed
feat: support template parameter packs and default values
1 parent 003a439 commit d4b8fcd

3 files changed

Lines changed: 54 additions & 12 deletions

File tree

src/dwarf2cpp/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ class TemplateParameter:
201201
kind: TemplateParameterKind
202202
type: str | None = None
203203
arg: str | None = field(default=None, compare=False)
204+
pack: list["TemplateParameter"] | None = field(default_factory=list, compare=False)
204205
default: str | None = None
205206

206207

src/dwarf2cpp/templates/template.jinja

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
template<
33
{%- for parameter in obj.parameters -%}
44
{%- if parameter.kind == "type" -%}
5-
typename{{ " " ~ parameter.name if parameter.name }}{{ " = {}".format(parameter.default) if parameter.default }}
5+
typename{{ " " ~ parameter.name if parameter.name }}{{ " = {}".format(parameter.default) if parameter.default is not none }}
66
{%- elif parameter.kind == "constant" -%}
7-
{{ parameter.type }}{{ " " ~ parameter.name if parameter.name }}
7+
{{ parameter.type }}{{ " " ~ parameter.name if parameter.name }}{{ " = {}".format(parameter.default) if parameter.default is not none }}
88
{%- elif parameter.kind == "pack" -%}
99
typename...{{ " " ~ parameter.name if parameter.name }}
1010
{%- elif parameter.kind == "template" -%}

src/dwarf2cpp/visitor.py

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,11 @@ def files(self) -> Generator[tuple[str, dict[int, list[Object]]]]:
107107
List of files
108108
"""
109109
for i, cu in (
110-
pbar := tqdm(
111-
enumerate(self.context.compile_units),
112-
total=self.context.num_compile_units,
113-
bar_format="[{n_fmt}/{total_fmt}] {desc}",
114-
)
110+
pbar := tqdm(
111+
enumerate(self.context.compile_units),
112+
total=self.context.num_compile_units,
113+
bar_format="[{n_fmt}/{total_fmt}] {desc}",
114+
)
115115
):
116116
cu_die = cu.unit_die
117117
name = cu_die.short_name
@@ -632,11 +632,50 @@ def visit_template_type_parameter(self, die: DWARFDie) -> None:
632632
self._cache[die.offset] = param
633633

634634
def visit_template_value_parameter(self, die: DWARFDie) -> None:
635-
ty = get_qualified_type(die.find("DW_AT_type").as_referenced_die())
636-
self._cache[die.offset] = TemplateParameter(die.short_name, TemplateParameterKind.CONSTANT, type=ty)
635+
param = TemplateParameter(die.short_name, TemplateParameterKind.CONSTANT)
636+
param.type = get_qualified_type(die.find("DW_AT_type").as_referenced_die())
637+
638+
if value := die.find("DW_AT_const_value"):
639+
param.arg = value.as_constant()
640+
641+
for attribute in die.attributes:
642+
if attribute.name in {"DW_AT_name", "DW_AT_type", "DW_AT_const_value", "DW_AT_location"}:
643+
continue
644+
645+
match attribute.name:
646+
case "DW_AT_default_value":
647+
param.default = param.arg
648+
case _:
649+
raise ValueError(f"Unhandled attribute {attribute.name}")
650+
651+
for child in die.children:
652+
raise ValueError(f"Unhandled child tag {child.tag}")
653+
654+
self._cache[die.offset] = param
637655

638656
def visit_GNU_template_parameter_pack(self, die: DWARFDie) -> None:
639-
self._cache[die.offset] = TemplateParameter(die.short_name, TemplateParameterKind.PACK)
657+
param = TemplateParameter(die.short_name, TemplateParameterKind.PACK)
658+
659+
for attribute in die.attributes:
660+
if attribute.name in {"DW_AT_name"}:
661+
continue
662+
663+
match attribute.name:
664+
case _:
665+
raise ValueError(f"Unhandled attribute {attribute.name}")
666+
667+
pack = []
668+
for child in die.children:
669+
if child.tag in {"DW_TAG_template_type_parameter", "DW_TAG_template_value_parameter"}:
670+
self.visit(child)
671+
pack.append(self._cache[child.offset])
672+
else:
673+
raise ValueError(f"Unhandled child tag {child.tag}")
674+
675+
if pack:
676+
param.pack = pack
677+
678+
self._cache[die.offset] = param
640679

641680
def visit_GNU_template_template_param(self, die: DWARFDie) -> None:
642681
self._cache[die.offset] = TemplateParameter(die.short_name, TemplateParameterKind.TEMPLATE)
@@ -661,9 +700,11 @@ def _register_template(self, key: str | int, lineno: int, template: Template) ->
661700
# make a copy for template declaration
662701
template = copy.copy(template)
663702
for parameter in template.parameters:
664-
parameter.arg = None # declaration must not have type replacement
703+
# declaration must not have type replacement
704+
parameter.arg = None
705+
parameter.pack = None
665706

666-
# try to merge with existing templates
707+
# try to merge with existing templates
667708
for t in templates:
668709
if t.merge(template):
669710
return None

0 commit comments

Comments
 (0)