Index: c-typeprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-typeprint.c,v retrieving revision 1.50 diff -u -p -r1.50 c-typeprint.c --- c-typeprint.c 1 Jan 2010 07:31:30 -0000 1.50 +++ c-typeprint.c 28 Jan 2010 23:05:37 -0000 @@ -32,6 +32,7 @@ #include "c-lang.h" #include "typeprint.h" #include "cp-abi.h" +#include "jv-lang.h" #include "gdb_string.h" #include @@ -40,8 +41,6 @@ static void cp_type_print_method_args (s char *varstring, int staticp, struct ui_file *stream); -static void c_type_print_args (struct type *, struct ui_file *); - static void cp_type_print_derivation_info (struct ui_file *, struct type *); static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int, @@ -197,6 +196,23 @@ cp_type_print_method_args (struct type * fprintf_filtered (stream, "void"); fprintf_filtered (stream, ")"); + + /* For non-static methods, read qualifiers from the type of + THIS. */ + if (!staticp) + { + struct type *domain; + + gdb_assert (nargs > 0); + gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR); + domain = TYPE_TARGET_TYPE (args[0].type); + + if (TYPE_CONST (domain)) + fprintf_filtered (stream, " const"); + + if (TYPE_VOLATILE (domain)) + fprintf_filtered (stream, " volatile"); + } } @@ -353,10 +369,14 @@ c_type_print_modifier (struct type *type /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD or TYPE_CODE_FUNC, to STREAM. Artificial arguments, such as "this" - in non-static methods, are displayed. */ + in non-static methods, are displayed if SHOW_ARTIFICIAL is + non-zero. LANGUAGE is the language in which TYPE was defined. This is + a necessary evil since this code is used by the C, C++, and Java + backends. */ -static void -c_type_print_args (struct type *type, struct ui_file *stream) +void +c_type_print_args (struct type *type, struct ui_file *stream, + int show_artificial, enum language language) { int i, len; struct field *args; @@ -368,13 +388,19 @@ c_type_print_args (struct type *type, st for (i = 0; i < TYPE_NFIELDS (type); i++) { + if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial) + continue; + if (printed_any) { fprintf_filtered (stream, ", "); wrap_here (" "); } - c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); + if (language == language_java) + java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); + else + c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); printed_any = 1; } @@ -591,7 +617,7 @@ c_type_print_varspec_suffix (struct type if (passed_a_ptr) fprintf_filtered (stream, ")"); if (!demangled_args) - c_type_print_args (type, stream); + c_type_print_args (type, stream, 1, language_c); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.352 diff -u -p -r1.352 dwarf2read.c --- dwarf2read.c 26 Jan 2010 15:48:25 -0000 1.352 +++ dwarf2read.c 28 Jan 2010 23:05:43 -0000 @@ -48,6 +48,9 @@ #include "gdbcmd.h" #include "block.h" #include "addrmap.h" +#include "typeprint.h" +#include "jv-lang.h" +#include "vec.h" #include #include "gdb_string.h" @@ -487,8 +490,7 @@ struct partial_die_info unsigned int has_byte_size : 1; /* The name of this DIE. Normally the value of DW_AT_name, but - sometimes DW_TAG_MIPS_linkage_name or a string computed in some - other fashion. */ + sometimes a default name for unnamed DIEs. */ char *name; /* The scope to prepend to our children. This is generally @@ -677,6 +679,11 @@ struct field_info int nfnfields; }; +/* A vector used during linkage name generation. */ +typedef struct die_info *die_info_p; +DEF_VEC_P (die_info_p); +static VEC(die_info_p) *die_list; + /* One item on the queue of compilation units to read in full symbols for. */ struct dwarf2_queue_item @@ -788,7 +795,7 @@ static void scan_partial_symbols (struct static void add_partial_symbol (struct partial_die_info *, struct dwarf2_cu *); -static int pdi_needs_namespace (enum dwarf_tag tag); +static int die_needs_namespace (struct die_info *, struct dwarf2_cu *); static void add_partial_namespace (struct partial_die_info *pdi, CORE_ADDR *lowpc, CORE_ADDR *highpc, @@ -940,6 +947,11 @@ static struct type *tag_type_to_type (st static struct type *read_type_die (struct die_info *, struct dwarf2_cu *); +static char *physname_prefix (struct die_info *die, struct dwarf2_cu *); + +static void physname_prefix_1 (struct ui_file *, struct die_info *, + struct dwarf2_cu *); + static char *determine_prefix (struct die_info *die, struct dwarf2_cu *); static char *typename_concat (struct obstack *, @@ -984,9 +996,6 @@ static void dwarf2_attach_fn_fields_to_t static void process_structure_scope (struct die_info *, struct dwarf2_cu *); -static const char *determine_class_name (struct die_info *die, - struct dwarf2_cu *cu); - static void read_common_block (struct die_info *, struct dwarf2_cu *); static void read_namespace (struct die_info *die, struct dwarf2_cu *); @@ -1028,7 +1037,7 @@ static gdb_byte *read_full_die (const st static void process_die (struct die_info *, struct dwarf2_cu *); -static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *); +static char *dwarf2_physname (struct die_info *, struct dwarf2_cu *); static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *, struct obstack *); @@ -2441,12 +2450,9 @@ add_partial_symbol (struct partial_die_i baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (pdi_needs_namespace (pdi->tag)) - { - actual_name = partial_die_full_name (pdi, cu); - if (actual_name) - built_actual_name = 1; - } + actual_name = partial_die_full_name (pdi, cu); + if (actual_name) + built_actual_name = 1; if (actual_name == NULL) actual_name = pdi->name; @@ -2586,34 +2592,17 @@ add_partial_symbol (struct partial_die_i break; } - /* Check to see if we should scan the name for possible namespace - info. Only do this if this is C++, if we don't have namespace - debugging info in the file, if the psym is of an appropriate type - (otherwise we'll have psym == NULL), and if we actually had a - mangled name to begin with. */ - - /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the - cases which do not set PSYM above? */ - - if (cu->language == language_cplus - && cu->has_namespace_info == 0 - && psym != NULL - && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL) - cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym), - objfile); - if (built_actual_name) xfree (actual_name); } -/* Determine whether a die of type TAG living in a C++ class or - namespace needs to have the name of the scope prepended to the - name listed in the die. */ +/* Determine whether DIE needs to have the name of the scope prepended + to the name listed in the die. */ static int -pdi_needs_namespace (enum dwarf_tag tag) +die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu) { - switch (tag) + switch (die->tag) { case DW_TAG_namespace: case DW_TAG_typedef: @@ -2623,7 +2612,23 @@ pdi_needs_namespace (enum dwarf_tag tag) case DW_TAG_union_type: case DW_TAG_enumeration_type: case DW_TAG_enumerator: + case DW_TAG_subprogram: + case DW_TAG_member: return 1; + + case DW_TAG_variable: + { + struct attribute *attr; + attr = dwarf2_attr (die, DW_AT_specification, cu); + if (attr) + return 1; + attr = dwarf2_attr (die, DW_AT_external, cu); + if (attr == NULL && die->parent->tag != DW_TAG_namespace) + return 0; + return 1; + } + break; + default: return 0; } @@ -2752,27 +2757,6 @@ guess_structure_name (struct partial_die if (real_pdi->die_parent != NULL) return; - - while (child_pdi != NULL) - { - if (child_pdi->tag == DW_TAG_subprogram) - { - char *actual_class_name - = language_class_name_from_physname (cu->language_defn, - child_pdi->name); - if (actual_class_name != NULL) - { - struct_pdi->name - = obsavestring (actual_class_name, - strlen (actual_class_name), - &cu->comp_unit_obstack); - xfree (actual_class_name); - } - break; - } - - child_pdi = child_pdi->die_sibling; - } } } @@ -3340,37 +3324,52 @@ process_die (struct die_info *die, struc /* Return the fully qualified name of DIE, based on its DW_AT_name. If scope qualifiers are appropriate they will be added. The result will be allocated on the objfile_obstack, or NULL if the DIE does - not have a name. */ + not have a name. + + The output string will be canonicalized (if C++/Java). */ static const char * dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu) { - struct attribute *attr; - char *prefix, *name; - struct ui_file *buf = NULL; + char *name; name = dwarf2_name (die, cu); - if (!name) - return NULL; /* These are the only languages we know how to qualify names in. */ - if (cu->language != language_cplus - && cu->language != language_java) - return name; + if (name != NULL + && (cu->language == language_cplus || cu->language == language_java)) + { + if (die_needs_namespace (die, cu)) + { + long length; + char *prefix; + struct ui_file *buf; + + buf = mem_fileopen (); + prefix = determine_prefix (die, cu); + if (*prefix != '\0') + { + char *prefixed_name = typename_concat (NULL, prefix, name, cu); + fputs_unfiltered (prefixed_name, buf); + xfree (prefixed_name); + } + else + fputs_unfiltered (name, buf); - /* If no prefix is necessary for this type of DIE, return the - unqualified name. The other three tags listed could be handled - in pdi_needs_namespace, but that requires broader changes. */ - if (!pdi_needs_namespace (die->tag) - && die->tag != DW_TAG_subprogram - && die->tag != DW_TAG_variable - && die->tag != DW_TAG_member) - return name; + name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, + &length); + ui_file_delete (buf); - prefix = determine_prefix (die, cu); - if (*prefix != '\0') - name = typename_concat (&cu->objfile->objfile_obstack, prefix, - name, cu); + if (cu->language == language_cplus) + { + char *cname + = dwarf2_canonicalize_name (name, cu, + &cu->objfile->objfile_obstack); + if (cname != NULL) + name = cname; + } + } + } return name; } @@ -3843,7 +3842,7 @@ read_func_scope (struct die_info *die, s baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - name = dwarf2_linkage_name (die, cu); + name = dwarf2_name (die, cu); /* Ignore functions with missing or empty names and functions with missing or invalid low and high pc attributes. */ @@ -4517,7 +4516,7 @@ dwarf2_add_field (struct field_info *fip return; /* Get physical name. */ - physname = dwarf2_linkage_name (die, cu); + physname = dwarf2_physname (die, cu); /* The name is already allocated along with this objfile, so we don't need to duplicate it for the type. */ @@ -4679,7 +4678,7 @@ dwarf2_add_member_fn (struct field_info return; /* Get the mangled name. */ - physname = dwarf2_linkage_name (die, cu); + physname = dwarf2_physname (die, cu); /* Look up member function name in fieldlist. */ for (i = 0; i < fip->nfnfields; i++) @@ -4986,14 +4985,18 @@ read_structure_type (struct die_info *di if (cu->language == language_cplus || cu->language == language_java) { - const char *new_prefix = determine_class_name (die, cu); - TYPE_TAG_NAME (type) = (char *) new_prefix; + TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (die, cu); + if (die->tag == DW_TAG_structure_type + || die->tag == DW_TAG_class_type) + TYPE_NAME (type) = TYPE_TAG_NAME (type); } else { /* The name is already allocated along with this objfile, so we don't need to duplicate it for the type. */ - TYPE_TAG_NAME (type) = name; + TYPE_TAG_NAME (type) = (char *) name; + if (die->tag == DW_TAG_class_type) + TYPE_NAME (type) = TYPE_TAG_NAME (type); } } @@ -5236,51 +5239,6 @@ read_enumeration_type (struct die_info * return set_die_type (die, type, cu); } -/* Determine the name of the type represented by DIE, which should be - a named C++ or Java compound type. Return the name in question, - allocated on the objfile obstack. */ - -static const char * -determine_class_name (struct die_info *die, struct dwarf2_cu *cu) -{ - const char *new_prefix = NULL; - - /* If we don't have namespace debug info, guess the name by trying - to demangle the names of members, just like we did in - guess_structure_name. */ - if (!processing_has_namespace_info) - { - struct die_info *child; - - for (child = die->child; - child != NULL && child->tag != 0; - child = sibling_die (child)) - { - if (child->tag == DW_TAG_subprogram) - { - char *phys_prefix - = language_class_name_from_physname (cu->language_defn, - dwarf2_linkage_name - (child, cu)); - - if (phys_prefix != NULL) - { - new_prefix - = obsavestring (phys_prefix, strlen (phys_prefix), - &cu->objfile->objfile_obstack); - xfree (phys_prefix); - break; - } - } - } - } - - if (new_prefix == NULL) - new_prefix = dwarf2_full_name (die, cu); - - return new_prefix; -} - /* Given a pointer to a die which begins an enumeration, process all the dies that define the members of the enumeration, and create the symbol for the enumeration type. @@ -6764,7 +6722,8 @@ read_partial_die (struct partial_die_inf } break; case DW_AT_MIPS_linkage_name: - part_die->name = DW_STRING (&attr); + if (cu->language == language_ada) + part_die->name = DW_STRING (&attr); break; case DW_AT_low_pc: has_low_pc_attr = 1; @@ -8329,13 +8288,11 @@ new_symbol (struct die_info *die, struct baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)); - if (die->tag != DW_TAG_namespace) - name = dwarf2_linkage_name (die, cu); - else - name = TYPE_NAME (type); - + name = dwarf2_name (die, cu); if (name) { + const char *linkagename; + sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol)); OBJSTAT (objfile, n_syms++); @@ -8343,7 +8300,8 @@ new_symbol (struct die_info *die, struct /* Cache this symbol's name and the name's demangled form (if any). */ SYMBOL_LANGUAGE (sym) = cu->language; - SYMBOL_SET_NAMES (sym, name, strlen (name), 0, objfile); + linkagename = dwarf2_physname (die, cu); + SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile); /* Default assumptions. Use the passed type or decode it from the die. */ @@ -8617,8 +8575,7 @@ new_symbol (struct die_info *die, struct /* For the benefit of old versions of GCC, check for anonymous namespaces based on the demangled name. */ if (!processing_has_namespace_info - && cu->language == language_cplus - && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL) + && cu->language == language_cplus) cp_scan_for_anonymous_namespaces (sym); } return (sym); @@ -9021,6 +8978,96 @@ determine_prefix (struct die_info *die, } } +/* Determines the prefix for a symbol's physname. Unlike determine_prefix, + this method does not simply look at the DIE's immediate parent. + It will compute the symbol's physname by scanning through all parent + DIEs until it gets to the compilation unit's DIE. */ + +static char * +physname_prefix (struct die_info *die, struct dwarf2_cu *cu) +{ + long length; + struct ui_file *buf; + struct die_info *d, *spec_die; + struct dwarf2_cu *spec_cu; + char *name; + + /* Construct a stack containing all of the DIE's parents. Caution + must be observed for dealing with DW_AT_specification. */ + spec_cu = cu; + spec_die = die_specification (die, &spec_cu); + if (spec_die != NULL) + d = spec_die->parent; + else + d = die->parent; + while (d != NULL && d->tag != DW_TAG_compile_unit) + { + struct attribute *attr; + + spec_die = die_specification (d, &spec_cu); + if (spec_die != NULL) + d = spec_die; + + VEC_quick_push (die_info_p, die_list, d); + d = d->parent; + } + + /* Now pop all the elements, printing their names as we go. */ + buf = mem_fileopen (); + while (!VEC_empty (die_info_p, die_list)) + { + d = VEC_pop (die_info_p, die_list); + physname_prefix_1 (buf, d, cu); + + if (!VEC_empty (die_info_p, die_list)) + { + if (cu->language == language_cplus) + fputs_unfiltered ("::", buf); + else + fputs_unfiltered (".", buf); + } + } + + name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, &length); + ui_file_delete (buf); + return name; +} + +static void +physname_prefix_1 (struct ui_file *buf, struct die_info *die, + struct dwarf2_cu *cu) +{ + const char *name = NULL; + gdb_assert (buf != NULL); + + if (die != NULL) + { + switch (die->tag) + { + case DW_TAG_namespace: + name = dwarf2_name (die, cu); + if (name == NULL) + name = "(anonymous namespace)"; + break; + + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + case DW_TAG_interface_type: + case DW_TAG_subprogram: + name = dwarf2_name (die, cu); + break; + + default: + break; + } + } + + if (name != NULL) + fputs_unfiltered (name, buf); +} + /* Return a newly-allocated string formed by concatenating PREFIX and SUFFIX with appropriate separator. If PREFIX or SUFFIX is NULL or empty, then simply copy the SUFFIX or PREFIX, respectively. If OBS is non-null, @@ -9070,17 +9117,78 @@ sibling_die (struct die_info *die) return die->sibling; } -/* Get linkage name of a die, return NULL if not found. */ +/* Construct a physname for the given DIE in CU. */ static char * -dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu) +dwarf2_physname (struct die_info *die, struct dwarf2_cu *cu) { struct attribute *attr; + char *name; + + name = dwarf2_name (die, cu); + + /* These are the only languages we know how to qualify names in. */ + if (cu->language != language_cplus + && cu->language != language_java) + return name; + + if (die_needs_namespace (die, cu)) + { + long length; + char *prefix; + struct ui_file *buf; + + prefix = physname_prefix (die, cu); + buf = mem_fileopen (); + if (*prefix != '\0') + { + char *prefixed_name = typename_concat (NULL, prefix, name, cu); + fputs_unfiltered (prefixed_name, buf); + xfree (prefixed_name); + } + else + fputs_unfiltered (name ? name : "", buf); + + /* For Java and C++ methods, append formal parameter type + information. */ + if ((cu->language == language_cplus || cu->language == language_java) + && die->tag == DW_TAG_subprogram) + { + struct type *type = read_type_die (die, cu); - attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu); - if (attr && DW_STRING (attr)) - return DW_STRING (attr); - return dwarf2_name (die, cu); + c_type_print_args (type, buf, 0, cu->language); + + if (cu->language == language_java) + { + /* For java, we must append the return type to method names. */ + if (die->tag == DW_TAG_subprogram) + java_print_type (TYPE_TARGET_TYPE (type), "", buf, 0, 0); + } + else if (cu->language == language_cplus) + { + /* c_type_print_args adds argument types, but it does + not add any necessary "const". */ + if (TYPE_NFIELDS (type) > 0 && TYPE_FIELD_ARTIFICIAL (type, 0) + && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)))) + fputs_unfiltered (" const", buf); + } + } + + name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, + &length); + ui_file_delete (buf); + + if (cu->language == language_cplus) + { + char *cname + = dwarf2_canonicalize_name (name, cu, + &cu->objfile->objfile_obstack); + if (cname != NULL) + name = cname; + } + } + + return name; } /* Get name of a die, return NULL if not found. */ @@ -11977,6 +12085,7 @@ void _initialize_dwarf2_read (void); void _initialize_dwarf2_read (void) { + die_list = VEC_alloc (die_info_p, 32); dwarf2_objfile_data_key = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free); Index: gnu-v3-abi.c =================================================================== RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v retrieving revision 1.58 diff -u -p -r1.58 gnu-v3-abi.c --- gnu-v3-abi.c 1 Jan 2010 07:31:32 -0000 1.58 +++ gnu-v3-abi.c 28 Jan 2010 23:05:46 -0000 @@ -26,6 +26,7 @@ #include "demangle.h" #include "objfiles.h" #include "valprint.h" +#include "c-lang.h" #include "gdb_assert.h" #include "gdb_string.h" @@ -456,10 +457,8 @@ gnuv3_find_method_in (struct type *domai LONGEST adjustment) { int i; - const char *physname; /* Search this class first. */ - physname = NULL; if (adjustment == 0) { int len; @@ -587,15 +586,24 @@ gnuv3_print_method_ptr (const gdb_byte * { char *demangled_name = cplus_demangle (physname, DMGL_ANSI | DMGL_PARAMS); - if (demangled_name != NULL) + fprintf_filtered (stream, "&virtual "); + if (demangled_name == NULL) + fputs_filtered (physname, stream); + else { - fprintf_filtered (stream, "&virtual "); fputs_filtered (demangled_name, stream); xfree (demangled_name); - return; } + return; } } + else if (ptr_value != 0) + { + /* Found a non-virtual function: print out the type. */ + fputs_filtered ("(", stream); + c_print_type (type, "", stream, -1, 0); + fputs_filtered (") ", stream); + } /* We didn't find it; print the raw data. */ if (vbit) Index: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.224 diff -u -p -r1.224 symtab.c --- symtab.c 26 Jan 2010 15:48:25 -0000 1.224 +++ symtab.c 28 Jan 2010 23:05:50 -0000 @@ -498,7 +495,7 @@ symbol_find_demangled_name (struct gener || gsymbol->language == language_auto) { demangled = - cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); + cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE); if (demangled != NULL) { gsymbol->language = language_cplus; Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.146 diff -u -p -r1.146 symtab.h --- symtab.h 27 Jan 2010 00:15:59 -0000 1.146 +++ symtab.h 28 Jan 2010 23:05:53 -0000 @@ -172,9 +172,6 @@ extern CORE_ADDR symbol_overlayed_addres #define SYMBOL_SECTION(symbol) (symbol)->ginfo.section #define SYMBOL_OBJ_SECTION(symbol) (symbol)->ginfo.obj_section -#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol) \ - (symbol)->ginfo.language_specific.cplus_specific.demangled_name - /* Initializes the language dependent portion of a symbol depending upon the language for the symbol. */ #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \ @@ -994,7 +991,6 @@ extern struct symbol *lookup_symbol (con that can't think of anything better to do. */ extern struct symbol *basic_lookup_symbol_nonlocal (const char *, - const char *, const struct block *, const domain_enum); @@ -1005,7 +1001,6 @@ extern struct symbol *basic_lookup_symbo is one; do nothing if BLOCK is NULL or a global block. */ extern struct symbol *lookup_symbol_static (const char *name, - const char *linkage_name, const struct block *block, const domain_enum domain); @@ -1013,7 +1008,6 @@ extern struct symbol *lookup_symbol_stat necessary). */ extern struct symbol *lookup_symbol_global (const char *name, - const char *linkage_name, const struct block *block, const domain_enum domain); @@ -1022,21 +1016,18 @@ extern struct symbol *lookup_symbol_glob will fix up the symbol if necessary. */ extern struct symbol *lookup_symbol_aux_block (const char *name, - const char *linkage_name, const struct block *block, const domain_enum domain); /* Lookup a partial symbol. */ extern struct partial_symbol *lookup_partial_symbol (struct partial_symtab *, - const char *, const char *, int, domain_enum); /* lookup a symbol by name, within a specified block */ extern struct symbol *lookup_block_symbol (const struct block *, const char *, - const char *, const domain_enum); /* lookup a [struct, union, enum] by name, within a specified block */ @@ -1372,7 +1363,6 @@ extern /*const */ char *main_name (void) /* Check global symbols in objfile. */ struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile, const char *name, - const char *linkage_name, const domain_enum domain); extern struct symtabs_and_lines Index: typeprint.h =================================================================== RCS file: /cvs/src/src/gdb/typeprint.h,v retrieving revision 1.9 diff -u -p -r1.9 typeprint.h --- typeprint.h 1 Jan 2010 07:31:43 -0000 1.9 +++ typeprint.h 28 Jan 2010 23:05:56 -0000 @@ -20,10 +20,13 @@ #ifndef TYPEPRINT_H #define TYPEPRINT_H +enum language; struct ui_file; void print_type_scalar (struct type * type, LONGEST, struct ui_file *); void c_type_print_varspec_suffix (struct type *, struct ui_file *, int, int, int); + +void c_type_print_args (struct type *, struct ui_file *, int, enum language); #endif Index: ui-file.c =================================================================== RCS file: /cvs/src/src/gdb/ui-file.c,v retrieving revision 1.20 diff -u -p -r1.20 ui-file.c --- ui-file.c 1 Jan 2010 07:31:43 -0000 1.20 +++ ui-file.c 28 Jan 2010 23:06:00 -0000 @@ -22,6 +22,7 @@ #include "defs.h" #include "ui-file.h" +#include "gdb_obstack.h" #include "gdb_string.h" #include "gdb_select.h" @@ -264,7 +265,7 @@ set_ui_file_data (struct ui_file *file, } /* ui_file utility function for converting a ``struct ui_file'' into - a memory buffer''. */ + a memory buffer. */ struct accumulated_ui_file { @@ -298,6 +299,23 @@ ui_file_xstrdup (struct ui_file *file, l *length = acc.length; return acc.buffer; } + +static void +do_ui_file_obsavestring (void *context, const char *buffer, long length) +{ + struct obstack *obstack = (struct obstack *) context; + obstack_grow (obstack, buffer, length); +} + +char * +ui_file_obsavestring (struct ui_file *file, struct obstack *obstack, + long *length) +{ + ui_file_put (file, do_ui_file_obsavestring, obstack); + *length = obstack_object_size (obstack); + obstack_1grow (obstack, '\0'); + return obstack_finish (obstack); +} /* A pure memory based ``struct ui_file'' that can be used an output buffer. The buffers accumulated contents are available via Index: ui-file.h =================================================================== RCS file: /cvs/src/src/gdb/ui-file.h,v retrieving revision 1.11 diff -u -p -r1.11 ui-file.h --- ui-file.h 1 Jan 2010 07:31:43 -0000 1.11 +++ ui-file.h 28 Jan 2010 23:06:03 -0000 @@ -20,6 +20,7 @@ #ifndef UI_FILE_H #define UI_FILE_H +struct obstack; struct ui_file; /* Create a generic ui_file object with null methods. */ @@ -78,7 +79,10 @@ extern void ui_file_put (struct ui_file minus that appended NUL. */ extern char *ui_file_xstrdup (struct ui_file *file, long *length); - +/* Similar to ui_file_xstrdup, but return a new string allocated on + OBSTACK. */ +extern char *ui_file_obsavestring (struct ui_file *file, + struct obstack *obstack, long *length); extern long ui_file_read (struct ui_file *file, char *buf, long length_buf); Index: valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.233 diff -u -p -r1.233 valops.c --- valops.c 26 Jan 2010 16:47:34 -0000 1.233 +++ valops.c 28 Jan 2010 23:06:09 -0000 @@ -2328,12 +2328,25 @@ find_overload_match (struct type **arg_t if (method) { gdb_assert (obj); + + /* OBJ may be a pointer value rather than the object itself. */ + obj = coerce_ref (obj); + while (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_PTR) + obj = coerce_ref (value_ind (obj)); obj_type_name = TYPE_NAME (value_type (obj)); - /* Hack: evaluate_subexp_standard often passes in a pointer - value rather than the object itself, so try again. */ - if ((!obj_type_name || !*obj_type_name) - && (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR)) - obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj))); + + /* First check whether this is a data member, e.g. a pointer to + a function. */ + if (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_STRUCT) + { + *valp = search_struct_field (name, obj, 0, + check_typedef (value_type (obj)), 0); + if (*valp) + { + *staticp = 1; + return 0; + } + } fns_ptr = value_find_oload_method_list (&temp, name, 0, &num_fns, @@ -2353,16 +2366,29 @@ find_overload_match (struct type **arg_t } else { - const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym); + const char *qualified_name = SYMBOL_NATURAL_NAME (fsym); + + /* If we have a function with a C++ name, try to extract just + the function part. Do not try this for non-functions (e.g. + function pointers). */ + if (qualified_name + && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC) + { + func_name = cp_func_name (qualified_name); + + /* If cp_func_name did not remove anything, the name of the + symbol did not include scope or argument types - it was + probably a C-style function. */ + if (func_name && strcmp (func_name, qualified_name) == 0) + { + xfree (func_name); + func_name = NULL; + } + } - /* If we have a C++ name, try to extract just the function - part. */ - if (qualified_name) - func_name = cp_func_name (qualified_name); - - /* If there was no C++ name, this must be a C-style function. - Just return the same symbol. Do the same if cp_func_name - fails for some reason. */ + /* If there was no C++ name, this must be a C-style function or + not a function at all. Just return the same symbol. Do the + same if cp_func_name fails for some reason. */ if (func_name == NULL) { *symp = fsym; Index: linespec.c =================================================================== RCS file: /cvs/src/src/gdb/linespec.c,v retrieving revision 1.95 diff -u -p -r1.95 linespec.c --- linespec.c 12 Jan 2010 05:48:56 -0000 1.95 +++ linespec.c 28 Jan 2010 23:06:13 -0000 @@ -40,6 +40,7 @@ #include "interps.h" #include "mi/mi-cmds.h" #include "target.h" +#include "arch-utils.h" /* We share this one with symtab.c, but it is not exported widely. */ @@ -50,8 +51,6 @@ extern char *operator_chars (char *, cha static void initialize_defaults (struct symtab **default_symtab, int *default_line); -static void set_flags (char *arg, int *is_quoted, char **paren_pointer); - static struct symtabs_and_lines decode_indirect (char **argptr); static char *locate_first_half (char **argptr, int *is_quote_enclosed); @@ -628,6 +627,37 @@ See set/show multiple-symbol.")); discard_cleanups (old_chain); return return_values; } + +/* A helper function for decode_line_1 and friends which skips P + past any method overload information at the beginning of P, e.g., + "(const struct foo *)". + + This function assumes that P has already been validated to contain + overload information, and it will assert if *P != '('. */ +static char * +find_method_overload_end (char *p) +{ + int depth = 0; + + gdb_assert (*p == '('); + + while (*p) + { + if (*p == '(') + ++depth; + else if (*p == ')') + { + if (--depth == 0) + { + ++p; + break; + } + } + ++p; + } + + return p; +} /* The parser of linespec itself. */ @@ -688,9 +718,6 @@ decode_line_1 (char **argptr, int funfir struct symtab *file_symtab = NULL; char *copy; - /* This is NULL if there are no parens in *ARGPTR, or a pointer to - the closing parenthesis if there are parens. */ - char *paren_pointer; /* This says whether or not something in *ARGPTR is quoted with completer_quotes (i.e. with single quotes). */ int is_quoted; @@ -711,12 +738,9 @@ decode_line_1 (char **argptr, int funfir if (**argptr == '*') return decode_indirect (argptr); - /* Set various flags. 'paren_pointer' is important for overload - checking, where we allow things like: - (gdb) break c::f(int) - */ - - set_flags (*argptr, &is_quoted, &paren_pointer); + is_quoted = (*argptr + && strchr (get_gdb_completer_quote_characters (), + **argptr) != NULL); /* Check to see if it's a multipart linespec (with colons or periods). */ @@ -732,10 +756,7 @@ decode_line_1 (char **argptr, int funfir /* Check if this is an Objective-C method (anything that starts with a '+' or '-' and a '['). */ if (is_objc_method_format (p)) - { - is_objc_method = 1; - paren_pointer = NULL; /* Just a category name. Ignore it. */ - } + is_objc_method = 1; /* Check if the symbol could be an Objective-C selector. */ @@ -749,7 +770,7 @@ decode_line_1 (char **argptr, int funfir /* Does it look like there actually were two parts? */ - if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL) + if (p[0] == ':' || p[0] == '.') { if (is_quoted) *argptr = *argptr + 1; @@ -762,48 +783,31 @@ decode_line_1 (char **argptr, int funfir can return now. */ if (p[0] == '.' || p[1] == ':') - return decode_compound (argptr, funfirstline, canonical, - saved_arg, p, not_found_ptr); + { + struct symtabs_and_lines values; + + if (is_quote_enclosed) + ++saved_arg; + values = decode_compound (argptr, funfirstline, canonical, + saved_arg, p, not_found_ptr); + if (is_quoted && **argptr == '\'') + *argptr = *argptr + 1; + return values; + } /* No, the first part is a filename; set file_symtab to be that file's symtab. Also, move argptr past the filename. */ file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, not_found_ptr); - } -#if 0 - /* No one really seems to know why this was added. It certainly - breaks the command line, though, whenever the passed - name is of the form ClassName::Method. This bit of code - singles out the class name, and if funfirstline is set (for - example, you are setting a breakpoint at this function), - you get an error. This did not occur with earlier - verions, so I am ifdef'ing this out. 3/29/99 */ - else - { - /* Check if what we have till now is a symbol name */ - - /* We may be looking at a template instantiation such - as "foo". Check here whether we know about it, - instead of falling through to the code below which - handles ordinary function names, because that code - doesn't like seeing '<' and '>' in a name -- the - skip_quoted call doesn't go past them. So see if we - can figure it out right now. */ - - copy = (char *) alloca (p - *argptr + 1); - memcpy (copy, *argptr, p - *argptr); - copy[p - *argptr] = '\000'; - sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0); - if (sym) + if (file_symtab != NULL) { - *argptr = (*p == '\'') ? p + 1 : p; - return symbol_found (funfirstline, canonical, copy, sym, NULL); + /* Double-check if the remainder of the argument is quoted. + The rbreak command uses syntax like this. */ + if (**argptr == '\'') + is_quoted = 1; } - /* Otherwise fall out from here and go to file/line spec - processing, etc. */ } -#endif /* file_symtab is specified file's symtab, or 0 if no file specified. arg no longer contains the file name. */ @@ -838,10 +842,6 @@ decode_line_1 (char **argptr, int funfir /* allow word separators in method names for Obj-C */ p = skip_quoted_chars (*argptr, NULL, ""); } - else if (paren_pointer != NULL) - { - p = paren_pointer + 1; - } else { p = skip_quoted (*argptr); @@ -851,6 +851,14 @@ decode_line_1 (char **argptr, int funfir if (*p == '<') p = find_template_name_end (p); + /* Keep method overload information. */ + if (*p == '(') + p = find_method_overload_end (p); + + /* Make sure we keep important kewords like "const" */ + if (strncmp (p, " const", 6) == 0) + p += 6; + copy = (char *) alloca (p - *argptr + 1); memcpy (copy, *argptr, p - *argptr); copy[p - *argptr] = '\0'; @@ -926,44 +934,6 @@ initialize_defaults (struct symtab **def } } -static void -set_flags (char *arg, int *is_quoted, char **paren_pointer) -{ - char *ii; - int has_if = 0; - - /* 'has_if' is for the syntax: - (gdb) break foo if (a==b) - */ - if ((ii = strstr (arg, " if ")) != NULL || - (ii = strstr (arg, "\tif ")) != NULL || - (ii = strstr (arg, " if\t")) != NULL || - (ii = strstr (arg, "\tif\t")) != NULL || - (ii = strstr (arg, " if(")) != NULL || - (ii = strstr (arg, "\tif( ")) != NULL) - has_if = 1; - /* Temporarily zap out "if (condition)" to not confuse the - parenthesis-checking code below. This is undone below. Do not - change ii!! */ - if (has_if) - { - *ii = '\0'; - } - - *is_quoted = (*arg - && strchr (get_gdb_completer_quote_characters (), - *arg) != NULL); - - *paren_pointer = strchr (arg, '('); - if (*paren_pointer != NULL) - *paren_pointer = strrchr (*paren_pointer, ')'); - - /* Now that we're safely past the paren_pointer check, put back " if - (condition)" so outer layers can see it. */ - if (has_if) - *ii = ' '; -} - /* Decode arg of the form *PC. */ @@ -1063,8 +1033,9 @@ locate_first_half (char **argptr, int *i if (p[0] == '.' && strchr (p, ':') == NULL) { /* Java qualified method. Find the *last* '.', since the - others are package qualifiers. */ - for (p1 = p; *p1; p1++) + others are package qualifiers. Stop at any open parenthesis + which might provide overload information. */ + for (p1 = p; *p1 && *p1 != '('; p1++) { if (*p1 == '.') p = p1; @@ -1216,6 +1187,7 @@ decode_compound (char **argptr, int funf struct symbol *sym_class; struct symbol **sym_arr; struct type *t; + char *saved_java_argptr = NULL; /* First check for "global" namespace specification, of the form "::foo". If found, skip over the colons and jump to normal @@ -1264,7 +1236,8 @@ decode_compound (char **argptr, int funf /* PASS2: p2->"::fun", p->":fun" */ /* Move pointer ahead to next double-colon. */ - while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')) + while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'') + && (*p != '(')) { if (current_language->la_language == language_cplus) p += cp_validate_operator (p); @@ -1342,8 +1315,10 @@ decode_compound (char **argptr, int funf else { /* At this point argptr->"fun". */ + char *a; p = *argptr; - while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':') + while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':' + && *p != '(') p++; /* At this point p->"". String ended. */ /* Nope, C++ operators could have spaces in them @@ -1355,6 +1330,42 @@ decode_compound (char **argptr, int funf /* The above loop has already swallowed "operator". */ p += cp_validate_operator (p - 8) - 8; } + + /* Keep any template parameters */ + if (*p == '<') + p = find_template_name_end (p); + + /* Keep method overload information. */ + a = strchr (p, '('); + if (a != NULL) + p = find_method_overload_end (a); + + /* Make sure we keep important kewords like "const" */ + if (strncmp (p, " const", 6) == 0) + p += 6; + + /* Java may append typenames, so assume that if there is + anything else left in *argptr, it must be a typename. */ + if (*p && current_language->la_language == language_java) + { + struct type *type; + p2 = p; + while (*p2) + ++p2; + copy = (char *) alloca (p2 - p + 1); + memcpy (copy, p, p2 - p); + copy[p2 - p] = '\0'; + type = lookup_typename (current_language, get_current_arch (), + copy, NULL, 1); + if (type != NULL) + { + /* Save the location of this just in case this + method/type combination isn't actually defined. + It will be checked later. */ + saved_java_argptr = p; + p = p2; + } + } } /* Allocate our own copy of the substring between argptr and @@ -1383,9 +1394,26 @@ decode_compound (char **argptr, int funf here, we return. If not, and we are at the and of the string, we'll lookup the whole string in the symbol tables. */ - return find_method (funfirstline, canonical, saved_arg, - copy, t, sym_class, not_found_ptr); - + values = find_method (funfirstline, canonical, saved_arg, + copy, t, sym_class, not_found_ptr); + if (saved_java_argptr != NULL && values.nelts == 1) + { + /* The user specified a specific return type for a java method. + Double-check that it really is the one the user specified. + [This is a necessary evil because strcmp_iw_ordered stops + comparisons too prematurely.] */ + sym = find_pc_sect_function (values.sals[0].pc, + values.sals[0].section); + /* We just found a SAL, we had better be able to go backwards! */ + gdb_assert (sym != NULL); + if (strcmp_iw (SYMBOL_LINKAGE_NAME (sym), saved_arg) != 0) + { + xfree (values.sals); + error (_("the class `%s' does not have any method instance named %s\n"), + SYMBOL_PRINT_NAME (sym_class), copy); + } + } + return values; } /* End if symbol found */ @@ -1509,8 +1537,39 @@ find_method (int funfirstline, char ***c } if (i1 > 0) { - /* There is more than one field with that name - (overloaded). Ask the user which one to use. */ + /* If we were given a specific overload instance, use that + (or error if no matches were found). Otherwise ask the user + which one to use. */ + if (strchr (saved_arg, '(') != NULL) + { + int i; + for (i = 0; i < i1; ++i) + { + char *name = saved_arg; + char *canon = cp_canonicalize_string (name); + if (canon != NULL) + name = canon; + + if (strcmp_iw (name, SYMBOL_LINKAGE_NAME (sym_arr[i])) == 0) + { + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + values.sals[0] = find_function_start_sal (sym_arr[i], + funfirstline); + if (canon) + xfree (canon); + return values; + } + + if (canon) + xfree (canon); + } + + error (_("the class `%s' does not have any method instance named %s\n"), + SYMBOL_PRINT_NAME (sym_class), copy); + } + return decode_line_2 (sym_arr, i1, funfirstline, canonical); } else @@ -1815,7 +1874,7 @@ symbol_found (int funfirstline, char *** { struct blockvector *bv = BLOCKVECTOR (SYMBOL_SYMTAB (sym)); struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL) + if (lookup_block_symbol (b, copy, VAR_DOMAIN) != NULL) build_canonical_line_spec (values.sals, copy, canonical); } return values;