/* Multiple source language support for GDB.

   Copyright (C) 1991-2025 Free Software Foundation, Inc.

   Contributed by the Department of Computer Science at the State University
   of New York at Buffalo.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* This file contains functions that return things that are specific
   to languages.  Each function should examine current_language if necessary,
   and return the appropriate result.  */

/* FIXME:  Most of these would be better organized as macros which
   return data out of a "language-specific" struct pointer that is set
   whenever the working language changes.  That would be a lot faster.  */

#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "cli/cli-cmds.h"
#include "expression.h"
#include "language.h"
#include "varobj.h"
#include "target.h"
#include "parser-defs.h"
#include "demangle.h"
#include "symfile.h"
#include "cp-support.h"
#include "frame.h"
#include "c-lang.h"
#include <algorithm>
#include "gdbarch.h"

static void set_range_case (void);

/* range_mode ==
   range_mode_auto:   range_check set automatically to default of language.
   range_mode_manual: range_check set manually by user.  */

enum range_mode
  {
    range_mode_auto, range_mode_manual
  };

/* case_mode ==
   case_mode_auto:   case_sensitivity set upon selection of scope.
   case_mode_manual: case_sensitivity set only by user.  */

enum case_mode
  {
    case_mode_auto, case_mode_manual
  };

/* The current (default at startup) state of type and range checking.
   (If the modes are set to "auto", though, these are changed based
   on the default language at startup, and then again based on the
   language of the first source file.  */

static enum range_mode range_mode = range_mode_auto;
enum range_check range_check = range_check_off;
static enum case_mode case_mode = case_mode_auto;
enum case_sensitivity case_sensitivity = case_sensitive_on;

/* The current language and language_mode (see language.h).  */

static const struct language_defn *global_current_language;
static lazily_set_language_ftype *lazy_language_setter;
enum language_mode language_mode = language_mode_auto;

/* Whether to warn on language changes.  */
bool warn_frame_lang_mismatch = true;

/* See language.h.  */

const struct language_defn *
get_current_language ()
{
  if (lazy_language_setter != nullptr)
    {
      /* Avoid recursive calls -- set_language refers to
	 current_language.  */
      lazily_set_language_ftype *call = lazy_language_setter;
      lazy_language_setter = nullptr;
      call ();
    }
  return global_current_language;
}

void
lazily_set_language (lazily_set_language_ftype *fun)
{
  lazy_language_setter = fun;
}

scoped_restore_current_language::scoped_restore_current_language ()
  : m_lang (global_current_language),
    m_fun (lazy_language_setter)
{
}

scoped_restore_current_language::scoped_restore_current_language
    (enum language lang)
  : scoped_restore_current_language ()
{
  set_language (lang);
}

scoped_restore_current_language::~scoped_restore_current_language ()
{
  /* If both are NULL, then that means dont_restore was called.  */
  if (m_lang != nullptr || m_fun != nullptr)
    {
      global_current_language = m_lang;
      lazy_language_setter = m_fun;
      if (lazy_language_setter == nullptr)
	set_range_case ();
    }
}

/* The language that the user expects to be typing in (the language
   of main(), or the last language we notified them about, or C).  */

const struct language_defn *expected_language;

/* Define the array containing all languages.  */

const struct language_defn *language_defn::languages[nr_languages];

/* The current values of the "set language/range/case-sensitive" enum
   commands.  */
static const char *range;
static const char *case_sensitive;

/* See language.h.  */
const char lang_frame_mismatch_warn[] =
N_("Warning: the current language does not match this frame.");

/* This page contains the functions corresponding to GDB commands
   and their helpers.  */

/* Show command.  Display a warning if the language set
   does not match the frame.  */
static void
show_language_command (struct ui_file *file, int from_tty,
		       struct cmd_list_element *c, const char *value)
{
  enum language flang;		/* The language of the frame.  */

  if (language_mode == language_mode_auto)
    gdb_printf (file,
		_("The current source language is "
		  "\"auto; currently %s\".\n"),
		current_language->name ());
  else
    gdb_printf (file,
		_("The current source language is \"%s\".\n"),
		current_language->name ());

  if (warn_frame_lang_mismatch && has_stack_frames ())
    {
      frame_info_ptr frame;

      frame = get_selected_frame (NULL);
      flang = get_frame_language (frame);
      if (flang != language_unknown
	  && language_mode == language_mode_manual
	  && current_language->la_language != flang)
	gdb_printf (file, "%s\n", _(lang_frame_mismatch_warn));
    }
}

/* Set callback for the "set/show language" setting.  */

static void
set_language (const char *language)
{
  enum language flang = language_unknown;

  /* "local" is a synonym of "auto".  */
  if (strcmp (language, "auto") == 0
      || strcmp (language, "local") == 0)
    {
      /* Enter auto mode.  Set to the current frame's language, if
	 known, or fallback to the initial language.  */
      language_mode = language_mode_auto;
      try
	{
	  frame_info_ptr frame;

	  frame = get_selected_frame (NULL);
	  flang = get_frame_language (frame);
	}
      catch (const gdb_exception_error &ex)
	{
	  flang = language_unknown;
	}

      if (flang != language_unknown)
	set_language (flang);
      else
	set_initial_language ();

      expected_language = current_language;
      return;
    }

  /* Search the list of languages for a match.  */
  for (const auto &lang : language_defn::languages)
    {
      if (strcmp (lang->name (), language) != 0)
	continue;

      /* Found it!  Go into manual mode, and use this language.  */
      language_mode = language_mode_manual;
      lazy_language_setter = nullptr;
      global_current_language = lang;
      set_range_case ();
      expected_language = lang;
      return;
    }

  internal_error ("Couldn't find language `%s' in known languages list.",
		  language);
}

/* Get callback for the "set/show language" setting.  */

static const char *
get_language ()
{
  if (language_mode == language_mode_auto)
    return "auto";

  return current_language->name ();
}

/* Show command.  Display a warning if the range setting does
   not match the current language.  */
static void
show_range_command (struct ui_file *file, int from_tty,
		    struct cmd_list_element *c, const char *value)
{
  if (range_mode == range_mode_auto)
    {
      const char *tmp;

      switch (range_check)
	{
	case range_check_on:
	  tmp = "on";
	  break;
	case range_check_off:
	  tmp = "off";
	  break;
	case range_check_warn:
	  tmp = "warn";
	  break;
	default:
	  internal_error ("Unrecognized range check setting.");
	}

      gdb_printf (file,
		  _("Range checking is \"auto; currently %s\".\n"),
		  tmp);
    }
  else
    gdb_printf (file, _("Range checking is \"%s\".\n"),
		value);

  if (range_check == range_check_warn
      || ((range_check == range_check_on)
	  != current_language->range_checking_on_by_default ()))
    warning (_("the current range check setting "
	       "does not match the language."));
}

/* Set command.  Change the setting for range checking.  */
static void
set_range_command (const char *ignore,
		   int from_tty, struct cmd_list_element *c)
{
  if (strcmp (range, "on") == 0)
    {
      range_check = range_check_on;
      range_mode = range_mode_manual;
    }
  else if (strcmp (range, "warn") == 0)
    {
      range_check = range_check_warn;
      range_mode = range_mode_manual;
    }
  else if (strcmp (range, "off") == 0)
    {
      range_check = range_check_off;
      range_mode = range_mode_manual;
    }
  else if (strcmp (range, "auto") == 0)
    {
      range_mode = range_mode_auto;
      set_range_case ();
      return;
    }
  else
    {
      internal_error (_("Unrecognized range check setting: \"%s\""), range);
    }
  if (range_check == range_check_warn
      || ((range_check == range_check_on)
	  != current_language->range_checking_on_by_default ()))
    warning (_("the current range check setting "
	       "does not match the language."));
}

/* Show command.  Display a warning if the case sensitivity setting does
   not match the current language.  */
static void
show_case_command (struct ui_file *file, int from_tty,
		   struct cmd_list_element *c, const char *value)
{
  if (case_mode == case_mode_auto)
    {
      const char *tmp = NULL;

      switch (case_sensitivity)
	{
	case case_sensitive_on:
	  tmp = "on";
	  break;
	case case_sensitive_off:
	  tmp = "off";
	  break;
	default:
	  internal_error ("Unrecognized case-sensitive setting.");
	}

      gdb_printf (file,
		  _("Case sensitivity in "
		    "name search is \"auto; currently %s\".\n"),
		  tmp);
    }
  else
    gdb_printf (file,
		_("Case sensitivity in name search is \"%s\".\n"),
		value);

  if (case_sensitivity != current_language->case_sensitivity ())
    warning (_("the current case sensitivity setting does not match "
	       "the language."));
}

/* Set command.  Change the setting for case sensitivity.  */

static void
set_case_command (const char *ignore, int from_tty, struct cmd_list_element *c)
{
   if (strcmp (case_sensitive, "on") == 0)
     {
       case_sensitivity = case_sensitive_on;
       case_mode = case_mode_manual;
     }
   else if (strcmp (case_sensitive, "off") == 0)
     {
       case_sensitivity = case_sensitive_off;
       case_mode = case_mode_manual;
     }
   else if (strcmp (case_sensitive, "auto") == 0)
     {
       case_mode = case_mode_auto;
       set_range_case ();
       return;
     }
   else
     {
       internal_error ("Unrecognized case-sensitive setting: \"%s\"",
		       case_sensitive);
     }

   if (case_sensitivity != current_language->case_sensitivity ())
     warning (_("the current case sensitivity setting does not match "
		"the language."));
}

/* Set the status of range and type checking and case sensitivity based on
   the current modes and the current language.
   If SHOW is non-zero, then print out the current language,
   type and range checking status.  */
static void
set_range_case (void)
{
  if (range_mode == range_mode_auto)
    range_check = (current_language->range_checking_on_by_default ()
		   ? range_check_on : range_check_off);

  if (case_mode == case_mode_auto)
    case_sensitivity = current_language->case_sensitivity ();
}

/* See language.h.  */

void
set_language (enum language lang)
{
  lazy_language_setter = nullptr;
  global_current_language = language_def (lang);
  set_range_case ();
}


/* See language.h.  */

void
language_info ()
{
  if (expected_language == current_language)
    return;

  expected_language = current_language;
  gdb_printf (_("Current language:  %s\n"), get_language ());
  show_language_command (gdb_stdout, 1, NULL, NULL);
}

/* This page contains functions for the printing out of
   error messages that occur during type- and range-
   checking.  */

/* This is called when a language fails a range-check.  The
   first argument should be a printf()-style format string, and the
   rest of the arguments should be its arguments.  If range_check is
   range_check_on, an error is printed;  if range_check_warn, a warning;
   otherwise just the message.  */

void
range_error (const char *string,...)
{
  va_list args;

  va_start (args, string);
  switch (range_check)
    {
    case range_check_warn:
      vwarning (string, args);
      break;
    case range_check_on:
      verror (string, args);
      break;
    case range_check_off:
      /* FIXME: cagney/2002-01-30: Should this function print anything
	 when range error is off?  */
      gdb_vprintf (gdb_stderr, string, args);
      gdb_printf (gdb_stderr, "\n");
      break;
    default:
      internal_error (_("bad switch"));
    }
  va_end (args);
}


/* This page contains miscellaneous functions.  */

/* Return the language enum for a given language string.  */

enum language
language_enum (const char *str)
{
  for (const auto &lang : language_defn::languages)
    if (strcmp (lang->name (), str) == 0)
      return lang->la_language;

  return language_unknown;
}

/* Return the language struct for a given language enum.  */

const struct language_defn *
language_def (enum language lang)
{
  const struct language_defn *l = language_defn::languages[lang];
  gdb_assert (l != nullptr);
  return l;
}

/* Return the language as a string.  */

const char *
language_str (enum language lang)
{
  return language_def (lang)->name ();
}



/* Build and install the "set language LANG" command.  */

static void
add_set_language_command ()
{
  static const char **language_names;

  /* Build the language names array, to be used as enumeration in the
     "set language" enum command.  +3 for "auto", "local" and NULL
     termination.  */
  language_names = new const char *[ARRAY_SIZE (language_defn::languages) + 3];

  /* Display "auto", "local" and "unknown" first, and then the rest,
     alpha sorted.  */
  const char **language_names_p = language_names;
  *language_names_p++ = "auto";
  *language_names_p++ = "local";
  *language_names_p++ = language_def (language_unknown)->name ();
  const char **sort_begin = language_names_p;
  for (const auto &lang : language_defn::languages)
    {
      /* Already handled above.  */
      if (lang->la_language == language_unknown)
	continue;
      *language_names_p++ = lang->name ();
    }
  *language_names_p = NULL;
  std::sort (sort_begin, language_names_p, compare_cstrings);

  /* Add the filename extensions.  */
  for (const auto &lang : language_defn::languages)
    for (const char * const &ext : lang->filename_extensions ())
      add_filename_language (ext, lang->la_language);

  /* Build the "help set language" docs.  */
  string_file doc;

  doc.printf (_("Set the current source language.\n"
		"The currently understood settings are:\n\nlocal or "
		"auto    Automatic setting based on source file"));

  for (const auto &lang : language_defn::languages)
    {
      /* Already dealt with these above.  */
      if (lang->la_language == language_unknown)
	continue;

      /* Note that we add the newline at the front, so we don't wind
	 up with a trailing newline.  */
      doc.printf ("\n%-16s Use the %s language",
		  lang->name (),
		  lang->natural_name ());
    }

  add_setshow_enum_cmd ("language", class_support,
			language_names,
			doc.c_str (),
			_("Show the current source language."),
			NULL,
			set_language,
			get_language,
			show_language_command,
			&setlist, &showlist);
}

/* Iterate through all registered languages looking for and calling
   any non-NULL struct language_defn.skip_trampoline() functions.
   Return the result from the first that returns non-zero, or 0 if all
   `fail'.  */
CORE_ADDR 
skip_language_trampoline (const frame_info_ptr &frame, CORE_ADDR pc)
{
  for (const auto &lang : language_defn::languages)
    {
      CORE_ADDR real_pc = lang->skip_trampoline (frame, pc);

      if (real_pc != 0)
	return real_pc;
    }

  return 0;
}

/* Return information about whether TYPE should be passed
   (and returned) by reference at the language level.  */

struct language_pass_by_ref_info
language_pass_by_reference (struct type *type)
{
  return current_language->pass_by_reference_info (type);
}

/* Return the default string containing the list of characters
   delimiting words.  This is a reasonable default value that
   most languages should be able to use.  */

const char *
default_word_break_characters (void)
{
  return " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-";
}

/* See language.h.  */

void
language_defn::print_array_index (struct type *index_type, LONGEST index,
				  struct ui_file *stream,
				  const value_print_options *options) const
{
  struct value *index_value = value_from_longest (index_type, index);

  gdb_printf (stream, "[");
  value_print (index_value, stream, options);
  gdb_printf (stream, "] = ");
}

/* See language.h.  */

gdb::unique_xmalloc_ptr<char>
language_defn::watch_location_expression (struct type *type,
					  CORE_ADDR addr) const
{
  /* Generates an expression that assumes a C like syntax is valid.  */
  type = check_typedef (check_typedef (type)->target_type ());
  std::string name = type_to_string (type);
  return xstrprintf ("* (%s *) %s", name.c_str (), core_addr_to_string (addr));
}

/* See language.h.  */

void
language_defn::value_print (struct value *val, struct ui_file *stream,
	       const struct value_print_options *options) const
{
  return c_value_print (val, stream, options);
}

/* See language.h.  */

int
language_defn::parser (struct parser_state *ps) const
{
  return c_parse (ps);
}

/* See language.h.  */

void
language_defn::value_print_inner
	(struct value *val, struct ui_file *stream, int recurse,
	 const struct value_print_options *options) const
{
  return c_value_print_inner (val, stream, recurse, options);
}

/* See language.h.  */

void
language_defn::print_typedef (struct type *type, struct symbol *new_symbol,
			      struct ui_file *stream) const
{
  c_print_typedef (type, new_symbol, stream);
}

/* See language.h.  */

bool
language_defn::is_string_type_p (struct type *type) const
{
  return c_is_string_type_p (type);
}

/* The default implementation of the get_symbol_name_matcher_inner method
   from the language_defn class.  Matches with strncmp_iw.  */

static bool
default_symbol_name_matcher (const char *symbol_search_name,
			     const lookup_name_info &lookup_name,
			     completion_match_result *comp_match_res)
{
  std::string_view name = lookup_name.name ();
  completion_match_for_lcd *match_for_lcd
    = (comp_match_res != NULL ? &comp_match_res->match_for_lcd : NULL);
  strncmp_iw_mode mode = (lookup_name.completion_mode ()
			  ? strncmp_iw_mode::NORMAL
			  : strncmp_iw_mode::MATCH_PARAMS);

  if (strncmp_iw_with_mode (symbol_search_name, name.data (), name.size (),
			    mode, language_minimal, match_for_lcd) == 0)
    {
      if (comp_match_res != NULL)
	comp_match_res->set_match (symbol_search_name);
      return true;
    }
  else
    return false;
}

/* See language.h.  */

symbol_name_matcher_ftype *
language_defn::get_symbol_name_matcher
	(const lookup_name_info &lookup_name) const
{
  /* If currently in Ada mode, and the lookup name is wrapped in
     '<...>', hijack all symbol name comparisons using the Ada
     matcher, which handles the verbatim matching.  */
  if (current_language->la_language == language_ada
      && lookup_name.ada ().verbatim_p ())
    return current_language->get_symbol_name_matcher_inner (lookup_name);

  return this->get_symbol_name_matcher_inner (lookup_name);
}

/* See language.h.  */

symbol_name_matcher_ftype *
language_defn::get_symbol_name_matcher_inner
	(const lookup_name_info &lookup_name) const
{
  return default_symbol_name_matcher;
}

/* See language.h.  */

const struct lang_varobj_ops *
language_defn::varobj_ops () const
{
  /* The ops for the C language are suitable for the vast majority of the
     supported languages.  */
  return &c_varobj_ops;
}

/* Class representing the "unknown" language.  */

class unknown_language : public language_defn
{
public:
  unknown_language () : language_defn (language_unknown)
  { /* Nothing.  */ }

  /* See language.h.  */
  void language_arch_info (struct gdbarch *gdbarch,
			   struct language_arch_info *lai) const override
  {
    lai->set_string_char_type (builtin_type (gdbarch)->builtin_char);
    lai->set_bool_type (builtin_type (gdbarch)->builtin_int);
  }

  /* 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 (_("type printing not implemented for language \"%s\""),
	   natural_name ());
  }

  /* See language.h.  */

  gdb::unique_xmalloc_ptr<char> demangle_symbol (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 (_("value printing not implemented for language \"%s\""),
	   natural_name ());
  }

  /* 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 (_("inner value printing not implemented for language \"%s\""),
	   natural_name ());
  }

  /* See language.h.  */

  int parser (struct parser_state *ps) const override
  {
    error (_("expression parsing not implemented for language \"%s\""),
	   natural_name ());
  }

  /* See language.h.  */

  void emitchar (int ch, struct type *chtype,
		 struct ui_file *stream, int quoter) const override
  {
    error (_("emit character not implemented for language \"%s\""),
	   natural_name ());
  }

  /* See language.h.  */

  void printchar (int ch, struct type *chtype,
		  struct ui_file *stream) const override
  {
    error (_("print character not implemented for language \"%s\""),
	   natural_name ());
  }

  /* 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
  {
    error (_("print string not implemented for language \"%s\""),
	   natural_name ());
  }

  /* See language.h.  */

  void print_typedef (struct type *type, struct symbol *new_symbol,
		      struct ui_file *stream) const override
  {
    error (_("print typedef not implemented for language \"%s\""),
	   natural_name ());
  }

  /* See language.h.  */

  bool is_string_type_p (struct type *type) const override
  {
    type = check_typedef (type);
    while (type->code () == TYPE_CODE_REF)
      {
	type = type->target_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.  */

  const char *name () const override
  { return "unknown"; }

  /* See language.h.  */

  const char *natural_name () const override
  { return "Unknown"; }

  /* 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;


/* Per-architecture language information.  */

struct language_gdbarch
{
  /* A vector of per-language per-architecture info.  Indexed by "enum
     language".  */
  struct language_arch_info arch_info[nr_languages];
};

static const registry<gdbarch>::key<language_gdbarch> language_gdbarch_data;

static language_gdbarch *
get_language_gdbarch (struct gdbarch *gdbarch)
{
  struct language_gdbarch *l = language_gdbarch_data.get (gdbarch);
  if (l == nullptr)
    {
      l = new struct language_gdbarch;
      for (const auto &lang : language_defn::languages)
	{
	  gdb_assert (lang != nullptr);
	  lang->language_arch_info (gdbarch, &l->arch_info[lang->la_language]);
	}
      language_gdbarch_data.set (gdbarch, l);
    }

  return l;
}

/* See language.h.  */

struct type *
language_string_char_type (const struct language_defn *la,
			   struct gdbarch *gdbarch)
{
  struct language_gdbarch *ld = get_language_gdbarch (gdbarch);
  return ld->arch_info[la->la_language].string_char_type ();
}

/* See language.h.  */

struct value *
language_defn::value_string (struct gdbarch *gdbarch,
			     const char *ptr, ssize_t len) const
{
  struct type *type = language_string_char_type (this, gdbarch);
  return value_cstring (ptr, len, type);
}

/* See language.h.  */

struct type *
language_bool_type (const struct language_defn *la,
		    struct gdbarch *gdbarch)
{
  struct language_gdbarch *ld = get_language_gdbarch (gdbarch);
  return ld->arch_info[la->la_language].bool_type ();
}

/* See language.h.  */

struct type *
language_arch_info::bool_type () const
{
  if (m_bool_type_name != nullptr)
    {
      struct symbol *sym;

      sym = lookup_symbol (m_bool_type_name, nullptr, SEARCH_TYPE_DOMAIN,
			   nullptr).symbol;
      if (sym != nullptr)
	{
	  struct type *type = sym->type ();
	  if (type != nullptr && type->code () == TYPE_CODE_BOOL)
	    return type;
	}
    }

  return m_bool_type_default;
}

/* See language.h.  */

struct symbol *
language_arch_info::type_and_symbol::alloc_type_symbol
	(enum language lang, struct type *type)
{
  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 (TYPE_DOMAIN);
  symbol->set_loc_class_index (LOC_TYPEDEF);
  return symbol;
}

/* 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 (tas.type ()->name (), name) == 0)
	return &tas;
    }

  return nullptr;
}

/* See language.h.  */

struct type *
language_arch_info::lookup_primitive_type (const char *name)
{
  type_and_symbol *tas = lookup_primitive_type_and_symbol (name);
  if (tas != nullptr)
    return tas->type ();
  return nullptr;
}

/* See language.h.  */

struct type *
language_arch_info::lookup_primitive_type
  (gdb::function_view<bool (struct type *)> filter)
{
  for (struct type_and_symbol &tas : primitive_types_and_symbols)
    {
      if (filter (tas.type ()))
	return tas.type ();
    }

  return nullptr;
}

/* See language.h.  */

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;
}

/* Helper for the language_lookup_primitive_type overloads to forward
   to the corresponding language's lookup_primitive_type overload.  */

template<typename T>
static struct type *
language_lookup_primitive_type_1 (const struct language_defn *la,
				  struct gdbarch *gdbarch,
				  T arg)
{
  struct language_gdbarch *ld = get_language_gdbarch (gdbarch);
  return ld->arch_info[la->la_language].lookup_primitive_type (arg);
}

/* See language.h.  */

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);
}

/* See language.h.  */

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.  */

struct symbol *
language_lookup_primitive_type_as_symbol (const struct language_defn *la,
					  struct gdbarch *gdbarch,
					  const char *name)
{
  struct language_gdbarch *ld = get_language_gdbarch (gdbarch);
  struct language_arch_info *lai = &ld->arch_info[la->la_language];

  symbol_lookup_debug_printf
    ("language = \"%s\", gdbarch @ %s, type = \"%s\")",
     la->name (), host_address_to_string (gdbarch), name);

  struct symbol *sym
    = lai->lookup_primitive_type_as_symbol (name, la->la_language);

  symbol_lookup_debug_printf ("found symbol @ %s",
			      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;
}

/* Initialize the language routines.  */

INIT_GDB_FILE (language)
{
  static const char *const type_or_range_names[]
    = { "on", "off", "warn", "auto", NULL };

  static const char *const case_sensitive_names[]
    = { "on", "off", "auto", NULL };

  /* GDB commands for language specific stuff.  */

  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)."),
			_("Show range checking (on/warn/off/auto)."),
			NULL, set_range_command,
			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)."), _("\
Show case sensitivity in name search (on/off/auto)."), _("\
For Fortran the default is off; for other languages the default is on."),
			set_case_command,
			show_case_command,
			&setlist, &showlist);

  add_setshow_boolean_cmd ("warn-language-frame-mismatch", class_obscure,
			   &warn_frame_lang_mismatch, _("\
Enable or disable the frame language-mismatch warning."),
			   _("\
Show the current setting of the frame language-mismatch warning."),
			   _("\
The frame-language-mismatch warning is issued when the current language\n\
does not match the selected frame's language."), nullptr, nullptr,
			   &setlist, &showlist);

  add_set_language_command ();
}
