*last_char_p = buffer[length - 1];
}
+/* Return the DIE's linkage name attribute, either DW_AT_linkage_name
+ or DW_AT_MIPS_linkage_name. Returns NULL if the attribute is not
+ defined for the given DIE. */
+
+static const char *
+dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+ const char *linkage_name;
+
+ linkage_name = dwarf2_string_attr (die, DW_AT_linkage_name, cu);
+ if (linkage_name == NULL)
+ linkage_name = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
+
+ return linkage_name;
+}
+
/* Compute the fully qualified name of DIE in CU. If PHYSNAME is nonzero,
compute the physname for the object, which include a method's:
- - formal parameters (C++/Java),
+ - formal parameters (C++),
- receiver type (Go),
- - return type (Java).
The term "physname" is a bit confusing.
For C++, for example, it is the demangled name.
&& (type_name[len] == '\0' || type_name[len] == '<'));
}
-/* Add a member function to the proper fieldlist. */
+/* Return true if this member function is a destructor, false
+ otherwise. */
-static void
-dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
- struct type *type, struct dwarf2_cu *cu)
+static int
+dwarf2_is_destructor (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->objfile;
- struct attribute *attr;
- struct fnfieldlist *flp;
- int i;
- struct fn_field *fnp;
const char *fieldname;
- struct nextfnfield *new_fnfield;
- struct type *this_type;
- enum dwarf_access_attribute accessibility;
+ const char *linkage_name;
- if (cu->language == language_ada)
- error (_("unexpected member function in Ada type"));
+ /* If there is a linkage name, use it to determine if this DIE represents
+ a destructor. */
+ linkage_name = dw2_linkage_name (die, cu);
+ if (linkage_name != NULL)
+ return is_destructor_name (linkage_name) != 0;
+
+ if (die->parent == NULL)
+ return 0;
+
+ if (die->parent->tag != DW_TAG_structure_type
+ && die->parent->tag != DW_TAG_union_type
+ && die->parent->tag != DW_TAG_class_type)
+ return 0;
- /* Get name of member function. */
fieldname = dwarf2_name (die, cu);
- if (fieldname == NULL)
- return;
+ return (fieldname != NULL && *fieldname == '~');
+}
- /* Look up member function name in fieldlist. */
- for (i = 0; i < fip->nfnfields; i++)
- {
- if (strcmp (fip->fnfieldlists[i].name, fieldname) == 0)
- break;
- }
+/* Create a new fn_field which may represent an alias to an existing
+ field (if a constructor or destructor). TYPE_DIE and TYPE_CU
+ may be NULL, in which case they default to NAME_DIE and NAME_CU,
+ i.e., not an aliased method. */
- /* Create new list element if necessary. */
- if (i < fip->nfnfields)
- flp = &fip->fnfieldlists[i];
- else
- {
- if ((fip->nfnfields % DW_FIELD_ALLOC_CHUNK) == 0)
- {
- fip->fnfieldlists = (struct fnfieldlist *)
- xrealloc (fip->fnfieldlists,
- (fip->nfnfields + DW_FIELD_ALLOC_CHUNK)
- * sizeof (struct fnfieldlist));
- if (fip->nfnfields == 0)
- make_cleanup (free_current_contents, &fip->fnfieldlists);
- }
- flp = &fip->fnfieldlists[fip->nfnfields];
- flp->name = fieldname;
- flp->length = 0;
- flp->head = NULL;
- i = fip->nfnfields++;
- }
+static struct fn_field
+new_fn_field (struct die_info *name_die, struct dwarf2_cu *name_cu,
+ struct die_info *type_die, struct dwarf2_cu *type_cu,
+ struct type *type, const char *fieldname,
+ int fnl_idx, int field_idx)
+{
+ struct fn_field fnfield;
+ struct objfile *objfile;
+ struct attribute *attr;
+ struct type *this_type;
+ enum dwarf_access_attribute accessibility;
- /* Create a new member function field and chain it to the field list
- entry. */
- new_fnfield = XNEW (struct nextfnfield);
- make_cleanup (xfree, new_fnfield);
- memset (new_fnfield, 0, sizeof (struct nextfnfield));
- new_fnfield->next = flp->head;
- flp->head = new_fnfield;
- flp->length++;
+ memset (&fnfield, 0, sizeof (fnfield));
- /* Fill in the member function field info. */
- fnp = &new_fnfield->fnfield;
+ if (type_die == NULL)
+ type_die = name_die;
+ if (type_cu == NULL)
+ type_cu = name_cu;
+
+ objfile = type_cu->objfile;
/* Delay processing of the physname until later. */
- if (type_cu->language == language_cplus || type_cu->language == language_java)
- if (cu->language == language_cplus)
++ if (type_cu->language == language_cplus)
{
- add_to_method_list (type, i, flp->length - 1, fieldname,
- die, cu);
+ add_to_method_list (type, field_idx, fnl_idx, fieldname,
+ name_die, name_cu);
}
else
{
}
}
+ /* Copy fi.nested_types_list linked list elements content into the
+ allocated array TYPE_NESTED_TYPES_ARRAY (type). */
+ if (fi.nested_types_list != NULL)
+ {
+ int i = fi.nested_types_list_count;
+
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_NESTED_TYPES_ARRAY (type)
+ = ((struct decl_field *)
+ TYPE_ALLOC (type, sizeof (struct decl_field) * i));
+ TYPE_NESTED_TYPES_COUNT (type) = i;
+
+ /* Reverse the list order to keep the debug info elements order. */
+ while (--i >= 0)
+ {
+ struct decl_field *dest, *src;
+
+ dest = &TYPE_NESTED_TYPES_FIELD (type, i);
+ src = &fi.nested_types_list->field;
+ fi.nested_types_list = fi.nested_types_list->next;
+ *dest = *src;
+ }
+ }
+
do_cleanups (back_to);
-
- if (HAVE_CPLUS_STRUCT (type))
- TYPE_CPLUS_REALLY_JAVA (type) = cu->language == language_java;
}
quirk_gcc_member_function_pointer (type, objfile);