]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Print more template parameters with ptype
authorTom Tromey <tom@tromey.com>
Fri, 28 Nov 2025 19:55:07 +0000 (12:55 -0700)
committerTom Tromey <tom@tromey.com>
Wed, 3 Dec 2025 16:22:20 +0000 (09:22 -0700)
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 <christina.schimpe@intel.com>
Approved-By: Andrew Burgess <aburgess@redhat.com>
gdb/c-typeprint.c
gdb/printcmd.c
gdb/testsuite/gdb.cp/temargs.exp
gdb/testsuite/gdb.dwarf2/missing-type-name-for-templates.exp
gdb/value.h

index 1dab82135d08f4feb5c512cdd2747363a13a75c5..2f921aec8fc32e26c5835164fdc1816e04951c3e 100644 (file)
@@ -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
index b9618f0a333450515a02b48d136c022716bf342a..c46527a9ee0bd727bce64ff316832a3cc70aafd4 100644 (file)
@@ -2325,24 +2325,13 @@ clear_dangling_display_expressions (struct objfile *objfile)
 }
 \f
 
-/* 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 (),
-                     "<error reading variable %s (%s)>", name,
+                     "<error reading variable: %s>",
                      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");
 }
index 750f739f73356d3d908eeff23ed19ed3937f825b..dbd8875e54b7ff328809529f56f08fc750093657 100644 (file)
@@ -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 <a_global>, MP = &S::f.*" \
+    "print type of Base"
+
 #
 # Tests in Inner::inner_m.
 #
index 5d97ba49b4ee00bac783de5fdd299326e293922c..5b28f9d4846cf7847f44559a556af335ccbcfe91 100644 (file)
@@ -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 <unnamed1> = int, <unnamed3> = float\\\] {" \
+    "type = struct template_var3<0, int, 11, float> \\\[with <unnamed0> = 0, <unnamed1> = int, <unnamed2> = 11, <unnamed3> = float\\\] {" \
     "    <unnamed1> me;" \
     "    <unnamed3> me2;" \
     "}"]
index 67c12a9ac62dac278875ae4a412b1133c56ef427..5d241abc2bb093b9c0d042d8cb5addbaaf537b66 100644 (file)
@@ -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,