static void set_function_parameters()

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, &current_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);
    }