diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 16 | ||||
-rw-r--r-- | gdb/c-exp.y | 4 | ||||
-rw-r--r-- | gdb/cp-namespace.c | 8 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 16 | ||||
-rw-r--r-- | gdb/gdbtypes.c | 26 | ||||
-rw-r--r-- | gdb/gdbtypes.h | 2 | ||||
-rw-r--r-- | gdb/valops.c | 10 | ||||
-rw-r--r-- | gdb/value.h | 2 |
8 files changed, 75 insertions, 9 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b92b762..02689af 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ 2011-05-06 Jan Kratochvil <jan.kratochvil@redhat.com> + * c-exp.y (qualified_name): Call destructor_name_p with $1.type. + (classify_inner_name): Call cp_lookup_nested_type with + yylval.tsym.type. + * cp-namespace.c (cp_lookup_nested_type): New variable + saved_parent_type. Call CHECK_TYPEDEF for parent_type. Call + type_name_no_tag_or_error with saved_parent_type. + * dwarf2read.c (load_partial_dies): Read in any children of + DW_TAG_typedef with complaint in such case. + * gdbtypes.c (type_name_no_tag_or_error): New function. + * gdbtypes.h (type_name_no_tag_or_error): New prototype. + * valops.c (destructor_name_p): New comment for parameter type. Remove + type const. Make dname and cp const. Call type_name_no_tag_or_error. + * value.h (destructor_name_p): Remove type const. + +2011-05-06 Jan Kratochvil <jan.kratochvil@redhat.com> + * symtab.c (compare_symbol_name): New function. (completion_list_add_name, expand_partial_symbol_name): Call it, remove the variable ncmp. diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 3a02e9d..94d0737 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -804,7 +804,7 @@ qualified_name: TYPENAME COLONCOLON name tmp_token.ptr[tmp_token.length] = 0; /* Check for valid destructor name. */ - destructor_name_p (tmp_token.ptr, type); + destructor_name_p (tmp_token.ptr, $1.type); write_exp_elt_opcode (OP_SCOPE); write_exp_elt_type (type); write_exp_string (tmp_token); @@ -2486,7 +2486,7 @@ classify_inner_name (struct block *block, int first_name) return NAME; copy = copy_name (yylval.tsym.stoken); - new_type = cp_lookup_nested_type (type, copy, block); + new_type = cp_lookup_nested_type (yylval.tsym.type, copy, block); if (new_type == NULL) /* We know the caller won't expect us to update yylval. */ diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index 030cfb9..00c68b3 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -630,6 +630,12 @@ cp_lookup_nested_type (struct type *parent_type, const char *nested_name, const struct block *block) { + /* type_name_no_tag_required provides better error reporting using the + original type. */ + struct type *saved_parent_type = parent_type; + + CHECK_TYPEDEF (parent_type); + switch (TYPE_CODE (parent_type)) { case TYPE_CODE_STRUCT: @@ -643,7 +649,7 @@ cp_lookup_nested_type (struct type *parent_type, just like members of namespaces; in particular, lookup_symbol_namespace works when looking them up. */ - const char *parent_name = TYPE_TAG_NAME (parent_type); + const char *parent_name = type_name_no_tag_or_error (saved_parent_type); struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name, nested_name, block, VAR_DOMAIN); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index fdab83d..eb5d924 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -8946,7 +8946,7 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, if (parent_die == NULL && part_die->has_specification == 0 && part_die->is_declaration == 0 - && (part_die->tag == DW_TAG_typedef + && ((part_die->tag == DW_TAG_typedef && !part_die->has_children) || part_die->tag == DW_TAG_base_type || part_die->tag == DW_TAG_subrange_type)) { @@ -8959,6 +8959,20 @@ load_partial_dies (bfd *abfd, gdb_byte *buffer, gdb_byte *info_ptr, continue; } + /* The exception for DW_TAG_typedef with has_children above is + a workaround of GCC PR debug/47510. In the case of this complaint + type_name_no_tag_or_error will error on such types later. + + GDB skipped children of DW_TAG_typedef by the shortcut above and then + it could not find the child DIEs referenced later, this is checked + above. In correct DWARF DW_TAG_typedef should have no children. */ + + if (part_die->tag == DW_TAG_typedef && part_die->has_children) + complaint (&symfile_complaints, + _("DW_TAG_typedef has childen - GCC PR debug/47510 bug " + "- DIE at 0x%x [in module %s]"), + part_die->offset, cu->objfile->name); + /* If we're at the second level, and we're an enumerator, and our parent has no specification (meaning possibly lives in a namespace elsewhere), then we can add the partial symbol now diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 3b45931..2bdb4eb 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1105,6 +1105,32 @@ type_name_no_tag (const struct type *type) return TYPE_NAME (type); } +/* A wrapper of type_name_no_tag which calls error if the type is anonymous. + Since GCC PR debug/47510 DWARF provides associated information to detect the + anonymous class linkage name from its typedef. + + Parameter TYPE should not yet have CHECK_TYPEDEF applied, this function will + apply it itself. */ + +const char * +type_name_no_tag_or_error (struct type *type) +{ + struct type *saved_type = type; + const char *name; + struct objfile *objfile; + + CHECK_TYPEDEF (type); + + name = type_name_no_tag (type); + if (name != NULL) + return name; + + name = type_name_no_tag (saved_type); + objfile = TYPE_OBJFILE (saved_type); + error (_("Invalid anonymous type %s [in module %s], GCC PR debug/47510 bug?"), + name ? name : "<anonymous>", objfile ? objfile->name : "<arch>"); +} + /* Lookup a typedef or primitive type named NAME, visible in lexical block BLOCK. If NOERR is nonzero, return zero if NAME is not suitably defined. */ diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 39ca1b4..5a588a2 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -1362,6 +1362,8 @@ extern struct type *allocate_stub_method (struct type *); extern char *type_name_no_tag (const struct type *); +extern const char *type_name_no_tag_or_error (struct type *type); + extern struct type *lookup_struct_elt_type (struct type *, char *, int); extern struct type *make_pointer_type (struct type *, struct type **); diff --git a/gdb/valops.c b/gdb/valops.c index 99115b7..3676103 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -3098,14 +3098,16 @@ classify_oload_match (struct badness_vector *oload_champ_bv, /* C++: return 1 is NAME is a legitimate name for the destructor of type TYPE. If TYPE does not have a destructor, or if NAME is - inappropriate for TYPE, an error is signaled. */ + inappropriate for TYPE, an error is signaled. Parameter TYPE should not yet + have CHECK_TYPEDEF applied, this function will apply it itself. */ + int -destructor_name_p (const char *name, const struct type *type) +destructor_name_p (const char *name, struct type *type) { if (name[0] == '~') { - char *dname = type_name_no_tag (type); - char *cp = strchr (dname, '<'); + const char *dname = type_name_no_tag_or_error (type); + const char *cp = strchr (dname, '<'); unsigned int len; /* Do not compare the template part for template classes. */ diff --git a/gdb/value.h b/gdb/value.h index 0889cef..4c42633 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -736,7 +736,7 @@ extern int binop_user_defined_p (enum exp_opcode op, struct value *arg1, extern int unop_user_defined_p (enum exp_opcode op, struct value *arg1); -extern int destructor_name_p (const char *name, const struct type *type); +extern int destructor_name_p (const char *name, struct type *type); extern void value_incref (struct value *val); |