/* Multiple source language support for GDB.
- Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1991-2019 Free Software Foundation, Inc.
Contributed by the Department of Computer Science at the State University
of New York at Buffalo.
/* 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. */
+ 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
#include "defs.h"
#include <ctype.h>
-#include "gdb_string.h"
-
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcmd.h"
#include "expression.h"
#include "language.h"
+#include "varobj.h"
#include "target.h"
#include "parser-defs.h"
-#include "jv-lang.h"
#include "demangle.h"
#include "symfile.h"
+#include "cp-support.h"
+#include "frame.h"
+#include "c-lang.h"
+#include <algorithm>
+#include "gdbarch.h"
-extern void _initialize_language (void);
-
-static void set_case_str (void);
-
-static void set_range_str (void);
-
-static void set_type_str (void);
-
-static void set_lang_str (void);
-
-static void unk_lang_error (char *);
-
-static int unk_lang_parser (void);
+static int unk_lang_parser (struct parser_state *);
-static void show_check (char *, int);
+static void set_range_case (void);
-static void set_check (char *, int);
+static void unk_lang_emit_char (int c, struct type *type,
+ struct ui_file *stream, int quoter);
-static void set_type_range_case (void);
+static void unk_lang_printchar (int c, struct type *type,
+ struct ui_file *stream);
-static void unk_lang_emit_char (int c, struct ui_file *stream, int quoter);
-
-static void unk_lang_printchar (int c, struct ui_file *stream);
-
-static void unk_lang_print_type (struct type *, char *, struct ui_file *,
- int, int);
-
-static int unk_lang_value_print (struct value *, struct ui_file *, int, enum val_prettyprint);
+static void unk_lang_value_print (struct value *, struct ui_file *,
+ const struct value_print_options *);
static CORE_ADDR unk_lang_trampoline (struct frame_info *, CORE_ADDR pc);
enum range_mode range_mode = range_mode_auto;
enum range_check range_check = range_check_off;
-enum type_mode type_mode = type_mode_auto;
-enum type_check type_check = type_check_off;
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) */
+/* The current language and language_mode (see language.h). */
const struct language_defn *current_language = &unknown_language_defn;
enum language_mode language_mode = language_mode_auto;
const struct language_defn *expected_language;
-/* The list of supported languages. The list itself is malloc'd. */
-
-static const struct language_defn **languages;
-static unsigned languages_size;
-static unsigned languages_allocsize;
-#define DEFAULT_ALLOCSIZE 4
-
-/* The "set language/type/range" commands all put stuff in these
- buffers. This is to make them work as set/show commands. The
- user's string is copied here, then the set_* commands look at
- them and update them to something that looks nice when it is
- printed out. */
+/* The list of supported languages. Keep this in the same order as
+ the 'enum language' values. */
+
+static const struct language_defn *languages[] = {
+ &unknown_language_defn,
+ &auto_language_defn,
+ &c_language_defn,
+ &objc_language_defn,
+ &cplus_language_defn,
+ &d_language_defn,
+ &go_language_defn,
+ &f_language_defn,
+ &m2_language_defn,
+ &asm_language_defn,
+ &pascal_language_defn,
+ &opencl_language_defn,
+ &rust_language_defn,
+ &minimal_language_defn,
+ &ada_language_defn,
+};
-static char *language;
-static char *type;
-static char *range;
-static char *case_sensitive;
+/* The current values of the "set language/range/case-sensitive" enum
+ commands. */
+static const char *language;
+static const char *range;
+static const char *case_sensitive;
-/* Warning issued when current_language and the language of the current
- frame do not match. */
-char lang_frame_mismatch_warn[] =
-"Warning: the current language does not match this frame.";
+/* See language.h. */
+const char lang_frame_mismatch_warn[] =
+N_("Warning: the current language does not match this frame.");
\f
/* This page contains the functions corresponding to GDB commands
- and their helpers. */
+ and their helpers. */
/* Show command. Display a warning if the language set
- does not match the frame. */
+ 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 current frame */
-
- deprecated_show_value_hack (file, from_tty, c, value);
- flang = get_frame_language ();
- if (flang != language_unknown &&
- language_mode == language_mode_manual &&
- current_language->la_language != flang)
- printf_filtered ("%s\n", lang_frame_mismatch_warn);
+ enum language flang; /* The language of the frame. */
+
+ if (language_mode == language_mode_auto)
+ fprintf_filtered (gdb_stdout,
+ _("The current source language is "
+ "\"auto; currently %s\".\n"),
+ current_language->la_name);
+ else
+ fprintf_filtered (gdb_stdout,
+ _("The current source language is \"%s\".\n"),
+ current_language->la_name);
+
+ if (has_stack_frames ())
+ {
+ struct frame_info *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)
+ printf_filtered ("%s\n", _(lang_frame_mismatch_warn));
+ }
}
-/* Set command. Change the current working language. */
+/* Set command. Change the current working language. */
static void
-set_language_command (char *ignore, int from_tty, struct cmd_list_element *c)
+set_language_command (const char *ignore,
+ int from_tty, struct cmd_list_element *c)
{
- int i;
- enum language flang;
- char *err_lang;
+ enum language flang = language_unknown;
- if (!language || !language[0])
- {
- printf_unfiltered (_("\
-The currently understood settings are:\n\n\
-local or auto Automatic setting based on source file\n"));
-
- for (i = 0; i < languages_size; ++i)
- {
- /* Already dealt with these above. */
- if (languages[i]->la_language == language_unknown
- || languages[i]->la_language == language_auto)
- continue;
-
- /* FIXME: i18n: for now assume that the human-readable name
- is just a capitalization of the internal name. */
- printf_unfiltered ("%-16s Use the %c%s language\n",
- languages[i]->la_name,
- /* Capitalize first letter of language
- name. */
- toupper (languages[i]->la_name[0]),
- languages[i]->la_name + 1);
- }
- /* Restore the silly string. */
- set_language (current_language->la_language);
- return;
- }
+ /* "local" is a synonym of "auto". */
+ if (strcmp (language, "local") == 0)
+ language = "auto";
/* Search the list of languages for a match. */
- for (i = 0; i < languages_size; i++)
+ for (const auto &lang : languages)
{
- if (strcmp (languages[i]->la_name, language) == 0)
+ if (strcmp (lang->la_name, language) == 0)
{
/* Found it! Go into manual mode, and use this language. */
- if (languages[i]->la_language == language_auto)
+ if (lang->la_language == language_auto)
{
/* Enter auto mode. Set to the current frame's language, if
known, or fallback to the initial language. */
language_mode = language_mode_auto;
- flang = get_frame_language ();
+ try
+ {
+ struct frame_info *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
{
/* Enter manual mode. Set the specified language. */
language_mode = language_mode_manual;
- current_language = languages[i];
- set_type_range_case ();
- set_lang_str ();
+ current_language = lang;
+ set_range_case ();
expected_language = current_language;
return;
}
}
}
- /* Reset the language (esp. the global string "language") to the
- correct values. */
- err_lang = savestring (language, strlen (language));
- make_cleanup (xfree, err_lang); /* Free it after error */
- set_language (current_language->la_language);
- error (_("Unknown language `%s'."), err_lang);
+ internal_error (__FILE__, __LINE__,
+ "Couldn't find language `%s' in known languages list.",
+ language);
}
-/* Show command. Display a warning if the type setting does
- not match the current language. */
-static void
-show_type_command (struct ui_file *file, int from_tty,
- struct cmd_list_element *c, const char *value)
-{
- deprecated_show_value_hack (file, from_tty, c, value);
- if (type_check != current_language->la_type_check)
- printf_unfiltered (
- "Warning: the current type check setting does not match the language.\n");
-}
-
-/* Set command. Change the setting for type checking. */
+/* Show command. Display a warning if the range setting does
+ not match the current language. */
static void
-set_type_command (char *ignore, int from_tty, struct cmd_list_element *c)
+show_range_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
{
- if (strcmp (type, "on") == 0)
- {
- type_check = type_check_on;
- type_mode = type_mode_manual;
- }
- else if (strcmp (type, "warn") == 0)
- {
- type_check = type_check_warn;
- type_mode = type_mode_manual;
- }
- else if (strcmp (type, "off") == 0)
- {
- type_check = type_check_off;
- type_mode = type_mode_manual;
- }
- else if (strcmp (type, "auto") == 0)
+ if (range_mode == range_mode_auto)
{
- type_mode = type_mode_auto;
- set_type_range_case ();
- /* Avoid hitting the set_type_str call below. We
- did it in set_type_range_case. */
- return;
+ 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 (__FILE__, __LINE__,
+ "Unrecognized range check setting.");
+ }
+
+ fprintf_filtered (gdb_stdout,
+ _("Range checking is \"auto; currently %s\".\n"),
+ tmp);
}
else
- {
- warning (_("Unrecognized type check setting: \"%s\""), type);
- }
- set_type_str ();
- show_type_command (NULL, from_tty, NULL, NULL);
-}
+ fprintf_filtered (gdb_stdout, _("Range checking is \"%s\".\n"),
+ value);
-/* 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)
-{
- deprecated_show_value_hack (file, from_tty, c, value);
if (range_check != current_language->la_range_check)
- printf_unfiltered (
- "Warning: the current range check setting does not match the language.\n");
+ warning (_("the current range check setting "
+ "does not match the language.\n"));
}
-/* Set command. Change the setting for range checking. */
+/* Set command. Change the setting for range checking. */
static void
-set_range_command (char *ignore, int from_tty, struct cmd_list_element *c)
+set_range_command (const char *ignore,
+ int from_tty, struct cmd_list_element *c)
{
if (strcmp (range, "on") == 0)
{
else if (strcmp (range, "auto") == 0)
{
range_mode = range_mode_auto;
- set_type_range_case ();
- /* Avoid hitting the set_range_str call below. We
- did it in set_type_range_case. */
+ set_range_case ();
return;
}
else
{
- warning (_("Unrecognized range check setting: \"%s\""), range);
+ internal_error (__FILE__, __LINE__,
+ _("Unrecognized range check setting: \"%s\""), range);
}
- set_range_str ();
- show_range_command (NULL, from_tty, NULL, NULL);
+ if (range_check != current_language->la_range_check)
+ warning (_("the current range check setting "
+ "does not match the language.\n"));
}
/* Show command. Display a warning if the case sensitivity setting does
- not match the current language. */
+ 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)
{
- deprecated_show_value_hack (file, from_tty, c, 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 (__FILE__, __LINE__,
+ "Unrecognized case-sensitive setting.");
+ }
+
+ fprintf_filtered (gdb_stdout,
+ _("Case sensitivity in "
+ "name search is \"auto; currently %s\".\n"),
+ tmp);
+ }
+ else
+ fprintf_filtered (gdb_stdout,
+ _("Case sensitivity in name search is \"%s\".\n"),
+ value);
+
if (case_sensitivity != current_language->la_case_sensitivity)
- printf_unfiltered(
-"Warning: the current case sensitivity setting does not match the language.\n");
+ warning (_("the current case sensitivity setting does not match "
+ "the language.\n"));
}
/* Set command. Change the setting for case sensitivity. */
static void
-set_case_command (char *ignore, int from_tty, struct cmd_list_element *c)
+set_case_command (const char *ignore, int from_tty, struct cmd_list_element *c)
{
if (strcmp (case_sensitive, "on") == 0)
{
else if (strcmp (case_sensitive, "auto") == 0)
{
case_mode = case_mode_auto;
- set_type_range_case ();
- /* Avoid hitting the set_case_str call below. We did it in
- set_type_range_case. */
+ set_range_case ();
return;
}
else
{
- warning (_("Unrecognized case-sensitive setting: \"%s\""),
- case_sensitive);
+ internal_error (__FILE__, __LINE__,
+ "Unrecognized case-sensitive setting: \"%s\"",
+ case_sensitive);
}
- set_case_str();
- show_case_command (NULL, from_tty, NULL, NULL);
+
+ if (case_sensitivity != current_language->la_case_sensitivity)
+ warning (_("the current case sensitivity setting does not match "
+ "the language.\n"));
}
/* 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. */
+ type and range checking status. */
static void
-set_type_range_case (void)
+set_range_case (void)
{
-
if (range_mode == range_mode_auto)
range_check = current_language->la_range_check;
- if (type_mode == type_mode_auto)
- type_check = current_language->la_type_check;
-
if (case_mode == case_mode_auto)
case_sensitivity = current_language->la_case_sensitivity;
-
- set_type_str ();
- set_range_str ();
- set_case_str ();
}
-/* Set current language to (enum language) LANG. Returns previous language. */
+/* Set current language to (enum language) LANG. Returns previous
+ language. */
enum language
set_language (enum language lang)
{
- int i;
enum language prev_language;
prev_language = current_language->la_language;
-
- for (i = 0; i < languages_size; i++)
- {
- if (languages[i]->la_language == lang)
- {
- current_language = languages[i];
- set_type_range_case ();
- set_lang_str ();
- break;
- }
- }
-
+ current_language = languages[lang];
+ set_range_case ();
return prev_language;
}
\f
-/* This page contains functions that update the global vars
- language, type and range. */
-static void
-set_lang_str (void)
-{
- char *prefix = "";
-
- if (language)
- xfree (language);
- if (language_mode == language_mode_auto)
- prefix = "auto; currently ";
-
- language = concat (prefix, current_language->la_name, (char *)NULL);
-}
-
-static void
-set_type_str (void)
-{
- char *tmp = NULL, *prefix = "";
-
- if (type)
- xfree (type);
- if (type_mode == type_mode_auto)
- prefix = "auto; currently ";
-
- switch (type_check)
- {
- case type_check_on:
- tmp = "on";
- break;
- case type_check_off:
- tmp = "off";
- break;
- case type_check_warn:
- tmp = "warn";
- break;
- default:
- error (_("Unrecognized type check setting."));
- }
-
- type = concat (prefix, tmp, (char *)NULL);
-}
-
-static void
-set_range_str (void)
-{
- char *tmp, *pref = "";
-
- if (range_mode == range_mode_auto)
- pref = "auto; currently ";
-
- 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:
- error (_("Unrecognized range check setting."));
- }
-
- if (range)
- xfree (range);
- range = concat (pref, tmp, (char *)NULL);
-}
-
-static void
-set_case_str (void)
-{
- char *tmp = NULL, *prefix = "";
-
- if (case_mode==case_mode_auto)
- prefix = "auto; currently ";
-
- switch (case_sensitivity)
- {
- case case_sensitive_on:
- tmp = "on";
- break;
- case case_sensitive_off:
- tmp = "off";
- break;
- default:
- error (_("Unrecognized case-sensitive setting."));
- }
-
- xfree (case_sensitive);
- case_sensitive = concat (prefix, tmp, (char *)NULL);
-}
/* Print out the current language settings: language, range and
type checking. If QUIETLY, print only what has changed. */
if (!quietly)
{
- printf_unfiltered (_("Type checking: %s\n"), type);
- show_type_command (NULL, 1, NULL, NULL);
printf_unfiltered (_("Range checking: %s\n"), range);
show_range_command (NULL, 1, NULL, NULL);
printf_unfiltered (_("Case sensitivity: %s\n"), case_sensitive);
}
}
\f
-/* Return the result of a binary operation. */
-
-#if 0 /* Currently unused */
-
-struct type *
-binop_result_type (struct value *v1, struct value *v2)
-{
- int size, uns;
- struct type *t1 = check_typedef (VALUE_TYPE (v1));
- struct type *t2 = check_typedef (VALUE_TYPE (v2));
-
- int l1 = TYPE_LENGTH (t1);
- int l2 = TYPE_LENGTH (t2);
-
- switch (current_language->la_language)
- {
- case language_c:
- case language_cplus:
- case language_objc:
- if (TYPE_CODE (t1) == TYPE_CODE_FLT)
- return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ?
- VALUE_TYPE (v2) : VALUE_TYPE (v1);
- else if (TYPE_CODE (t2) == TYPE_CODE_FLT)
- return TYPE_CODE (t1) == TYPE_CODE_FLT && l1 > l2 ?
- VALUE_TYPE (v1) : VALUE_TYPE (v2);
- else if (TYPE_UNSIGNED (t1) && l1 > l2)
- return VALUE_TYPE (v1);
- else if (TYPE_UNSIGNED (t2) && l2 > l1)
- return VALUE_TYPE (v2);
- else /* Both are signed. Result is the longer type */
- return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
- break;
- case language_m2:
- /* If we are doing type-checking, l1 should equal l2, so this is
- not needed. */
- return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
- break;
- }
- internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
- return (struct type *) 0; /* For lint */
-}
-
-#endif /* 0 */
-#if 0
-/* This page contains functions that are used in type/range checking.
- They all return zero if the type/range check fails.
-
- It is hoped that these will make extending GDB to parse different
- languages a little easier. These are primarily used in eval.c when
- evaluating expressions and making sure that their types are correct.
- Instead of having a mess of conjucted/disjuncted expressions in an "if",
- the ideas of type can be wrapped up in the following functions.
-
- Note that some of them are not currently dependent upon which language
- is currently being parsed. For example, floats are the same in
- C and Modula-2 (ie. the only floating point type has TYPE_CODE of
- TYPE_CODE_FLT), while booleans are different. */
-
-/* Returns non-zero if its argument is a simple type. This is the same for
- both Modula-2 and for C. In the C case, TYPE_CODE_CHAR will never occur,
- and thus will never cause the failure of the test. */
-int
-simple_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_ENUM:
- case TYPE_CODE_FLT:
- case TYPE_CODE_RANGE:
- case TYPE_CODE_BOOL:
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* Returns non-zero if its argument is of an ordered type.
- An ordered type is one in which the elements can be tested for the
- properties of "greater than", "less than", etc, or for which the
- operations "increment" or "decrement" make sense. */
-int
-ordered_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_ENUM:
- case TYPE_CODE_FLT:
- case TYPE_CODE_RANGE:
- return 1;
-
- default:
- return 0;
- }
-}
-/* Returns non-zero if the two types are the same */
-int
-same_type (struct type *arg1, struct type *arg2)
-{
- CHECK_TYPEDEF (type);
- if (structured_type (arg1) ? !structured_type (arg2) : structured_type (arg2))
- /* One is structured and one isn't */
- return 0;
- else if (structured_type (arg1) && structured_type (arg2))
- return arg1 == arg2;
- else if (numeric_type (arg1) && numeric_type (arg2))
- return (TYPE_CODE (arg2) == TYPE_CODE (arg1)) &&
- (TYPE_UNSIGNED (arg1) == TYPE_UNSIGNED (arg2))
- ? 1 : 0;
- else
- return arg1 == arg2;
-}
-
-/* Returns non-zero if the type is integral */
-int
-integral_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- switch (current_language->la_language)
- {
- case language_c:
- case language_cplus:
- case language_objc:
- return (TYPE_CODE (type) != TYPE_CODE_INT) &&
- (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1;
- case language_m2:
- case language_pascal:
- return TYPE_CODE (type) != TYPE_CODE_INT ? 0 : 1;
- default:
- error (_("Language not supported."));
- }
-}
-
-/* Returns non-zero if the value is numeric */
-int
-numeric_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_FLT:
- return 1;
-
- default:
- return 0;
- }
-}
-
-/* Returns non-zero if the value is a character type */
-int
-character_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- switch (current_language->la_language)
- {
- case language_m2:
- case language_pascal:
- return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1;
-
- case language_c:
- case language_cplus:
- case language_objc:
- return (TYPE_CODE (type) == TYPE_CODE_INT) &&
- TYPE_LENGTH (type) == sizeof (char)
- ? 1 : 0;
- default:
- return (0);
- }
-}
-
-/* Returns non-zero if the value is a string type */
-int
-string_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- switch (current_language->la_language)
- {
- case language_m2:
- case language_pascal:
- return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1;
-
- case language_c:
- case language_cplus:
- case language_objc:
- /* C does not have distinct string type. */
- return (0);
- default:
- return (0);
- }
-}
-
-/* Returns non-zero if the value is a boolean type */
-int
-boolean_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- if (TYPE_CODE (type) == TYPE_CODE_BOOL)
- return 1;
- switch (current_language->la_language)
- {
- case language_c:
- case language_cplus:
- case language_objc:
- /* Might be more cleanly handled by having a
- TYPE_CODE_INT_NOT_BOOL for (the deleted) CHILL and such
- languages, or a TYPE_CODE_INT_OR_BOOL for C. */
- if (TYPE_CODE (type) == TYPE_CODE_INT)
- return 1;
- default:
- break;
- }
- return 0;
-}
-
-/* Returns non-zero if the value is a floating-point type */
-int
-float_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- return TYPE_CODE (type) == TYPE_CODE_FLT;
-}
-
-/* Returns non-zero if the value is a pointer type */
+/* Returns non-zero if the value is a pointer type. */
int
pointer_type (struct type *type)
{
- return TYPE_CODE (type) == TYPE_CODE_PTR ||
- TYPE_CODE (type) == TYPE_CODE_REF;
+ return TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type);
}
-/* Returns non-zero if the value is a structured type */
-int
-structured_type (struct type *type)
-{
- CHECK_TYPEDEF (type);
- switch (current_language->la_language)
- {
- case language_c:
- case language_cplus:
- case language_objc:
- return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
- (TYPE_CODE (type) == TYPE_CODE_UNION) ||
- (TYPE_CODE (type) == TYPE_CODE_ARRAY);
- case language_pascal:
- return (TYPE_CODE(type) == TYPE_CODE_STRUCT) ||
- (TYPE_CODE(type) == TYPE_CODE_UNION) ||
- (TYPE_CODE(type) == TYPE_CODE_SET) ||
- (TYPE_CODE(type) == TYPE_CODE_ARRAY);
- case language_m2:
- return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
- (TYPE_CODE (type) == TYPE_CODE_SET) ||
- (TYPE_CODE (type) == TYPE_CODE_ARRAY);
- default:
- return (0);
- }
-}
-#endif
-\f
-struct type *
-lang_bool_type (void)
-{
- struct symbol *sym;
- struct type *type;
- switch (current_language->la_language)
- {
- case language_fortran:
- sym = lookup_symbol ("logical", NULL, VAR_DOMAIN, NULL, NULL);
- if (sym)
- {
- type = SYMBOL_TYPE (sym);
- if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
- return type;
- }
- return builtin_type_f_logical_s2;
- case language_cplus:
- case language_pascal:
- case language_ada:
- if (current_language->la_language==language_cplus)
- {sym = lookup_symbol ("bool", NULL, VAR_DOMAIN, NULL, NULL);}
- else
- {sym = lookup_symbol ("boolean", NULL, VAR_DOMAIN, NULL, NULL);}
- if (sym)
- {
- type = SYMBOL_TYPE (sym);
- if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
- return type;
- }
- return builtin_type_bool;
- case language_java:
- sym = lookup_symbol ("boolean", NULL, VAR_DOMAIN, NULL, NULL);
- if (sym)
- {
- type = SYMBOL_TYPE (sym);
- if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
- return type;
- }
- return java_boolean_type;
-
- default:
- return builtin_type_int;
- }
-}
\f
/* This page contains functions that return info about
- (struct value) values used in GDB. */
+ (struct value) values used in GDB. */
-/* Returns non-zero if the value VAL represents a true value. */
+/* Returns non-zero if the value VAL represents a true value. */
int
value_true (struct value *val)
{
\f
/* This page contains functions for the printing out of
error messages that occur during type- and range-
- checking. */
+ checking. */
-/* These are called when a language fails a type- or range-check. The
+/* 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
- [type|range]_check is [type|range]_check_on, an error is printed;
- if [type|range]_check_warn, a warning; otherwise just the
- message. */
-
-void
-type_error (const char *string,...)
-{
- va_list args;
- va_start (args, string);
-
- switch (type_check)
- {
- case type_check_warn:
- vwarning (string, args);
- break;
- case type_check_on:
- verror (string, args);
- break;
- case type_check_off:
- /* FIXME: cagney/2002-01-30: Should this function print anything
- when type error is off? */
- vfprintf_filtered (gdb_stderr, string, args);
- fprintf_filtered (gdb_stderr, "\n");
- break;
- default:
- internal_error (__FILE__, __LINE__, _("bad switch"));
- }
- va_end (args);
-}
+ 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);
+ va_start (args, string);
switch (range_check)
{
case range_check_warn:
}
\f
-/* This page contains miscellaneous functions */
+/* This page contains miscellaneous functions. */
-/* Return the language enum for a given language string. */
+/* Return the language enum for a given language string. */
enum language
-language_enum (char *str)
+language_enum (const char *str)
{
- int i;
+ for (const auto &lang : languages)
+ if (strcmp (lang->la_name, str) == 0)
+ return lang->la_language;
- for (i = 0; i < languages_size; i++)
- if (strcmp (languages[i]->la_name, str) == 0)
- return languages[i]->la_language;
+ if (strcmp (str, "local") == 0)
+ return language_auto;
return language_unknown;
}
-/* Return the language struct for a given language enum. */
+/* Return the language struct for a given language enum. */
const struct language_defn *
language_def (enum language lang)
{
- int i;
-
- for (i = 0; i < languages_size; i++)
- {
- if (languages[i]->la_language == lang)
- {
- return languages[i];
- }
- }
- return NULL;
+ return languages[lang];
}
-/* Return the language as a string */
-char *
+/* Return the language as a string. */
+
+const char *
language_str (enum language lang)
{
- int i;
-
- for (i = 0; i < languages_size; i++)
- {
- if (languages[i]->la_language == lang)
- {
- return languages[i]->la_name;
- }
- }
- return "Unknown";
+ return languages[lang]->la_name;
}
static void
-set_check (char *ignore, int from_tty)
+set_check (const char *ignore, int from_tty)
{
printf_unfiltered (
"\"set check\" must be followed by the name of a check subcommand.\n");
- help_list (setchecklist, "set check ", -1, gdb_stdout);
+ help_list (setchecklist, "set check ", all_commands, gdb_stdout);
}
static void
-show_check (char *ignore, int from_tty)
+show_check (const char *ignore, int from_tty)
{
cmd_show_list (showchecklist, from_tty, "");
}
\f
-/* Add a language to the set of known languages. */
-void
-add_language (const struct language_defn *lang)
-{
- if (lang->la_magic != LANG_MAGIC)
- {
- fprintf_unfiltered (gdb_stderr, "Magic number of %s language struct wrong\n",
- lang->la_name);
- internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
- }
+/* Build and install the "set language LANG" command. */
- if (!languages)
+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. +1 for "local" and +1 for NULL
+ termination. */
+ language_names = new const char *[ARRAY_SIZE (languages) + 2];
+
+ /* Display "auto", "local" and "unknown" first, and then the rest,
+ alpha sorted. */
+ const char **language_names_p = language_names;
+ *language_names_p++ = auto_language_defn.la_name;
+ *language_names_p++ = "local";
+ *language_names_p++ = unknown_language_defn.la_name;
+ const char **sort_begin = language_names_p;
+ for (const auto &lang : languages)
{
- languages_allocsize = DEFAULT_ALLOCSIZE;
- languages = (const struct language_defn **) xmalloc
- (languages_allocsize * sizeof (*languages));
+ /* Already handled above. */
+ if (lang->la_language == language_auto
+ || lang->la_language == language_unknown)
+ continue;
+ *language_names_p++ = lang->la_name;
}
- if (languages_size >= languages_allocsize)
+ *language_names_p = NULL;
+ std::sort (sort_begin, language_names_p, compare_cstrings);
+
+ /* Add the filename extensions. */
+ for (const auto &lang : languages)
+ if (lang->la_filename_extensions != NULL)
+ {
+ for (size_t i = 0; lang->la_filename_extensions[i] != NULL; ++i)
+ add_filename_language (lang->la_filename_extensions[i],
+ 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 : languages)
{
- languages_allocsize *= 2;
- languages = (const struct language_defn **) xrealloc ((char *) languages,
- languages_allocsize * sizeof (*languages));
+ /* Already dealt with these above. */
+ if (lang->la_language == language_unknown
+ || lang->la_language == language_auto)
+ continue;
+
+ /* FIXME: i18n: for now assume that the human-readable name is
+ just a capitalization of the internal name. */
+ /* 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 %c%s language",
+ lang->la_name,
+ /* Capitalize first letter of language name. */
+ toupper (lang->la_name[0]),
+ lang->la_name + 1);
}
- languages[languages_size++] = lang;
+
+ add_setshow_enum_cmd ("language", class_support,
+ language_names,
+ &language,
+ doc.c_str (),
+ _("Show the current source language."),
+ NULL, set_language_command,
+ show_language_command,
+ &setlist, &showlist);
}
/* Iterate through all registered languages looking for and calling
CORE_ADDR
skip_language_trampoline (struct frame_info *frame, CORE_ADDR pc)
{
- int i;
-
- for (i = 0; i < languages_size; i++)
+ for (const auto &lang : languages)
{
- if (languages[i]->skip_trampoline)
+ if (lang->skip_trampoline != NULL)
{
- CORE_ADDR real_pc = (languages[i]->skip_trampoline) (frame, pc);
+ CORE_ADDR real_pc = lang->skip_trampoline (frame, pc);
+
if (real_pc)
return real_pc;
}
return 0;
}
-/* Return demangled language symbol, or NULL.
+/* Return demangled language symbol, or NULL.
FIXME: Options are only useful for certain languages and ignored
by others, so it would be better to remove them here and have a
- more flexible demangler for the languages that need it.
+ 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 *
return NULL;
}
+/* See language.h. */
+
+int
+language_sniff_from_mangled_name (const struct language_defn *lang,
+ const char *mangled, char **demangled)
+{
+ gdb_assert (lang != NULL);
+
+ if (lang->la_sniff_from_mangled_name == NULL)
+ {
+ *demangled = NULL;
+ return 0;
+ }
+
+ return lang->la_sniff_from_mangled_name (mangled, demangled);
+}
+
/* Return class name from physname or NULL. */
char *
-language_class_name_from_physname (const struct language_defn *current_language,
+language_class_name_from_physname (const struct language_defn *lang,
const char *physname)
{
- if (current_language != NULL && current_language->la_class_name_from_physname)
- return current_language->la_class_name_from_physname (physname);
+ if (lang != NULL && lang->la_class_name_from_physname)
+ return lang->la_class_name_from_physname (physname);
return NULL;
}
delimiting words. This is a reasonable default value that
most languages should be able to use. */
-char *
+const char *
default_word_break_characters (void)
{
return " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-";
void
default_print_array_index (struct value *index_value, struct ui_file *stream,
- int format, enum val_prettyprint pretty)
+ const struct value_print_options *options)
{
fprintf_filtered (stream, "[");
- LA_VALUE_PRINT (index_value, stream, format, pretty);
+ LA_VALUE_PRINT (index_value, stream, options);
fprintf_filtered (stream, "] = ");
}
+/* See language.h. */
+
+bool
+default_symbol_name_matcher (const char *symbol_search_name,
+ const lookup_name_info &lookup_name,
+ completion_match_result *comp_match_res)
+{
+ const std::string &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.c_str (), 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. */
+
+bool
+default_is_string_type_p (struct type *type)
+{
+ type = check_typedef (type);
+ while (TYPE_CODE (type) == TYPE_CODE_REF)
+ {
+ type = TYPE_TARGET_TYPE (type);
+ type = check_typedef (type);
+ }
+ return (TYPE_CODE (type) == TYPE_CODE_STRING);
+}
+
+/* See language.h. */
+
+symbol_name_matcher_ftype *
+get_symbol_name_matcher (const language_defn *lang,
+ const lookup_name_info &lookup_name)
+{
+ /* 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->la_get_symbol_name_matcher (lookup_name);
+
+ if (lang->la_get_symbol_name_matcher != nullptr)
+ return lang->la_get_symbol_name_matcher (lookup_name);
+ return default_symbol_name_matcher;
+}
+
/* Define the language that is no language. */
static int
-unk_lang_parser (void)
+unk_lang_parser (struct parser_state *ps)
{
return 1;
}
static void
-unk_lang_error (char *msg)
+unk_lang_emit_char (int c, struct type *type, struct ui_file *stream,
+ int quoter)
{
- error (_("Attempted to parse an expression with unknown language"));
+ error (_("internal error - unimplemented "
+ "function unk_lang_emit_char called."));
}
static void
-unk_lang_emit_char (int c, struct ui_file *stream, int quoter)
+unk_lang_printchar (int c, struct type *type, struct ui_file *stream)
{
- error (_("internal error - unimplemented function unk_lang_emit_char called."));
+ error (_("internal error - unimplemented "
+ "function unk_lang_printchar called."));
}
static void
-unk_lang_printchar (int c, struct ui_file *stream)
+unk_lang_printstr (struct ui_file *stream, struct type *type,
+ const gdb_byte *string, unsigned int length,
+ const char *encoding, int force_ellipses,
+ const struct value_print_options *options)
{
- error (_("internal error - unimplemented function unk_lang_printchar called."));
+ error (_("internal error - unimplemented "
+ "function unk_lang_printstr called."));
}
static void
-unk_lang_printstr (struct ui_file *stream, const gdb_byte *string,
- unsigned int length, int width, int force_ellipses)
+unk_lang_print_type (struct type *type, const char *varstring,
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags)
{
- error (_("internal error - unimplemented function unk_lang_printstr called."));
+ error (_("internal error - unimplemented "
+ "function unk_lang_print_type called."));
}
static void
-unk_lang_print_type (struct type *type, char *varstring, struct ui_file *stream,
- int show, int level)
-{
- error (_("internal error - unimplemented function unk_lang_print_type called."));
-}
-
-static int
-unk_lang_val_print (struct type *type, const gdb_byte *valaddr,
+unk_lang_val_print (struct type *type,
int embedded_offset, CORE_ADDR address,
- struct ui_file *stream, int format,
- int deref_ref, int recurse, enum val_prettyprint pretty)
+ struct ui_file *stream, int recurse,
+ struct value *val,
+ const struct value_print_options *options)
{
- error (_("internal error - unimplemented function unk_lang_val_print called."));
+ error (_("internal error - unimplemented "
+ "function unk_lang_val_print called."));
}
-static int
-unk_lang_value_print (struct value *val, struct ui_file *stream, int format,
- enum val_prettyprint pretty)
+static void
+unk_lang_value_print (struct value *val, struct ui_file *stream,
+ const struct value_print_options *options)
{
- error (_("internal error - unimplemented function unk_lang_value_print called."));
+ error (_("internal error - unimplemented "
+ "function unk_lang_value_print called."));
}
static CORE_ADDR unk_lang_trampoline (struct frame_info *frame, CORE_ADDR pc)
/* Unknown languages just use the cplus demangler. */
static char *unk_lang_demangle (const char *mangled, int options)
{
- return cplus_demangle (mangled, options);
+ return gdb_demangle (mangled, options);
}
static char *unk_lang_class_name (const char *mangled)
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 *);
}
const struct language_defn unknown_language_defn =
{
"unknown",
+ "Unknown",
language_unknown,
range_check_off,
- type_check_off,
- array_row_major,
case_sensitive_on,
+ array_row_major,
+ macro_expansion_no,
+ NULL,
&exp_descriptor_standard,
unk_lang_parser,
- unk_lang_error,
null_post_parser,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_print_type, /* Print a type using appropriate syntax */
+ default_print_typedef, /* Print a typedef using appropriate syntax */
unk_lang_val_print, /* Print a value using appropriate syntax */
unk_lang_value_print, /* Print a top-level value */
+ default_read_var_value, /* la_read_var_value */
unk_lang_trampoline, /* Language specific skip_trampoline */
"this", /* name_of_this */
+ true, /* store_sym_names_in_linkage_form_p */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
unk_lang_demangle, /* Language specific symbol demangler */
- unk_lang_class_name, /* Language specific class_name_from_physname */
+ NULL,
+ unk_lang_class_name, /* Language specific
+ class_name_from_physname */
unk_op_print_tab, /* expression operators for printing */
1, /* c-style arrays */
0, /* String lower bound */
default_word_break_characters,
- default_make_symbol_completion_list,
+ default_collect_symbol_completion_matches,
unknown_language_arch_info, /* la_language_arch_info. */
default_print_array_index,
default_pass_by_reference,
- LANG_MAGIC
+ c_watch_location_expression,
+ NULL, /* la_get_symbol_name_matcher */
+ iterate_over_symbols,
+ default_search_name_hash,
+ &default_varobj_ops,
+ NULL,
+ NULL,
+ default_is_string_type_p,
+ "{...}" /* la_struct_too_deep_ellipsis */
};
-/* These two structs define fake entries for the "local" and "auto" options. */
+/* These two structs define fake entries for the "local" and "auto"
+ options. */
const struct language_defn auto_language_defn =
{
"auto",
+ "Auto",
language_auto,
range_check_off,
- type_check_off,
- array_row_major,
case_sensitive_on,
+ array_row_major,
+ macro_expansion_no,
+ NULL,
&exp_descriptor_standard,
unk_lang_parser,
- unk_lang_error,
null_post_parser,
unk_lang_printchar, /* Print character constant */
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_print_type, /* Print a type using appropriate syntax */
+ default_print_typedef, /* Print a typedef using appropriate syntax */
unk_lang_val_print, /* Print a value using appropriate syntax */
unk_lang_value_print, /* Print a top-level value */
+ default_read_var_value, /* la_read_var_value */
unk_lang_trampoline, /* Language specific skip_trampoline */
"this", /* name_of_this */
+ false, /* store_sym_names_in_linkage_form_p */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
unk_lang_demangle, /* Language specific symbol demangler */
- unk_lang_class_name, /* Language specific class_name_from_physname */
+ NULL,
+ unk_lang_class_name, /* Language specific
+ class_name_from_physname */
unk_op_print_tab, /* expression operators for printing */
1, /* c-style arrays */
0, /* String lower bound */
default_word_break_characters,
- default_make_symbol_completion_list,
+ default_collect_symbol_completion_matches,
unknown_language_arch_info, /* la_language_arch_info. */
default_print_array_index,
default_pass_by_reference,
- LANG_MAGIC
+ c_watch_location_expression,
+ NULL, /* la_get_symbol_name_matcher */
+ iterate_over_symbols,
+ default_search_name_hash,
+ &default_varobj_ops,
+ NULL,
+ NULL,
+ default_is_string_type_p,
+ "{...}" /* la_struct_too_deep_ellipsis */
};
-const struct language_defn local_language_defn =
-{
- "local",
- language_auto,
- range_check_off,
- type_check_off,
- case_sensitive_on,
- array_row_major,
- &exp_descriptor_standard,
- unk_lang_parser,
- unk_lang_error,
- null_post_parser,
- unk_lang_printchar, /* Print character constant */
- unk_lang_printstr,
- unk_lang_emit_char,
- unk_lang_print_type, /* Print a type using appropriate syntax */
- unk_lang_val_print, /* Print a value using appropriate syntax */
- unk_lang_value_print, /* Print a top-level value */
- unk_lang_trampoline, /* Language specific skip_trampoline */
- "this", /* name_of_this */
- basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
- basic_lookup_transparent_type,/* lookup_transparent_type */
- unk_lang_demangle, /* Language specific symbol demangler */
- unk_lang_class_name, /* Language specific class_name_from_physname */
- unk_op_print_tab, /* expression operators for printing */
- 1, /* c-style arrays */
- 0, /* String lower bound */
- default_word_break_characters,
- default_make_symbol_completion_list,
- unknown_language_arch_info, /* la_language_arch_info. */
- default_print_array_index,
- default_pass_by_reference,
- LANG_MAGIC
-};
\f
/* Per-architecture language information. */
language_gdbarch_post_init (struct gdbarch *gdbarch)
{
struct language_gdbarch *l;
- int i;
l = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct language_gdbarch);
- for (i = 0; i < languages_size; i++)
- {
- if (languages[i] != NULL
- && languages[i]->la_language_arch_info != NULL)
- languages[i]->la_language_arch_info
- (gdbarch, l->arch_info + languages[i]->la_language);
- }
+ for (const auto &lang : languages)
+ if (lang != NULL && lang->la_language_arch_info != NULL)
+ {
+ lang->la_language_arch_info (gdbarch,
+ l->arch_info + lang->la_language);
+ }
+
return l;
}
language_string_char_type (const struct language_defn *la,
struct gdbarch *gdbarch)
{
- struct language_gdbarch *ld = gdbarch_data (gdbarch,
- language_gdbarch_data);
+ struct language_gdbarch *ld
+ = (struct language_gdbarch *) gdbarch_data (gdbarch, language_gdbarch_data);
+
return ld->arch_info[la->la_language].string_char_type;
}
struct type *
-language_lookup_primitive_type_by_name (const struct language_defn *la,
- struct gdbarch *gdbarch,
- const char *name)
+language_bool_type (const struct language_defn *la,
+ struct gdbarch *gdbarch)
{
- struct language_gdbarch *ld = gdbarch_data (gdbarch,
- language_gdbarch_data);
- struct type *const *p;
- for (p = ld->arch_info[la->la_language].primitive_type_vector;
- (*p) != NULL;
- p++)
+ struct language_gdbarch *ld
+ = (struct language_gdbarch *) gdbarch_data (gdbarch, language_gdbarch_data);
+
+ if (ld->arch_info[la->la_language].bool_type_symbol)
+ {
+ struct symbol *sym;
+
+ sym = lookup_symbol (ld->arch_info[la->la_language].bool_type_symbol,
+ NULL, VAR_DOMAIN, NULL).symbol;
+ if (sym)
+ {
+ struct type *type = SYMBOL_TYPE (sym);
+
+ if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
+ return type;
+ }
+ }
+
+ return ld->arch_info[la->la_language].bool_type_default;
+}
+
+/* Helper function for primitive type lookup. */
+
+static struct type **
+language_lookup_primitive_type_1 (const struct language_arch_info *lai,
+ const char *name)
+{
+ struct type **p;
+
+ for (p = lai->primitive_type_vector; (*p) != NULL; p++)
{
if (strcmp (TYPE_NAME (*p), name) == 0)
- return (*p);
+ return p;
}
- return (NULL);
+ return NULL;
+}
+
+/* See language.h. */
+
+struct type *
+language_lookup_primitive_type (const struct language_defn *la,
+ struct gdbarch *gdbarch,
+ 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;
}
-/* Initialize the language routines */
+/* Helper function for type lookup as a symbol.
+ Create the symbol corresponding to type TYPE in language LANG. */
+
+static struct symbol *
+language_alloc_type_symbol (enum language lang, struct type *type)
+{
+ struct symbol *symbol;
+ struct gdbarch *gdbarch;
+
+ gdb_assert (!TYPE_OBJFILE_OWNED (type));
+
+ gdbarch = TYPE_OWNER (type).gdbarch;
+ symbol = new (gdbarch_obstack (gdbarch)) struct symbol ();
+
+ symbol->name = TYPE_NAME (type);
+ symbol->set_language (lang, nullptr);
+ symbol->owner.arch = gdbarch;
+ SYMBOL_OBJFILE_OWNED (symbol) = 0;
+ SYMBOL_TYPE (symbol) = type;
+ SYMBOL_DOMAIN (symbol) = VAR_DOMAIN;
+ SYMBOL_ACLASS_INDEX (symbol) = LOC_TYPEDEF;
+
+ return symbol;
+}
+
+/* Initialize the primitive type symbols of language LD.
+ The primitive type vector must have already been initialized. */
+
+static void
+language_init_primitive_type_symbols (struct language_arch_info *lai,
+ const struct language_defn *la,
+ struct gdbarch *gdbarch)
+{
+ int n;
+
+ gdb_assert (lai->primitive_type_vector != NULL);
+
+ for (n = 0; lai->primitive_type_vector[n] != NULL; ++n)
+ continue;
+
+ lai->primitive_type_symbols
+ = GDBARCH_OBSTACK_CALLOC (gdbarch, n + 1, struct symbol *);
+
+ 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]);
+ }
+
+ /* 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. */
+}
+
+/* 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
+ = (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->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);
+
+ sym = lai->primitive_type_symbols[typep - lai->primitive_type_vector];
+
+ if (symbol_lookup_debug)
+ fprintf_unfiltered (gdb_stdlog, " = %s\n", host_address_to_string (sym));
+ return sym;
+}
+
+/* Initialize the language routines. */
void
_initialize_language (void)
{
- struct cmd_list_element *set, *show;
+ static const char *const type_or_range_names[]
+ = { "on", "off", "warn", "auto", NULL };
+
+ static const char *const case_sensitive_names[]
+ = { "on", "off", "auto", NULL };
language_gdbarch_data
= gdbarch_data_register_post_init (language_gdbarch_post_init);
- /* GDB commands for language specific stuff */
-
- /* FIXME: cagney/2005-02-20: This should be implemented using an
- enum. */
- add_setshow_string_noescape_cmd ("language", class_support, &language, _("\
-Set the current source language."), _("\
-Show the current source language."), NULL,
- set_language_command,
- show_language_command,
- &setlist, &showlist);
+ /* GDB commands for language specific stuff. */
add_prefix_cmd ("check", no_class, set_check,
_("Set the status of the type/range checker."),
add_alias_cmd ("c", "check", no_class, 1, &showlist);
add_alias_cmd ("ch", "check", no_class, 1, &showlist);
- /* FIXME: cagney/2005-02-20: This should be implemented using an
- enum. */
- add_setshow_string_noescape_cmd ("type", class_support, &type, _("\
-Set type checking. (on/warn/off/auto)"), _("\
-Show type checking. (on/warn/off/auto)"), NULL,
- set_type_command,
- show_type_command,
- &setchecklist, &showchecklist);
-
- /* FIXME: cagney/2005-02-20: This should be implemented using an
- enum. */
- add_setshow_string_noescape_cmd ("range", class_support, &range, _("\
-Set range checking. (on/warn/off/auto)"), _("\
-Show range checking. (on/warn/off/auto)"), NULL,
- set_range_command,
- show_range_command,
- &setchecklist, &showchecklist);
-
- /* FIXME: cagney/2005-02-20: This should be implemented using an
- enum. */
- add_setshow_string_noescape_cmd ("case-sensitive", class_support,
- &case_sensitive, _("\
-Set case sensitivity in name search. (on/off/auto)"), _("\
-Show case sensitivity in name search. (on/off/auto)"), _("\
+ 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);
+
+ 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);
+ set_case_command,
+ show_case_command,
+ &setlist, &showlist);
- add_language (&unknown_language_defn);
- add_language (&local_language_defn);
- add_language (&auto_language_defn);
+ add_set_language_command ();
- language = savestring ("auto", strlen ("auto"));
- type = savestring ("auto", strlen ("auto"));
- range = savestring ("auto", strlen ("auto"));
- case_sensitive = savestring ("auto",strlen ("auto"));
+ language = "auto";
+ range = "auto";
+ case_sensitive = "auto";
- /* Have the above take effect */
+ /* Have the above take effect. */
set_language (language_auto);
}