aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2read.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2010-01-22 17:06:49 +0000
committerTom Tromey <tromey@redhat.com>2010-01-22 17:06:49 +0000
commit0b92b5bb46877299511949f5a437883ddb7dd60e (patch)
tree3bb64ee1fd4918b2274cb7c725749f23452f8786 /gdb/dwarf2read.c
parent911e63d0e72aaf928548703237fe9ac1dcbb4c45 (diff)
downloadgdb-0b92b5bb46877299511949f5a437883ddb7dd60e.zip
gdb-0b92b5bb46877299511949f5a437883ddb7dd60e.tar.gz
gdb-0b92b5bb46877299511949f5a437883ddb7dd60e.tar.bz2
gdb
PR symtab/11199: * dwarf2read.c (quirk_gcc_member_function_pointer): Change return type and arguments. Use smash_to_methodptr_type. (read_structure_type): Call quirk_gcc_member_function_pointer later. * gdbtypes.h (smash_to_methodptr_type): Declare. * gdbtypes.c (smash_to_methodptr_type): New function. (lookup_methodptr_type): Use it. gdb/testsuite 2010-01-22 Jan Kratochvil <jan.kratochvil@redhat.com> PR symtab/11199: * gdb.dwarf2/member-ptr-forwardref.exp, gdb.dwarf2/member-ptr-forwardref.S: New.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r--gdb/dwarf2read.c64
1 files changed, 21 insertions, 43 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 15ef3e9..8088830 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -4892,68 +4892,48 @@ is_vtable_name (const char *name, struct dwarf2_cu *cu)
}
/* GCC outputs unnamed structures that are really pointers to member
- functions, with the ABI-specified layout. If DIE (from CU) describes
- such a structure, set its type, and return nonzero. Otherwise return
- zero.
+ functions, with the ABI-specified layout. If TYPE describes
+ such a structure, smash it into a member function type.
GCC shouldn't do this; it should just output pointer to member DIEs.
This is GCC PR debug/28767. */
-static struct type *
-quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
+static void
+quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
{
- struct objfile *objfile = cu->objfile;
- struct type *type;
- struct die_info *pfn_die, *delta_die;
- struct attribute *pfn_name, *delta_name;
- struct type *pfn_type, *domain_type;
+ struct type *pfn_type, *domain_type, *new_type;
/* Check for a structure with no name and two children. */
- if (die->tag != DW_TAG_structure_type
- || dwarf2_attr (die, DW_AT_name, cu) != NULL
- || die->child == NULL
- || die->child->sibling == NULL
- || (die->child->sibling->sibling != NULL
- && die->child->sibling->sibling->tag != DW_TAG_padding))
- return NULL;
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
+ return;
/* Check for __pfn and __delta members. */
- pfn_die = die->child;
- pfn_name = dwarf2_attr (pfn_die, DW_AT_name, cu);
- if (pfn_die->tag != DW_TAG_member
- || pfn_name == NULL
- || DW_STRING (pfn_name) == NULL
- || strcmp ("__pfn", DW_STRING (pfn_name)) != 0)
- return NULL;
-
- delta_die = pfn_die->sibling;
- delta_name = dwarf2_attr (delta_die, DW_AT_name, cu);
- if (delta_die->tag != DW_TAG_member
- || delta_name == NULL
- || DW_STRING (delta_name) == NULL
- || strcmp ("__delta", DW_STRING (delta_name)) != 0)
- return NULL;
+ if (TYPE_FIELD_NAME (type, 0) == NULL
+ || strcmp (TYPE_FIELD_NAME (type, 0), "__pfn") != 0
+ || TYPE_FIELD_NAME (type, 1) == NULL
+ || strcmp (TYPE_FIELD_NAME (type, 1), "__delta") != 0)
+ return;
/* Find the type of the method. */
- pfn_type = die_type (pfn_die, cu);
+ pfn_type = TYPE_FIELD_TYPE (type, 0);
if (pfn_type == NULL
|| TYPE_CODE (pfn_type) != TYPE_CODE_PTR
|| TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
- return NULL;
+ return;
/* Look for the "this" argument. */
pfn_type = TYPE_TARGET_TYPE (pfn_type);
if (TYPE_NFIELDS (pfn_type) == 0
+ /* || TYPE_FIELD_TYPE (pfn_type, 0) == NULL */
|| TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
- return NULL;
+ return;
domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
- type = alloc_type (objfile);
- smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type),
+ new_type = alloc_type (objfile);
+ smash_to_method_type (new_type, domain_type, TYPE_TARGET_TYPE (pfn_type),
TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
TYPE_VARARGS (pfn_type));
- type = lookup_methodptr_type (type);
- return set_die_type (die, type, cu);
+ smash_to_methodptr_type (type, new_type);
}
/* Called when we find the DIE that starts a structure or union scope
@@ -4981,10 +4961,6 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
char *name;
struct cleanup *back_to = make_cleanup (null_cleanup, 0);
- type = quirk_gcc_member_function_pointer (die, cu);
- if (type)
- return type;
-
/* If the definition of this type lives in .debug_types, read that type.
Don't follow DW_AT_specification though, that will take us back up
the chain and we want to go down. */
@@ -5163,6 +5139,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
}
}
+ quirk_gcc_member_function_pointer (type, cu->objfile);
+
do_cleanups (back_to);
return type;
}