2002-05-06 Elena Zannoni <ezannoni@redhat.com>
[deliverable/binutils-gdb.git] / gdb / gdbtypes.c
index a46f9ce51a63dab0e7f3b6c19ce55adea9c52146..ccff12fa74b5b2a874af5ffe72a38e3ba67c7ad3 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for manipulating internal types for GDB.
-   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000
+   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
@@ -71,11 +71,25 @@ struct type *builtin_type_uint64;
 struct type *builtin_type_int128;
 struct type *builtin_type_uint128;
 struct type *builtin_type_bool;
+
+/* 128 bit long vector types */
+struct type *builtin_type_v4_float;
+struct type *builtin_type_v4_int32;
+struct type *builtin_type_v8_int16;
+struct type *builtin_type_v16_int8;
+/* 64 bit long vector types */
+struct type *builtin_type_v2_int32;
+struct type *builtin_type_v4_int16;
+struct type *builtin_type_v8_int8;
+
 struct type *builtin_type_v4sf;
 struct type *builtin_type_v4si;
+struct type *builtin_type_v16qi;
 struct type *builtin_type_v8qi;
+struct type *builtin_type_v8hi;
 struct type *builtin_type_v4hi;
 struct type *builtin_type_v2si;
+struct type *builtin_type_vec128;
 struct type *builtin_type_ieee_single_big;
 struct type *builtin_type_ieee_single_little;
 struct type *builtin_type_ieee_double_big;
@@ -516,6 +530,38 @@ finish_cv_type (struct type *type)
     }
 }
 
+/* Replace the contents of ntype with the type *type.
+
+   In order to build recursive types, it's inevitable that we'll need
+   to update types in place --- but this sort of indiscriminate
+   smashing is ugly, and needs to be replaced with something more
+   controlled.  For example, Daniel Jacobowitz has suggested moving
+   the fields common to a set of c/v variants into their own object,
+   which the variants would share.
+
+   This function does not handle the replacement type being
+   cv-qualified; it could be easily fixed to, but it would be better
+   to just change the whole approach.  */
+void
+replace_type (struct type *ntype, struct type *type)
+{
+  struct type *cv_chain, *as_chain, *ptr, *ref;
+
+  cv_chain = TYPE_CV_TYPE (ntype);
+  as_chain = TYPE_AS_TYPE (ntype);
+  ptr = TYPE_POINTER_TYPE (ntype);
+  ref = TYPE_REFERENCE_TYPE (ntype);
+
+  *ntype = *type;
+
+  TYPE_POINTER_TYPE (ntype) = ptr;
+  TYPE_REFERENCE_TYPE (ntype) = ref;
+  TYPE_CV_TYPE (ntype) = cv_chain;
+  TYPE_AS_TYPE (ntype) = as_chain;
+
+  finish_cv_type (ntype);
+}
+
 /* Implement direct support for MEMBER_TYPE in GNU C++.
    May need to construct such a type if this is the first use.
    The TYPE is the type of the member.  The DOMAIN is the type
@@ -569,7 +615,7 @@ create_range_type (struct type *result_type, struct type *index_type,
     }
   TYPE_CODE (result_type) = TYPE_CODE_RANGE;
   TYPE_TARGET_TYPE (result_type) = index_type;
-  if (TYPE_FLAGS (index_type) & TYPE_FLAG_STUB)
+  if (TYPE_STUB (index_type))
     TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
   else
     TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
@@ -732,7 +778,7 @@ create_set_type (struct type *result_type, struct type *domain_type)
     TYPE_ALLOC (result_type, 1 * sizeof (struct field));
   memset (TYPE_FIELDS (result_type), 0, sizeof (struct field));
 
-  if (!(TYPE_FLAGS (domain_type) & TYPE_FLAG_STUB))
+  if (!TYPE_STUB (domain_type))
     {
       if (get_discrete_bounds (domain_type, &low_bound, &high_bound) < 0)
        low_bound = high_bound = 0;
@@ -748,7 +794,6 @@ create_set_type (struct type *result_type, struct type *domain_type)
   return (result_type);
 }
 
-
 /* Construct and return a type of the form:
        struct NAME { ELT_TYPE ELT_NAME[N]; }
    We use these types for SIMD registers.  For example, the type of
@@ -764,28 +809,57 @@ init_simd_type (char *name,
                char *elt_name,
                int n)
 {
+  struct type *simd_type;
+  struct type *array_type;
+  
+  simd_type = init_composite_type (name, TYPE_CODE_STRUCT);
+  array_type = create_array_type (0, elt_type,
+                                 create_range_type (0, builtin_type_int,
+                                                    0, n-1));
+  append_composite_type_field (simd_type, elt_name, array_type);
+  return simd_type;
+}
+
+static struct type *
+init_vector_type (struct type *elt_type, int n)
+{
+  struct type *array_type;
+  array_type = create_array_type (0, elt_type,
+                                 create_range_type (0, builtin_type_int,
+                                                    0, n-1));
+  TYPE_FLAGS (array_type) |= TYPE_FLAG_VECTOR;
+  return array_type;
+}
+
+static struct type *
+build_builtin_type_vec128 (void)
+{
+  /* Construct a type for the 128 bit registers.  The type we're
+     building is this: */
+#if 0
+ union __gdb_builtin_type_vec128 
+  {
+    int128_t uint128;
+    float v4_float[4];
+    int32_t v4_int32[4];
+    int16_t v8_int16[8];
+    int8_t v16_int8[16];
+  };
+#endif
+
   struct type *t;
-  struct field *f;
 
-  /* Build the field structure.  */
-  f = xmalloc (sizeof (*f));
-  memset (f, 0, sizeof (*f));
-  f->loc.bitpos = 0;
-  f->type = create_array_type (0, elt_type,
-                              create_range_type (0, builtin_type_int,
-                                                 0, n-1));
-  f->name = elt_name;
-
-  /* Build a struct type with that field.  */
-  t = init_type (TYPE_CODE_STRUCT, n * TYPE_LENGTH (elt_type), 0, 0, 0);
-  t->nfields = 1;
-  t->fields = f;
-  t->tag_name = name;
+  t = init_composite_type ("__gdb_builtin_type_vec128", TYPE_CODE_UNION);
+  append_composite_type_field (t, "uint128", builtin_type_int128);
+  append_composite_type_field (t, "v4_float", builtin_type_v4_float);
+  append_composite_type_field (t, "v4_int32", builtin_type_v4_int32);
+  append_composite_type_field (t, "v8_int16", builtin_type_v8_int16);
+  append_composite_type_field (t, "v16_int8", builtin_type_v16_int8);
 
   return t;
 }
 
-
 /* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. 
    A MEMBER is a wierd thing -- it amounts to a typed offset into
    a struct, e.g. "an int at offset 8".  A MEMBER TYPE doesn't
@@ -1245,7 +1319,7 @@ check_typedef (struct type *type)
        make_cv_type (is_const, is_volatile, newtype, &type);
     }
   /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
-  else if ((TYPE_FLAGS (type) & TYPE_FLAG_STUB) && !currently_reading_symtab)
+  else if (TYPE_STUB (type) && !currently_reading_symtab)
     {
       char *name = type_name_no_tag (type);
       /* FIXME: shouldn't we separately check the TYPE_NAME and the
@@ -1263,12 +1337,12 @@ check_typedef (struct type *type)
        make_cv_type (is_const, is_volatile, SYMBOL_TYPE (sym), &type);
     }
 
-  if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
+  if (TYPE_TARGET_STUB (type))
     {
       struct type *range_type;
       struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
 
-      if (TYPE_FLAGS (target_type) & (TYPE_FLAG_STUB | TYPE_FLAG_TARGET_STUB))
+      if (TYPE_STUB (target_type) || TYPE_TARGET_STUB (target_type))
        {
        }
       else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
@@ -1680,6 +1754,48 @@ init_type (enum type_code code, int length, int flags, char *name,
   return (type);
 }
 
+/* Helper function.  Create an empty composite type.  */
+
+struct type *
+init_composite_type (char *name, enum type_code code)
+{
+  struct type *t;
+  gdb_assert (code == TYPE_CODE_STRUCT
+             || code == TYPE_CODE_UNION);
+  t = init_type (code, 0, 0, NULL, NULL);
+  TYPE_TAG_NAME (t) = name;
+  return t;
+}
+
+/* Helper function.  Append a field to a composite type.  */
+
+void
+append_composite_type_field (struct type *t, char *name, struct type *field)
+{
+  struct field *f;
+  TYPE_NFIELDS (t) = TYPE_NFIELDS (t) + 1;
+  TYPE_FIELDS (t) = xrealloc (TYPE_FIELDS (t),
+                             sizeof (struct field) * TYPE_NFIELDS (t));
+  f = &(TYPE_FIELDS (t)[TYPE_NFIELDS (t) - 1]);
+  memset (f, 0, sizeof f[0]);
+  FIELD_TYPE (f[0]) = field;
+  FIELD_NAME (f[0]) = name;
+  if (TYPE_CODE (t) == TYPE_CODE_UNION)
+    {
+      if (TYPE_LENGTH (t) < TYPE_LENGTH (field))
+       TYPE_LENGTH (t) = TYPE_LENGTH (field);
+    }
+  else if (TYPE_CODE (t) == TYPE_CODE_STRUCT)
+    {
+      TYPE_LENGTH (t) = TYPE_LENGTH (t) + TYPE_LENGTH (field);
+      if (TYPE_NFIELDS (t) > 1)
+       {
+         FIELD_BITPOS (f[0]) = (FIELD_BITPOS (f[-1])
+                                + TYPE_LENGTH (field) * TARGET_CHAR_BIT);
+       }
+    }
+}
+
 /* Look up a fundamental type for the specified objfile.
    May need to construct such a type if this is the first use.
 
@@ -2944,6 +3060,13 @@ recursive_dump_type (struct type *type, int spaces)
     {
       puts_filtered (" TYPE_FLAG_VARARGS");
     }
+  /* This is used for things like AltiVec registers on ppc.  Gcc emits
+     an attribute for the array type, which tells whether or not we
+     have a vector, instead of a regular array.  */
+  if (TYPE_VECTOR (type))
+    {
+      puts_filtered (" TYPE_FLAG_VECTOR");
+    }
   puts_filtered ("\n");
   printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type));
   gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout);
@@ -3029,7 +3152,8 @@ build_gdbtypes (void)
               "void", (struct objfile *) NULL);
   builtin_type_char =
     init_type (TYPE_CODE_INT, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
-              TYPE_FLAG_NOSIGN,
+              (TYPE_FLAG_NOSIGN
+                | (TARGET_CHAR_SIGNED ? 0 : TYPE_FLAG_UNSIGNED)),
               "char", (struct objfile *) NULL);
   builtin_type_true_char =
     init_type (TYPE_CODE_CHAR, TARGET_CHAR_BIT / TARGET_CHAR_BIT,
@@ -3079,17 +3203,31 @@ build_gdbtypes (void)
     init_type (TYPE_CODE_FLT, TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
               0,
               "float", (struct objfile *) NULL);
+/* vinschen@redhat.com 2002-02-08:
+   The below lines are disabled since they are doing the wrong
+   thing for non-multiarch targets.  They are setting the correct
+   type of floats for the target but while on multiarch targets
+   this is done everytime the architecture changes, it's done on
+   non-multiarch targets only on startup, leaving the wrong values
+   in even if the architecture changes (eg. from big-endian to
+   little-endian).  */
+#if 0
   TYPE_FLOATFORMAT (builtin_type_float) = TARGET_FLOAT_FORMAT;
+#endif
   builtin_type_double =
     init_type (TYPE_CODE_FLT, TARGET_DOUBLE_BIT / TARGET_CHAR_BIT,
               0,
               "double", (struct objfile *) NULL);
+#if 0
   TYPE_FLOATFORMAT (builtin_type_double) = TARGET_DOUBLE_FORMAT;
+#endif
   builtin_type_long_double =
     init_type (TYPE_CODE_FLT, TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT,
               0,
               "long double", (struct objfile *) NULL);
+#if 0
   TYPE_FLOATFORMAT (builtin_type_long_double) = TARGET_LONG_DOUBLE_FORMAT;
+#endif
   builtin_type_complex =
     init_type (TYPE_CODE_COMPLEX, 2 * TARGET_FLOAT_BIT / TARGET_CHAR_BIT,
               0,
@@ -3162,13 +3300,30 @@ build_gdbtypes (void)
     = init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4);
   builtin_type_v4si
     = init_simd_type ("__builtin_v4si", builtin_type_int32, "f", 4);
+  builtin_type_v16qi
+    = init_simd_type ("__builtin_v16qi", builtin_type_int8, "f", 16);
   builtin_type_v8qi
     = init_simd_type ("__builtin_v8qi", builtin_type_int8, "f", 8);
+  builtin_type_v8hi
+    = init_simd_type ("__builtin_v8hi", builtin_type_int16, "f", 8);
   builtin_type_v4hi
     = init_simd_type ("__builtin_v4hi", builtin_type_int16, "f", 4);
   builtin_type_v2si
     = init_simd_type ("__builtin_v2si", builtin_type_int32, "f", 2);
 
+  /* 128 bit vectors.  */
+  builtin_type_v4_float = init_vector_type (builtin_type_float, 4);
+  builtin_type_v4_int32 = init_vector_type (builtin_type_int32, 4);
+  builtin_type_v8_int16 = init_vector_type (builtin_type_int16, 8);
+  builtin_type_v16_int8 = init_vector_type (builtin_type_int8, 16);
+  /* 64 bit vectors.  */
+  builtin_type_v2_int32 = init_vector_type (builtin_type_int32, 2);
+  builtin_type_v4_int16 = init_vector_type (builtin_type_int16, 4);
+  builtin_type_v8_int8 = init_vector_type (builtin_type_int8, 8);
+
+  /* Vector types. */
+  builtin_type_vec128 = build_builtin_type_vec128 ();
+
   /* Pointer/Address types. */
 
   /* NOTE: on some targets, addresses and pointers are not necessarily
@@ -3251,9 +3406,19 @@ _initialize_gdbtypes (void)
   register_gdbarch_swap (&builtin_type_uint128, sizeof (struct type *), NULL);
   register_gdbarch_swap (&builtin_type_v4sf, sizeof (struct type *), NULL);
   register_gdbarch_swap (&builtin_type_v4si, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v16qi, sizeof (struct type *), NULL);
   register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v8hi, sizeof (struct type *), NULL);
   register_gdbarch_swap (&builtin_type_v4hi, sizeof (struct type *), NULL);
   register_gdbarch_swap (&builtin_type_v2si, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v4_float, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v4_int32, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v8_int16, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v16_int8, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v2_int32, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v8_int8, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_v4_int16, sizeof (struct type *), NULL);
+  register_gdbarch_swap (&builtin_type_vec128, sizeof (struct type *), NULL);
   REGISTER_GDBARCH_SWAP (builtin_type_void_data_ptr);
   REGISTER_GDBARCH_SWAP (builtin_type_void_func_ptr);
   REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR);
@@ -3269,15 +3434,19 @@ _initialize_gdbtypes (void)
   builtin_type_ieee_single_little =
     init_type (TYPE_CODE_FLT, floatformat_ieee_single_little.totalsize / 8,
               0, "builtin_type_ieee_single_little", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ieee_single_little) = &floatformat_ieee_single_little;
   builtin_type_ieee_double_big =
     init_type (TYPE_CODE_FLT, floatformat_ieee_double_big.totalsize / 8,
               0, "builtin_type_ieee_double_big", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ieee_double_big) = &floatformat_ieee_double_big;
   builtin_type_ieee_double_little =
     init_type (TYPE_CODE_FLT, floatformat_ieee_double_little.totalsize / 8,
               0, "builtin_type_ieee_double_little", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ieee_double_little) = &floatformat_ieee_double_little;
   builtin_type_ieee_double_littlebyte_bigword =
     init_type (TYPE_CODE_FLT, floatformat_ieee_double_littlebyte_bigword.totalsize / 8,
               0, "builtin_type_ieee_double_littlebyte_bigword", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ieee_double_littlebyte_bigword) = &floatformat_ieee_double_littlebyte_bigword;
   builtin_type_i387_ext =
     init_type (TYPE_CODE_FLT, floatformat_i387_ext.totalsize / 8,
               0, "builtin_type_i387_ext", NULL);
@@ -3285,33 +3454,43 @@ _initialize_gdbtypes (void)
   builtin_type_m68881_ext =
     init_type (TYPE_CODE_FLT, floatformat_m68881_ext.totalsize / 8,
               0, "builtin_type_m68881_ext", NULL);
+  TYPE_FLOATFORMAT (builtin_type_m68881_ext) = &floatformat_m68881_ext;
   builtin_type_i960_ext =
     init_type (TYPE_CODE_FLT, floatformat_i960_ext.totalsize / 8,
               0, "builtin_type_i960_ext", NULL);
+  TYPE_FLOATFORMAT (builtin_type_i960_ext) = &floatformat_i960_ext;
   builtin_type_m88110_ext =
     init_type (TYPE_CODE_FLT, floatformat_m88110_ext.totalsize / 8,
               0, "builtin_type_m88110_ext", NULL);
+  TYPE_FLOATFORMAT (builtin_type_m88110_ext) = &floatformat_m88110_ext;
   builtin_type_m88110_harris_ext =
     init_type (TYPE_CODE_FLT, floatformat_m88110_harris_ext.totalsize / 8,
               0, "builtin_type_m88110_harris_ext", NULL);
+  TYPE_FLOATFORMAT (builtin_type_m88110_harris_ext) = &floatformat_m88110_harris_ext;
   builtin_type_arm_ext_big =
     init_type (TYPE_CODE_FLT, floatformat_arm_ext_big.totalsize / 8,
               0, "builtin_type_arm_ext_big", NULL);
+  TYPE_FLOATFORMAT (builtin_type_arm_ext_big) = &floatformat_arm_ext_big;
   builtin_type_arm_ext_littlebyte_bigword =
     init_type (TYPE_CODE_FLT, floatformat_arm_ext_littlebyte_bigword.totalsize / 8,
               0, "builtin_type_arm_ext_littlebyte_bigword", NULL);
+  TYPE_FLOATFORMAT (builtin_type_arm_ext_littlebyte_bigword) = &floatformat_arm_ext_littlebyte_bigword;
   builtin_type_ia64_spill_big =
     init_type (TYPE_CODE_FLT, floatformat_ia64_spill_big.totalsize / 8,
               0, "builtin_type_ia64_spill_big", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ia64_spill_big) = &floatformat_ia64_spill_big;
   builtin_type_ia64_spill_little =
     init_type (TYPE_CODE_FLT, floatformat_ia64_spill_little.totalsize / 8,
               0, "builtin_type_ia64_spill_little", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ia64_spill_little) = &floatformat_ia64_spill_little;
   builtin_type_ia64_quad_big =
     init_type (TYPE_CODE_FLT, floatformat_ia64_quad_big.totalsize / 8,
               0, "builtin_type_ia64_quad_big", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ia64_quad_big) = &floatformat_ia64_quad_big;
   builtin_type_ia64_quad_little =
     init_type (TYPE_CODE_FLT, floatformat_ia64_quad_little.totalsize / 8,
               0, "builtin_type_ia64_quad_little", NULL);
+  TYPE_FLOATFORMAT (builtin_type_ia64_quad_little) = &floatformat_ia64_quad_little;
 
   add_show_from_set (
                     add_set_cmd ("overload", no_class, var_zinteger, (char *) &overload_debug,
This page took 0.029612 seconds and 4 git commands to generate.