/* Multiple source language support for GDB.
- Copyright (C) 1991-1996, 1998-2005, 2007-2012 Free Software
- Foundation, Inc.
+ Copyright (C) 1991-2017 Free Software Foundation, Inc.
Contributed by the Department of Computer Science at the State University
of New York at Buffalo.
#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"
extern void _initialize_language (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_check (char *, int);
-static void set_type_range_case (void);
+static void set_range_case (void);
static void unk_lang_emit_char (int c, struct type *type,
struct ui_file *stream, int quoter);
static void unk_lang_printchar (int c, struct type *type,
struct ui_file *stream);
-static void unk_lang_print_type (struct type *, const char *, struct ui_file *,
- int, int);
-
static void unk_lang_value_print (struct value *, struct ui_file *,
const struct value_print_options *);
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;
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. */
+ enum language flang; /* The language of the frame. */
if (language_mode == language_mode_auto)
fprintf_filtered (gdb_stdout,
_("The current source language is \"%s\".\n"),
current_language->la_name);
- 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);
+ 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_language_command (char *ignore, int from_tty, struct cmd_list_element *c)
{
int i;
- enum language flang;
+ enum language flang = language_unknown;
/* Search the list of languages for a match. */
for (i = 0; i < languages_size; i++)
/* 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 (ex, RETURN_MASK_ERROR)
+ {
+ flang = language_unknown;
+ }
+ END_CATCH
+
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_range_case ();
expected_language = current_language;
return;
}
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)
-{
- if (type_mode == type_mode_auto)
- {
- char *tmp = NULL;
-
- 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:
- internal_error (__FILE__, __LINE__,
- "Unrecognized type check setting.");
- }
-
- fprintf_filtered (gdb_stdout,
- _("Type checking is \"auto; currently %s\".\n"),
- tmp);
- }
- else
- fprintf_filtered (gdb_stdout, _("Type checking is \"%s\".\n"),
- value);
-
- if (type_check != current_language->la_type_check)
- warning (_("the current type check setting"
- " does not match the language.\n"));
-}
-
-/* Set command. Change the setting for type checking. */
-static void
-set_type_command (char *ignore, int from_tty, struct cmd_list_element *c)
-{
- 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)
- {
- type_mode = type_mode_auto;
- set_type_range_case ();
- return;
- }
- else
- internal_error (__FILE__, __LINE__,
- _("Unrecognized type check setting: \"%s\""), type);
-
- if (type_check != current_language->la_type_check)
- warning (_("the current type check setting"
- " does not match the language.\n"));
-}
-
/* Show command. Display a warning if the range setting does
not match the current language. */
static void
else if (strcmp (range, "auto") == 0)
{
range_mode = range_mode_auto;
- set_type_range_case ();
+ set_range_case ();
return;
}
else
else if (strcmp (case_sensitive, "auto") == 0)
{
case_mode = case_mode_auto;
- set_type_range_case ();
+ set_range_case ();
return;
}
else
If SHOW is non-zero, then print out the current language,
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;
}
if (languages[i]->la_language == lang)
{
current_language = languages[i];
- set_type_range_case ();
+ set_range_case ();
break;
}
}
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);
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);
}
\f
error messages that occur during type- and range-
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,...)
}
/* Return the language as a string. */
-char *
+const char *
language_str (enum language lang)
{
int i;
{
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
add_language (const struct language_defn *lang)
{
/* For the "set language" command. */
- static char **language_names = NULL;
+ static const char **language_names = NULL;
/* For the "help set language" command. */
- char *language_set_doc = NULL;
-
- int i;
- struct ui_file *tmp_stream;
if (lang->la_magic != LANG_MAGIC)
{
if (!languages)
{
languages_allocsize = DEFAULT_ALLOCSIZE;
- languages = (const struct language_defn **) xmalloc
- (languages_allocsize * sizeof (*languages));
+ languages = XNEWVEC (const struct language_defn *, languages_allocsize);
}
if (languages_size >= languages_allocsize)
{
/* Build the language names array, to be used as enumeration in the
set language" enum command. */
- language_names = xrealloc (language_names,
- (languages_size + 1) * sizeof (const char *));
- for (i = 0; i < languages_size; ++i)
+ language_names = XRESIZEVEC (const char *, language_names,
+ languages_size + 1);
+
+ for (int i = 0; i < languages_size; ++i)
language_names[i] = languages[i]->la_name;
- language_names[i] = NULL;
+ language_names[languages_size] = NULL;
+
+ /* Add the filename extensions. */
+ if (lang->la_filename_extensions != NULL)
+ {
+ int i;
+
+ for (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. */
- tmp_stream = mem_fileopen ();
+ string_file doc;
- fprintf_unfiltered (tmp_stream,
- _("Set the current source language.\n"
- "The currently understood settings are:\n\nlocal or "
- "auto Automatic setting based on source file\n"));
+ doc.printf (_("Set the current source language.\n"
+ "The currently understood settings are:\n\nlocal or "
+ "auto Automatic setting based on source file\n"));
- for (i = 0; i < languages_size; ++i)
+ for (int 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. */
- fprintf_unfiltered (tmp_stream, "%-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);
+ /* FIXME: i18n: for now assume that the human-readable name is
+ just a capitalization of the internal name. */
+ doc.printf ("%-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);
}
- language_set_doc = ui_file_xstrdup (tmp_stream, NULL);
- ui_file_delete (tmp_stream);
-
add_setshow_enum_cmd ("language", class_support,
(const char **) language_names,
&language,
- language_set_doc,
+ doc.c_str (),
_("Show the current source language."),
NULL, set_language_command,
show_language_command,
&setlist, &showlist);
-
- xfree (language_set_doc);
}
/* Iterate through all registered languages looking for and calling
return NULL;
}
+/* See langauge.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 *lang,
/* 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_print_type (struct type *type, const char *varstring,
- struct ui_file *stream, int show, int level)
+ struct ui_file *stream, int show, int level,
+ const struct type_print_options *flags)
{
error (_("internal error - unimplemented "
"function unk_lang_print_type called."));
}
static void
-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 recurse,
- const struct value *val,
+ struct value *val,
const struct value_print_options *options)
{
error (_("internal error - unimplemented "
/* 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)
const struct language_defn unknown_language_defn =
{
"unknown",
+ "Unknown",
language_unknown,
range_check_off,
- type_check_off,
case_sensitive_on,
array_row_major,
macro_expansion_no,
+ NULL,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
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 */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
unk_lang_demangle, /* Language specific symbol demangler */
+ NULL,
unk_lang_class_name, /* Language specific
class_name_from_physname */
unk_op_print_tab, /* expression operators for printing */
default_get_string,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
+ &default_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};
const struct language_defn auto_language_defn =
{
"auto",
+ "Auto",
language_auto,
range_check_off,
- type_check_off,
case_sensitive_on,
array_row_major,
macro_expansion_no,
+ NULL,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
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 */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
unk_lang_demangle, /* Language specific symbol demangler */
+ NULL,
unk_lang_class_name, /* Language specific
class_name_from_physname */
unk_op_print_tab, /* expression operators for printing */
default_get_string,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
+ &default_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};
const struct language_defn local_language_defn =
{
"local",
+ "Local",
language_auto,
range_check_off,
- type_check_off,
case_sensitive_on,
array_row_major,
macro_expansion_no,
+ NULL,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
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 */
basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
basic_lookup_transparent_type,/* lookup_transparent_type */
unk_lang_demangle, /* Language specific symbol demangler */
+ NULL,
unk_lang_class_name, /* Language specific
class_name_from_physname */
unk_op_print_tab, /* expression operators for printing */
default_get_string,
NULL, /* la_get_symbol_name_cmp */
iterate_over_symbols,
+ &default_varobj_ops,
+ NULL,
+ NULL,
LANG_MAGIC
};
\f
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;
}
language_bool_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);
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);
+ NULL, VAR_DOMAIN, NULL).symbol;
if (sym)
{
struct type *type = SYMBOL_TYPE (sym);
return ld->arch_info[la->la_language].bool_type_default;
}
-struct type *
-language_lookup_primitive_type_by_name (const struct language_defn *la,
- struct gdbarch *gdbarch,
- const char *name)
+/* Helper function for primitive type lookup. */
+
+static struct type **
+language_lookup_primitive_type_1 (const struct language_arch_info *lai,
+ const char *name)
{
- struct language_gdbarch *ld = gdbarch_data (gdbarch,
- language_gdbarch_data);
- struct type *const *p;
+ struct type **p;
- for (p = ld->arch_info[la->la_language].primitive_type_vector;
- (*p) != NULL;
- p++)
+ for (p = lai->primitive_type_vector; (*p) != NULL; p++)
{
if (strcmp (TYPE_NAME (*p), name) == 0)
- return (*p);
+ return p;
+ }
+ 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;
+}
+
+/* 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 = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct symbol);
+
+ symbol->ginfo.name = TYPE_NAME (type);
+ symbol->ginfo.language = lang;
+ 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]);
}
- return (NULL);
+
+ /* 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. */
add_alias_cmd ("c", "check", no_class, 1, &showlist);
add_alias_cmd ("ch", "check", no_class, 1, &showlist);
- add_setshow_enum_cmd ("type", class_support, type_or_range_names, &type,
- _("Set type checking. (on/warn/off/auto)"),
- _("Show type checking. (on/warn/off/auto)"),
- NULL, set_type_command,
- show_type_command,
- &setchecklist, &showchecklist);
-
add_setshow_enum_cmd ("range", class_support, type_or_range_names,
&range,
_("Set range checking. (on/warn/off/auto)"),