mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
gdb/
* 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.
This commit is contained in:
parent
1976171a47
commit
d8228535f5
@ -1,3 +1,19 @@
|
||||
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.
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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 **);
|
||||
|
10
gdb/valops.c
10
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. */
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user