gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / rust-lang.c
index 139e4c2f2ce4577a21afd88886044dd63121cf3b..0929daf0511090df9acc46aa5f0cad19e10d2eaf 100644 (file)
@@ -68,38 +68,37 @@ rust_crate_for_block (const struct block *block)
    enum.  */
 
 static bool
-rust_enum_p (const struct type *type)
+rust_enum_p (struct type *type)
 {
-  return (TYPE_CODE (type) == TYPE_CODE_STRUCT
-         && TYPE_NFIELDS (type) == 1
-         && TYPE_FLAG_DISCRIMINATED_UNION (TYPE_FIELD_TYPE (type, 0)));
+  /* is_dynamic_type will return true if any field has a dynamic
+     attribute -- but we only want to check the top level.  */
+  return TYPE_HAS_VARIANT_PARTS (type);
 }
 
-/* Return true if TYPE, which must be an enum type, has no
-   variants.  */
+/* Return true if TYPE, which must be an already-resolved enum type,
+   has no variants.  */
 
 static bool
 rust_empty_enum_p (const struct type *type)
 {
-  gdb_assert (rust_enum_p (type));
-  /* In Rust the enum always fills the containing structure.  */
-  gdb_assert (TYPE_FIELD_BITPOS (type, 0) == 0);
-
-  return TYPE_NFIELDS (TYPE_FIELD_TYPE (type, 0)) == 0;
+  return type->num_fields () == 0;
 }
 
-/* Given an enum type and contents, find which variant is active.  */
+/* Given an already-resolved enum type and contents, find which
+   variant is active.  */
 
-static struct field *
-rust_enum_variant (struct type *type, const gdb_byte *contents)
+static int
+rust_enum_variant (struct type *type)
 {
-  /* In Rust the enum always fills the containing structure.  */
-  gdb_assert (TYPE_FIELD_BITPOS (type, 0) == 0);
-
-  struct type *union_type = TYPE_FIELD_TYPE (type, 0);
-
-  int fieldno = value_union_variant (union_type, contents);
-  return &TYPE_FIELD (union_type, fieldno);
+  /* The active variant is simply the first non-artificial field.  */
+  for (int i = 0; i < type->num_fields (); ++i)
+    if (!TYPE_FIELD_ARTIFICIAL (type, i))
+      return i;
+
+  /* Perhaps we could get here by trying to print an Ada variant
+     record in Rust mode.  Unlikely, but an error is safer than an
+     assert.  */
+  error (_("Could not find active enum variant"));
 }
 
 /* See rust-lang.h.  */
@@ -110,9 +109,9 @@ rust_tuple_type_p (struct type *type)
   /* The current implementation is a bit of a hack, but there's
      nothing else in the debuginfo to distinguish a tuple from a
      struct.  */
-  return (TYPE_CODE (type) == TYPE_CODE_STRUCT
-         && TYPE_NAME (type) != NULL
-         && TYPE_NAME (type)[0] == '(');
+  return (type->code () == TYPE_CODE_STRUCT
+         && type->name () != NULL
+         && type->name ()[0] == '(');
 }
 
 /* Return true if all non-static fields of a structlike type are in a
@@ -125,11 +124,11 @@ rust_underscore_fields (struct type *type)
 
   field_number = 0;
 
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT)
+  if (type->code () != TYPE_CODE_STRUCT)
     return false;
-  for (i = 0; i < TYPE_NFIELDS (type); ++i)
+  for (i = 0; i < type->num_fields (); ++i)
     {
-      if (!field_is_static (&TYPE_FIELD (type, i)))
+      if (!field_is_static (&type->field (i)))
        {
          char buf[20];
 
@@ -150,7 +149,7 @@ rust_tuple_struct_type_p (struct type *type)
   /* This is just an approximation until DWARF can represent Rust more
      precisely.  We exclude zero-length structs because they may not
      be tuple structs, and there's no way to tell.  */
-  return TYPE_NFIELDS (type) > 0 && rust_underscore_fields (type);
+  return type->num_fields () > 0 && rust_underscore_fields (type);
 }
 
 /* Return true if TYPE is a slice type, otherwise false.  */
@@ -158,10 +157,10 @@ rust_tuple_struct_type_p (struct type *type)
 static bool
 rust_slice_type_p (struct type *type)
 {
-  return (TYPE_CODE (type) == TYPE_CODE_STRUCT
-         && TYPE_NAME (type) != NULL
-         && (strncmp (TYPE_NAME (type), "&[", 2) == 0
-             || strcmp (TYPE_NAME (type), "&str") == 0));
+  return (type->code () == TYPE_CODE_STRUCT
+         && type->name () != NULL
+         && (strncmp (type->name (), "&[", 2) == 0
+             || strcmp (type->name (), "&str") == 0));
 }
 
 /* Return true if TYPE is a range type, otherwise false.  */
@@ -171,23 +170,23 @@ rust_range_type_p (struct type *type)
 {
   int i;
 
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-      || TYPE_NFIELDS (type) > 2
-      || TYPE_NAME (type) == NULL
-      || strstr (TYPE_NAME (type), "::Range") == NULL)
+  if (type->code () != TYPE_CODE_STRUCT
+      || type->num_fields () > 2
+      || type->name () == NULL
+      || strstr (type->name (), "::Range") == NULL)
     return false;
 
-  if (TYPE_NFIELDS (type) == 0)
+  if (type->num_fields () == 0)
     return true;
 
   i = 0;
   if (strcmp (TYPE_FIELD_NAME (type, 0), "start") == 0)
     {
-      if (TYPE_NFIELDS (type) == 1)
+      if (type->num_fields () == 1)
        return true;
       i = 1;
     }
-  else if (TYPE_NFIELDS (type) == 2)
+  else if (type->num_fields () == 2)
     {
       /* First field had to be "start".  */
       return false;
@@ -203,8 +202,8 @@ rust_range_type_p (struct type *type)
 static bool
 rust_inclusive_range_type_p (struct type *type)
 {
-  return (strstr (TYPE_NAME (type), "::RangeInclusive") != NULL
-         || strstr (TYPE_NAME (type), "::RangeToInclusive") != NULL);
+  return (strstr (type->name (), "::RangeInclusive") != NULL
+         || strstr (type->name (), "::RangeToInclusive") != NULL);
 }
 
 /* Return true if TYPE seems to be the type "u8", otherwise false.  */
@@ -212,7 +211,7 @@ rust_inclusive_range_type_p (struct type *type)
 static bool
 rust_u8_type_p (struct type *type)
 {
-  return (TYPE_CODE (type) == TYPE_CODE_INT
+  return (type->code () == TYPE_CODE_INT
          && TYPE_UNSIGNED (type)
          && TYPE_LENGTH (type) == 1);
 }
@@ -222,7 +221,7 @@ rust_u8_type_p (struct type *type)
 static bool
 rust_chartype_p (struct type *type)
 {
-  return (TYPE_CODE (type) == TYPE_CODE_CHAR
+  return (type->code () == TYPE_CODE_CHAR
          && TYPE_LENGTH (type) == 4
          && TYPE_UNSIGNED (type));
 }
@@ -235,16 +234,16 @@ rust_is_string_type_p (struct type *type)
   LONGEST low_bound, high_bound;
 
   type = check_typedef (type);
-  return ((TYPE_CODE (type) == TYPE_CODE_STRING)
-         || (TYPE_CODE (type) == TYPE_CODE_PTR
-             && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY
+  return ((type->code () == TYPE_CODE_STRING)
+         || (type->code () == TYPE_CODE_PTR
+             && (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ARRAY
                  && rust_u8_type_p (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)))
                  && get_array_bounds (TYPE_TARGET_TYPE (type), &low_bound,
                                       &high_bound)))
-         || (TYPE_CODE (type) == TYPE_CODE_STRUCT
+         || (type->code () == TYPE_CODE_STRUCT
              && !rust_enum_p (type)
              && rust_slice_type_p (type)
-             && strcmp (TYPE_NAME (type), "&str") == 0));
+             && strcmp (type->name (), "&str") == 0));
 }
 
 /* If VALUE represents a trait object pointer, return the underlying
@@ -256,7 +255,7 @@ rust_get_trait_object_pointer (struct value *value)
 {
   struct type *type = check_typedef (value_type (value));
 
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
+  if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
     return NULL;
 
   /* Try to be a bit resilient if the ABI changes.  */
@@ -380,7 +379,7 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse,
   int first_field;
   struct type *type = check_typedef (value_type (val));
 
-  if (rust_slice_type_p (type) && strcmp (TYPE_NAME (type), "&str") == 0)
+  if (rust_slice_type_p (type) && strcmp (type->name (), "&str") == 0)
     {
       /* If what we are printing here is actually a string within a
         structure then VAL will be the original parent value, while TYPE
@@ -400,13 +399,13 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse,
 
   if (!is_tuple)
     {
-      if (TYPE_NAME (type) != NULL)
-        fprintf_filtered (stream, "%s", TYPE_NAME (type));
+      if (type->name () != NULL)
+        fprintf_filtered (stream, "%s", type->name ());
 
-      if (TYPE_NFIELDS (type) == 0)
+      if (type->num_fields () == 0)
         return;
 
-      if (TYPE_NAME (type) != NULL)
+      if (type->name () != NULL)
         fputs_filtered (" ", stream);
     }
 
@@ -419,9 +418,9 @@ val_print_struct (struct value *val, struct ui_file *stream, int recurse,
   opts.deref_ref = 0;
 
   first_field = 1;
-  for (i = 0; i < TYPE_NFIELDS (type); ++i)
+  for (i = 0; i < type->num_fields (); ++i)
     {
-      if (field_is_static (&TYPE_FIELD (type, i)))
+      if (field_is_static (&type->field (i)))
         continue;
 
       if (!first_field)
@@ -471,24 +470,29 @@ rust_print_enum (struct value *val, struct ui_file *stream, int recurse,
 
   opts.deref_ref = 0;
 
+  gdb_assert (rust_enum_p (type));
+  gdb::array_view<const gdb_byte> view (value_contents_for_printing (val),
+                                       TYPE_LENGTH (value_type (val)));
+  type = resolve_dynamic_type (type, view, value_address (val));
+
   if (rust_empty_enum_p (type))
     {
       /* Print the enum type name here to be more clear.  */
       fprintf_filtered (stream, _("%s {%p[<No data fields>%p]}"),
-                       TYPE_NAME (type),
+                       type->name (),
                        metadata_style.style ().ptr (), nullptr);
       return;
     }
 
-  const gdb_byte *valaddr = value_contents_for_printing (val);
-  struct field *variant_field = rust_enum_variant (type, valaddr);
-  struct type *variant_type = FIELD_TYPE (*variant_field);
+  int variant_fieldno = rust_enum_variant (type);
+  val = value_field (val, variant_fieldno);
+  struct type *variant_type = TYPE_FIELD_TYPE (type, variant_fieldno);
 
-  int nfields = TYPE_NFIELDS (variant_type);
+  int nfields = variant_type->num_fields ();
 
   bool is_tuple = rust_tuple_struct_type_p (variant_type);
 
-  fprintf_filtered (stream, "%s", TYPE_NAME (variant_type));
+  fprintf_filtered (stream, "%s", variant_type->name ());
   if (nfields == 0)
     {
       /* In case of a nullary variant like 'None', just output
@@ -505,12 +509,8 @@ rust_print_enum (struct value *val, struct ui_file *stream, int recurse,
       fprintf_filtered (stream, "{");
     }
 
-  struct value *union_value = value_field (val, 0);
-  int fieldno = (variant_field - &TYPE_FIELD (value_type (union_value), 0));
-  val = value_field (union_value, fieldno);
-
   bool first_field = true;
-  for (int j = 0; j < TYPE_NFIELDS (variant_type); j++)
+  for (int j = 0; j < variant_type->num_fields (); j++)
     {
       if (!first_field)
        fputs_filtered (", ", stream);
@@ -559,13 +559,13 @@ rust_value_print_inner (struct value *val, struct ui_file *stream,
                         ? Val_prettyformat : Val_no_prettyformat);
 
   struct type *type = check_typedef (value_type (val));
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_PTR:
       {
        LONGEST low_bound, high_bound;
        
-       if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY
+       if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ARRAY
            && rust_u8_type_p (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type)))
            && get_array_bounds (TYPE_TARGET_TYPE (type), &low_bound,
                                 &high_bound))
@@ -599,7 +599,7 @@ rust_value_print_inner (struct value *val, struct ui_file *stream,
     case TYPE_CODE_INT:
       /* Recognize the unit type.  */
       if (TYPE_UNSIGNED (type) && TYPE_LENGTH (type) == 0
-         && TYPE_NAME (type) != NULL && strcmp (TYPE_NAME (type), "()") == 0)
+         && type->name () != NULL && strcmp (type->name (), "()") == 0)
        {
          fputs_filtered ("()", stream);
          break;
@@ -676,7 +676,7 @@ rust_print_struct_def (struct type *type, const char *varstring,
   /* Print a tuple type simply.  */
   if (rust_tuple_type_p (type))
     {
-      fputs_filtered (TYPE_NAME (type), stream);
+      fputs_filtered (type->name (), stream);
       return;
     }
 
@@ -693,13 +693,11 @@ rust_print_struct_def (struct type *type, const char *varstring,
 
   /* Compute properties of TYPE here because, in the enum case, the
      rest of the code ends up looking only at the variant part.  */
-  const char *tagname = TYPE_NAME (type);
+  const char *tagname = type->name ();
   bool is_tuple_struct = rust_tuple_struct_type_p (type);
   bool is_tuple = rust_tuple_type_p (type);
   bool is_enum = rust_enum_p (type);
 
-  int enum_discriminant_index = -1;
-
   if (for_rust_enum)
     {
       /* Already printing an outer enum, so nothing to print here.  */
@@ -710,27 +708,11 @@ rust_print_struct_def (struct type *type, const char *varstring,
       if (is_enum)
        {
          fputs_filtered ("enum ", stream);
-
-         if (rust_empty_enum_p (type))
-           {
-             if (tagname != NULL)
-               {
-                 fputs_filtered (tagname, stream);
-                 fputs_filtered (" ", stream);
-               }
-             fputs_filtered ("{}", stream);
-             return;
-           }
-
-         type = TYPE_FIELD_TYPE (type, 0);
-
-         struct dynamic_prop *discriminant_prop
-           = get_dyn_prop (DYN_PROP_DISCRIMINATED, type);
-         struct discriminant_info *info
-           = (struct discriminant_info *) discriminant_prop->data.baton;
-         enum_discriminant_index = info->discriminant_index;
+         dynamic_prop *prop = type->dyn_prop (DYN_PROP_VARIANT_PARTS);
+         if (prop != nullptr && prop->kind == PROP_TYPE)
+           type = prop->data.original_type;
        }
-      else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+      else if (type->code () == TYPE_CODE_STRUCT)
        fputs_filtered ("struct ", stream);
       else
        fputs_filtered ("union ", stream);
@@ -739,7 +721,7 @@ rust_print_struct_def (struct type *type, const char *varstring,
        fputs_filtered (tagname, stream);
     }
 
-  if (TYPE_NFIELDS (type) == 0 && !is_tuple)
+  if (type->num_fields () == 0 && !is_tuple)
     return;
   if (for_rust_enum && !flags->print_offsets)
     fputs_filtered (is_tuple_struct ? "(" : "{", stream);
@@ -751,11 +733,11 @@ rust_print_struct_def (struct type *type, const char *varstring,
      field indices here because it simplifies calls to
      print_offset_data::update below.  */
   std::vector<int> fields;
-  for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+  for (int i = 0; i < type->num_fields (); ++i)
     {
-      if (field_is_static (&TYPE_FIELD (type, i)))
+      if (field_is_static (&type->field (i)))
        continue;
-      if (is_enum && i == enum_discriminant_index)
+      if (is_enum && TYPE_FIELD_ARTIFICIAL (type, i))
        continue;
       fields.push_back (i);
     }
@@ -771,8 +753,8 @@ rust_print_struct_def (struct type *type, const char *varstring,
     {
       QUIT;
 
-      gdb_assert (!field_is_static (&TYPE_FIELD (type, i)));
-      gdb_assert (! (is_enum && i == enum_discriminant_index));
+      gdb_assert (!field_is_static (&type->field (i)));
+      gdb_assert (! (is_enum && TYPE_FIELD_ARTIFICIAL (type, i)));
 
       if (flags->print_offsets)
        podata->update (type, i, stream);
@@ -801,7 +783,7 @@ rust_print_struct_def (struct type *type, const char *varstring,
       /* Note that this check of "I" is ok because we only sorted the
         fields by offset when print_offsets was set, so we won't take
         this branch in that case.  */
-      else if (i + 1 < TYPE_NFIELDS (type))
+      else if (i + 1 < type->num_fields ())
        fputs_filtered (", ", stream);
     }
 
@@ -842,19 +824,19 @@ rust_internal_print_type (struct type *type, const char *varstring,
 {
   QUIT;
   if (show <= 0
-      && TYPE_NAME (type) != NULL)
+      && type->name () != NULL)
     {
       /* Rust calls the unit type "void" in its debuginfo,
          but we don't want to print it as that.  */
-      if (TYPE_CODE (type) == TYPE_CODE_VOID)
+      if (type->code () == TYPE_CODE_VOID)
         fputs_filtered ("()", stream);
       else
-        fputs_filtered (TYPE_NAME (type), stream);
+        fputs_filtered (type->name (), stream);
       return;
     }
 
   type = check_typedef (type);
-  switch (TYPE_CODE (type))
+  switch (type->code ())
     {
     case TYPE_CODE_VOID:
       /* If we have an enum, we've already printed the type's
@@ -873,7 +855,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
       if (varstring != NULL)
        fputs_filtered (varstring, stream);
       fputs_filtered ("(", stream);
-      for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+      for (int i = 0; i < type->num_fields (); ++i)
        {
          QUIT;
          if (i > 0)
@@ -883,7 +865,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
        }
       fputs_filtered (")", stream);
       /* If it returns unit, we can omit the return type.  */
-      if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+      if (TYPE_TARGET_TYPE (type)->code () != TYPE_CODE_VOID)
         {
           fputs_filtered (" -> ", stream);
           rust_internal_print_type (TYPE_TARGET_TYPE (type), "", stream,
@@ -921,22 +903,22 @@ rust_internal_print_type (struct type *type, const char *varstring,
        int len = 0;
 
        fputs_filtered ("enum ", stream);
-       if (TYPE_NAME (type) != NULL)
+       if (type->name () != NULL)
          {
-           fputs_filtered (TYPE_NAME (type), stream);
+           fputs_filtered (type->name (), stream);
            fputs_filtered (" ", stream);
-           len = strlen (TYPE_NAME (type));
+           len = strlen (type->name ());
          }
        fputs_filtered ("{\n", stream);
 
-       for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+       for (int i = 0; i < type->num_fields (); ++i)
          {
            const char *name = TYPE_FIELD_NAME (type, i);
 
            QUIT;
 
            if (len > 0
-               && strncmp (name, TYPE_NAME (type), len) == 0
+               && strncmp (name, type->name (), len) == 0
                && name[len] == ':'
                && name[len + 1] == ':')
              name += len + 2;
@@ -951,8 +933,8 @@ rust_internal_print_type (struct type *type, const char *varstring,
 
     case TYPE_CODE_PTR:
       {
-       if (TYPE_NAME (type) != nullptr)
-         fputs_filtered (TYPE_NAME (type), stream);
+       if (type->name () != nullptr)
+         fputs_filtered (type->name (), stream);
        else
          {
            /* We currently can't distinguish between pointers and
@@ -969,16 +951,6 @@ rust_internal_print_type (struct type *type, const char *varstring,
     }
 }
 
-static void
-rust_print_type (struct type *type, const char *varstring,
-                struct ui_file *stream, int show, int level,
-                const struct type_print_options *flags)
-{
-  print_offset_data podata;
-  rust_internal_print_type (type, varstring, stream, show, level,
-                           flags, false, &podata);
-}
-
 \f
 
 /* Like arch_composite_type, but uses TYPE to decide how to allocate
@@ -999,18 +971,18 @@ rust_composite_type (struct type *original,
   if (field2 != NULL)
     ++nfields;
 
-  TYPE_CODE (result) = TYPE_CODE_STRUCT;
-  TYPE_NAME (result) = name;
+  result->set_code (TYPE_CODE_STRUCT);
+  result->set_name (name);
 
-  TYPE_NFIELDS (result) = nfields;
-  TYPE_FIELDS (result)
-    = (struct field *) TYPE_ZALLOC (result, nfields * sizeof (struct field));
+  result->set_num_fields (nfields);
+  result->set_fields
+    ((struct field *) TYPE_ZALLOC (result, nfields * sizeof (struct field)));
 
   i = 0;
   bitpos = 0;
   if (field1 != NULL)
     {
-      struct field *field = &TYPE_FIELD (result, i);
+      struct field *field = &result->field (i);
 
       SET_FIELD_BITPOS (*field, bitpos);
       bitpos += TYPE_LENGTH (type1) * TARGET_CHAR_BIT;
@@ -1021,7 +993,7 @@ rust_composite_type (struct type *original,
     }
   if (field2 != NULL)
     {
-      struct field *field = &TYPE_FIELD (result, i);
+      struct field *field = &result->field (i);
       unsigned align = type_align (type2);
 
       if (align != 0)
@@ -1084,51 +1056,6 @@ enum rust_primitive_types
   nr_rust_primitive_types
 };
 
-/* la_language_arch_info implementation for Rust.  */
-
-static void
-rust_language_arch_info (struct gdbarch *gdbarch,
-                        struct language_arch_info *lai)
-{
-  const struct builtin_type *builtin = builtin_type (gdbarch);
-  struct type *tem;
-  struct type **types;
-  unsigned int length;
-
-  types = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_rust_primitive_types + 1,
-                                 struct type *);
-
-  types[rust_primitive_bool] = arch_boolean_type (gdbarch, 8, 1, "bool");
-  types[rust_primitive_char] = arch_character_type (gdbarch, 32, 1, "char");
-  types[rust_primitive_i8] = arch_integer_type (gdbarch, 8, 0, "i8");
-  types[rust_primitive_u8] = arch_integer_type (gdbarch, 8, 1, "u8");
-  types[rust_primitive_i16] = arch_integer_type (gdbarch, 16, 0, "i16");
-  types[rust_primitive_u16] = arch_integer_type (gdbarch, 16, 1, "u16");
-  types[rust_primitive_i32] = arch_integer_type (gdbarch, 32, 0, "i32");
-  types[rust_primitive_u32] = arch_integer_type (gdbarch, 32, 1, "u32");
-  types[rust_primitive_i64] = arch_integer_type (gdbarch, 64, 0, "i64");
-  types[rust_primitive_u64] = arch_integer_type (gdbarch, 64, 1, "u64");
-
-  length = 8 * TYPE_LENGTH (builtin->builtin_data_ptr);
-  types[rust_primitive_isize] = arch_integer_type (gdbarch, length, 0, "isize");
-  types[rust_primitive_usize] = arch_integer_type (gdbarch, length, 1, "usize");
-
-  types[rust_primitive_f32] = arch_float_type (gdbarch, 32, "f32",
-                                              floatformats_ieee_single);
-  types[rust_primitive_f64] = arch_float_type (gdbarch, 64, "f64",
-                                              floatformats_ieee_double);
-
-  types[rust_primitive_unit] = arch_integer_type (gdbarch, 0, 1, "()");
-
-  tem = make_cv_type (1, 0, types[rust_primitive_u8], NULL);
-  types[rust_primitive_str] = rust_slice_type ("&str", tem,
-                                              types[rust_primitive_usize]);
-
-  lai->primitive_type_vector = types;
-  lai->bool_type_default = types[rust_primitive_bool];
-  lai->string_char_type = types[rust_primitive_u8];
-}
-
 \f
 
 /* A helper for rust_evaluate_subexp that handles OP_FUNCALL.  */
@@ -1169,19 +1096,19 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
   args[0] = arg0;
 
   /* We don't yet implement real Deref semantics.  */
-  while (TYPE_CODE (value_type (args[0])) == TYPE_CODE_PTR)
+  while (value_type (args[0])->code () == TYPE_CODE_PTR)
     args[0] = value_ind (args[0]);
 
   type = value_type (args[0]);
-  if ((TYPE_CODE (type) != TYPE_CODE_STRUCT
-       && TYPE_CODE (type) != TYPE_CODE_UNION
-       && TYPE_CODE (type) != TYPE_CODE_ENUM)
+  if ((type->code () != TYPE_CODE_STRUCT
+       && type->code () != TYPE_CODE_UNION
+       && type->code () != TYPE_CODE_ENUM)
       || rust_tuple_type_p (type))
     error (_("Method calls only supported on struct or enum types"));
-  if (TYPE_NAME (type) == NULL)
+  if (type->name () == NULL)
     error (_("Method call on nameless type"));
 
-  std::string name = std::string (TYPE_NAME (type)) + "::" + method;
+  std::string name = std::string (type->name ()) + "::" + method;
 
   block = get_selected_block (0);
   sym = lookup_symbol (name.c_str (), block, VAR_DOMAIN, NULL);
@@ -1189,10 +1116,10 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
     error (_("Could not find function named '%s'"), name.c_str ());
 
   fn_type = SYMBOL_TYPE (sym.symbol);
-  if (TYPE_NFIELDS (fn_type) == 0)
+  if (fn_type->num_fields () == 0)
     error (_("Function '%s' takes no arguments"), name.c_str ());
 
-  if (TYPE_CODE (TYPE_FIELD_TYPE (fn_type, 0)) == TYPE_CODE_PTR)
+  if (TYPE_FIELD_TYPE (fn_type, 0)->code () == TYPE_CODE_PTR)
     args[0] = value_addr (args[0]);
 
   function = address_of_variable (sym.symbol, block);
@@ -1321,7 +1248,7 @@ rust_compute_range (struct type *type, struct value *range,
   *high = 0;
   *kind = BOTH_BOUND_DEFAULT;
 
-  if (TYPE_NFIELDS (type) == 0)
+  if (type->num_fields () == 0)
     return;
 
   i = 0;
@@ -1331,7 +1258,7 @@ rust_compute_range (struct type *type, struct value *range,
       *low = value_as_long (value_field (range, 0));
       ++i;
     }
-  if (TYPE_NFIELDS (type) > i
+  if (type->num_fields () > i
       && strcmp (TYPE_FIELD_NAME (type, i), "end") == 0)
     {
       *kind = (*kind == BOTH_BOUND_DEFAULT
@@ -1379,11 +1306,11 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
   if (noside == EVAL_AVOID_SIDE_EFFECTS)
     {
       struct type *base_type = nullptr;
-      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+      if (type->code () == TYPE_CODE_ARRAY)
        base_type = TYPE_TARGET_TYPE (type);
       else if (rust_slice_type_p (type))
        {
-         for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+         for (int i = 0; i < type->num_fields (); ++i)
            {
              if (strcmp (TYPE_FIELD_NAME (type, i), "data_ptr") == 0)
                {
@@ -1394,7 +1321,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
          if (base_type == nullptr)
            error (_("Could not find 'data_ptr' in slice type"));
        }
-      else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+      else if (type->code () == TYPE_CODE_PTR)
        base_type = TYPE_TARGET_TYPE (type);
       else
        error (_("Cannot subscript non-array type"));
@@ -1423,7 +1350,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
       LONGEST low_bound;
       struct value *base;
 
-      if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
+      if (type->code () == TYPE_CODE_ARRAY)
        {
          base = lhs;
          if (!get_array_bounds (type, &low_bound, &high_bound))
@@ -1441,7 +1368,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
          low_bound = 0;
          high_bound = value_as_long (len);
        }
-      else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+      else if (type->code () == TYPE_CODE_PTR)
        {
          base = lhs;
          low_bound = 0;
@@ -1483,7 +1410,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
                                                  "usize");
          const char *new_name = ((type != nullptr
                                   && rust_slice_type_p (type))
-                                 ? TYPE_NAME (type) : "&[*gdb*]");
+                                 ? type->name () : "&[*gdb*]");
 
          slice = rust_slice_type (new_name, value_type (result), usize);
 
@@ -1544,7 +1471,7 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
            /* Preserving the type is enough.  */
            return value;
          }
-       if (TYPE_CODE (value_type (value)) == TYPE_CODE_BOOL)
+       if (value_type (value)->code () == TYPE_CODE_BOOL)
          result = value_from_longest (value_type (value),
                                       value_logical_not (value));
        else
@@ -1673,45 +1600,41 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
 
         type = value_type (lhs);
 
-       if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
+       if (type->code () == TYPE_CODE_STRUCT)
          {
            struct type *outer_type = NULL;
 
            if (rust_enum_p (type))
              {
+               gdb::array_view<const gdb_byte> view (value_contents (lhs),
+                                                     TYPE_LENGTH (type));
+               type = resolve_dynamic_type (type, view, value_address (lhs));
+
                if (rust_empty_enum_p (type))
                  error (_("Cannot access field %d of empty enum %s"),
-                        field_number, TYPE_NAME (type));
+                        field_number, type->name ());
 
-               const gdb_byte *valaddr = value_contents (lhs);
-               struct field *variant_field = rust_enum_variant (type, valaddr);
-
-               struct value *union_value = value_primitive_field (lhs, 0, 0,
-                                                                  type);
-
-               int fieldno = (variant_field
-                              - &TYPE_FIELD (value_type (union_value), 0));
-               lhs = value_primitive_field (union_value, 0, fieldno,
-                                            value_type (union_value));
+               int fieldno = rust_enum_variant (type);
+               lhs = value_primitive_field (lhs, 0, fieldno, type);
                outer_type = type;
                type = value_type (lhs);
              }
 
            /* Tuples and tuple structs */
-           nfields = TYPE_NFIELDS (type);
+           nfields = type->num_fields ();
 
            if (field_number >= nfields || field_number < 0)
              {
                if (outer_type != NULL)
                  error(_("Cannot access field %d of variant %s::%s, "
                          "there are only %d fields"),
-                       field_number, TYPE_NAME (outer_type),
-                       rust_last_path_segment (TYPE_NAME (type)),
+                       field_number, outer_type->name (),
+                       rust_last_path_segment (type->name ()),
                        nfields);
                else
                  error(_("Cannot access field %d of %s, "
                          "there are only %d fields"),
-                       field_number, TYPE_NAME (type), nfields);
+                       field_number, type->name (), nfields);
              }
 
            /* Tuples are tuple structs too.  */
@@ -1719,13 +1642,13 @@ rust_evaluate_subexp (struct type *expect_type, struct expression *exp,
              {
                if (outer_type != NULL)
                  error(_("Variant %s::%s is not a tuple variant"),
-                       TYPE_NAME (outer_type),
-                       rust_last_path_segment (TYPE_NAME (type)));
+                       outer_type->name (),
+                       rust_last_path_segment (type->name ()));
                else
                  error(_("Attempting to access anonymous field %d "
                          "of %s, which is not a tuple, tuple struct, or "
                          "tuple-like variant"),
-                     field_number, TYPE_NAME (type));
+                     field_number, type->name ());
              }
 
            result = value_primitive_field (lhs, 0, field_number, type);
@@ -1749,30 +1672,26 @@ tuple structs, and tuple-like enum variants"));
 
        const char *field_name = &exp->elts[pc + 2].string;
         type = value_type (lhs);
-        if (TYPE_CODE (type) == TYPE_CODE_STRUCT && rust_enum_p (type))
+        if (type->code () == TYPE_CODE_STRUCT && rust_enum_p (type))
          {
+           gdb::array_view<const gdb_byte> view (value_contents (lhs),
+                                                 TYPE_LENGTH (type));
+           type = resolve_dynamic_type (type, view, value_address (lhs));
+
            if (rust_empty_enum_p (type))
              error (_("Cannot access field %s of empty enum %s"),
-                    field_name, TYPE_NAME (type));
+                    field_name, type->name ());
 
-           const gdb_byte *valaddr = value_contents (lhs);
-           struct field *variant_field = rust_enum_variant (type, valaddr);
-
-           struct value *union_value = value_primitive_field (lhs, 0, 0,
-                                                              type);
-
-           int fieldno = (variant_field
-                          - &TYPE_FIELD (value_type (union_value), 0));
-           lhs = value_primitive_field (union_value, 0, fieldno,
-                                        value_type (union_value));
+           int fieldno = rust_enum_variant (type);
+           lhs = value_primitive_field (lhs, 0, fieldno, type);
 
            struct type *outer_type = type;
            type = value_type (lhs);
            if (rust_tuple_type_p (type) || rust_tuple_struct_type_p (type))
                error (_("Attempting to access named field %s of tuple "
                         "variant %s::%s, which has only anonymous fields"),
-                      field_name, TYPE_NAME (outer_type),
-                      rust_last_path_segment (TYPE_NAME (type)));
+                      field_name, outer_type->name (),
+                      rust_last_path_segment (type->name ()));
 
            try
              {
@@ -1782,8 +1701,8 @@ tuple structs, and tuple-like enum variants"));
            catch (const gdb_exception_error &except)
              {
                error (_("Could not find field %s of struct variant %s::%s"),
-                      field_name, TYPE_NAME (outer_type),
-                      rust_last_path_segment (TYPE_NAME (type)));
+                      field_name, outer_type->name (),
+                      rust_last_path_segment (type->name ()));
              }
          }
        else
@@ -2087,17 +2006,6 @@ rust_lookup_symbol_nonlocal (const struct language_defn *langdef,
 
 \f
 
-/* la_sniff_from_mangled_name for Rust.  */
-
-static int
-rust_sniff_from_mangled_name (const char *mangled, char **demangled)
-{
-  *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
-  return *demangled != NULL;
-}
-
-\f
-
 /* la_watch_location_expression for Rust.  */
 
 static gdb::unique_xmalloc_ptr<char>
@@ -2127,7 +2035,9 @@ static const char *rust_extensions[] =
   ".rs", NULL
 };
 
-extern const struct language_defn rust_language_defn =
+/* Constant data representing the Rust language.  */
+
+extern const struct language_data rust_language_data =
 {
   "rust",
   "Rust",
@@ -2143,18 +2053,12 @@ extern const struct language_defn rust_language_defn =
   rust_printchar,              /* Print a character constant */
   rust_printstr,               /* Function to print string constant */
   rust_emitchar,               /* Print a single char */
-  rust_print_type,             /* Print a type using appropriate syntax */
   rust_print_typedef,          /* Print a typedef using appropriate syntax */
   rust_value_print_inner,      /* la_value_print_inner */
   c_value_print,               /* Print a top-level value */
-  default_read_var_value,      /* la_read_var_value */
-  NULL,                                /* Language specific skip_trampoline */
   NULL,                                /* name_of_this */
   false,                       /* la_store_sym_names_in_linkage_form_p */
   rust_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
-  basic_lookup_transparent_type,/* lookup_transparent_type */
-  gdb_demangle,                        /* Language specific symbol demangler */
-  rust_sniff_from_mangled_name,
   NULL,                                /* Language specific
                                   class_name_from_physname */
   c_op_print_tab,              /* expression operators for printing */
@@ -2162,16 +2066,91 @@ extern const struct language_defn rust_language_defn =
   0,                           /* String lower bound */
   default_word_break_characters,
   default_collect_symbol_completion_matches,
-  rust_language_arch_info,
-  default_print_array_index,
-  default_pass_by_reference,
   rust_watch_location_expression,
   NULL,                                /* la_get_symbol_name_matcher */
-  iterate_over_symbols,
-  default_search_name_hash,
   &default_varobj_ops,
   NULL,
-  NULL,
   rust_is_string_type_p,
   "{...}"                      /* la_struct_too_deep_ellipsis */
 };
+
+/* Class representing the Rust language.  */
+
+class rust_language : public language_defn
+{
+public:
+  rust_language ()
+    : language_defn (language_rust, rust_language_data)
+  { /* Nothing.  */ }
+
+  /* See language.h.  */
+  void language_arch_info (struct gdbarch *gdbarch,
+                          struct language_arch_info *lai) const override
+  {
+    const struct builtin_type *builtin = builtin_type (gdbarch);
+
+    struct type **types
+      = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_rust_primitive_types + 1,
+                               struct type *);
+
+    types[rust_primitive_bool] = arch_boolean_type (gdbarch, 8, 1, "bool");
+    types[rust_primitive_char] = arch_character_type (gdbarch, 32, 1, "char");
+    types[rust_primitive_i8] = arch_integer_type (gdbarch, 8, 0, "i8");
+    types[rust_primitive_u8] = arch_integer_type (gdbarch, 8, 1, "u8");
+    types[rust_primitive_i16] = arch_integer_type (gdbarch, 16, 0, "i16");
+    types[rust_primitive_u16] = arch_integer_type (gdbarch, 16, 1, "u16");
+    types[rust_primitive_i32] = arch_integer_type (gdbarch, 32, 0, "i32");
+    types[rust_primitive_u32] = arch_integer_type (gdbarch, 32, 1, "u32");
+    types[rust_primitive_i64] = arch_integer_type (gdbarch, 64, 0, "i64");
+    types[rust_primitive_u64] = arch_integer_type (gdbarch, 64, 1, "u64");
+
+    unsigned int length = 8 * TYPE_LENGTH (builtin->builtin_data_ptr);
+    types[rust_primitive_isize] = arch_integer_type (gdbarch, length, 0, "isize");
+    types[rust_primitive_usize] = arch_integer_type (gdbarch, length, 1, "usize");
+
+    types[rust_primitive_f32] = arch_float_type (gdbarch, 32, "f32",
+                                                floatformats_ieee_single);
+    types[rust_primitive_f64] = arch_float_type (gdbarch, 64, "f64",
+                                                floatformats_ieee_double);
+
+    types[rust_primitive_unit] = arch_integer_type (gdbarch, 0, 1, "()");
+
+    struct type *tem = make_cv_type (1, 0, types[rust_primitive_u8], NULL);
+    types[rust_primitive_str] = rust_slice_type ("&str", tem,
+                                                types[rust_primitive_usize]);
+
+    lai->primitive_type_vector = types;
+    lai->bool_type_default = types[rust_primitive_bool];
+    lai->string_char_type = types[rust_primitive_u8];
+  }
+
+  /* See language.h.  */
+  bool sniff_from_mangled_name (const char *mangled,
+                               char **demangled) const override
+  {
+    *demangled = gdb_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+    return *demangled != NULL;
+  }
+
+  /* See language.h.  */
+
+  char *demangle (const char *mangled, int options) const override
+  {
+    return gdb_demangle (mangled, options);
+  }
+
+  /* See language.h.  */
+
+  void print_type (struct type *type, const char *varstring,
+                  struct ui_file *stream, int show, int level,
+                  const struct type_print_options *flags) const override
+  {
+    print_offset_data podata;
+    rust_internal_print_type (type, varstring, stream, show, level,
+                             flags, false, &podata);
+  }
+};
+
+/* Single instance of the Rust language class.  */
+
+static rust_language rust_language_defn;
This page took 0.038711 seconds and 4 git commands to generate.