aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2codeview.cc
diff options
context:
space:
mode:
authorMark Harmstone <mark@harmstone.com>2024-08-26 22:40:56 +0100
committerMark Harmstone <mark@harmstone.com>2024-08-29 02:53:08 +0100
commitc5043d89449758ecf6a3f1475e027a73976f58c3 (patch)
tree981815fa92a4f0326eb1928b39068fa80b5181a0 /gcc/dwarf2codeview.cc
parent6a9932ecdaac16c0fa21cc7c39589a3cd7cacf0f (diff)
downloadgcc-c5043d89449758ecf6a3f1475e027a73976f58c3.zip
gcc-c5043d89449758ecf6a3f1475e027a73976f58c3.tar.gz
gcc-c5043d89449758ecf6a3f1475e027a73976f58c3.tar.bz2
Record member functions in CodeView struct definitions
CodeView has two ways of recording struct member functions. Non-overloaded functions have an LF_ONEMETHOD sub-type in the field list, which records the name and the function type (LF_MFUNCTION). Overloaded functions have an LF_METHOD instead, which points to an LF_METHODLIST, which is an array of links to various LF_MFUNCTION types. gcc/ * dwarf2codeview.cc (enum cv_leaf_type): Add LF_MFUNCTION, LF_METHODLIST, LF_METHOD, and LF_ONEMETHOD. (struct codeview_subtype): Add lf_onemethod and lf_method to union. (struct lf_methodlist_entry): New type. (struct codeview_custom_type): Add lf_mfunc_id, lf_mfunction, and lf_methodlist to union. (struct codeview_method): New type. (struct method_hasher): New type. (get_type_num_subroutine_type): Add forward declaration. (write_lf_fieldlist): Handle LF_ONEMETHOD and LF_METHOD. (write_lf_mfunction): New function. (write_lf_methodlist): New function. (write_custom_types): Handle LF_MFUNCTION and LF_METHODLIST. (add_struct_function): New function. (get_mfunction_type): New function. (is_templated_func): New function. (get_type_num_struct): Handle DW_TAG_subprogram child DIEs. (get_type_num_subroutine_type): Add containing_class_type, this_type, and this_adjustment params, and handle creating LF_MFUNCTION types as well as LF_PROCEDURE. (get_type_num): New params for get_type_num_subroutine_type. (add_function): New params for get_type_num_subroutine_type. * dwarf2codeview.h (CV_METHOD_VANILLA, CV_METHOD_VIRTUAL): Define. (CV_METHOD_STATIC, CV_METHOD_FRIEND, CV_METHOD_INTRO): Likewise. (CV_METHOD_PUREVIRT, CV_METHOD_PUREINTRO): Likewise.
Diffstat (limited to 'gcc/dwarf2codeview.cc')
-rw-r--r--gcc/dwarf2codeview.cc530
1 files changed, 519 insertions, 11 deletions
diff --git a/gcc/dwarf2codeview.cc b/gcc/dwarf2codeview.cc
index e243e0f..00a1795 100644
--- a/gcc/dwarf2codeview.cc
+++ b/gcc/dwarf2codeview.cc
@@ -95,9 +95,11 @@ enum cv_leaf_type {
LF_MODIFIER = 0x1001,
LF_POINTER = 0x1002,
LF_PROCEDURE = 0x1008,
+ LF_MFUNCTION = 0x1009,
LF_ARGLIST = 0x1201,
LF_FIELDLIST = 0x1203,
LF_BITFIELD = 0x1205,
+ LF_METHODLIST = 0x1206,
LF_INDEX = 0x1404,
LF_ENUMERATE = 0x1502,
LF_ARRAY = 0x1503,
@@ -107,6 +109,8 @@ enum cv_leaf_type {
LF_ENUM = 0x1507,
LF_MEMBER = 0x150d,
LF_STMEMBER = 0x150e,
+ LF_METHOD = 0x150f,
+ LF_ONEMETHOD = 0x1511,
LF_FUNC_ID = 0x1601,
LF_STRING_ID = 0x1605,
LF_CHAR = 0x8000,
@@ -1225,9 +1229,27 @@ struct codeview_subtype
uint32_t type;
char *name;
} lf_static_member;
+ struct
+ {
+ uint16_t method_attribute;
+ uint32_t method_type;
+ char *name;
+ } lf_onemethod;
+ struct
+ {
+ uint16_t count;
+ uint32_t method_list;
+ char *name;
+ } lf_method;
};
};
+struct lf_methodlist_entry
+{
+ uint16_t method_attribute;
+ uint32_t method_type;
+};
+
struct codeview_custom_type
{
struct codeview_custom_type *next;
@@ -1303,9 +1325,31 @@ struct codeview_custom_type
} lf_func_id;
struct
{
+ uint32_t parent_type;
+ uint32_t function_type;
+ char *name;
+ } lf_mfunc_id;
+ struct
+ {
uint32_t substring;
char *string;
} lf_string_id;
+ struct
+ {
+ uint32_t return_type;
+ uint32_t containing_class_type;
+ uint32_t this_type;
+ uint8_t calling_convention;
+ uint8_t attributes;
+ uint16_t num_parameters;
+ uint32_t arglist;
+ int32_t this_adjustment;
+ } lf_mfunction;
+ struct
+ {
+ unsigned int count;
+ lf_methodlist_entry *entries;
+ } lf_methodlist;
};
};
@@ -1330,6 +1374,31 @@ struct string_id_hasher : nofree_ptr_hash <struct codeview_custom_type>
}
};
+struct codeview_method
+{
+ uint16_t attribute;
+ uint32_t type;
+ char *name;
+ unsigned int count;
+ struct codeview_method *next;
+ struct codeview_method *last;
+};
+
+struct method_hasher : nofree_ptr_hash <struct codeview_method>
+{
+ typedef const char *compare_type;
+
+ static hashval_t hash (const codeview_method *x)
+ {
+ return htab_hash_string (x->name);
+ }
+
+ static bool equal (const codeview_method *x, const char *y)
+ {
+ return !strcmp (x->name, y);
+ }
+};
+
static unsigned int line_label_num;
static unsigned int func_label_num;
static unsigned int sym_label_num;
@@ -1348,6 +1417,10 @@ static codeview_deferred_type *deferred_types, *last_deferred_type;
static hash_table<string_id_hasher> *string_id_htab;
static uint32_t get_type_num (dw_die_ref type, bool in_struct, bool no_fwd_ref);
+static uint32_t get_type_num_subroutine_type (dw_die_ref type, bool in_struct,
+ uint32_t containing_class_type,
+ uint32_t this_type,
+ int32_t this_adjustment);
/* Record new line number against the current function. */
@@ -3704,6 +3777,74 @@ write_lf_fieldlist (codeview_custom_type *t)
free (v->lf_static_member.name);
break;
+ case LF_ONEMETHOD:
+ /* This is lf_onemethod in binutils and lfOneMethod in Microsoft's
+ cvinfo.h:
+
+ struct lf_onemethod
+ {
+ uint16_t kind;
+ uint16_t method_attribute;
+ uint32_t method_type;
+ char name[];
+ } ATTRIBUTE_PACKED;
+ */
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, LF_ONEMETHOD);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, v->lf_onemethod.method_attribute);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, v->lf_onemethod.method_type);
+ putc ('\n', asm_out_file);
+
+ name_len = strlen (v->lf_onemethod.name) + 1;
+ ASM_OUTPUT_ASCII (asm_out_file, v->lf_onemethod.name, name_len);
+
+ leaf_len = 8 + name_len;
+ write_cv_padding (4 - (leaf_len % 4));
+
+ free (v->lf_onemethod.name);
+ break;
+
+ case LF_METHOD:
+ /* This is lf_method in binutils and lfMethod in Microsoft's
+ cvinfo.h:
+
+ struct lf_method
+ {
+ uint16_t kind;
+ uint16_t count;
+ uint32_t method_list;
+ char name[];
+ } ATTRIBUTE_PACKED;
+ */
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, LF_METHOD);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, v->lf_method.count);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, v->lf_method.method_list);
+ putc ('\n', asm_out_file);
+
+ name_len = strlen (v->lf_method.name) + 1;
+ ASM_OUTPUT_ASCII (asm_out_file, v->lf_method.name, name_len);
+
+ leaf_len = 8 + name_len;
+ write_cv_padding (4 - (leaf_len % 4));
+
+ free (v->lf_method.name);
+ break;
+
default:
break;
}
@@ -4196,6 +4337,129 @@ write_lf_string_id (codeview_custom_type *t)
asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
}
+/* Write an LF_MFUNCTION type, representing a member function. This is the
+ struct-scoped equivalent of the LF_PROCEDURE type. */
+
+static void
+write_lf_mfunction (codeview_custom_type *t)
+{
+ /* This is lf_mfunction in binutils and lfMFunc in Microsoft's cvinfo.h:
+
+ struct lf_mfunction
+ {
+ uint16_t size;
+ uint16_t kind;
+ uint32_t return_type;
+ uint32_t containing_class_type;
+ uint32_t this_type;
+ uint8_t calling_convention;
+ uint8_t attributes;
+ uint16_t num_parameters;
+ uint32_t arglist;
+ int32_t this_adjustment;
+ } ATTRIBUTE_PACKED;
+ */
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
+ t->num, t->num);
+
+ asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, t->kind);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.return_type);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.containing_class_type);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.this_type);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (1, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.calling_convention);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (1, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.attributes);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.num_parameters);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.arglist);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_mfunction.this_adjustment);
+ putc ('\n', asm_out_file);
+
+ asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
+}
+
+/* Write an LF_METHODLIST type, which is an array of type numbers for
+ LF_MFUNCTION types. Overloaded functions are represented by a LF_METHOD
+ subtype in the field list, which points to a LF_METHODLIST type for the
+ function's various forms. */
+
+static void
+write_lf_methodlist (codeview_custom_type *t)
+{
+ /* This is lf_methodlist in binutils and lMethodList in Microsoft's cvinfo.h:
+
+ struct lf_methodlist_entry
+ {
+ uint16_t method_attribute;
+ uint16_t padding;
+ uint32_t method_type;
+ } ATTRIBUTE_PACKED;
+
+ struct lf_methodlist
+ {
+ uint16_t size;
+ uint16_t kind;
+ struct lf_methodlist_entry entries[];
+ } ATTRIBUTE_PACKED;
+ */
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ asm_fprintf (asm_out_file, "%LLcv_type%x_end - %LLcv_type%x_start\n",
+ t->num, t->num);
+
+ asm_fprintf (asm_out_file, "%LLcv_type%x_start:\n", t->num);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, t->kind);
+ putc ('\n', asm_out_file);
+
+ for (unsigned int i = 0; i < t->lf_methodlist.count; i++)
+ {
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_methodlist.entries[i].method_attribute);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (2, false), asm_out_file);
+ fprint_whex (asm_out_file, 0);
+ putc ('\n', asm_out_file);
+
+ fputs (integer_asm_op (4, false), asm_out_file);
+ fprint_whex (asm_out_file, t->lf_methodlist.entries[i].method_type);
+ putc ('\n', asm_out_file);
+ }
+
+ free (t->lf_methodlist.entries);
+
+ asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
+}
+
/* Write the .debug$T section, which contains all of our custom type
definitions. */
@@ -4263,6 +4527,14 @@ write_custom_types (void)
write_lf_string_id (custom_types);
break;
+ case LF_MFUNCTION:
+ write_lf_mfunction (custom_types);
+ break;
+
+ case LF_METHODLIST:
+ write_lf_methodlist (custom_types);
+ break;
+
default:
break;
}
@@ -5057,6 +5329,123 @@ add_struct_static_member (dw_die_ref c, uint16_t accessibility,
*el_len += 4 - (*el_len % 4);
}
+/* Create a field list subtype for a struct function, returning its pointer in
+ el and its size in el_len. If the function is not overloaded, create an
+ LF_ONEMETHOD subtype pointing to the LF_MFUNCTION. Otherwise, add an
+ LF_METHODLIST type of the function's forms, and create an LF_METHOD subtype
+ pointing to this. */
+
+static void
+add_struct_function (dw_die_ref c, hash_table<method_hasher> *method_htab,
+ codeview_subtype **el, size_t *el_len)
+{
+ const char *name = get_AT_string (c, DW_AT_name);
+ codeview_method **slot, *meth;
+
+ slot = method_htab->find_slot_with_hash (name, htab_hash_string (name),
+ NO_INSERT);
+ if (!slot)
+ return;
+
+ meth = *slot;
+
+ *el = (codeview_subtype *) xmalloc (sizeof (**el));
+ (*el)->next = NULL;
+
+ if (meth->count == 1)
+ {
+ (*el)->kind = LF_ONEMETHOD;
+ (*el)->lf_onemethod.method_attribute = meth->attribute;
+ (*el)->lf_onemethod.method_type = meth->type;
+ (*el)->lf_onemethod.name = xstrdup (name);
+
+ *el_len = 9 + strlen ((*el)->lf_onemethod.name);
+ }
+ else
+ {
+ codeview_custom_type *ct;
+ lf_methodlist_entry *ent;
+
+ ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
+
+ ct->next = NULL;
+ ct->kind = LF_METHODLIST;
+ ct->lf_methodlist.count = meth->count;
+ ct->lf_methodlist.entries = (lf_methodlist_entry *)
+ xmalloc (meth->count * sizeof (lf_methodlist_entry));
+
+ ent = ct->lf_methodlist.entries;
+ for (codeview_method *m = meth; m; m = m->next)
+ {
+ ent->method_attribute = m->attribute;
+ ent->method_type = m->type;
+ ent++;
+ }
+
+ add_custom_type (ct);
+
+ (*el)->kind = LF_METHOD;
+ (*el)->lf_method.count = meth->count;
+ (*el)->lf_method.method_list = ct->num;
+ (*el)->lf_method.name = xstrdup (name);
+
+ *el_len = 9 + strlen ((*el)->lf_method.name);
+ }
+
+ if (*el_len % 4)
+ *el_len += 4 - (*el_len % 4);
+
+ method_htab->remove_elt_with_hash (name, htab_hash_string (name));
+
+ while (meth)
+ {
+ codeview_method *next = meth->next;
+
+ free (meth->name);
+ free (meth);
+ meth = next;
+ }
+}
+
+/* Create a new LF_MFUNCTION type for a struct function, add it to the
+ types_htab hash table, and return its type number. */
+
+static uint32_t
+get_mfunction_type (dw_die_ref c)
+{
+ uint32_t containing_class_type, this_type, mfunction_type;
+ dw_die_ref obj_pointer;
+ codeview_type **slot, *t;
+
+ containing_class_type = get_type_num (dw_get_die_parent (c), true, false);
+
+ obj_pointer = get_AT_ref (c, DW_AT_object_pointer);
+ if (obj_pointer && dw_get_die_tag (obj_pointer) == DW_TAG_formal_parameter)
+ {
+ this_type = get_type_num (get_AT_ref (obj_pointer, DW_AT_type),
+ true, false);
+ }
+ else
+ {
+ this_type = 0;
+ }
+
+ mfunction_type = get_type_num_subroutine_type (c, true, containing_class_type,
+ this_type, 0);
+
+ slot = types_htab->find_slot_with_hash (c, htab_hash_pointer (c), INSERT);
+
+ t = (codeview_type *) xmalloc (sizeof (codeview_type));
+
+ t->die = c;
+ t->num = mfunction_type;
+ t->is_fwd_ref = false;
+
+ *slot = t;
+
+ return mfunction_type;
+}
+
/* Translate a DWARF DW_AT_accessibility constant into its CodeView
equivalent. If implicit, follow the C++ rules. */
@@ -5084,6 +5473,30 @@ get_accessibility (dw_die_ref c)
}
}
+/* Returns true if the struct function pointed to by die is an instantiated
+ template function. These are skipped in CodeView struct definitions, as
+ otherwise the same type might not be deduplicated across different TUs. */
+
+static bool
+is_templated_func (dw_die_ref die)
+{
+ dw_die_ref c = dw_get_die_child (die);
+
+ if (!c)
+ return false;
+
+ do
+ {
+ c = dw_get_die_sib (c);
+
+ if (dw_get_die_tag (c) == DW_TAG_template_type_param)
+ return true;
+ }
+ while (c != dw_get_die_child (die));
+
+ return false;
+}
+
/* Process a DW_TAG_structure_type, DW_TAG_class_type, or DW_TAG_union_type
DIE, add an LF_FIELDLIST and an LF_STRUCTURE / LF_CLASS / LF_UNION type,
and return the number of the latter. */
@@ -5122,8 +5535,69 @@ get_type_num_struct (dw_die_ref type, bool in_struct, bool *is_fwd_ref)
if (first_child)
{
+ hash_table<method_hasher> *method_htab = NULL;
dw_die_ref c;
+ /* First, loop through and record any non-templated member functions.
+ This is because overloaded and non-overloaded functions are expressed
+ differently in CodeView, so we need to have a hash table on the name
+ to know how to record it later on. */
+
+ c = first_child;
+ do
+ {
+ c = dw_get_die_sib (c);
+
+ if (dw_get_die_tag (c) == DW_TAG_subprogram)
+ {
+ const char *name = get_AT_string (c, DW_AT_name);
+ codeview_method *meth, **slot;
+
+ if (is_templated_func (c))
+ continue;
+
+ if (!method_htab)
+ method_htab = new hash_table<method_hasher> (10);
+
+ meth = (codeview_method *) xmalloc (sizeof (*meth));
+
+ slot = method_htab->find_slot_with_hash (name,
+ htab_hash_string (name),
+ INSERT);
+
+ meth->attribute = get_accessibility (c);
+
+ if (!get_AT_ref (c, DW_AT_object_pointer))
+ meth->attribute |= CV_METHOD_STATIC;
+
+ meth->type = get_mfunction_type (c);
+ meth->next = NULL;
+
+ if (*slot)
+ {
+ if ((*slot)->last)
+ (*slot)->last->next = meth;
+ else
+ (*slot)->next = meth;
+
+ (*slot)->last = meth;
+ (*slot)->count++;
+
+ meth->name = NULL;
+ }
+ else
+ {
+ meth->name = xstrdup (name);
+ meth->last = NULL;
+ meth->count = 1;
+ *slot = meth;
+ }
+ }
+ }
+ while (c != first_child);
+
+ /* Now loop through again and record the actual members. */
+
c = first_child;
do
{
@@ -5145,6 +5619,11 @@ get_type_num_struct (dw_die_ref type, bool in_struct, bool *is_fwd_ref)
add_struct_static_member (c, accessibility, &el, &el_len);
break;
+ case DW_TAG_subprogram:
+ if (!is_templated_func (c))
+ add_struct_function (c, method_htab, &el, &el_len);
+ break;
+
default:
break;
}
@@ -5191,6 +5670,9 @@ get_type_num_struct (dw_die_ref type, bool in_struct, bool *is_fwd_ref)
num_members++;
}
while (c != first_child);
+
+ if (method_htab)
+ delete method_htab;
}
while (ct)
@@ -5252,10 +5734,13 @@ get_type_num_struct (dw_die_ref type, bool in_struct, bool *is_fwd_ref)
}
/* Process a DW_TAG_subroutine_type DIE, adding an LF_ARGLIST and an
- LF_PROCEDURE type, and returning the number of the latter. */
+ LF_PROCEDURE or LF_MFUNCTION type, and returning the number of the
+ latter. */
static uint32_t
-get_type_num_subroutine_type (dw_die_ref type, bool in_struct)
+get_type_num_subroutine_type (dw_die_ref type, bool in_struct,
+ uint32_t containing_class_type,
+ uint32_t this_type, int32_t this_adjustment)
{
codeview_custom_type *ct;
uint32_t return_type, arglist_type;
@@ -5294,6 +5779,10 @@ get_type_num_subroutine_type (dw_die_ref type, bool in_struct)
&& dw_get_die_tag (c) != DW_TAG_unspecified_parameters)
continue;
+ /* We ignore "this" params here. */
+ if (get_AT_flag (c, DW_AT_artificial) != 0)
+ continue;
+
num_args++;
}
while (c != first_child);
@@ -5323,6 +5812,9 @@ get_type_num_subroutine_type (dw_die_ref type, bool in_struct)
{
c = dw_get_die_sib (c);
+ if (get_AT_flag (c, DW_AT_artificial) != 0)
+ continue;
+
switch (dw_get_die_tag (c))
{
case DW_TAG_formal_parameter:
@@ -5351,17 +5843,33 @@ get_type_num_subroutine_type (dw_die_ref type, bool in_struct)
arglist_type = ct->num;
- /* Finally, create an LF_PROCEDURE. */
+ /* Finally, create an LF_PROCEDURE or LF_MFUNCTION type. */
ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
ct->next = NULL;
- ct->kind = LF_PROCEDURE;
- ct->lf_procedure.return_type = return_type;
- ct->lf_procedure.calling_convention = 0;
- ct->lf_procedure.attributes = 0;
- ct->lf_procedure.num_parameters = num_args;
- ct->lf_procedure.arglist = arglist_type;
+
+ if (containing_class_type != 0)
+ {
+ ct->kind = LF_MFUNCTION;
+ ct->lf_mfunction.return_type = return_type;
+ ct->lf_mfunction.containing_class_type = containing_class_type;
+ ct->lf_mfunction.this_type = this_type;
+ ct->lf_mfunction.calling_convention = 0;
+ ct->lf_mfunction.attributes = 0;
+ ct->lf_mfunction.num_parameters = num_args;
+ ct->lf_mfunction.arglist = arglist_type;
+ ct->lf_mfunction.this_adjustment = this_adjustment;
+ }
+ else
+ {
+ ct->kind = LF_PROCEDURE;
+ ct->lf_procedure.return_type = return_type;
+ ct->lf_procedure.calling_convention = 0;
+ ct->lf_procedure.attributes = 0;
+ ct->lf_procedure.num_parameters = num_args;
+ ct->lf_procedure.arglist = arglist_type;
+ }
add_custom_type (ct);
@@ -5562,7 +6070,7 @@ get_type_num (dw_die_ref type, bool in_struct, bool no_fwd_ref)
break;
case DW_TAG_subroutine_type:
- num = get_type_num_subroutine_type (type, in_struct);
+ num = get_type_num_subroutine_type (type, in_struct, 0, 0, 0);
break;
default:
@@ -5700,7 +6208,7 @@ add_function (dw_die_ref die)
/* Add an LF_FUNC_ID type for this function. */
- function_type = get_type_num_subroutine_type (die, false);
+ function_type = get_type_num_subroutine_type (die, false, 0, 0, 0);
scope_type = get_scope_string_id (die);
ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));