in src/backward.h [2749:2847]
static void set_function_parameters(
std::string& function_name,
std::vector<std::string>& ns,
dwarf_fileobject& fobj,
Dwarf_Die die)
{
Dwarf_Debug dwarf = fobj.dwarf_handle.get();
Dwarf_Error error = DW_DLE_NE;
Dwarf_Die current_die = 0;
std::string parameters;
bool has_spec = true;
// Check if we have a spec DIE. If we do we use it as it contains
// more information, like parameter names.
Dwarf_Die spec_die = get_spec_die(fobj, die);
if (!spec_die) {
has_spec = false;
spec_die = die;
}
std::vector<std::string>::const_iterator it = ns.begin();
std::string ns_name;
for (it = ns.begin(); it < ns.end(); ++it) {
ns_name.append(*it).append("::");
}
if (!ns_name.empty()) {
function_name.insert(0, ns_name);
}
// See if we have a function return type. It can be either on the
// current die or in its spec one (usually true for inlined functions)
std::string return_type = get_referenced_die_name(dwarf, die, DW_AT_type, true);
if (return_type.empty()) {
return_type = get_referenced_die_name(dwarf, spec_die, DW_AT_type, true);
}
if (!return_type.empty()) {
return_type.append(" ");
function_name.insert(0, return_type);
}
if (dwarf_child(spec_die, ¤t_die, &error) == DW_DLV_OK) {
for (;;) {
Dwarf_Die sibling_die = 0;
Dwarf_Half tag_value;
dwarf_tag(current_die, &tag_value, &error);
if (tag_value == DW_TAG_formal_parameter) {
// Ignore artificial (ie, compiler generated) parameters
bool is_artificial = false;
Dwarf_Attribute attr_mem;
if (dwarf_attr(current_die, DW_AT_artificial, &attr_mem, &error) == DW_DLV_OK) {
Dwarf_Bool flag = 0;
if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) {
is_artificial = flag != 0;
}
dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
}
if (!is_artificial) {
type_context_t context;
set_parameter_string(fobj, current_die, context);
if (parameters.empty()) {
parameters.append("(");
}
else {
parameters.append(", ");
}
parameters.append(context.text);
}
}
int result = dwarf_siblingof(dwarf, current_die, &sibling_die, &error);
if (result == DW_DLV_ERROR) {
break;
}
else if (result == DW_DLV_NO_ENTRY) {
break;
}
if (current_die != die) {
dwarf_dealloc(dwarf, current_die, DW_DLA_DIE);
current_die = 0;
}
current_die = sibling_die;
}
}
if (parameters.empty())
parameters = "(";
parameters.append(")");
// If we got a spec DIE we need to deallocate it
if (has_spec)
dwarf_dealloc(dwarf, spec_die, DW_DLA_DIE);
function_name.append(parameters);
}