[gdb/testsuite] Fix captured_command_loop breakpoint in selftests
[binutils-gdb.git] / gdb / rust-lang.c
index 26e2ad5ce25265d5b02114d9ee50ebe12199f2e1..ddd4b57d29442f9702eecc9c058b009115fedd32 100644 (file)
@@ -226,26 +226,6 @@ rust_chartype_p (struct type *type)
          && TYPE_UNSIGNED (type));
 }
 
-/* Return true if TYPE is a string type.  */
-
-static bool
-rust_is_string_type_p (struct type *type)
-{
-  LONGEST low_bound, high_bound;
-
-  type = check_typedef (type);
-  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_CODE_STRUCT
-             && !rust_enum_p (type)
-             && rust_slice_type_p (type)
-             && strcmp (type->name (), "&str") == 0));
-}
-
 /* If VALUE represents a trait object pointer, return the underlying
    pointer with the correct (i.e., runtime) type.  Otherwise, return
    NULL.  */
@@ -281,43 +261,7 @@ rust_get_trait_object_pointer (struct value *value)
 
 \f
 
-/* la_emitchar implementation for Rust.  */
-
-static void
-rust_emitchar (int c, struct type *type, struct ui_file *stream, int quoter)
-{
-  if (!rust_chartype_p (type))
-    generic_emit_char (c, type, stream, quoter,
-                      target_charset (get_type_arch (type)));
-  else if (c == '\\' || c == quoter)
-    fprintf_filtered (stream, "\\%c", c);
-  else if (c == '\n')
-    fputs_filtered ("\\n", stream);
-  else if (c == '\r')
-    fputs_filtered ("\\r", stream);
-  else if (c == '\t')
-    fputs_filtered ("\\t", stream);
-  else if (c == '\0')
-    fputs_filtered ("\\0", stream);
-  else if (c >= 32 && c <= 127 && isprint (c))
-    fputc_filtered (c, stream);
-  else if (c <= 255)
-    fprintf_filtered (stream, "\\x%02x", c);
-  else
-    fprintf_filtered (stream, "\\u{%06x}", c);
-}
-
-/* la_printchar implementation for Rust.  */
-
-static void
-rust_printchar (int c, struct type *type, struct ui_file *stream)
-{
-  fputs_filtered ("'", stream);
-  LA_EMIT_CHAR (c, type, stream, '\'');
-  fputs_filtered ("'", stream);
-}
-
-/* la_printstr implementation for Rust.  */
+/* language_defn::printstr implementation for Rust.  */
 
 static void
 rust_printstr (struct ui_file *stream, struct type *type,
@@ -486,7 +430,7 @@ rust_print_enum (struct value *val, struct ui_file *stream, int recurse,
 
   int variant_fieldno = rust_enum_variant (type);
   val = value_field (val, variant_fieldno);
-  struct type *variant_type = TYPE_FIELD_TYPE (type, variant_fieldno);
+  struct type *variant_type = type->field (variant_fieldno).type ();
 
   int nfields = variant_type->num_fields ();
 
@@ -709,8 +653,8 @@ rust_print_struct_def (struct type *type, const char *varstring,
        {
          fputs_filtered ("enum ", stream);
          dynamic_prop *prop = type->dyn_prop (DYN_PROP_VARIANT_PARTS);
-         if (prop != nullptr && prop->kind == PROP_TYPE)
-           type = prop->data.original_type;
+         if (prop != nullptr && prop->kind () == PROP_TYPE)
+           type = prop->original_type ();
        }
       else if (type->code () == TYPE_CODE_STRUCT)
        fputs_filtered ("struct ", stream);
@@ -775,7 +719,7 @@ rust_print_struct_def (struct type *type, const char *varstring,
                          styled_string (variable_name_style.style (),
                                         TYPE_FIELD_NAME (type, i)));
 
-      rust_internal_print_type (TYPE_FIELD_TYPE (type, i), NULL,
+      rust_internal_print_type (type->field (i).type (), NULL,
                                stream, (is_enum ? show : show - 1),
                                level + 2, flags, is_enum, podata);
       if (!for_rust_enum || flags->print_offsets)
@@ -801,19 +745,6 @@ rust_print_struct_def (struct type *type, const char *varstring,
   fputs_filtered (is_tuple_struct ? ")" : "}", stream);
 }
 
-/* la_print_typedef implementation for Rust.  */
-
-static void
-rust_print_typedef (struct type *type,
-                   struct symbol *new_symbol,
-                   struct ui_file *stream)
-{
-  type = check_typedef (type);
-  fprintf_filtered (stream, "type %s = ", new_symbol->print_name ());
-  type_print (type, "", stream, 0);
-  fprintf_filtered (stream, ";");
-}
-
 /* la_print_type implementation for Rust.  */
 
 static void
@@ -860,7 +791,7 @@ rust_internal_print_type (struct type *type, const char *varstring,
          QUIT;
          if (i > 0)
            fputs_filtered (", ", stream);
-         rust_internal_print_type (TYPE_FIELD_TYPE (type, i), "", stream,
+         rust_internal_print_type (type->field (i).type (), "", stream,
                                    -1, 0, flags, false, podata);
        }
       fputs_filtered (")", stream);
@@ -882,8 +813,8 @@ rust_internal_print_type (struct type *type, const char *varstring,
                                  stream, show - 1, level, flags, false,
                                  podata);
 
-       if (TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCEXPR
-           || TYPE_HIGH_BOUND_KIND (TYPE_INDEX_TYPE (type)) == PROP_LOCLIST)
+       if (type->bounds ()->high.kind () == PROP_LOCEXPR
+           || type->bounds ()->high.kind () == PROP_LOCLIST)
          fprintf_filtered (stream, "; variable length");
        else if (get_array_bounds (type, &low_bound, &high_bound))
          fprintf_filtered (stream, "; %s",
@@ -951,16 +882,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
@@ -998,7 +919,7 @@ rust_composite_type (struct type *original,
       bitpos += TYPE_LENGTH (type1) * TARGET_CHAR_BIT;
 
       FIELD_NAME (*field) = field1;
-      FIELD_TYPE (*field) = type1;
+      field->set_type (type1);
       ++i;
     }
   if (field2 != NULL)
@@ -1018,14 +939,14 @@ rust_composite_type (struct type *original,
       SET_FIELD_BITPOS (*field, bitpos);
 
       FIELD_NAME (*field) = field2;
-      FIELD_TYPE (*field) = type2;
+      field->set_type (type2);
       ++i;
     }
 
   if (i > 0)
     TYPE_LENGTH (result)
       = (TYPE_FIELD_BITPOS (result, i - 1) / TARGET_CHAR_BIT +
-        TYPE_LENGTH (TYPE_FIELD_TYPE (result, i - 1)));
+        TYPE_LENGTH (result->field (i - 1).type ()));
   return result;
 }
 
@@ -1129,7 +1050,7 @@ rust_evaluate_funcall (struct expression *exp, int *pos, enum noside noside)
   if (fn_type->num_fields () == 0)
     error (_("Function '%s' takes no arguments"), name.c_str ());
 
-  if (TYPE_FIELD_TYPE (fn_type, 0)->code () == TYPE_CODE_PTR)
+  if (fn_type->field (0).type ()->code () == TYPE_CODE_PTR)
     args[0] = value_addr (args[0]);
 
   function = address_of_variable (sym.symbol, block);
@@ -1324,7 +1245,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside,
            {
              if (strcmp (TYPE_FIELD_NAME (type, i), "data_ptr") == 0)
                {
-                 base_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, i));
+                 base_type = TYPE_TARGET_TYPE (type->field (i).type ());
                  break;
                }
            }
@@ -1971,76 +1892,6 @@ rust_operator_check (struct expression *exp, int pos,
 
 \f
 
-/* Implementation of la_lookup_symbol_nonlocal for Rust.  */
-
-static struct block_symbol
-rust_lookup_symbol_nonlocal (const struct language_defn *langdef,
-                            const char *name,
-                            const struct block *block,
-                            const domain_enum domain)
-{
-  struct block_symbol result = {};
-
-  if (symbol_lookup_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog,
-                         "rust_lookup_symbol_non_local"
-                         " (%s, %s (scope %s), %s)\n",
-                         name, host_address_to_string (block),
-                         block_scope (block), domain_name (domain));
-    }
-
-  /* Look up bare names in the block's scope.  */
-  std::string scopedname;
-  if (name[cp_find_first_component (name)] == '\0')
-    {
-      const char *scope = block_scope (block);
-
-      if (scope[0] != '\0')
-       {
-         scopedname = std::string (scope) + "::" + name;
-         name = scopedname.c_str ();
-       }
-      else
-       name = NULL;
-    }
-
-  if (name != NULL)
-    {
-      result = lookup_symbol_in_static_block (name, block, domain);
-      if (result.symbol == NULL)
-       result = lookup_global_symbol (name, block, domain);
-    }
-  return result;
-}
-
-\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>
-rust_watch_location_expression (struct type *type, CORE_ADDR addr)
-{
-  type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
-  std::string name = type_to_string (type);
-  return gdb::unique_xmalloc_ptr<char>
-    (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr),
-                name.c_str ()));
-}
-
-\f
-
 static const struct exp_descriptor exp_descriptor_rust = 
 {
   rust_print_subexp,
@@ -2069,33 +1920,12 @@ extern const struct language_data rust_language_data =
   macro_expansion_no,
   rust_extensions,
   &exp_descriptor_rust,
-  rust_parse,
-  null_post_parser,
-  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 */
-  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 */
-  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 */
   1,                           /* c-style arrays */
   0,                           /* String lower bound */
-  default_word_break_characters,
-  default_collect_symbol_completion_matches,
-  rust_watch_location_expression,
-  NULL,                                /* la_get_symbol_name_matcher */
   &default_varobj_ops,
-  NULL,
-  rust_is_string_type_p,
   "{...}"                      /* la_struct_too_deep_ellipsis */
 };
 
@@ -2148,6 +1978,178 @@ public:
     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);
+  }
+
+  /* See language.h.  */
+
+  gdb::unique_xmalloc_ptr<char> watch_location_expression
+       (struct type *type, CORE_ADDR addr) const override
+  {
+    type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
+    std::string name = type_to_string (type);
+    return gdb::unique_xmalloc_ptr<char>
+      (xstrprintf ("*(%s as *mut %s)", core_addr_to_string (addr),
+                  name.c_str ()));
+  }
+
+  /* See language.h.  */
+
+  void value_print_inner
+       (struct value *val, struct ui_file *stream, int recurse,
+        const struct value_print_options *options) const override
+  {
+    return rust_value_print_inner (val, stream, recurse, options);
+  }
+
+  /* See language.h.  */
+
+  struct block_symbol lookup_symbol_nonlocal
+       (const char *name, const struct block *block,
+        const domain_enum domain) const override
+  {
+    struct block_symbol result = {};
+
+    if (symbol_lookup_debug)
+      {
+       fprintf_unfiltered (gdb_stdlog,
+                           "rust_lookup_symbol_non_local"
+                           " (%s, %s (scope %s), %s)\n",
+                           name, host_address_to_string (block),
+                           block_scope (block), domain_name (domain));
+      }
+
+    /* Look up bare names in the block's scope.  */
+    std::string scopedname;
+    if (name[cp_find_first_component (name)] == '\0')
+      {
+       const char *scope = block_scope (block);
+
+       if (scope[0] != '\0')
+         {
+           scopedname = std::string (scope) + "::" + name;
+           name = scopedname.c_str ();
+         }
+       else
+         name = NULL;
+      }
+
+    if (name != NULL)
+      {
+       result = lookup_symbol_in_static_block (name, block, domain);
+       if (result.symbol == NULL)
+         result = lookup_global_symbol (name, block, domain);
+      }
+    return result;
+  }
+
+  /* See language.h.  */
+
+  int parser (struct parser_state *ps) const override
+  {
+    return rust_parse (ps);
+  }
+
+  /* See language.h.  */
+
+  void emitchar (int ch, struct type *chtype,
+                struct ui_file *stream, int quoter) const override
+  {
+    if (!rust_chartype_p (chtype))
+      generic_emit_char (ch, chtype, stream, quoter,
+                        target_charset (get_type_arch (chtype)));
+    else if (ch == '\\' || ch == quoter)
+      fprintf_filtered (stream, "\\%c", ch);
+    else if (ch == '\n')
+      fputs_filtered ("\\n", stream);
+    else if (ch == '\r')
+      fputs_filtered ("\\r", stream);
+    else if (ch == '\t')
+      fputs_filtered ("\\t", stream);
+    else if (ch == '\0')
+      fputs_filtered ("\\0", stream);
+    else if (ch >= 32 && ch <= 127 && isprint (ch))
+      fputc_filtered (ch, stream);
+    else if (ch <= 255)
+      fprintf_filtered (stream, "\\x%02x", ch);
+    else
+      fprintf_filtered (stream, "\\u{%06x}", ch);
+  }
+
+  /* See language.h.  */
+
+  void printchar (int ch, struct type *chtype,
+                 struct ui_file *stream) const override
+  {
+    fputs_filtered ("'", stream);
+    LA_EMIT_CHAR (ch, chtype, stream, '\'');
+    fputs_filtered ("'", stream);
+  }
+
+  /* See language.h.  */
+
+  void printstr (struct ui_file *stream, struct type *elttype,
+                const gdb_byte *string, unsigned int length,
+                const char *encoding, int force_ellipses,
+                const struct value_print_options *options) const override
+  {
+    rust_printstr (stream, elttype, string, length, encoding,
+                  force_ellipses, options);
+  }
+
+  /* See language.h.  */
+
+  void print_typedef (struct type *type, struct symbol *new_symbol,
+                     struct ui_file *stream) const override
+  {
+    type = check_typedef (type);
+    fprintf_filtered (stream, "type %s = ", new_symbol->print_name ());
+    type_print (type, "", stream, 0);
+    fprintf_filtered (stream, ";");
+  }
+
+  /* See language.h.  */
+
+  bool is_string_type_p (struct type *type) const override
+  {
+    LONGEST low_bound, high_bound;
+
+    type = check_typedef (type);
+    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_CODE_STRUCT
+               && !rust_enum_p (type)
+               && rust_slice_type_p (type)
+               && strcmp (type->name (), "&str") == 0));
+  }
 };
 
 /* Single instance of the Rust language class.  */