in src/backward.h [2637:2746]
static void set_parameter_string(dwarf_fileobject& fobj, Dwarf_Die die, type_context_t& context)
{
char* name;
Dwarf_Error error = DW_DLE_NE;
// typedefs contain also the base type, so we skip it and only
// print the typedef name
if (!context.is_typedef) {
if (dwarf_diename(die, &name, &error) == DW_DLV_OK) {
if (!context.text.empty()) {
context.text.insert(0, " ");
}
context.text.insert(0, std::string(name));
dwarf_dealloc(fobj.dwarf_handle.get(), name, DW_DLA_STRING);
}
}
else {
context.is_typedef = false;
context.has_type = true;
if (context.is_const) {
context.text.insert(0, "const ");
context.is_const = false;
}
}
bool next_type_is_const = false;
bool is_keyword = true;
Dwarf_Half tag = 0;
Dwarf_Bool has_attr = 0;
if (dwarf_tag(die, &tag, &error) == DW_DLV_OK) {
switch (tag) {
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type:
case DW_TAG_enumeration_type:
context.has_type = true;
if (dwarf_hasattr(die, DW_AT_signature, &has_attr, &error) == DW_DLV_OK) {
// If we have a signature it means the type is defined
// in .debug_types, so we need to load the DIE pointed
// at by the signature and resolve it
if (has_attr) {
std::string type = get_type_by_signature(fobj.dwarf_handle.get(), die);
if (context.is_const)
type.insert(0, "const ");
if (!context.text.empty())
context.text.insert(0, " ");
context.text.insert(0, type);
}
// Treat enums like typedefs, and skip printing its
// base type
context.is_typedef = (tag == DW_TAG_enumeration_type);
}
break;
case DW_TAG_const_type:
next_type_is_const = true;
break;
case DW_TAG_pointer_type:
context.text.insert(0, "*");
break;
case DW_TAG_reference_type:
context.text.insert(0, "&");
break;
case DW_TAG_restrict_type:
context.text.insert(0, "restrict ");
break;
case DW_TAG_rvalue_reference_type:
context.text.insert(0, "&&");
break;
case DW_TAG_volatile_type:
context.text.insert(0, "volatile ");
break;
case DW_TAG_typedef:
// Propagate the const-ness to the next type
// as typedefs are linked to its base type
next_type_is_const = context.is_const;
context.is_typedef = true;
context.has_type = true;
break;
case DW_TAG_base_type:
context.has_type = true;
break;
case DW_TAG_formal_parameter:
context.has_name = true;
break;
default:
is_keyword = false;
break;
}
}
if (!is_keyword && context.is_const) {
context.text.insert(0, "const ");
}
context.is_const = next_type_is_const;
Dwarf_Die ref = get_referenced_die(fobj.dwarf_handle.get(), die, DW_AT_type, true);
if (ref) {
set_parameter_string(fobj, ref, context);
dwarf_dealloc(fobj.dwarf_handle.get(), ref, DW_DLA_DIE);
}
if (!context.has_type && context.has_name) {
context.text.insert(0, "void ");
context.has_type = true;
}
}