gdb
[deliverable/binutils-gdb.git] / gdb / c-lang.c
index fc01f08d87a811b2c96911704a24366cdb5c6f94..255fabe2bfdf1798695da0e96e6df3a4ecc8492b 100644 (file)
@@ -65,7 +65,7 @@ charset_for_string_type (enum c_string_type str_type,
       else
        return "UTF-32LE";
     }
-  internal_error (__FILE__, __LINE__, "unhandled c_string_type");
+  internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
 }
 
 /* Classify ELTTYPE according to what kind of character it is.  Return
@@ -978,6 +978,7 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        struct value *result;
        enum c_string_type dest_type;
        const char *dest_charset;
+       int satisfy_expected = 0;
 
        obstack_init (&output);
        cleanup = make_cleanup_obstack_free (&output);
@@ -1008,12 +1009,28 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
                                    "char32_t", NULL, 0);
            break;
          default:
-           internal_error (__FILE__, __LINE__, "unhandled c_string_type");
+           internal_error (__FILE__, __LINE__, _("unhandled c_string_type"));
          }
 
        /* Ensure TYPE_LENGTH is valid for TYPE.  */
        check_typedef (type);
 
+       /* If the caller expects an array of some integral type,
+          satisfy them.  If something odder is expected, rely on the
+          caller to cast.  */
+       if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY)
+         {
+           struct type *element_type
+             = check_typedef (TYPE_TARGET_TYPE (expect_type));
+
+           if (TYPE_CODE (element_type) == TYPE_CODE_INT
+               || TYPE_CODE (element_type) == TYPE_CODE_CHAR)
+             {
+               type = element_type;
+               satisfy_expected = 1;
+             }
+         }
+
        dest_charset = charset_for_string_type (dest_type, exp->gdbarch);
 
        ++*pos;
@@ -1036,7 +1053,9 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
        if (noside == EVAL_SKIP)
          {
            /* Return a dummy value of the appropriate type.  */
-           if ((dest_type & C_CHAR) != 0)
+           if (expect_type != NULL)
+             result = allocate_value (expect_type);
+           else if ((dest_type & C_CHAR) != 0)
              result = allocate_value (type);
            else
              result = value_cstring ("", 0, type);
@@ -1049,7 +1068,8 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
            LONGEST value;
 
            if (obstack_object_size (&output) != TYPE_LENGTH (type))
-             error (_("Could not convert character constant to target character set"));
+             error (_("Could not convert character "
+                      "constant to target character set"));
            value = unpack_long (type, obstack_base (&output));
            result = value_from_longest (type, value);
          }
@@ -1060,9 +1080,30 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
            /* Write the terminating character.  */
            for (i = 0; i < TYPE_LENGTH (type); ++i)
              obstack_1grow (&output, 0);
-           result = value_cstring (obstack_base (&output),
-                                   obstack_object_size (&output),
-                                   type);
+
+           if (satisfy_expected)
+             {
+               LONGEST low_bound, high_bound;
+               int element_size = TYPE_LENGTH (type);
+
+               if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type),
+                                        &low_bound, &high_bound) < 0)
+                 {
+                   low_bound = 0;
+                   high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
+                 }
+               if (obstack_object_size (&output) / element_size
+                   > (high_bound - low_bound + 1))
+                 error (_("Too many array elements"));
+
+               result = allocate_value (expect_type);
+               memcpy (value_contents_raw (result), obstack_base (&output),
+                       obstack_object_size (&output));
+             }
+           else
+             result = value_cstring (obstack_base (&output),
+                                     obstack_object_size (&output),
+                                     type);
          }
        do_cleanups (cleanup);
        return result;
This page took 0.02754 seconds and 4 git commands to generate.