Use common_val_print in c-valprint.c
authorTom Tromey <tom@tromey.com>
Fri, 13 Mar 2020 23:39:52 +0000 (17:39 -0600)
committerTom Tromey <tom@tromey.com>
Sat, 14 Mar 2020 00:03:39 +0000 (18:03 -0600)
This changes c_value_print to call common_val_print.  This is more
complicated than the usual sort of common_val_print change, due to the
handling of RTTI.

gdb/ChangeLog
2020-03-13  Tom Tromey  <tom@tromey.com>

* c-valprint.c (c_value_print): Use common_val_print.

gdb/testsuite/ChangeLog
2020-03-13  Tom Tromey  <tom@tromey.com>

* gdb.base/printcmds.exp (test_print_strings): Add regression
test.
* gdb.base/printcmds.c (charptr): New typedef.
(teststring2): New global.

gdb/ChangeLog
gdb/c-valprint.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/printcmds.c
gdb/testsuite/gdb.base/printcmds.exp

index f43c406e3fd0623a25f4a275b828a50471a25196..a66a918424433292a5a5a7d4c0dd1fe5891286d6 100644 (file)
@@ -1,3 +1,7 @@
+2020-03-13  Tom Tromey  <tom@tromey.com>
+
+       * c-valprint.c (c_value_print): Use common_val_print.
+
 2020-03-13  Tom Tromey  <tom@tromey.com>
 
        * cp-valprint.c (cp_print_static_field): Use common_val_print.
index 157ffd7ff7a24ef0db05d4063679448b4aa81241..759ab43c723041eab5dea31145d717e4561b8f45 100644 (file)
@@ -567,7 +567,7 @@ void
 c_value_print (struct value *val, struct ui_file *stream, 
               const struct value_print_options *options)
 {
-  struct type *type, *real_type, *val_type;
+  struct type *type, *real_type;
   int full, using_enc;
   LONGEST top;
   struct value_print_options opts = *options;
@@ -581,24 +581,22 @@ c_value_print (struct value *val, struct ui_file *stream,
      C++: if it is a member pointer, we will take care
      of that when we print it.  */
 
-  /* Preserve the original type before stripping typedefs.  We prefer
-     to pass down the original type when possible, but for local
-     checks it is better to look past the typedefs.  */
-  val_type = value_type (val);
-  type = check_typedef (val_type);
+  type = check_typedef (value_type (val));
 
   if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
     {
+      struct type *original_type = value_type (val);
+
       /* Hack:  remove (char *) for char strings.  Their
          type is indicated by the quoted string anyway.
          (Don't use c_textual_element_type here; quoted strings
          are always exactly (char *), (wchar_t *), or the like.  */
-      if (TYPE_CODE (val_type) == TYPE_CODE_PTR
-         && TYPE_NAME (val_type) == NULL
-         && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL
-         && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)),
+      if (TYPE_CODE (original_type) == TYPE_CODE_PTR
+         && TYPE_NAME (original_type) == NULL
+         && TYPE_NAME (TYPE_TARGET_TYPE (original_type)) != NULL
+         && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (original_type)),
                      "char") == 0
-             || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type)))))
+             || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (original_type)))))
        {
          /* Print nothing.  */
        }
@@ -624,7 +622,6 @@ c_value_print (struct value *val, struct ui_file *stream,
              if (real_type)
                {
                  /* RTTI entry found.  */
-                 type = real_type;
 
                  /* Need to adjust pointer value.  */
                  val = value_from_pointer (real_type,
@@ -637,14 +634,11 @@ c_value_print (struct value *val, struct ui_file *stream,
            }
 
          if (is_ref)
-           {
-             val = value_ref (value_ind (val), refcode);
-             type = value_type (val);
-           }
+           val = value_ref (value_ind (val), refcode);
 
+         type = value_type (val);
          type_print (type, "", stream, -1);
          fprintf_filtered (stream, ") ");
-         val_type = type;
        }
       else
        {
@@ -667,36 +661,25 @@ c_value_print (struct value *val, struct ui_file *stream,
          /* We have RTTI information, so use it.  */
          val = value_full_object (val, real_type, 
                                   full, top, using_enc);
+         /* In a destructor we might see a real type that is a
+            superclass of the object's type.  In this case it is
+            better to leave the object as-is.  */
+         if (!(full
+               && (TYPE_LENGTH (real_type)
+                   < TYPE_LENGTH (value_enclosing_type (val)))))
+           val = value_cast (real_type, val);
          fprintf_filtered (stream, "(%s%s) ",
                            TYPE_NAME (real_type),
                            full ? "" : _(" [incomplete object]"));
-         /* Print out object: enclosing type is same as real_type if
-            full.  */
-         val_print (value_enclosing_type (val),
-                    0,
-                    value_address (val), stream, 0,
-                    val, &opts, current_language);
-         return;
-          /* Note: When we look up RTTI entries, we don't get any
-             information on const or volatile attributes.  */
        }
       else if (type != check_typedef (value_enclosing_type (val)))
        {
          /* No RTTI information, so let's do our best.  */
          fprintf_filtered (stream, "(%s ?) ",
                            TYPE_NAME (value_enclosing_type (val)));
-         val_print (value_enclosing_type (val),
-                    0,
-                    value_address (val), stream, 0,
-                    val, &opts, current_language);
-         return;
+         val = value_cast (value_enclosing_type (val), val);
        }
-      /* Otherwise, we end up at the return outside this "if".  */
     }
 
-  val_print (val_type,
-            value_embedded_offset (val),
-            value_address (val),
-            stream, 0,
-            val, &opts, current_language);
+  common_val_print (val, stream, 0, &opts, current_language);
 }
index 500aa51c3406fd7aaf8f902fd92feee6a4910a54..ec22de89d57898e1e51c5dc361312125ab382530 100644 (file)
@@ -1,3 +1,10 @@
+2020-03-13  Tom Tromey  <tom@tromey.com>
+
+       * gdb.base/printcmds.exp (test_print_strings): Add regression
+       test.
+       * gdb.base/printcmds.c (charptr): New typedef.
+       (teststring2): New global.
+
 2020-03-13  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * gdb.base/break-interp.exp: Use the tail of the filename, not the
index ed1e26b12a9c8d3c925c8a334ca574bf1b7d02b3..04b766fc0c2c9b0b870d23d0453a5b995fd30c64 100644 (file)
@@ -72,6 +72,9 @@ int int4dim[1][2][3][2] = {{{{0,1},{2,3},{4,5}},{{6,7},{8,9},{10,11}}}};
 
 char *teststring = (char*)"teststring contents";
 
+typedef char *charptr;
+charptr teststring2 = "more contents";
+
 /* Test printing of a struct containing character arrays. */
 
 struct some_arrays {
index c87a1517f0b747d60519e9746e633b40839a32bb..2c8baad5aa839c171c16629c745cdcd19d39ac55 100644 (file)
@@ -519,6 +519,9 @@ proc test_print_strings {} {
     gdb_test "p teststring" \
        " = (.unsigned char .. )?\"teststring contents\"" "p teststring with elements set to 20"
 
+    gdb_test "print teststring2" \
+       " = (charptr) \"more contents\""
+
     gdb_test_no_output "set print elements 8"
 
     # Set the target-charset to ASCII, because the output varies from