#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 "target.h"
#include "parser-defs.h"
#include "jv-lang.h"
#include "demangle.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 void show_check (char *, int);
static void set_check (char *, int);
static void set_type_range_case (void);
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 struct type *unk_lang_create_fundamental_type (struct objfile *, int);
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 CORE_ADDR unk_lang_trampoline (CORE_ADDR pc);
extern const struct language_defn unknown_language_defn;
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;
const struct language_defn *current_language = &unknown_language_defn;
enum language_mode language_mode = language_mode_auto;
const struct language_defn *expected_language;
static const struct language_defn **languages;
static unsigned languages_size;
static unsigned languages_allocsize;
#define DEFAULT_ALLOCSIZE 4
static char *language;
static char *type;
static char *range;
static char *case_sensitive;
char lang_frame_mismatch_warn[] =
"Warning: the current language does not match this frame.";
static void
show_language_command (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
enum language flang;
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);
}
static void
set_language_command (char *ignore, int from_tty, struct cmd_list_element *c)
{
int i;
enum language flang;
char *err_lang;
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)
{
if (languages[i]->la_language == language_unknown
|| languages[i]->la_language == language_auto)
continue;
printf_unfiltered ("%-16s Use the %c%s language\n",
languages[i]->la_name,
toupper (languages[i]->la_name[0]),
languages[i]->la_name + 1);
}
set_language (current_language->la_language);
return;
}
for (i = 0; i < languages_size; i++)
{
if (strcmp (languages[i]->la_name, language) == 0)
{
if (languages[i]->la_language == language_auto)
{
language_mode = language_mode_auto;
flang = get_frame_language ();
if (flang != language_unknown)
set_language (flang);
expected_language = current_language;
return;
}
else
{
language_mode = language_mode_manual;
current_language = languages[i];
set_type_range_case ();
set_lang_str ();
expected_language = current_language;
return;
}
}
}
err_lang = savestring (language, strlen (language));
make_cleanup (xfree, err_lang);
set_language (current_language->la_language);
error (_("Unknown language `%s'."), err_lang);
}
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");
}
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
{
warning (_("Unrecognized type check setting: \"%s\""), type);
}
set_type_str ();
show_type_command (NULL, from_tty, NULL, NULL);
}
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");
}
static void
set_range_command (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_type_range_case ();
return;
}
else
{
warning (_("Unrecognized range check setting: \"%s\""), range);
}
set_range_str ();
show_range_command (NULL, from_tty, NULL, NULL);
}
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_sensitivity != current_language->la_case_sensitivity)
printf_unfiltered(
"Warning: the current case sensitivity setting does not match the language.\n");
}
static void
set_case_command (char *ignore, int from_tty, struct cmd_list_element *c)
{
if (DEPRECATED_STREQ (case_sensitive, "on"))
{
case_sensitivity = case_sensitive_on;
case_mode = case_mode_manual;
}
else if (DEPRECATED_STREQ (case_sensitive, "off"))
{
case_sensitivity = case_sensitive_off;
case_mode = case_mode_manual;
}
else if (DEPRECATED_STREQ (case_sensitive, "auto"))
{
case_mode = case_mode_auto;
set_type_range_case ();
return;
}
else
{
warning (_("Unrecognized case-sensitive setting: \"%s\""), case_sensitive);
}
set_case_str();
show_case_command (NULL, from_tty, NULL, NULL);
}
static void
set_type_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 ();
}
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;
}
}
return prev_language;
}
static void
do_set_language (void *in_language)
{
enum language lang = (enum language) in_language;
set_language (lang);
}
struct cleanup *
make_cleanup_restore_language (enum language new_lang)
{
enum language lang = set_language (new_lang);
return make_cleanup (do_set_language, (void *) lang);
}
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);
}
void
language_info (int quietly)
{
if (quietly && expected_language == current_language)
return;
expected_language = current_language;
printf_unfiltered (_("Current language: %s\n"), language);
show_language_command (NULL, 1, NULL, NULL);
if (!quietly)
{
printf_unfiltered (_("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);
show_case_command (NULL, 1, NULL, NULL);
}
}
#if 0
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:
case language_objcplus:
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
return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
break;
case language_m2:
return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
break;
}
internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
return (struct type *) 0;
}
#endif
#if 0
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;
}
}
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;
}
}
int
same_type (struct type *arg1, struct type *arg2)
{
CHECK_TYPEDEF (type);
if (structured_type (arg1) ? !structured_type (arg2) : structured_type (arg2))
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;
}
int
integral_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (current_language->la_language)
{
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
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."));
}
}
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;
}
}
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:
case language_objcplus:
return (TYPE_CODE (type) == TYPE_CODE_INT) &&
TYPE_LENGTH (type) == sizeof (char)
? 1 : 0;
default:
return (0);
}
}
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:
case language_objcplus:
return (0);
default:
return (0);
}
}
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:
case language_objcplus:
if (TYPE_CODE (type) == TYPE_CODE_INT)
return 1;
default:
break;
}
return 0;
}
int
float_type (struct type *type)
{
CHECK_TYPEDEF (type);
return TYPE_CODE (type) == TYPE_CODE_FLT;
}
int
pointer_type (struct type *type)
{
return TYPE_CODE (type) == TYPE_CODE_PTR ||
TYPE_CODE (type) == TYPE_CODE_REF;
}
int
structured_type (struct type *type)
{
CHECK_TYPEDEF (type);
switch (current_language->la_language)
{
case language_c:
case language_cplus:
case language_objc:
case language_objcplus:
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
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_objcplus:
case language_pascal:
if (current_language->la_language == language_cplus
|| current_language->la_language == language_objcplus)
{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;
}
}
int
value_true (struct value *val)
{
return !value_logical_not (val);
}
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:
vfprintf_filtered (gdb_stderr, string, args);
fprintf_filtered (gdb_stderr, "\n");
break;
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
va_end (args);
}
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:
vfprintf_filtered (gdb_stderr, string, args);
fprintf_filtered (gdb_stderr, "\n");
break;
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
va_end (args);
}
enum language
language_enum (char *str)
{
int i;
for (i = 0; i < languages_size; i++)
if (DEPRECATED_STREQ (languages[i]->la_name, str))
return languages[i]->la_language;
return language_unknown;
}
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;
}
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";
}
static void
set_check (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);
}
static void
show_check (char *ignore, int from_tty)
{
cmd_show_list (showchecklist, from_tty, "");
}
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"));
}
if (!languages)
{
languages_allocsize = DEFAULT_ALLOCSIZE;
languages = (const struct language_defn **) xmalloc
(languages_allocsize * sizeof (*languages));
}
if (languages_size >= languages_allocsize)
{
languages_allocsize *= 2;
languages = (const struct language_defn **) xrealloc ((char *) languages,
languages_allocsize * sizeof (*languages));
}
languages[languages_size++] = lang;
}
CORE_ADDR
skip_language_trampoline (CORE_ADDR pc)
{
int i;
for (i = 0; i < languages_size; i++)
{
if (languages[i]->skip_trampoline)
{
CORE_ADDR real_pc = (languages[i]->skip_trampoline) (pc);
if (real_pc)
return real_pc;
}
}
return 0;
}
char *
language_demangle (const struct language_defn *current_language,
const char *mangled, int options)
{
if (current_language != NULL && current_language->la_demangle)
return current_language->la_demangle (mangled, options);
return NULL;
}
char *
language_class_name_from_physname (const struct language_defn *current_language,
const char *physname)
{
if (current_language != NULL && current_language->la_class_name_from_physname)
return current_language->la_class_name_from_physname (physname);
return NULL;
}
char *
default_word_break_characters (void)
{
return " \t\n!@#$%^&*()+=|~`}{[]\"';:?>.<,-";
}
static int
unk_lang_parser (void)
{
return 1;
}
static void
unk_lang_error (char *msg)
{
error (_("Attempted to parse an expression with unknown language"));
}
static void
unk_lang_emit_char (int c, struct ui_file *stream, int quoter)
{
error (_("internal error - unimplemented function unk_lang_emit_char called."));
}
static void
unk_lang_printchar (int c, struct ui_file *stream)
{
error (_("internal error - unimplemented function unk_lang_printchar called."));
}
static void
unk_lang_printstr (struct ui_file *stream, const gdb_byte *string,
unsigned int length, int width, int force_ellipses)
{
error (_("internal error - unimplemented function unk_lang_printstr called."));
}
static struct type *
unk_lang_create_fundamental_type (struct objfile *objfile, int typeid)
{
error (_("internal error - unimplemented function unk_lang_create_fundamental_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,
int embedded_offset, CORE_ADDR address,
struct ui_file *stream, int format,
int deref_ref, int recurse, enum val_prettyprint pretty)
{
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)
{
error (_("internal error - unimplemented function unk_lang_value_print called."));
}
static CORE_ADDR unk_lang_trampoline (CORE_ADDR pc)
{
return 0;
}
static char *unk_lang_demangle (const char *mangled, int options)
{
return cplus_demangle (mangled, options);
}
static char *unk_lang_class_name (const char *mangled)
{
return NULL;
}
static const struct op_print unk_op_print_tab[] =
{
{NULL, OP_NULL, PREC_NULL, 0}
};
static void
unknown_language_arch_info (struct gdbarch *gdbarch,
struct language_arch_info *lai)
{
lai->string_char_type = builtin_type (gdbarch)->builtin_char;
lai->primitive_type_vector = GDBARCH_OBSTACK_CALLOC (gdbarch, 1,
struct type *);
}
const struct language_defn unknown_language_defn =
{
"unknown",
language_unknown,
NULL,
range_check_off,
type_check_off,
array_row_major,
case_sensitive_on,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
null_post_parser,
unk_lang_printchar,
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type,
unk_lang_val_print,
unk_lang_value_print,
unk_lang_trampoline,
value_of_this,
basic_lookup_symbol_nonlocal,
basic_lookup_transparent_type,
unk_lang_demangle,
unk_lang_class_name,
unk_op_print_tab,
1,
0,
NULL,
default_word_break_characters,
unknown_language_arch_info,
LANG_MAGIC
};
const struct language_defn auto_language_defn =
{
"auto",
language_auto,
NULL,
range_check_off,
type_check_off,
array_row_major,
case_sensitive_on,
&exp_descriptor_standard,
unk_lang_parser,
unk_lang_error,
null_post_parser,
unk_lang_printchar,
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type,
unk_lang_val_print,
unk_lang_value_print,
unk_lang_trampoline,
value_of_this,
basic_lookup_symbol_nonlocal,
basic_lookup_transparent_type,
unk_lang_demangle,
unk_lang_class_name,
unk_op_print_tab,
1,
0,
NULL,
default_word_break_characters,
unknown_language_arch_info,
LANG_MAGIC
};
const struct language_defn local_language_defn =
{
"local",
language_auto,
NULL,
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,
unk_lang_printstr,
unk_lang_emit_char,
unk_lang_create_fundamental_type,
unk_lang_print_type,
unk_lang_val_print,
unk_lang_value_print,
unk_lang_trampoline,
value_of_this,
basic_lookup_symbol_nonlocal,
basic_lookup_transparent_type,
unk_lang_demangle,
unk_lang_class_name,
unk_op_print_tab,
1,
0,
NULL,
default_word_break_characters,
unknown_language_arch_info,
LANG_MAGIC
};
static struct gdbarch_data *language_gdbarch_data;
struct language_gdbarch
{
struct language_arch_info arch_info[nr_languages];
};
static void *
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);
}
return l;
}
struct type *
language_string_char_type (const struct language_defn *la,
struct gdbarch *gdbarch)
{
struct language_gdbarch *ld = gdbarch_data (gdbarch,
language_gdbarch_data);
if (ld->arch_info[la->la_language].string_char_type != NULL)
return ld->arch_info[la->la_language].string_char_type;
else
return (*la->string_char_type);
}
struct type *
language_lookup_primitive_type_by_name (const struct language_defn *la,
struct gdbarch *gdbarch,
const char *name)
{
struct language_gdbarch *ld = gdbarch_data (gdbarch,
language_gdbarch_data);
if (ld->arch_info[la->la_language].primitive_type_vector != NULL)
{
struct type *const *p;
for (p = ld->arch_info[la->la_language].primitive_type_vector;
(*p) != NULL;
p++)
{
if (strcmp (TYPE_NAME (*p), name) == 0)
return (*p);
}
}
else
{
struct type **const *p;
for (p = current_language->la_builtin_type_vector; *p != NULL; p++)
{
if (strcmp (TYPE_NAME (**p), name) == 0)
return (**p);
}
}
return (NULL);
}
void
_initialize_language (void)
{
struct cmd_list_element *set, *show;
language_gdbarch_data
= gdbarch_data_register_post_init (language_gdbarch_post_init);
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);
add_prefix_cmd ("check", no_class, set_check,
_("Set the status of the type/range checker."),
&setchecklist, "set check ", 0, &setlist);
add_alias_cmd ("c", "check", no_class, 1, &setlist);
add_alias_cmd ("ch", "check", no_class, 1, &setlist);
add_prefix_cmd ("check", no_class, show_check,
_("Show the status of the type/range checker."),
&showchecklist, "show check ", 0, &showlist);
add_alias_cmd ("c", "check", no_class, 1, &showlist);
add_alias_cmd ("ch", "check", no_class, 1, &showlist);
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);
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);
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)"), _("\
For Fortran the default is off; for other languages the default is on."),
set_case_command,
show_case_command,
&setlist, &showlist);
add_language (&unknown_language_defn);
add_language (&local_language_defn);
add_language (&auto_language_defn);
language = savestring ("auto", strlen ("auto"));
type = savestring ("auto", strlen ("auto"));
range = savestring ("auto", strlen ("auto"));
case_sensitive = savestring ("auto",strlen ("auto"));
set_language (language_auto);
}