/* Multiple source language support for GDB.

   Copyright (C) 1991-2026 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 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 ();
}
