gdb: use a range based for loop when iterating over an array
[binutils-gdb.git] / gdb / language.c
index b467512e80dba2d5f785343a7daf5b04a11564b2..69c73b0318e1b46db6ffc0eb8bc125aac0cf65bf 100644 (file)
@@ -1,6 +1,6 @@
 /* Multiple source language support for GDB.
 
-   Copyright (C) 1991-2020 Free Software Foundation, Inc.
+   Copyright (C) 1991-2022 Free Software Foundation, Inc.
 
    Contributed by the Department of Computer Science at the State University
    of New York at Buffalo.
@@ -46,6 +46,7 @@
 #include "c-lang.h"
 #include <algorithm>
 #include "gdbarch.h"
+#include "compile/compile-internal.h"
 
 static void set_range_case (void);
 
@@ -113,12 +114,12 @@ show_language_command (struct ui_file *file, int from_tty,
   enum language flang;         /* The language of the frame.  */
 
   if (language_mode == language_mode_auto)
-    fprintf_filtered (gdb_stdout,
+    fprintf_filtered (file,
                      _("The current source language is "
                        "\"auto; currently %s\".\n"),
                      current_language->name ());
   else
-    fprintf_filtered (gdb_stdout,
+    fprintf_filtered (file,
                      _("The current source language is \"%s\".\n"),
                      current_language->name ());
 
@@ -131,7 +132,7 @@ show_language_command (struct ui_file *file, int from_tty,
       if (flang != language_unknown
          && language_mode == language_mode_manual
          && current_language->la_language != flang)
-       printf_filtered ("%s\n", _(lang_frame_mismatch_warn));
+       fprintf_filtered (file, "%s\n", _(lang_frame_mismatch_warn));
     }
 }
 
@@ -155,7 +156,7 @@ set_language_command (const char *ignore,
          if (lang->la_language == language_auto)
            {
              /* Enter auto mode.  Set to the current frame's language, if
-                 known, or fallback to the initial language.  */
+                known, or fallback to the initial language.  */
              language_mode = language_mode_auto;
              try
                {
@@ -219,12 +220,12 @@ show_range_command (struct ui_file *file, int from_tty,
                          "Unrecognized range check setting.");
        }
 
-      fprintf_filtered (gdb_stdout,
+      fprintf_filtered (file,
                        _("Range checking is \"auto; currently %s\".\n"),
                        tmp);
     }
   else
-    fprintf_filtered (gdb_stdout, _("Range checking is \"%s\".\n"),
+    fprintf_filtered (file, _("Range checking is \"%s\".\n"),
                      value);
 
   if (range_check == range_check_warn
@@ -295,13 +296,13 @@ show_case_command (struct ui_file *file, int from_tty,
                          "Unrecognized case-sensitive setting.");
        }
 
-      fprintf_filtered (gdb_stdout,
+      fprintf_filtered (file,
                        _("Case sensitivity in "
                          "name search is \"auto; currently %s\".\n"),
                        tmp);
     }
   else
-    fprintf_filtered (gdb_stdout,
+    fprintf_filtered (file,
                      _("Case sensitivity in name search is \"%s\".\n"),
                      value);
 
@@ -373,51 +374,17 @@ set_language (enum language lang)
 }
 \f
 
-/* Print out the current language settings: language, range and
-   type checking.  If QUIETLY, print only what has changed.  */
+/* See language.h.  */
 
 void
-language_info (int quietly)
+language_info ()
 {
-  if (quietly && expected_language == current_language)
+  if (expected_language == current_language)
     return;
 
   expected_language = current_language;
-  printf_unfiltered (_("Current language:  %s\n"), language);
-  show_language_command (NULL, 1, NULL, NULL);
-
-  if (!quietly)
-    {
-      printf_unfiltered (_("Range checking:    %s\n"), range);
-      show_range_command (NULL, 1, NULL, NULL);
-      printf_unfiltered (_("Case sensitivity:  %s\n"), case_sensitive);
-      show_case_command (NULL, 1, NULL, NULL);
-    }
-}
-\f
-
-/* Returns non-zero if the value is a pointer type.  */
-int
-pointer_type (struct type *type)
-{
-  return type->code () == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type);
-}
-
-\f
-/* This page contains functions that return info about
-   (struct value) values used in GDB.  */
-
-/* Returns non-zero if the value VAL represents a true value.  */
-int
-value_true (struct value *val)
-{
-  /* It is possible that we should have some sort of error if a non-boolean
-     value is used in this context.  Possibly dependent on some kind of
-     "boolean-checking" option like range checking.  But it should probably
-     not depend on the language except insofar as is necessary to identify
-     a "boolean" value (i.e. in C using a float, pointer, etc., as a boolean
-     should be an error, probably).  */
-  return !value_logical_not (val);
+  printf_filtered (_("Current language:  %s\n"), language);
+  show_language_command (gdb_stdout, 1, NULL, NULL);
 }
 \f
 /* This page contains functions for the printing out of
@@ -446,7 +413,7 @@ range_error (const char *string,...)
       break;
     case range_check_off:
       /* FIXME: cagney/2002-01-30: Should this function print anything
-         when range error is off?  */
+        when range error is off?  */
       vfprintf_filtered (gdb_stderr, string, args);
       fprintf_filtered (gdb_stderr, "\n");
       break;
@@ -509,7 +476,8 @@ add_set_language_command ()
   /* Display "auto", "local" and "unknown" first, and then the rest,
      alpha sorted.  */
   const char **language_names_p = language_names;
-  *language_names_p++ = language_def (language_auto)->name ();
+  language = language_def (language_auto)->name ();
+  *language_names_p++ = language;
   *language_names_p++ = "local";
   *language_names_p++ = language_def (language_unknown)->name ();
   const char **sort_begin = language_names_p;
@@ -584,12 +552,12 @@ skip_language_trampoline (struct frame_info *frame, CORE_ADDR pc)
    more flexible demangler for the languages that need it.
    FIXME: Sometimes the demangler is invoked when we don't know the
    language, so we can't use this everywhere.  */
-char *
+gdb::unique_xmalloc_ptr<char>
 language_demangle (const struct language_defn *current_language, 
                                const char *mangled, int options)
 {
   if (current_language != NULL)
-    return current_language->demangle (mangled, options);
+    return current_language->demangle_symbol (mangled, options);
   return NULL;
 }
 
@@ -622,7 +590,7 @@ language_defn::print_array_index (struct type *index_type, LONGEST index,
   struct value *index_value = value_from_longest (index_type, index);
 
   fprintf_filtered (stream, "[");
-  LA_VALUE_PRINT (index_value, stream, options);
+  value_print (index_value, stream, options);
   fprintf_filtered (stream, "] = ");
 }
 
@@ -635,8 +603,7 @@ language_defn::watch_location_expression (struct type *type,
   /* Generates an expression that assumes a C like syntax is valid.  */
   type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
   std::string name = type_to_string (type);
-  return gdb::unique_xmalloc_ptr<char>
-    (xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr)));
+  return xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr));
 }
 
 /* See language.h.  */
@@ -677,15 +644,6 @@ language_defn::emitchar (int ch, struct type *chtype,
 
 /* See language.h.  */
 
-void
-language_defn::printchar (int ch, struct type *chtype,
-                         struct ui_file * stream) const
-{
-  c_printchar (ch, chtype, stream);
-}
-
-/* See language.h.  */
-
 void
 language_defn::printstr (struct ui_file *stream, struct type *elttype,
                         const gdb_byte *string, unsigned int length,
@@ -713,6 +671,14 @@ language_defn::is_string_type_p (struct type *type) const
   return c_is_string_type_p (type);
 }
 
+/* See language.h.  */
+
+std::unique_ptr<compile_instance>
+language_defn::get_compile_instance () const
+{
+  return {};
+}
+
 /* The default implementation of the get_symbol_name_matcher_inner method
    from the language_defn class.  Matches with strncmp_iw.  */
 
@@ -774,75 +740,23 @@ language_defn::varobj_ops () const
   return &c_varobj_ops;
 }
 
-/* See language.h.  */
+/* Parent class for both the "auto" and "unknown" languages.  These two
+   pseudo-languages are very similar so merging their implementations like
+   this makes sense.  */
 
-const struct exp_descriptor *
-language_defn::expression_ops () const
-{
-  return &exp_descriptor_standard;
-}
-
-/* Return true if TYPE is a string type, otherwise return false.  This
-   default implementation only detects TYPE_CODE_STRING.  */
-
-static bool
-default_is_string_type_p (struct type *type)
-{
-  type = check_typedef (type);
-  while (type->code () == TYPE_CODE_REF)
-    {
-      type = TYPE_TARGET_TYPE (type);
-      type = check_typedef (type);
-    }
-  return (type->code ()  == TYPE_CODE_STRING);
-}
-
-static const struct op_print unk_op_print_tab[] =
-{
-  {NULL, OP_NULL, PREC_NULL, 0}
-};
-
-static void
-unknown_language_arch_info (struct gdbarch *gdbarch,
-                           struct language_arch_info *lai)
-{
-  lai->string_char_type = builtin_type (gdbarch)->builtin_char;
-  lai->bool_type_default = builtin_type (gdbarch)->builtin_int;
-  lai->primitive_type_vector = GDBARCH_OBSTACK_CALLOC (gdbarch, 1,
-                                                      struct type *);
-}
-
-/* Constant data that describes the unknown language.  */
-
-extern const struct language_data unknown_language_data =
-{
-  unk_op_print_tab,            /* expression operators for printing */
-};
-
-/* Class representing the unknown language.  */
-
-class unknown_language : public language_defn
+class auto_or_unknown_language : public language_defn
 {
 public:
-  unknown_language ()
-    : language_defn (language_unknown, unknown_language_data)
+  auto_or_unknown_language (enum language lang)
+    : language_defn (lang)
   { /* Nothing.  */ }
 
-  /* See language.h.  */
-
-  const char *name () const override
-  { return "unknown"; }
-
-  /* See language.h.  */
-
-  const char *natural_name () const override
-  { return "Unknown"; }
-
   /* See language.h.  */
   void language_arch_info (struct gdbarch *gdbarch,
                           struct language_arch_info *lai) const override
   {
-    unknown_language_arch_info (gdbarch, lai);
+    lai->set_string_char_type (builtin_type (gdbarch)->builtin_char);
+    lai->set_bool_type (builtin_type (gdbarch)->builtin_int);
   }
 
   /* See language.h.  */
@@ -851,14 +765,16 @@ public:
                   struct ui_file *stream, int show, int level,
                   const struct type_print_options *flags) const override
   {
-    error (_("unimplemented unknown_language::print_type called"));
+    error (_("type printing not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
 
-  char *demangle (const char *mangled, int options) const override
+  gdb::unique_xmalloc_ptr<char> demangle_symbol (const char *mangled,
+                                                int options) const override
   {
-    /* The unknown language just uses the C++ demangler.  */
+    /* The auto language just uses the C++ demangler.  */
     return gdb_demangle (mangled, options);
   }
 
@@ -867,7 +783,8 @@ public:
   void value_print (struct value *val, struct ui_file *stream,
                    const struct value_print_options *options) const override
   {
-    error (_("unimplemented unknown_language::value_print called"));
+    error (_("value printing not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
@@ -876,15 +793,16 @@ public:
        (struct value *val, struct ui_file *stream, int recurse,
         const struct value_print_options *options) const override
   {
-    error (_("unimplemented unknown_language::value_print_inner called"));
+    error (_("inner value printing not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
 
   int parser (struct parser_state *ps) const override
   {
-    /* No parsing is done, just claim success.  */
-    return 1;
+    error (_("expression parsing not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
@@ -892,7 +810,8 @@ public:
   void emitchar (int ch, struct type *chtype,
                 struct ui_file *stream, int quoter) const override
   {
-    error (_("unimplemented unknown_language::emitchar called"));
+    error (_("emit character not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
@@ -900,7 +819,8 @@ public:
   void printchar (int ch, struct type *chtype,
                  struct ui_file *stream) const override
   {
-    error (_("unimplemented unknown_language::printchar called"));
+    error (_("print character not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
@@ -910,7 +830,8 @@ public:
                 const char *encoding, int force_ellipses,
                 const struct value_print_options *options) const override
   {
-    error (_("unimplemented unknown_language::printstr called"));
+    error (_("print string not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
@@ -918,45 +839,36 @@ public:
   void print_typedef (struct type *type, struct symbol *new_symbol,
                      struct ui_file *stream) const override
   {
-    error (_("unimplemented unknown_language::print_typedef called"));
+    error (_("print typedef not implemented for language \"%s\""),
+          natural_name ());
   }
 
   /* See language.h.  */
 
   bool is_string_type_p (struct type *type) const override
   {
-    return default_is_string_type_p (type);
+    type = check_typedef (type);
+    while (type->code () == TYPE_CODE_REF)
+      {
+       type = TYPE_TARGET_TYPE (type);
+       type = check_typedef (type);
+      }
+    return (type->code () == TYPE_CODE_STRING);
   }
 
   /* See language.h.  */
 
   const char *name_of_this () const override
   { return "this"; }
-
-  /* See language.h.  */
-
-  bool store_sym_names_in_linkage_form_p () const override
-  { return true; }
-};
-
-/* Single instance of the unknown language class.  */
-
-static unknown_language unknown_language_defn;
-
-/* Constant data for the fake "auto" language.  */
-
-extern const struct language_data auto_language_data =
-{
-  unk_op_print_tab,            /* expression operators for printing */
 };
 
 /* Class representing the fake "auto" language.  */
 
-class auto_language : public language_defn
+class auto_language : public auto_or_unknown_language
 {
 public:
   auto_language ()
-    : language_defn (language_auto, auto_language_data)
+    : auto_or_unknown_language (language_auto)
   { /* Nothing.  */ }
 
   /* See language.h.  */
@@ -968,106 +880,40 @@ public:
 
   const char *natural_name () const override
   { return "Auto"; }
+};
 
-  /* See language.h.  */
-  void language_arch_info (struct gdbarch *gdbarch,
-                          struct language_arch_info *lai) const override
-  {
-    unknown_language_arch_info (gdbarch, lai);
-  }
-
-  /* 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
-  {
-    error (_("unimplemented auto_language::print_type called"));
-  }
-
-  /* See language.h.  */
-
-  char *demangle (const char *mangled, int options) const override
-  {
-    /* The auto language just uses the C++ demangler.  */
-    return gdb_demangle (mangled, options);
-  }
-
-  /* See language.h.  */
-
-  void value_print (struct value *val, struct ui_file *stream,
-                   const struct value_print_options *options) const override
-  {
-    error (_("unimplemented auto_language::value_print called"));
-  }
-
-  /* See language.h.  */
-
-  void value_print_inner
-       (struct value *val, struct ui_file *stream, int recurse,
-        const struct value_print_options *options) const override
-  {
-    error (_("unimplemented auto_language::value_print_inner called"));
-  }
-
-  /* See language.h.  */
-
-  int parser (struct parser_state *ps) const override
-  {
-    /* No parsing is done, just claim success.  */
-    return 1;
-  }
-
-  /* See language.h.  */
-
-  void emitchar (int ch, struct type *chtype,
-                struct ui_file *stream, int quoter) const override
-  {
-    error (_("unimplemented auto_language::emitchar called"));
-  }
-
-  /* See language.h.  */
+/* Single instance of the fake "auto" language.  */
 
-  void printchar (int ch, struct type *chtype,
-                 struct ui_file *stream) const override
-  {
-    error (_("unimplemented auto_language::printchar called"));
-  }
+static auto_language auto_language_defn;
 
-  /* See language.h.  */
+/* Class representing the unknown language.  */
 
-  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
-  {
-    error (_("unimplemented auto_language::printstr called"));
-  }
+class unknown_language : public auto_or_unknown_language
+{
+public:
+  unknown_language ()
+    : auto_or_unknown_language (language_unknown)
+  { /* Nothing.  */ }
 
   /* See language.h.  */
 
-  void print_typedef (struct type *type, struct symbol *new_symbol,
-                     struct ui_file *stream) const override
-  {
-    error (_("unimplemented auto_language::print_typedef called"));
-  }
+  const char *name () const override
+  { return "unknown"; }
 
   /* See language.h.  */
 
-  bool is_string_type_p (struct type *type) const override
-  {
-    return default_is_string_type_p (type);
-  }
+  const char *natural_name () const override
+  { return "Unknown"; }
 
   /* See language.h.  */
 
-  const char *name_of_this () const override
-  { return "this"; }
+  bool store_sym_names_in_linkage_form_p () const override
+  { return true; }
 };
 
-/* Single instance of the fake "auto" language.  */
+/* Single instance of the unknown language class.  */
 
-static auto_language auto_language_defn;
+static unknown_language unknown_language_defn;
 
 \f
 /* Per-architecture language information.  */
@@ -1084,143 +930,166 @@ struct language_gdbarch
 static void *
 language_gdbarch_post_init (struct gdbarch *gdbarch)
 {
-  struct language_gdbarch *l;
-
-  l = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct language_gdbarch);
+  struct language_gdbarch *l
+    = obstack_new<struct language_gdbarch> (gdbarch_obstack (gdbarch));
   for (const auto &lang : language_defn::languages)
     {
       gdb_assert (lang != nullptr);
-      lang->language_arch_info (gdbarch,
-                               l->arch_info + lang->la_language);
+      lang->language_arch_info (gdbarch, &l->arch_info[lang->la_language]);
     }
 
   return l;
 }
 
+/* See language.h.  */
+
 struct type *
 language_string_char_type (const struct language_defn *la,
                           struct gdbarch *gdbarch)
 {
   struct language_gdbarch *ld
     = (struct language_gdbarch *) gdbarch_data (gdbarch, language_gdbarch_data);
-
-  return ld->arch_info[la->la_language].string_char_type;
+  return ld->arch_info[la->la_language].string_char_type ();
 }
 
+/* See language.h.  */
+
 struct type *
 language_bool_type (const struct language_defn *la,
                    struct gdbarch *gdbarch)
 {
   struct language_gdbarch *ld
     = (struct language_gdbarch *) gdbarch_data (gdbarch, language_gdbarch_data);
+  return ld->arch_info[la->la_language].bool_type ();
+}
+
+/* See language.h.  */
 
-  if (ld->arch_info[la->la_language].bool_type_symbol)
+struct type *
+language_arch_info::bool_type () const
+{
+  if (m_bool_type_name != nullptr)
     {
       struct symbol *sym;
 
-      sym = lookup_symbol (ld->arch_info[la->la_language].bool_type_symbol,
-                          NULL, VAR_DOMAIN, NULL).symbol;
-      if (sym)
+      sym = lookup_symbol (m_bool_type_name, NULL, VAR_DOMAIN, NULL).symbol;
+      if (sym != nullptr)
        {
-         struct type *type = SYMBOL_TYPE (sym);
-
-         if (type && type->code () == TYPE_CODE_BOOL)
+         struct type *type = sym->type ();
+         if (type != nullptr && type->code () == TYPE_CODE_BOOL)
            return type;
        }
     }
 
-  return ld->arch_info[la->la_language].bool_type_default;
+  return m_bool_type_default;
 }
 
-/* Helper function for primitive type lookup.  */
+/* See language.h.  */
 
-static struct type **
-language_lookup_primitive_type_1 (const struct language_arch_info *lai,
-                                 const char *name)
+struct symbol *
+language_arch_info::type_and_symbol::alloc_type_symbol
+       (enum language lang, struct type *type)
 {
-  struct type **p;
+  struct symbol *symbol;
+  struct gdbarch *gdbarch;
+  gdb_assert (!type->is_objfile_owned ());
+  gdbarch = type->arch_owner ();
+  symbol = new (gdbarch_obstack (gdbarch)) struct symbol ();
+  symbol->m_name = type->name ();
+  symbol->set_language (lang, nullptr);
+  symbol->owner.arch = gdbarch;
+  symbol->set_is_objfile_owned (0);
+  symbol->set_section_index (0);
+  symbol->set_type (type);
+  symbol->set_domain (VAR_DOMAIN);
+  symbol->set_aclass_index (LOC_TYPEDEF);
+  return symbol;
+}
 
-  for (p = lai->primitive_type_vector; (*p) != NULL; p++)
+/* See language.h.  */
+
+language_arch_info::type_and_symbol *
+language_arch_info::lookup_primitive_type_and_symbol (const char *name)
+{
+  for (struct type_and_symbol &tas : primitive_types_and_symbols)
     {
-      if (strcmp ((*p)->name (), name) == 0)
-       return p;
+      if (strcmp (tas.type ()->name (), name) == 0)
+       return &tas;
     }
-  return NULL;
+
+  return nullptr;
 }
 
 /* See language.h.  */
 
 struct type *
-language_lookup_primitive_type (const struct language_defn *la,
-                               struct gdbarch *gdbarch,
-                               const char *name)
+language_arch_info::lookup_primitive_type (const char *name)
 {
-  struct language_gdbarch *ld =
-    (struct language_gdbarch *) gdbarch_data (gdbarch, language_gdbarch_data);
-  struct type **typep;
-
-  typep = language_lookup_primitive_type_1 (&ld->arch_info[la->la_language],
-                                           name);
-  if (typep == NULL)
-    return NULL;
-  return *typep;
+  type_and_symbol *tas = lookup_primitive_type_and_symbol (name);
+  if (tas != nullptr)
+    return tas->type ();
+  return nullptr;
 }
 
-/* Helper function for type lookup as a symbol.
-   Create the symbol corresponding to type TYPE in language LANG.  */
+/* See language.h.  */
 
-static struct symbol *
-language_alloc_type_symbol (enum language lang, struct type *type)
+struct type *
+language_arch_info::lookup_primitive_type
+  (gdb::function_view<bool (struct type *)> filter)
 {
-  struct symbol *symbol;
-  struct gdbarch *gdbarch;
-
-  gdb_assert (!TYPE_OBJFILE_OWNED (type));
+  for (struct type_and_symbol &tas : primitive_types_and_symbols)
+    {
+      if (filter (tas.type ()))
+       return tas.type ();
+    }
 
-  gdbarch = TYPE_OWNER (type).gdbarch;
-  symbol = new (gdbarch_obstack (gdbarch)) struct symbol ();
+  return nullptr;
+}
 
-  symbol->m_name = type->name ();
-  symbol->set_language (lang, nullptr);
-  symbol->owner.arch = gdbarch;
-  SYMBOL_OBJFILE_OWNED (symbol) = 0;
-  SYMBOL_SECTION (symbol) = 0;
-  SYMBOL_TYPE (symbol) = type;
-  SYMBOL_DOMAIN (symbol) = VAR_DOMAIN;
-  SYMBOL_ACLASS_INDEX (symbol) = LOC_TYPEDEF;
+/* See language.h.  */
 
-  return symbol;
+struct symbol *
+language_arch_info::lookup_primitive_type_as_symbol (const char *name,
+                                                    enum language lang)
+{
+  type_and_symbol *tas = lookup_primitive_type_and_symbol (name);
+  if (tas != nullptr)
+    return tas->symbol (lang);
+  return nullptr;
 }
 
-/* Initialize the primitive type symbols of language LD.
-   The primitive type vector must have already been initialized.  */
+/* Helper for the language_lookup_primitive_type overloads to forward
+   to the corresponding language's lookup_primitive_type overload.  */
 
-static void
-language_init_primitive_type_symbols (struct language_arch_info *lai,
-                                     const struct language_defn *la,
-                                     struct gdbarch *gdbarch)
+template<typename T>
+static struct type *
+language_lookup_primitive_type_1 (const struct language_defn *la,
+                                 struct gdbarch *gdbarch,
+                                 T arg)
 {
-  int n;
-
-  gdb_assert (lai->primitive_type_vector != NULL);
+  struct language_gdbarch *ld =
+    (struct language_gdbarch *) gdbarch_data (gdbarch, language_gdbarch_data);
+  return ld->arch_info[la->la_language].lookup_primitive_type (arg);
+}
 
-  for (n = 0; lai->primitive_type_vector[n] != NULL; ++n)
-    continue;
+/* See language.h.  */
 
-  lai->primitive_type_symbols
-    = GDBARCH_OBSTACK_CALLOC (gdbarch, n + 1, struct symbol *);
+struct type *
+language_lookup_primitive_type (const struct language_defn *la,
+                               struct gdbarch *gdbarch,
+                               const char *name)
+{
+  return language_lookup_primitive_type_1 (la, gdbarch, name);
+}
 
-  for (n = 0; lai->primitive_type_vector[n] != NULL; ++n)
-    {
-      lai->primitive_type_symbols[n]
-       = language_alloc_type_symbol (la->la_language,
-                                     lai->primitive_type_vector[n]);
-    }
+/* See language.h.  */
 
-  /* Note: The result of symbol lookup is normally a symbol *and* the block
-     it was found in.  Builtin types don't live in blocks.  We *could* give
-     them one, but there is no current need so to keep things simple symbol
-     lookup is extended to allow for BLOCK_FOUND to be NULL.  */
+struct type *
+language_lookup_primitive_type (const struct language_defn *la,
+                               struct gdbarch *gdbarch,
+                               gdb::function_view<bool (struct type *)> filter)
+{
+  return language_lookup_primitive_type_1 (la, gdbarch, filter);
 }
 
 /* See language.h.  */
@@ -1233,33 +1102,24 @@ language_lookup_primitive_type_as_symbol (const struct language_defn *la,
   struct language_gdbarch *ld
     = (struct language_gdbarch *) gdbarch_data (gdbarch, language_gdbarch_data);
   struct language_arch_info *lai = &ld->arch_info[la->la_language];
-  struct type **typep;
-  struct symbol *sym;
 
   if (symbol_lookup_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog,
-                         "language_lookup_primitive_type_as_symbol"
-                         " (%s, %s, %s)",
-                         la->name (), host_address_to_string (gdbarch), name);
-    }
-
-  typep = language_lookup_primitive_type_1 (lai, name);
-  if (typep == NULL)
-    {
-      if (symbol_lookup_debug)
-       fprintf_unfiltered (gdb_stdlog, " = NULL\n");
-      return NULL;
-    }
-
-  /* The set of symbols is lazily initialized.  */
-  if (lai->primitive_type_symbols == NULL)
-    language_init_primitive_type_symbols (lai, la, gdbarch);
+    fprintf_unfiltered (gdb_stdlog,
+                       "language_lookup_primitive_type_as_symbol"
+                       " (%s, %s, %s)",
+                       la->name (), host_address_to_string (gdbarch), name);
 
-  sym = lai->primitive_type_symbols[typep - lai->primitive_type_vector];
+  struct symbol *sym
+    = lai->lookup_primitive_type_as_symbol (name, la->la_language);
 
   if (symbol_lookup_debug)
     fprintf_unfiltered (gdb_stdlog, " = %s\n", host_address_to_string (sym));
+
+  /* Note: The result of symbol lookup is normally a symbol *and* the block
+     it was found in.  Builtin types don't live in blocks.  We *could* give
+     them one, but there is no current need so to keep things simple symbol
+     lookup is extended to allow for BLOCK_FOUND to be NULL.  */
+
   return sym;
 }
 
@@ -1280,18 +1140,19 @@ _initialize_language ()
 
   /* GDB commands for language specific stuff.  */
 
-  add_basic_prefix_cmd ("check", no_class,
-                       _("Set the status of the type/range checker."),
-                       &setchecklist, "set check ", 0, &setlist);
-  add_alias_cmd ("c", "check", no_class, 1, &setlist);
-  add_alias_cmd ("ch", "check", no_class, 1, &setlist);
-
-  add_show_prefix_cmd ("check", no_class,
-                      _("Show the status of the type/range checker."),
-                      &showchecklist, "show check ", 0, &showlist);
-  add_alias_cmd ("c", "check", no_class, 1, &showlist);
-  add_alias_cmd ("ch", "check", no_class, 1, &showlist);
-
+  set_show_commands setshow_check_cmds
+    = add_setshow_prefix_cmd ("check", no_class,
+                             _("Set the status of the type/range checker."),
+                             _("Show the status of the type/range checker."),
+                             &setchecklist, &showchecklist,
+                             &setlist, &showlist);
+  add_alias_cmd ("c", setshow_check_cmds.set, no_class, 1, &setlist);
+  add_alias_cmd ("ch", setshow_check_cmds.set, no_class, 1, &setlist);
+  add_alias_cmd ("c", setshow_check_cmds.show, no_class, 1, &showlist);
+  add_alias_cmd ("ch", setshow_check_cmds.show, no_class, 1, &showlist);
+
+  range = type_or_range_names[3];
+  gdb_assert (strcmp (range, "auto") == 0);
   add_setshow_enum_cmd ("range", class_support, type_or_range_names,
                        &range,
                        _("Set range checking (on/warn/off/auto)."),
@@ -1300,6 +1161,8 @@ _initialize_language ()
                        show_range_command,
                        &setchecklist, &showchecklist);
 
+  case_sensitive = case_sensitive_names[2];
+  gdb_assert (strcmp (case_sensitive, "auto") == 0);
   add_setshow_enum_cmd ("case-sensitive", class_support, case_sensitive_names,
                        &case_sensitive, _("\
 Set case sensitivity in name search (on/off/auto)."), _("\
@@ -1316,10 +1179,6 @@ For Fortran the default is off; for other languages the default is on."),
 
   add_set_language_command ();
 
-  language = "auto";
-  range = "auto";
-  case_sensitive = "auto";
-
   /* Have the above take effect.  */
   set_language (language_auto);
 }