From: Tom Tromey Date: Fri, 28 Nov 2025 19:55:07 +0000 (-0700) Subject: Print more template parameters with ptype X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=67d6b595d8d9224e982c824e89e1989d52d39526;p=thirdparty%2Fbinutils-gdb.git Print more template parameters with ptype This bug points out that a template parameter that is a constant is not printed by 'ptype' -- in fact, only type parameters are displayed. However, there's no real reason for this, and any template parameter that the DWARF reader can turn into a symbol should be printable. Note that some parameters are still missing from the DWARF; see the kfails in the test for details. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33670 Reviewed-By: Christina Schimpe Approved-By: Andrew Burgess --- diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c index 1dab82135d0..2f921aec8fc 100644 --- a/gdb/c-typeprint.c +++ b/gdb/c-typeprint.c @@ -805,36 +805,32 @@ c_type_print_template_args (const struct type_print_options *flags, struct type *type, struct ui_file *stream, enum language language) { - int first = 1, i; - - if (flags->raw) + if (flags->raw || TYPE_N_TEMPLATE_ARGUMENTS (type) == 0) return; - for (i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i) + stream->wrap_here (4); + gdb_printf (stream, _("[with ")); + + for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i) { struct symbol *sym = TYPE_TEMPLATE_ARGUMENT (type, i); - if (sym->loc_class () != LOC_TYPEDEF) - continue; - - if (first) - { - stream->wrap_here (4); - gdb_printf (stream, _("[with %s = "), sym->linkage_name ()); - first = 0; - } - else + if (i > 0) { gdb_puts (", ", stream); stream->wrap_here (9); - gdb_printf (stream, "%s = ", sym->linkage_name ()); } - c_print_type (sym->type (), "", stream, -1, 0, language, flags); + gdb_printf (stream, "%ps = ", + styled_string (variable_name_style.style (), + sym->linkage_name ())); + if (sym->loc_class () == LOC_TYPEDEF) + c_print_type (sym->type (), "", stream, -1, 0, language, flags); + else + print_variable_value (sym, {}, stream, 0, language_def (language)); } - if (!first) - gdb_puts (_("] "), stream); + gdb_puts (_("] "), stream); } /* Use 'print_spaces', but take into consideration the diff --git a/gdb/printcmd.c b/gdb/printcmd.c index b9618f0a333..c46527a9ee0 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -2325,24 +2325,13 @@ clear_dangling_display_expressions (struct objfile *objfile) } -/* Print the value in stack frame FRAME of a variable specified by a - struct symbol. NAME is the name to print; if NULL then VAR's print - name will be used. STREAM is the ui_file on which to print the - value. INDENT specifies the number of indent levels to print - before printing the variable name. */ +/* See value.h. */ void -print_variable_and_value (const char *name, struct symbol *var, - const frame_info_ptr &frame, - struct ui_file *stream, int indent) +print_variable_value (symbol *var, const frame_info_ptr &frame, + ui_file *stream, int indent, + const language_defn *language) { - - if (!name) - name = var->print_name (); - - gdb_printf (stream, "%*s%ps = ", 2 * indent, "", - styled_string (variable_name_style.style (), name)); - try { struct value *val; @@ -2355,14 +2344,30 @@ print_variable_and_value (const char *name, struct symbol *var, val = read_var_value (var, NULL, frame); get_user_print_options (&opts); opts.deref_ref = true; - common_val_print_checked (val, stream, indent, &opts, current_language); + common_val_print_checked (val, stream, indent, &opts, language); } catch (const gdb_exception_error &except) { fprintf_styled (stream, metadata_style.style (), - "", name, + "", except.what ()); } +} + +/* See value.h. */ + +void +print_variable_and_value (const char *name, symbol *var, + const frame_info_ptr &frame, + ui_file *stream, int indent) +{ + if (name == nullptr) + name = var->print_name (); + + gdb_printf (stream, "%*s%ps = ", 2 * indent, "", + styled_string (variable_name_style.style (), name)); + + print_variable_value (var, frame, stream, indent, current_language); gdb_printf (stream, "\n"); } diff --git a/gdb/testsuite/gdb.cp/temargs.exp b/gdb/testsuite/gdb.cp/temargs.exp index 750f739f733..dbd8875e54b 100644 --- a/gdb/testsuite/gdb.cp/temargs.exp +++ b/gdb/testsuite/gdb.cp/temargs.exp @@ -88,6 +88,10 @@ gdb_test "print P == &a_global" " = true" "test value of P in base_m" if {!$have_pr_41736_fixed} { setup_xfail *-*-* } gdb_test "print MP" "&S::f" "test value of MP in base_m" +gdb_test "ptype/m *this" \ + "type = struct Base.*with T = double, I = 23, P = $hex , MP = &S::f.*" \ + "print type of Base" + # # Tests in Inner::inner_m. # diff --git a/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp b/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp index 5d97ba49b4e..5b28f9d4846 100644 --- a/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp +++ b/gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp @@ -174,7 +174,7 @@ gdb_test "ptype var2" [multi_line \ "}"] gdb_test "ptype var3" [multi_line \ - "type = struct template_var3<0, int, 11, float> \\\[with = int, = float\\\] {" \ + "type = struct template_var3<0, int, 11, float> \\\[with = 0, = int, = 11, = float\\\] {" \ " me;" \ " me2;" \ "}"] diff --git a/gdb/value.h b/gdb/value.h index 67c12a9ac62..5d241abc2bb 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -1568,10 +1568,27 @@ extern int val_print_string (struct type *elttype, const char *encoding, struct ui_file *stream, const struct value_print_options *options); +/* Print the value in stack frame FRAME of a variable specified by a + struct symbol. STREAM is the ui_file on which to print the value. + INDENT specifies the number of indent levels to print before + printing the variable name. LANGUAGE is the language to use for + printing. */ + +extern void print_variable_value (symbol *var, + const frame_info_ptr &frame, + ui_file *stream, int indent, + const language_defn *language); + +/* Print the value in stack frame FRAME of a variable specified by a + struct symbol. NAME is the name to print; if NULL then VAR's print + name will be used. STREAM is the ui_file on which to print the + value. INDENT specifies the number of indent levels to print + before printing the variable name. */ + extern void print_variable_and_value (const char *name, - struct symbol *var, + symbol *var, const frame_info_ptr &frame, - struct ui_file *stream, + ui_file *stream, int indent); extern void typedef_print (struct type *type, struct symbol *news,