Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.325 diff -u -p -r1.325 dwarf2read.c --- dwarf2read.c 28 Aug 2009 10:49:05 -0000 1.325 +++ dwarf2read.c 31 Aug 2009 20:37:23 -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" @@ -691,6 +694,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 @@ -804,6 +812,8 @@ static void add_partial_symbol (struct p 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, int need_pc, struct dwarf2_cu *cu); @@ -949,6 +959,11 @@ static struct type *read_type_die (struc static char *determine_prefix (struct die_info *die, 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 *typename_concat (struct obstack *, const char *prefix, const char *suffix, @@ -1036,6 +1051,8 @@ static void process_die (struct die_info 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 *); @@ -2577,6 +2594,44 @@ pdi_needs_namespace (enum dwarf_tag tag) } } +/* Determine whether DIE needs to have the name of the scope prepended + to the name listed in the die. */ + +static int +die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu) +{ + switch (die->tag) + { + case DW_TAG_namespace: + case DW_TAG_typedef: + case DW_TAG_class_type: + case DW_TAG_interface_type: + case DW_TAG_structure_type: + 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; + } +} + /* Read a partial die corresponding to a namespace; also, add a symbol corresponding to that namespace to the symbol table. NAMESPACE is the name of the enclosing namespace. */ @@ -8914,6 +8969,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, @@ -8976,6 +9121,80 @@ dwarf2_linkage_name (struct die_info *di return dwarf2_name (die, cu); } +/* Construct a physname for the given DIE in CU. */ + +static char * +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); + + c_type_print_args (type, buf, 0); + + 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. */ static char * Index: typeprint.h =================================================================== RCS file: /cvs/src/src/gdb/typeprint.h,v retrieving revision 1.8 diff -u -p -r1.8 typeprint.h --- typeprint.h 3 Jan 2009 05:57:53 -0000 1.8 +++ typeprint.h 31 Aug 2009 20:37:23 -0000 @@ -26,4 +26,6 @@ void print_type_scalar (struct type * ty 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); #endif Index: ui-file.h =================================================================== RCS file: /cvs/src/src/gdb/ui-file.h,v retrieving revision 1.10 diff -u -p -r1.10 ui-file.h --- ui-file.h 14 Aug 2009 00:32:32 -0000 1.10 +++ ui-file.h 31 Aug 2009 20:37:23 -0000 @@ -19,6 +19,7 @@ #ifndef UI_FILE_H #define UI_FILE_H +struct obstack; struct ui_file; /* Create a generic ui_file object with null methods. */ @@ -77,7 +78,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: c-typeprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-typeprint.c,v retrieving revision 1.47 diff -u -p -r1.47 c-typeprint.c --- c-typeprint.c 2 Jul 2009 12:57:14 -0000 1.47 +++ c-typeprint.c 31 Aug 2009 20:37:23 -0000 @@ -40,8 +40,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, @@ -355,10 +353,12 @@ 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. */ -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) { int i, len; struct field *args; @@ -370,6 +370,9 @@ 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, ", "); @@ -593,7 +596,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); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; Index: ui-file.c =================================================================== RCS file: /cvs/src/src/gdb/ui-file.c,v retrieving revision 1.18 diff -u -p -r1.18 ui-file.c --- ui-file.c 14 Aug 2009 00:32:32 -0000 1.18 +++ ui-file.c 31 Aug 2009 20:37:23 -0000 @@ -22,6 +22,7 @@ #include "defs.h" #include "ui-file.h" +#include "gdb_obstack.h" #include "gdb_string.h" #include @@ -297,6 +298,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