diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 2e23dd7..0120a4b 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -38,29 +38,37 @@ static void c_type_print_varspec_prefix (struct type *, struct ui_file *, - int, int, int); + int, int, int, int); /* Print "const", "volatile", or address space modifiers. */ static void c_type_print_modifier (struct type *, struct ui_file *, int, int); + +static void c_type_print_base_internal (struct type *, struct ui_file *, + int, int, int); + -/* LEVEL is the depth to indent lines by. */ +/* The real c_print_type. See c_print_type below for a description + of parameters and usage. -void -c_print_type (struct type *type, - const char *varstring, - struct ui_file *stream, - int show, int level) + LINKAGE_NAME should be non-zero if we are printing a linkage name + on the stream. */ + +static void +c_print_type_internal (struct type *type, + const char *varstring, + struct ui_file *stream, + int show, int level, int linkage_name) { enum type_code code; int demangled_args; int need_post_space; - if (show > 0) + if (show > 0 || linkage_name) CHECK_TYPEDEF (type); - c_type_print_base (type, stream, show, level); + c_type_print_base_internal (type, stream, show, level, linkage_name); code = TYPE_CODE (type); if ((varstring != NULL && *varstring != '\0') /* Need a space if going to print stars or brackets; @@ -74,7 +82,8 @@ c_print_type (struct type *type, || code == TYPE_CODE_REF))) fputs_filtered (" ", stream); need_post_space = (varstring != NULL && strcmp (varstring, "") != 0); - c_type_print_varspec_prefix (type, stream, show, 0, need_post_space); + c_type_print_varspec_prefix (type, stream, show, 0, need_post_space, + linkage_name); if (varstring != NULL) { @@ -85,10 +94,25 @@ c_print_type (struct type *type, demangled_args = strchr (varstring, '(') != NULL; c_type_print_varspec_suffix (type, stream, show, - 0, demangled_args); + 0, demangled_args, linkage_name); } } +/* Print TYPE to the STREAM. + VARSTRING (optional) is the name of the field being printed. + If SHOW is greater than zero, print the details of the type. Otherwise + simply print the type name. + LEVEL is the depth to indent lines by. */ + +void +c_print_type (struct type *type, + const char *varstring, + struct ui_file *stream, + int show, int level) +{ + c_print_type_internal (type, varstring, stream, show, level, 0); +} + /* Print a typedef using C syntax. TYPE is the underlying type. NEW_SYMBOL is the symbol naming the type. STREAM is the stream on which to print. */ @@ -166,17 +190,14 @@ cp_type_print_derivation_info (struct ui_file *stream, /* Print the C++ method arguments ARGS to the file STREAM. */ static void -cp_type_print_method_args (struct type *mtype, char *prefix, - char *varstring, int staticp, - struct ui_file *stream) +cp_type_print_method_args (struct type *mtype, char *varstring, + int staticp, struct ui_file *stream) { struct field *args = TYPE_FIELDS (mtype); int nargs = TYPE_NFIELDS (mtype); int varargs = TYPE_VARARGS (mtype); int i; - fprintf_symbol_filtered (stream, prefix, - language_cplus, DMGL_ANSI); fprintf_symbol_filtered (stream, varstring, language_cplus, DMGL_ANSI); fputs_filtered ("(", stream); @@ -231,36 +252,42 @@ cp_type_print_method_args (struct type *mtype, char *prefix, NEED_POST_SPACE is non-zero when a space will be be needed between a trailing qualifier and a field, variable, or function - name. */ + name. + + LINKAGE_NAME is non-zero when constructing the phsyname for the type. */ static void c_type_print_varspec_prefix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr, - int need_post_space) + int need_post_space, + int linkage_name) { char *name; if (type == 0) return; - if (TYPE_NAME (type) && show <= 0) + if (TYPE_NAME (type) && show <= 0 && !linkage_name) return; QUIT; + if (linkage_name) + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), - stream, show, 1, 1); + stream, show, 1, 1, linkage_name); fprintf_filtered (stream, "*"); c_type_print_modifier (type, stream, 1, need_post_space); break; case TYPE_CODE_MEMBERPTR: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), - stream, show, 0, 0); + stream, show, 0, 0, linkage_name); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); if (name) fputs_filtered (name, stream); @@ -272,7 +299,7 @@ c_type_print_varspec_prefix (struct type *type, case TYPE_CODE_METHODPTR: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), - stream, show, 0, 0); + stream, show, 0, 0, linkage_name); fprintf_filtered (stream, "("); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); if (name) @@ -285,7 +312,7 @@ c_type_print_varspec_prefix (struct type *type, case TYPE_CODE_REF: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), - stream, show, 1, 0); + stream, show, 1, 0, linkage_name); fprintf_filtered (stream, "&"); c_type_print_modifier (type, stream, 1, need_post_space); break; @@ -293,21 +320,21 @@ c_type_print_varspec_prefix (struct type *type, case TYPE_CODE_METHOD: case TYPE_CODE_FUNC: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), - stream, show, 0, 0); + stream, show, 0, 0, linkage_name); if (passed_a_ptr) fprintf_filtered (stream, "("); break; case TYPE_CODE_ARRAY: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), - stream, show, 0, 0); + stream, show, 0, 0, linkage_name); if (passed_a_ptr) fprintf_filtered (stream, "("); break; case TYPE_CODE_TYPEDEF: c_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), - stream, show, 0, 0); + stream, show, 0, 0, linkage_name); break; case TYPE_CODE_UNDEF: @@ -386,17 +413,27 @@ c_type_print_modifier (struct type *type, struct ui_file *stream, /* 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 if LINKAGE_NAME is zero. If - LINKAGE_NAME is non-zero and LANGUAGE is language_cplus the topmost - parameter types get removed their possible const and volatile qualifiers to + or TYPE_CODE_FUNC, to STREAM. + + KIND describes the type of symbol to print to the stream. If KIND + is NAME_KIND_PHYS (the SYMBOL_LINKAGE_NAME of TYPE is being printed), + artifical parameters such as "this" in non-static methods are skipped + and all typedefs will be removed/expanded. + + Additionally if LANGUAGE is language_cplus, topmost parameter types + may have any possible const and volatile qualifiers removed to match demangled linkage name parameters part of such function type. + + If KIND is NAME_KIND_PRINT (when the SYMBOL_PRINT_NAME of TYPE is + being printed), artificial parameters are skipped, but any typedef'd + parameter types are left intact. + 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. */ void c_type_print_args (struct type *type, struct ui_file *stream, - int linkage_name, enum language language) + enum name_kind kind, enum language language) { int i, len; struct field *args; @@ -410,7 +447,8 @@ c_type_print_args (struct type *type, struct ui_file *stream, { struct type *param_type; - if (TYPE_FIELD_ARTIFICIAL (type, i) && linkage_name) + if (TYPE_FIELD_ARTIFICIAL (type, i) + && (kind == NAME_KIND_PHYS || kind == NAME_KIND_PRINT)) continue; if (printed_any) @@ -421,7 +459,7 @@ c_type_print_args (struct type *type, struct ui_file *stream, param_type = TYPE_FIELD_TYPE (type, i); - if (language == language_cplus && linkage_name) + if (language == language_cplus && kind == NAME_KIND_PHYS) { /* C++ standard, 13.1 Overloadable declarations, point 3, item: - Parameter declarations that differ only in the presence or @@ -433,10 +471,14 @@ c_type_print_args (struct type *type, struct ui_file *stream, param_type = make_cv_type (0, 0, param_type, NULL); } + if (kind == NAME_KIND_PHYS) + CHECK_TYPEDEF (param_type); + if (language == language_java) java_print_type (param_type, "", stream, -1, 0); else - c_print_type (param_type, "", stream, -1, 0); + c_print_type_internal (param_type, "", stream, -1, 0, + kind == NAME_KIND_PHYS ? 1 : 0); printed_any = 1; } @@ -599,22 +641,28 @@ remove_qualifiers (char *qid) /* Print any array sizes, function arguments or close parentheses needed after the variable name (to describe its type). - Args work like c_type_print_varspec_prefix. */ + Args work like c_type_print_varspec_prefix. + + LINKAGE_NAME is non-zero when printing the linkage name of a + function or method. */ void c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr, - int demangled_args) + int demangled_args, int linkage_name) { if (type == 0) return; - if (TYPE_NAME (type) && show <= 0) + if (TYPE_NAME (type) && show <= 0 && !linkage_name) return; QUIT; + if (linkage_name) + CHECK_TYPEDEF (type); + switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: @@ -631,25 +679,25 @@ c_type_print_varspec_suffix (struct type *type, fprintf_filtered (stream, "]"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, - show, 0, 0); + show, 0, 0, linkage_name); } break; case TYPE_CODE_MEMBERPTR: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, - show, 0, 0); + show, 0, 0, linkage_name); break; case TYPE_CODE_METHODPTR: fprintf_filtered (stream, ")"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, - show, 0, 0); + show, 0, 0, linkage_name); break; case TYPE_CODE_PTR: case TYPE_CODE_REF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, - show, 1, 0); + show, 1, 0, linkage_name); break; case TYPE_CODE_METHOD: @@ -657,14 +705,19 @@ c_type_print_varspec_suffix (struct type *type, if (passed_a_ptr) fprintf_filtered (stream, ")"); if (!demangled_args) - c_type_print_args (type, stream, 0, current_language->la_language); + { + enum name_kind kind; + + kind = linkage_name ? NAME_KIND_PHYS : NAME_KIND_FULL; + c_type_print_args (type, stream, kind, current_language->la_language); + } c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, - show, passed_a_ptr, 0); + show, passed_a_ptr, 0, linkage_name); break; case TYPE_CODE_TYPEDEF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, - show, passed_a_ptr, 0); + show, passed_a_ptr, 0, linkage_name); break; case TYPE_CODE_UNDEF: @@ -694,27 +747,14 @@ c_type_print_varspec_suffix (struct type *type, } } -/* Print the name of the type (or the ultimate pointer target, - function value or array element), or the description of a structure - or union. - - SHOW positive means print details about the type (e.g. enum - values), and print structure elements passing SHOW - 1 for show. - - SHOW negative means just print the type name or struct tag if there - is one. If there is no name, print something sensible but concise - like "struct {...}". - - SHOW zero means just print the type name or struct tag if there is - one. If there is no name, print something sensible but not as - concise like "struct {int x; int y;}". - - LEVEL is the number of spaces to indent by. - We increase it for some recursive calls. */ +/* The real c_type_print_base_internal. This function takes an + additional argument over the API function c_type_print_base: + LINKAGE_NAME, which is non-zero when the linkage name is being + printed to the STREAM. */ -void -c_type_print_base (struct type *type, struct ui_file *stream, - int show, int level) +static void +c_type_print_base_internal (struct type *type, struct ui_file *stream, + int show, int level, int linkage_name) { int i; int len, real_len; @@ -747,7 +787,8 @@ c_type_print_base (struct type *type, struct ui_file *stream, class5 *foo". */ if (show <= 0 - && TYPE_NAME (type) != NULL) + && TYPE_NAME (type) != NULL + && !linkage_name) { c_type_print_modifier (type, stream, 0, 1); fputs_filtered (TYPE_NAME (type), stream); @@ -773,14 +814,17 @@ c_type_print_base (struct type *type, struct ui_file *stream, case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: case TYPE_CODE_METHODPTR: - c_type_print_base (TYPE_TARGET_TYPE (type), - stream, show, level); + c_type_print_base_internal (TYPE_TARGET_TYPE (type), + stream, show, level, linkage_name); break; case TYPE_CODE_STRUCT: c_type_print_modifier (type, stream, 0, 1); if (TYPE_DECLARED_CLASS (type)) - fprintf_filtered (stream, "class "); + { + if (!linkage_name) + fprintf_filtered (stream, "class "); + } else fprintf_filtered (stream, "struct "); goto struct_union; @@ -954,9 +998,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, print_spaces_filtered (level + 4, stream); if (field_is_static (&TYPE_FIELD (type, i))) fprintf_filtered (stream, "static "); - c_print_type (TYPE_FIELD_TYPE (type, i), - TYPE_FIELD_NAME (type, i), - stream, show - 1, level + 4); + c_print_type_internal (TYPE_FIELD_TYPE (type, i), + TYPE_FIELD_NAME (type, i), + stream, show - 1, level + 4, + linkage_name); if (!field_is_static (&TYPE_FIELD (type, i)) && TYPE_FIELD_PACKED (type, i)) { @@ -1085,7 +1130,6 @@ c_type_print_base (struct type *type, struct ui_file *stream, struct type *mtype = TYPE_FN_FIELD_TYPE (f, j); cp_type_print_method_args (mtype, - "", method_name, staticp, stream); @@ -1145,8 +1189,10 @@ c_type_print_base (struct type *type, struct ui_file *stream, print_spaces_filtered (level + 4, stream); fprintf_filtered (stream, "typedef "); - c_print_type (target, TYPE_TYPEDEF_FIELD_NAME (type, i), - stream, show - 1, level + 4); + c_print_type_internal (target, + TYPE_TYPEDEF_FIELD_NAME (type, i), + stream, show - 1, level + 4, + linkage_name); fprintf_filtered (stream, ";\n"); } } @@ -1251,3 +1297,28 @@ c_type_print_base (struct type *type, struct ui_file *stream, break; } } + +/* Print the name of the type (or the ultimate pointer target, + function value or array element), or the description of a structure + or union. + + SHOW positive means print details about the type (e.g. enum + values), and print structure elements passing SHOW - 1 for show. + + SHOW negative means just print the type name or struct tag if there + is one. If there is no name, print something sensible but concise + like "struct {...}". + + SHOW zero means just print the type name or struct tag if there is + one. If there is no name, print something sensible but not as + concise like "struct {int x; int y;}". + + LEVEL is the number of spaces to indent by. + We increase it for some recursive calls. */ + +void +c_type_print_base (struct type *type, struct ui_file *stream, + int show, int level) +{ + c_type_print_base_internal (type, stream, show, level, 0); +} diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 81b20c7..374b9d5 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -4888,7 +4888,7 @@ do_ui_file_peek_last (void *object, const char *buffer, long length) static const char * dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, - int physname) + enum name_kind kind) { if (name == NULL) name = dwarf2_name (die, cu); @@ -4896,7 +4896,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, /* For Fortran GDB prefers DW_AT_*linkage_name if present but otherwise compute it by typename_concat inside GDB. */ if (cu->language == language_ada - || (cu->language == language_fortran && physname)) + || (cu->language == language_fortran && kind == NAME_KIND_PHYS)) { /* For Ada unit, we prefer the linkage name over the name, as the former contains the exported name, which the user expects @@ -4928,7 +4928,8 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, if (*prefix != '\0') { char *prefixed_name = typename_concat (NULL, prefix, name, - physname, cu); + (kind == NAME_KIND_PHYS), + cu); fputs_unfiltered (prefixed_name, buf); xfree (prefixed_name); @@ -5065,13 +5066,14 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, /* For Java and C++ methods, append formal parameter type information, if PHYSNAME. */ - if (physname && die->tag == DW_TAG_subprogram + if ((kind == NAME_KIND_PHYS || kind == NAME_KIND_PRINT) + && die->tag == DW_TAG_subprogram && (cu->language == language_cplus || cu->language == language_java)) { struct type *type = read_type_die (die, cu); - c_type_print_args (type, buf, 1, cu->language); + c_type_print_args (type, buf, kind, cu->language); if (cu->language == language_java) { @@ -5127,7 +5129,7 @@ dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu, static const char * dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu) { - return dwarf2_compute_name (name, die, cu, 0); + return dwarf2_compute_name (name, die, cu, NAME_KIND_FULL); } /* Construct a physname for the given DIE in CU. NAME may either be @@ -5140,7 +5142,13 @@ dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu) static const char * dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu) { - return dwarf2_compute_name (name, die, cu, 1); + return dwarf2_compute_name (name, die, cu, NAME_KIND_PHYS); +} + +static const char * +dwarf2_print_name (char *name, struct die_info *die, struct dwarf2_cu *cu) +{ + return dwarf2_compute_name (name, die, cu, NAME_KIND_PRINT); } /* Read the import statement specified by the given die and record it. */ @@ -11072,6 +11080,20 @@ new_symbol_full (struct die_info *die, struct type *type, struct dwarf2_cu *cu, linkagename = dwarf2_physname (name, die, cu); SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile); + /* For C++ set the symbol's demangled name if it is different than + the computed physname. This can happen when the source defines + a method with typedef'd parameters. This is ultimately used by + the type printer. */ + if (cu->language == language_cplus && die->tag == DW_TAG_subprogram) + { + const char *print_name = dwarf2_print_name (name, die, cu); + if (strcmp (print_name, linkagename)) + { + symbol_set_demangled_name (&(sym->ginfo), + (char *) print_name, NULL); + } + } + /* Fortran does not have mangling standard and the mangling does differ between gfortran, iFort etc. */ if (cu->language == language_fortran diff --git a/gdb/jv-typeprint.c b/gdb/jv-typeprint.c index 0a709e9..12743c7 100644 --- a/gdb/jv-typeprint.c +++ b/gdb/jv-typeprint.c @@ -328,9 +328,6 @@ java_type_print_base (struct type *type, struct ui_file *stream, int show, /* LEVEL is the depth to indent lines by. */ -extern void c_type_print_varspec_suffix (struct type *, struct ui_file *, - int, int, int); - void java_print_type (struct type *type, const char *varstring, struct ui_file *stream, int show, int level) @@ -349,5 +346,5 @@ java_print_type (struct type *type, const char *varstring, so don't print an additional pair of ()'s. */ demangled_args = varstring != NULL && strchr (varstring, '(') != NULL; - c_type_print_varspec_suffix (type, stream, show, 0, demangled_args); + c_type_print_varspec_suffix (type, stream, show, 0, demangled_args, 0); } diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 249675b..a906524 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -902,7 +902,7 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name, msymbol = &msym_bunch->contents[msym_bunch_index]; SYMBOL_SET_LANGUAGE (msymbol, language_auto); SYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, objfile); - + SYMBOL_FLAGS (msymbol) |= GSYMBOL_FLAG_MSYMBOL; SYMBOL_VALUE_ADDRESS (msymbol) = address; SYMBOL_SECTION (msymbol) = section; SYMBOL_OBJ_SECTION (msymbol) = NULL; diff --git a/gdb/symtab.c b/gdb/symtab.c index 84e01a6..b7c42bd 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -740,17 +740,21 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol) return NULL; } -/* Return the search name of a symbol---generally the demangled or - linkage name of the symbol, depending on how it will be searched for. - If there is no distinct demangled name, then returns the same value - (same pointer) as SYMBOL_LINKAGE_NAME. */ +/* Return the SYMBOL_SEARCH_NAME of GSYMBOL. */ + char * symbol_search_name (const struct general_symbol_info *gsymbol) { if (gsymbol->language == language_ada) return gsymbol->name; else - return symbol_natural_name (gsymbol); + { + if (gsymbol->flags & GSYMBOL_FLAG_MSYMBOL + || gsymbol->language != language_cplus) + return symbol_natural_name (gsymbol); + else + return gsymbol->name; + } } /* Initialize the structure fields to zero values. */ diff --git a/gdb/symtab.h b/gdb/symtab.h index 12f52a2..cc3ed96 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -34,6 +34,14 @@ struct axs_value; struct agent_expr; struct program_space; +/* A set of flags to describe a general symbol. */ + +enum gsymbol_flags +{ + /* This general symbol is a minimal symbol. */ + GSYMBOL_FLAG_MSYMBOL = (1 << 0) +}; + /* Some of the structures in this file are space critical. The space-critical structures are: @@ -147,6 +155,10 @@ struct general_symbol_info ENUM_BITFIELD(language) language : 8; + /* Flags for this symbol. */ + + ENUM_BITFIELD(gsymbol_flags) flags : 1; + /* Which section is this symbol in? This is an index into section_offsets for this objfile. Negative means that the symbol does not get relocated relative to a section. @@ -184,6 +196,7 @@ extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *); #define SYMBOL_LANGUAGE(symbol) (symbol)->ginfo.language #define SYMBOL_SECTION(symbol) (symbol)->ginfo.section #define SYMBOL_OBJ_SECTION(symbol) (symbol)->ginfo.obj_section +#define SYMBOL_FLAGS(symbol) (symbol)->ginfo.flags /* Initializes the language dependent portion of a symbol depending upon the language for the symbol. */ diff --git a/gdb/typeprint.h b/gdb/typeprint.h index 82cf61a..b271bcc 100644 --- a/gdb/typeprint.h +++ b/gdb/typeprint.h @@ -23,10 +23,21 @@ enum language; struct ui_file; +/* An enumeration for specifying the type of a computed symobl name. */ +enum name_kind + { + NAME_KIND_FULL, /* The fullname (methods do not + contain any formal parameters). */ + NAME_KIND_PHYS, /* The physname used to lookup symbols. */ + NAME_KIND_PRINT /* The name used when printing the symbol. */ + }; + 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); + int, int, int); + +void c_type_print_args (struct type *, struct ui_file *, + enum name_kind, enum language); -void c_type_print_args (struct type *, struct ui_file *, int, enum language); #endif