From: Keith Seitz Date: Tue, 11 Apr 2017 21:00:46 +0000 (-0700) Subject: Support anonymous types with external linkage. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8a09f3176f68934292829175ba7d612641519c71;p=thirdparty%2Fbinutils-gdb.git Support anonymous types with external linkage. This removes the "use the linkage name" hack (type_name_no_tag_or_error). --- diff --git a/gdb/c-exp.y b/gdb/c-exp.y index e89a600ed15..31c1288233e 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -958,8 +958,6 @@ qualified_name: TYPENAME COLONCOLON name memcpy (buf+1, $4.ptr, $4.length); buf[tmp_token.length] = 0; - /* Check for valid destructor name. */ - destructor_name_p (tmp_token.ptr, $1.type); write_exp_elt_opcode (pstate, OP_SCOPE); write_exp_elt_type (pstate, type); write_exp_string (pstate, tmp_token); diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index ca0ab4730e3..a2fe552b097 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -301,6 +301,9 @@ cp_lookup_symbol_in_namespace (const char *the_namespace, const char *name, unsigned int prefix_len; struct block_symbol sym; + if (the_namespace == NULL) + return cp_lookup_bare_symbol (NULL, name, block, domain, search); + if (the_namespace[0] != '\0') { concatenated_name @@ -927,8 +930,6 @@ cp_lookup_nested_symbol (struct type *parent_type, const struct block *block, const domain_enum domain) { - /* type_name_no_tag_or_error provides better error reporting using the - original type. */ struct type *saved_parent_type = parent_type; parent_type = check_typedef (parent_type); @@ -956,16 +957,20 @@ cp_lookup_nested_symbol (struct type *parent_type, case TYPE_CODE_MODULE: { int size; - const char *parent_name = type_name_no_tag_or_error (saved_parent_type); + const char *parent_name = TYPE_TAG_NAME (saved_parent_type); struct block_symbol sym; char *concatenated_name; int is_in_anonymous; - size = strlen (parent_name) + 2 + strlen (nested_name) + 1; + size = (parent_name == NULL ? CP_ANONYMOUS_NAMESPACE_LEN + : strlen (parent_name)) + 2 + strlen (nested_name) + 1; concatenated_name = (char *) alloca (size); xsnprintf (concatenated_name, size, "%s::%s", - parent_name, nested_name); - is_in_anonymous = cp_is_in_anonymous (concatenated_name); + (parent_name == NULL + ? CP_ANONYMOUS_NAMESPACE_STR : parent_name) + , nested_name); + is_in_anonymous = (parent_name == NULL + ? 1 :cp_is_in_anonymous (concatenated_name)); sym = cp_lookup_nested_symbol_1 (parent_type, nested_name, concatenated_name, block, domain, diff --git a/gdb/d-namespace.c b/gdb/d-namespace.c index ae2e7e38130..edcf2019658 100644 --- a/gdb/d-namespace.c +++ b/gdb/d-namespace.c @@ -325,8 +325,7 @@ d_lookup_nested_symbol (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. */ + /* We report more useful errors using the original type. */ struct type *saved_parent_type = parent_type; parent_type = check_typedef (parent_type); @@ -339,7 +338,7 @@ d_lookup_nested_symbol (struct type *parent_type, case TYPE_CODE_MODULE: { int size; - const char *parent_name = type_name_no_tag_or_error (saved_parent_type); + const char *parent_name = TYPE_TAG_NAME (saved_parent_type); struct block_symbol sym = d_lookup_symbol_in_module (parent_name, nested_name, block, VAR_DOMAIN, 0); diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 4cc571922af..cbe33b58a7f 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -16370,8 +16370,7 @@ load_partial_dies (const struct die_reader_specs *reader, } /* 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. + a workaround of GCC PR debug/47510. 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 @@ -16912,38 +16911,6 @@ fixup_partial_die (struct partial_die_info *part_die, || part_die->tag == DW_TAG_union_type)) guess_partial_die_structure_name (part_die, cu); - /* GCC might emit a nameless struct or union that has a linkage - name. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */ - if (part_die->name == NULL - && (part_die->tag == DW_TAG_class_type - || part_die->tag == DW_TAG_interface_type - || part_die->tag == DW_TAG_structure_type - || part_die->tag == DW_TAG_union_type) - && part_die->linkage_name != NULL) - { - char *demangled; - - demangled = gdb_demangle (part_die->linkage_name, DMGL_TYPES); - if (demangled) - { - const char *base; - - /* Strip any leading namespaces/classes, keep only the base name. - DW_AT_name for named DIEs does not contain the prefixes. */ - base = strrchr (demangled, ':'); - if (base && base > demangled && base[-1] == ':') - base++; - else - base = demangled; - - part_die->name - = ((const char *) - obstack_copy0 (&cu->objfile->per_bfd->storage_obstack, - base, strlen (base))); - xfree (demangled); - } - } - part_die->fixup_called = 1; } @@ -20182,42 +20149,6 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu) return NULL; } -/* GCC might emit a nameless typedef that has a linkage name. Determine the - prefix part in such case. See - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */ - -static char * -anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu) -{ - struct attribute *attr; - const char *base; - - if (die->tag != DW_TAG_class_type && die->tag != DW_TAG_interface_type - && die->tag != DW_TAG_structure_type && die->tag != DW_TAG_union_type) - return NULL; - - if (dwarf2_string_attr (die, DW_AT_name, cu) != NULL) - return NULL; - - attr = dwarf2_attr (die, DW_AT_linkage_name, cu); - if (attr == NULL) - attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); - if (attr == NULL || DW_STRING (attr) == NULL) - return NULL; - - /* dwarf2_name had to be already called. */ - gdb_assert (DW_STRING_IS_CANONICAL (attr)); - - /* Strip the base name, keep any leading namespaces/classes. */ - base = strrchr (DW_STRING (attr), ':'); - if (base == NULL || base == DW_STRING (attr) || base[-1] != ':') - return ""; - - return (char *) obstack_copy0 (&cu->objfile->per_bfd->storage_obstack, - DW_STRING (attr), - &base[-1] - DW_STRING (attr)); -} - /* Return the name of the namespace/class that DIE is defined within, or "" if we can't tell. The caller should not xfree the result. @@ -20239,17 +20170,12 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu) struct die_info *parent, *spec_die; struct dwarf2_cu *spec_cu; struct type *parent_type; - char *retval; if (cu->language != language_cplus && cu->language != language_fortran && cu->language != language_d && cu->language != language_rust) return ""; - retval = anonymous_struct_prefix (die, cu); - if (retval) - return retval; - /* We have to be careful in the presence of DW_AT_specification. For example, with GCC 3.4, given the code @@ -20485,10 +20411,10 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu) attr = dwarf2_attr (die, DW_AT_name, cu); if ((!attr || !DW_STRING (attr)) && die->tag != DW_TAG_namespace - && die->tag != DW_TAG_class_type + /* && die->tag != DW_TAG_class_type && die->tag != DW_TAG_interface_type && die->tag != DW_TAG_structure_type - && die->tag != DW_TAG_union_type) + && die->tag != DW_TAG_union_type*/) return NULL; switch (die->tag) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 5e5db2776b1..fd45a13a542 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1384,33 +1384,6 @@ 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; - - type = 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 : "", - objfile ? objfile_name (objfile) : ""); -} - /* 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 1064f0ae1b0..44a6bc8a6bd 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -1834,8 +1834,6 @@ extern struct type *allocate_stub_method (struct type *); extern const 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 *, const char *, int); extern struct type *make_pointer_type (struct type *, struct type **); diff --git a/gdb/testsuite/gdb.cp/anon-struct.exp b/gdb/testsuite/gdb.cp/anon-struct.exp index e6a438aa622..f8303fbddd5 100644 --- a/gdb/testsuite/gdb.cp/anon-struct.exp +++ b/gdb/testsuite/gdb.cp/anon-struct.exp @@ -28,11 +28,11 @@ if { [is_aarch32_target] } { "print type of t::t" } -gdb_test "ptype X::t2" "type = struct X::t2 {\[\r\n \]*X::C2 m;\[\r\n \]*}" \ +gdb_test "ptype X::t2" "type = struct {\[\r\n \]*X::C2 m;\[\r\n \]*}" \ "print type of X::t2" if { [is_aarch32_target] } { - gdb_test "ptype X::t2::t2" "type = struct X::t2 {\r\n X::C2 m;\r\n} \\*\\(X::t2 \\* const\\)" \ + gdb_test "ptype X::t2::t2" "type = struct {\r\n X::C2 m;\r\n} \\*\\(X::t2 \\* const\\)" \ "print type of X::t2::t2" gdb_test "ptype t3::~t3" "type = void \\*\\(t3 \\* const\\)" \ "print type of t3::~t3" diff --git a/gdb/valops.c b/gdb/valops.c index fcd3cfbfca1..f51637b9f4d 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -3169,33 +3169,6 @@ classify_oload_match (struct badness_vector *oload_champ_bv, return worst; } -/* 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. Parameter TYPE should not yet - have CHECK_TYPEDEF applied, this function will apply it itself. */ - -int -destructor_name_p (const char *name, struct type *type) -{ - if (name[0] == '~') - { - 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. */ - if (cp == NULL) - len = strlen (dname); - else - len = cp - dname; - if (strlen (name + 1) != len || strncmp (dname, name + 1, len) != 0) - error (_("name of destructor must equal name of class")); - else - return 1; - } - return 0; -} - /* Find an enum constant named NAME in TYPE. TYPE must be an "enum class". If the name is found, return a value representing it; otherwise throw an exception. */ diff --git a/gdb/value.h b/gdb/value.h index c57ea7979e0..dc8376f2422 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1012,8 +1012,6 @@ 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, struct type *type); - extern void value_incref (struct value *val); extern void value_free (struct value *val);