X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Flanguage.c;h=5693419407995f8ad23ee5ad29d58beac4a781a8;hb=79d43c6168cdc6f263988e7c2fad9d4c82b5cd42;hp=dc94ebdd8c3c38c42a8d42b69d13598995a0f132;hpb=db034ac5129e86e2dfccebe047f0ee50fd933ec9;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/language.c b/gdb/language.c index dc94ebdd8c..5693419407 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -1,6 +1,8 @@ /* Multiple source language support for GDB. - Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. + + Copyright (C) 1991-1996, 1998-2005, 2007-2012 Free Software + Foundation, Inc. + Contributed by the Department of Computer Science at the State University of New York at Buffalo. @@ -8,7 +10,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,13 +19,11 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ /* 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 @@ -42,33 +42,11 @@ #include "target.h" #include "parser-defs.h" #include "jv-lang.h" +#include "demangle.h" +#include "symfile.h" extern void _initialize_language (void); -static void show_language_command (char *, int); - -static void set_language_command (char *, int); - -static void show_type_command (char *, int); - -static void set_type_command (char *, int); - -static void show_range_command (char *, int); - -static void set_range_command (char *, int); - -static void show_case_command (char *, int); - -static void set_case_command (char *, int); - -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); @@ -77,26 +55,18 @@ 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 set_range_case (void); -static void unk_lang_printchar (int c, struct ui_file *stream); +static void unk_lang_emit_char (int c, struct type *type, + struct ui_file *stream, int quoter); -static void unk_lang_printstr (struct ui_file * stream, char *string, - unsigned int length, int width, - int force_ellipses); +static void unk_lang_printchar (int c, struct type *type, + struct ui_file *stream); -static struct type *unk_lang_create_fundamental_type (struct objfile *, int); +static void unk_lang_value_print (struct value *, struct ui_file *, + const struct value_print_options *); -static void unk_lang_print_type (struct type *, char *, struct ui_file *, - int, int); - -static int unk_lang_val_print (struct type *, char *, int, CORE_ADDR, - struct ui_file *, int, int, int, - enum val_prettyprint); - -static int unk_lang_value_print (struct value *, struct ui_file *, int, enum val_prettyprint); +static CORE_ADDR unk_lang_trampoline (struct frame_info *, CORE_ADDR pc); /* Forward declaration */ extern const struct language_defn unknown_language_defn; @@ -108,12 +78,10 @@ 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; -/* 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; @@ -130,32 +98,38 @@ 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. */ - -static char *language; -static char *type; -static char *range; -static char *case_sensitive; +/* The current values of the "set language/type/range" enum + commands. */ +static const char *language; +static const char *type; +static const char *range; +static const char *case_sensitive; /* Warning issued when current_language and the language of the current - frame do not match. */ + frame do not match. */ char lang_frame_mismatch_warn[] = "Warning: the current language does not match this frame."; - /* 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 (char *ignore, int from_tty) +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 current 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); flang = get_frame_language (); if (flang != language_unknown && @@ -164,53 +138,29 @@ show_language_command (char *ignore, int from_tty) 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) +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"); - printf_unfiltered ("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 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; - } /* Search the list of languages for a match. */ for (i = 0; i < languages_size; i++) { - if (STREQ (languages[i]->la_name, language)) + if (strcmp (languages[i]->la_name, language) == 0) { /* Found it! Go into manual mode, and use this language. */ if (languages[i]->la_language == language_auto) { - /* Enter auto mode. Set to the current frame's language, if known. */ + /* 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 (); if (flang != language_unknown) set_language (flang); + else + set_initial_language (); expected_language = current_language; return; } @@ -219,176 +169,179 @@ set_language_command (char *ignore, int from_tty) /* Enter manual mode. Set the specified language. */ language_mode = language_mode_manual; current_language = languages[i]; - set_type_range_case (); - set_lang_str (); + 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 (char *ignore, int from_tty) -{ - 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) +show_range_command (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) { - if (STREQ (type, "on")) - { - type_check = type_check_on; - type_mode = type_mode_manual; - } - else if (STREQ (type, "warn")) - { - type_check = type_check_warn; - type_mode = type_mode_manual; - } - else if (STREQ (type, "off")) - { - type_check = type_check_off; - type_mode = type_mode_manual; - } - else if (STREQ (type, "auto")) + 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; + 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 ((char *) NULL, from_tty); -} - -/* Show command. Display a warning if the range setting does - not match the current language. */ -static void -show_range_command (char *ignore, int from_tty) -{ + fprintf_filtered (gdb_stdout, _("Range checking is \"%s\".\n"), + 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) +set_range_command (char *ignore, int from_tty, struct cmd_list_element *c) { - if (STREQ (range, "on")) + if (strcmp (range, "on") == 0) { range_check = range_check_on; range_mode = range_mode_manual; } - else if (STREQ (range, "warn")) + else if (strcmp (range, "warn") == 0) { range_check = range_check_warn; range_mode = range_mode_manual; } - else if (STREQ (range, "off")) + else if (strcmp (range, "off") == 0) { range_check = range_check_off; range_mode = range_mode_manual; } - else if (STREQ (range, "auto")) + 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 ((char *) 0, from_tty); + 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 (char *ignore, int from_tty) +show_case_command (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) { - if (case_sensitivity != current_language->la_case_sensitivity) - printf_unfiltered( -"Warning: the current case sensitivity setting does not match the language.\n"); + if (case_mode == case_mode_auto) + { + 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) + warning (_("the current case sensitivity setting does not match " + "the language.\n")); } -/* Set command. Change the setting for case sensitivity. */ +/* Set command. Change the setting for case sensitivity. */ + static void -set_case_command (char *ignore, int from_tty) +set_case_command (char *ignore, int from_tty, struct cmd_list_element *c) { - if (STREQ (case_sensitive, "on")) - { - case_sensitivity = case_sensitive_on; - case_mode = case_mode_manual; - } - else if (STREQ (case_sensitive, "off")) - { - case_sensitivity = case_sensitive_off; - case_mode = case_mode_manual; - } - else if (STREQ (case_sensitive, "auto")) - { - 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. */ - return; - } + if (strcmp (case_sensitive, "on") == 0) + { + case_sensitivity = case_sensitive_on; + case_mode = case_mode_manual; + } + else if (strcmp (case_sensitive, "off") == 0) + { + case_sensitivity = case_sensitive_off; + case_mode = case_mode_manual; + } + else if (strcmp (case_sensitive, "auto") == 0) + { + case_mode = case_mode_auto; + set_range_case (); + return; + } else - { - warning ("Unrecognized case-sensitive setting: \"%s\"", case_sensitive); - } - set_case_str(); - show_case_command ((char *) NULL, from_tty); + { + internal_error (__FILE__, __LINE__, + "Unrecognized case-sensitive setting: \"%s\"", + case_sensitive); + } + + 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) @@ -403,8 +356,7 @@ set_language (enum language lang) if (languages[i]->la_language == lang) { current_language = languages[i]; - set_type_range_case (); - set_lang_str (); + set_range_case (); break; } } @@ -412,100 +364,6 @@ set_language (enum language lang) return prev_language; } -/* 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, 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, 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, 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, NULL); -} /* Print out the current language settings: language, range and type checking. If QUIETLY, print only what has changed. */ @@ -517,377 +375,20 @@ language_info (int quietly) return; expected_language = current_language; - printf_unfiltered ("Current language: %s\n", language); - show_language_command ((char *) 0, 1); + 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 ((char *) 0, 1); - printf_unfiltered ("Range checking: %s\n", range); - show_range_command ((char *) 0, 1); - printf_unfiltered ("Case sensitivity: %s\n", case_sensitive); - show_case_command ((char *) 0, 1); - } -} - -/* 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: - 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; - /* OBSOLETE case language_chill: */ - /* OBSOLETE error ("Missing Chill support in function binop_result_check."); */ /*FIXME */ - } - internal_error (__FILE__, __LINE__, "failed internal consistency check"); - return (struct type *) 0; /* For lint */ -} - -#endif /* 0 */ - - -/* This page contains functions that return format strings for - printf for printing out numbers in different formats */ - -/* Returns the appropriate printf format for hexadecimal - numbers. */ -char * -local_hex_format_custom (char *pre) -{ - static char form[50]; - - strcpy (form, local_hex_format_prefix ()); - strcat (form, "%"); - strcat (form, pre); - strcat (form, local_hex_format_specifier ()); - strcat (form, local_hex_format_suffix ()); - return form; -} - -/* Converts a LONGEST to custom hexadecimal and stores it in a static - string. Returns a pointer to this string. */ -char * -local_hex_string (LONGEST num) -{ - return local_hex_string_custom (num, "l"); -} - -/* Converts a LONGEST number to custom hexadecimal and stores it in a static - string. Returns a pointer to this string. Note that the width parameter - should end with "l", e.g. "08l" as with calls to local_hex_string_custom */ - -char * -local_hex_string_custom (LONGEST num, char *width) -{ -#define RESULT_BUF_LEN 50 - static char res2[RESULT_BUF_LEN]; - char format[RESULT_BUF_LEN]; - int field_width; - int num_len; - int num_pad_chars; - char *pad_char; /* string with one character */ - int pad_on_left; - char *parse_ptr; - char temp_nbr_buf[RESULT_BUF_LEN]; - - /* Use phex_nz to print the number into a string, then - build the result string from local_hex_format_prefix, padding and - the hex representation as indicated by "width". */ - strcpy (temp_nbr_buf, phex_nz (num, sizeof (num))); - /* parse width */ - parse_ptr = width; - pad_on_left = 1; - pad_char = " "; - if (*parse_ptr == '-') - { - parse_ptr++; - pad_on_left = 0; - } - if (*parse_ptr == '0') - { - parse_ptr++; - if (pad_on_left) - pad_char = "0"; /* If padding is on the right, it is blank */ + 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); } - field_width = atoi (parse_ptr); - num_len = strlen (temp_nbr_buf); - num_pad_chars = field_width - strlen (temp_nbr_buf); /* possibly negative */ - - if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars - >= RESULT_BUF_LEN) /* paranoia */ - internal_error (__FILE__, __LINE__, - "local_hex_string_custom: insufficient space to store result"); - - strcpy (res2, local_hex_format_prefix ()); - if (pad_on_left) - { - while (num_pad_chars > 0) - { - strcat (res2, pad_char); - num_pad_chars--; - } - } - strcat (res2, temp_nbr_buf); - if (!pad_on_left) - { - while (num_pad_chars > 0) - { - strcat (res2, pad_char); - num_pad_chars--; - } - } - return res2; - -} /* local_hex_string_custom */ - -/* Returns the appropriate printf format for octal - numbers. */ -char * -local_octal_format_custom (char *pre) -{ - static char form[50]; - - strcpy (form, local_octal_format_prefix ()); - strcat (form, "%"); - strcat (form, pre); - strcat (form, local_octal_format_specifier ()); - strcat (form, local_octal_format_suffix ()); - return form; -} - -/* Returns the appropriate printf format for decimal numbers. */ -char * -local_decimal_format_custom (char *pre) -{ - static char form[50]; - - strcpy (form, local_decimal_format_prefix ()); - strcat (form, "%"); - strcat (form, pre); - strcat (form, local_decimal_format_specifier ()); - strcat (form, local_decimal_format_suffix ()); - return form; } -#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: - 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; - /* OBSOLETE case language_chill: */ - /* OBSOLETE error ("Missing Chill support in function integral_type."); *//*FIXME */ - 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) - { - /* OBSOLETE case language_chill: */ - case language_m2: - case language_pascal: - return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1; - - case language_c: - case language_cplus: - 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) - { - /* OBSOLETE case language_chill: */ - case language_m2: - case language_pascal: - return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1; - - case language_c: - case language_cplus: - /* 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: - /* Might be more cleanly handled by having a - TYPE_CODE_INT_NOT_BOOL for (OBSOLETE) 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) { @@ -895,86 +396,11 @@ pointer_type (struct type *type) TYPE_CODE (type) == TYPE_CODE_REF; } -/* 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: - 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); - /* OBSOLETE case language_chill: */ - /* OBSOLETE error ("Missing Chill support in function structured_type."); *//*FIXME */ - default: - return (0); - } -} -#endif - -struct type * -lang_bool_type (void) -{ - struct symbol *sym; - struct type *type; - switch (current_language->la_language) - { -#if 0 - /* OBSOLETE case language_chill: */ - /* OBSOLETE return builtin_type_chill_bool; */ -#endif - case language_fortran: - sym = lookup_symbol ("logical", NULL, VAR_NAMESPACE, 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: - if (current_language->la_language==language_cplus) - {sym = lookup_symbol ("bool", NULL, VAR_NAMESPACE, NULL, NULL);} - else - {sym = lookup_symbol ("boolean", NULL, VAR_NAMESPACE, 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_NAMESPACE, 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; - } -} /* 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) { @@ -987,253 +413,22 @@ value_true (struct value *val) return !value_logical_not (val); } -/* Returns non-zero if the operator OP is defined on - the values ARG1 and ARG2. */ - -#if 0 /* Currently unused */ - -void -binop_type_check (struct value *arg1, struct value *arg2, int op) -{ - struct type *t1, *t2; - - /* If we're not checking types, always return success. */ - if (!STRICT_TYPE) - return; - - t1 = VALUE_TYPE (arg1); - if (arg2 != NULL) - t2 = VALUE_TYPE (arg2); - else - t2 = NULL; - - switch (op) - { - case BINOP_ADD: - case BINOP_SUB: - if ((numeric_type (t1) && pointer_type (t2)) || - (pointer_type (t1) && numeric_type (t2))) - { - warning ("combining pointer and integer.\n"); - break; - } - case BINOP_MUL: - case BINOP_LSH: - case BINOP_RSH: - if (!numeric_type (t1) || !numeric_type (t2)) - type_op_error ("Arguments to %s must be numbers.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_LOGICAL_AND: - case BINOP_LOGICAL_OR: - if (!boolean_type (t1) || !boolean_type (t2)) - type_op_error ("Arguments to %s must be of boolean type.", op); - break; - - case BINOP_EQUAL: - if ((pointer_type (t1) && !(pointer_type (t2) || integral_type (t2))) || - (pointer_type (t2) && !(pointer_type (t1) || integral_type (t1)))) - type_op_error ("A pointer can only be compared to an integer or pointer.", op); - else if ((pointer_type (t1) && integral_type (t2)) || - (integral_type (t1) && pointer_type (t2))) - { - warning ("combining integer and pointer.\n"); - break; - } - else if (!simple_type (t1) || !simple_type (t2)) - type_op_error ("Arguments to %s must be of simple type.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_REM: - case BINOP_MOD: - if (!integral_type (t1) || !integral_type (t2)) - type_op_error ("Arguments to %s must be of integral type.", op); - break; - - case BINOP_LESS: - case BINOP_GTR: - case BINOP_LEQ: - case BINOP_GEQ: - if (!ordered_type (t1) || !ordered_type (t2)) - type_op_error ("Arguments to %s must be of ordered type.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_ASSIGN: - if (pointer_type (t1) && !integral_type (t2)) - type_op_error ("A pointer can only be assigned an integer.", op); - else if (pointer_type (t1) && integral_type (t2)) - { - warning ("combining integer and pointer."); - break; - } - else if (!simple_type (t1) || !simple_type (t2)) - type_op_error ("Arguments to %s must be of simple type.", op); - else if (!same_type (t1, t2)) - type_op_error ("Arguments to %s must be of the same type.", op); - break; - - case BINOP_CONCAT: - /* FIXME: Needs to handle bitstrings as well. */ - if (!(string_type (t1) || character_type (t1) || integral_type (t1)) - || !(string_type (t2) || character_type (t2) || integral_type (t2))) - type_op_error ("Arguments to %s must be strings or characters.", op); - break; - - /* Unary checks -- arg2 is null */ - - case UNOP_LOGICAL_NOT: - if (!boolean_type (t1)) - type_op_error ("Argument to %s must be of boolean type.", op); - break; - - case UNOP_PLUS: - case UNOP_NEG: - if (!numeric_type (t1)) - type_op_error ("Argument to %s must be of numeric type.", op); - break; - - case UNOP_IND: - if (integral_type (t1)) - { - warning ("combining pointer and integer.\n"); - break; - } - else if (!pointer_type (t1)) - type_op_error ("Argument to %s must be a pointer.", op); - break; - - case UNOP_PREINCREMENT: - case UNOP_POSTINCREMENT: - case UNOP_PREDECREMENT: - case UNOP_POSTDECREMENT: - if (!ordered_type (t1)) - type_op_error ("Argument to %s must be of an ordered type.", op); - break; - - default: - /* Ok. The following operators have different meanings in - different languages. */ - switch (current_language->la_language) - { -#ifdef _LANG_c - case language_c: - case language_cplus: - switch (op) - { - case BINOP_DIV: - if (!numeric_type (t1) || !numeric_type (t2)) - type_op_error ("Arguments to %s must be numbers.", op); - break; - } - break; -#endif - -#ifdef _LANG_m2 - case language_m2: - switch (op) - { - case BINOP_DIV: - if (!float_type (t1) || !float_type (t2)) - type_op_error ("Arguments to %s must be floating point numbers.", op); - break; - case BINOP_INTDIV: - if (!integral_type (t1) || !integral_type (t2)) - type_op_error ("Arguments to %s must be of integral type.", op); - break; - } -#endif - -#ifdef _LANG_pascal - case language_pascal: - switch(op) - { - case BINOP_DIV: - if (!float_type(t1) && !float_type(t2)) - type_op_error ("Arguments to %s must be floating point numbers.",op); - break; - case BINOP_INTDIV: - if (!integral_type(t1) || !integral_type(t2)) - type_op_error ("Arguments to %s must be of integral type.",op); - break; - } -#endif - -#ifdef _LANG_chill /* OBSOLETE */ - /* OBSOLETE case language_chill: */ - /* OBSOLETE error ("Missing Chill support in function binop_type_check."); *//*FIXME */ -#endif - - } - } -} - -#endif /* 0 */ - - /* This page contains functions for the printing out of error messages that occur during type- and range- - checking. */ - -/* Prints the format string FMT with the operator as a string - corresponding to the opcode OP. If FATAL is non-zero, then - this is an error and error () is called. Otherwise, it is - a warning and printf() is called. */ -void -op_error (char *fmt, enum exp_opcode op, int fatal) -{ - if (fatal) - error (fmt, op_string (op)); - else - { - warning (fmt, op_string (op)); - } -} + 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: @@ -1249,15 +444,15 @@ range_error (const char *string,...) fprintf_filtered (gdb_stderr, "\n"); break; default: - internal_error (__FILE__, __LINE__, "bad switch"); + internal_error (__FILE__, __LINE__, _("bad switch")); } va_end (args); } -/* 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) @@ -1265,13 +460,13 @@ language_enum (char *str) int i; for (i = 0; i < languages_size; i++) - if (STREQ (languages[i]->la_name, str)) + if (strcmp (languages[i]->la_name, str) == 0) return languages[i]->la_language; 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) @@ -1288,7 +483,7 @@ language_def (enum language lang) return NULL; } -/* Return the language as a string */ +/* Return the language as a string. */ char * language_str (enum language lang) { @@ -1323,11 +518,21 @@ show_check (char *ignore, int from_tty) void add_language (const struct language_defn *lang) { + /* For the "set language" command. */ + static 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) { - fprintf_unfiltered (gdb_stderr, "Magic number of %s language struct wrong\n", + fprintf_unfiltered (gdb_stderr, + "Magic number of %s language struct wrong\n", lang->la_name); - internal_error (__FILE__, __LINE__, "failed internal consistency check"); + internal_error (__FILE__, __LINE__, + _("failed internal consistency check")); } if (!languages) @@ -1343,6 +548,146 @@ add_language (const struct language_defn *lang) languages_allocsize * sizeof (*languages)); } languages[languages_size++] = lang; + + /* 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[i] = languages[i]->la_name; + language_names[i] = NULL; + + /* Build the "help set language" docs. */ + tmp_stream = mem_fileopen (); + + 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")); + + 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. */ + 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); + } + + 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, + _("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 + any non-NULL struct language_defn.skip_trampoline() functions. + Return the result from the first that returns non-zero, or 0 if all + `fail'. */ +CORE_ADDR +skip_language_trampoline (struct frame_info *frame, 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) (frame, pc); + + if (real_pc) + return real_pc; + } + } + + return 0; +} + +/* 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. + FIXME: Sometimes the demangler is invoked when we don't know the + language, so we can't use this everywhere. */ +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; +} + +/* Return class name from physname or NULL. */ +char * +language_class_name_from_physname (const struct language_defn *lang, + const char *physname) +{ + if (lang != NULL && lang->la_class_name_from_physname) + return lang->la_class_name_from_physname (physname); + return NULL; +} + +/* Return non-zero if TYPE should be passed (and returned) by + reference at the language level. */ +int +language_pass_by_reference (struct type *type) +{ + return current_language->la_pass_by_reference (type); +} + +/* Return zero; by default, types are passed by value at the language + level. The target ABI may pass or return some structs by reference + independent of this. */ +int +default_pass_by_reference (struct type *type) +{ + return 0; +} + +/* Return the default string containing the list of characters + delimiting words. This is a reasonable default value that + most languages should be able to use. */ + +char * +default_word_break_characters (void) +{ + return " \t\n!@#$%^&*()+=|~`}{[]\"';:?/>.<,-"; +} + +/* Print the index of array elements using the C99 syntax. */ + +void +default_print_array_index (struct value *index_value, struct ui_file *stream, + const struct value_print_options *options) +{ + fprintf_filtered (stream, "["); + LA_VALUE_PRINT (index_value, stream, options); + fprintf_filtered (stream, "] = "); +} + +void +default_get_string (struct value *value, gdb_byte **buffer, int *length, + struct type **char_type, const char **charset) +{ + error (_("Getting a string is unsupported in this language.")); } /* Define the language that is no language. */ @@ -1356,121 +701,174 @@ unk_lang_parser (void) static void unk_lang_error (char *msg) { - error ("Attempted to parse an expression with unknown language"); + error (_("Attempted to parse an expression with unknown language")); } static void -unk_lang_emit_char (register int c, struct ui_file *stream, int quoter) +unk_lang_emit_char (int c, struct type *type, struct ui_file *stream, + int quoter) { - error ("internal error - unimplemented function unk_lang_emit_char called."); + error (_("internal error - unimplemented " + "function unk_lang_emit_char called.")); } static void -unk_lang_printchar (register int c, struct ui_file *stream) +unk_lang_printchar (int c, struct type *type, struct ui_file *stream) { - error ("internal error - unimplemented function unk_lang_printchar called."); + error (_("internal error - unimplemented " + "function unk_lang_printchar called.")); } static void -unk_lang_printstr (struct ui_file *stream, char *string, unsigned int length, - int width, int force_ellipses) +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_printstr called."); + error (_("internal error - unimplemented " + "function unk_lang_printstr called.")); } -static struct type * -unk_lang_create_fundamental_type (struct objfile *objfile, int typeid) +static void +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_create_fundamental_type 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) +unk_lang_val_print (struct type *type, const gdb_byte *valaddr, + int embedded_offset, CORE_ADDR address, + struct ui_file *stream, int recurse, + const struct value *val, + const struct value_print_options *options) { - error ("internal error - unimplemented function unk_lang_print_type called."); + error (_("internal error - unimplemented " + "function unk_lang_val_print called.")); } -static int -unk_lang_val_print (struct type *type, char *valaddr, int embedded_offset, - CORE_ADDR address, struct ui_file *stream, int format, - int deref_ref, int recurse, 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_val_print called."); + error (_("internal error - unimplemented " + "function unk_lang_value_print called.")); } -static int -unk_lang_value_print (struct value *val, struct ui_file *stream, int format, - enum val_prettyprint pretty) +static CORE_ADDR unk_lang_trampoline (struct frame_info *frame, CORE_ADDR pc) { - error ("internal error - unimplemented function unk_lang_value_print called."); + return 0; } -static struct type **const (unknown_builtin_types[]) = +/* Unknown languages just use the cplus demangler. */ +static char *unk_lang_demangle (const char *mangled, int options) { - 0 -}; + 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->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", language_unknown, - &unknown_builtin_types[0], range_check_off, - type_check_off, case_sensitive_on, + array_row_major, + macro_expansion_no, + &exp_descriptor_standard, unk_lang_parser, unk_lang_error, - evaluate_subexp_standard, + null_post_parser, unk_lang_printchar, /* Print character constant */ unk_lang_printstr, unk_lang_emit_char, - unk_lang_create_fundamental_type, 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 */ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ + 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 */ + 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 */ - &builtin_type_char, /* Type of string elements */ + 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, + default_get_string, + NULL, /* la_get_symbol_name_cmp */ + iterate_over_symbols, LANG_MAGIC }; -/* 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", language_auto, - &unknown_builtin_types[0], range_check_off, - type_check_off, case_sensitive_on, + array_row_major, + macro_expansion_no, + &exp_descriptor_standard, unk_lang_parser, unk_lang_error, - evaluate_subexp_standard, + null_post_parser, unk_lang_printchar, /* Print character constant */ unk_lang_printstr, unk_lang_emit_char, - unk_lang_create_fundamental_type, 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 */ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ + 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 */ + 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 */ - &builtin_type_char, /* Type of string elements */ + 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, + default_get_string, + NULL, /* la_get_symbol_name_cmp */ + iterate_over_symbols, LANG_MAGIC }; @@ -1478,94 +876,179 @@ const struct language_defn local_language_defn = { "local", language_auto, - &unknown_builtin_types[0], range_check_off, - type_check_off, case_sensitive_on, + array_row_major, + macro_expansion_no, + &exp_descriptor_standard, unk_lang_parser, unk_lang_error, - evaluate_subexp_standard, + null_post_parser, unk_lang_printchar, /* Print character constant */ unk_lang_printstr, unk_lang_emit_char, - unk_lang_create_fundamental_type, 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 */ - {"", "", "", ""}, /* Binary format info */ - {"0%lo", "0", "o", ""}, /* Octal format info */ - {"%ld", "", "d", ""}, /* Decimal format info */ - {"0x%lx", "0x", "x", ""}, /* Hex format info */ + 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 */ + 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 */ - &builtin_type_char, /* Type of string elements */ + 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, + default_get_string, + NULL, /* la_get_symbol_name_cmp */ + iterate_over_symbols, LANG_MAGIC }; -/* Initialize the language routines */ +/* Per-architecture language information. */ + +static struct gdbarch_data *language_gdbarch_data; + +struct language_gdbarch +{ + /* A vector of per-language per-architecture info. Indexed by "enum + language". */ + 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); + + return ld->arch_info[la->la_language].string_char_type; +} + +struct type * +language_bool_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].bool_type_symbol) + { + struct symbol *sym; + + sym = lookup_symbol (ld->arch_info[la->la_language].bool_type_symbol, + NULL, VAR_DOMAIN, NULL); + 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; +} + +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); + 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); + } + return (NULL); +} + +/* 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 }; - /* GDB commands for language specific stuff */ + static const char *const case_sensitive_names[] + = { "on", "off", "auto", NULL }; - set = add_set_cmd ("language", class_support, var_string_noescape, - (char *) &language, - "Set the current source language.", - &setlist); - show = add_show_from_set (set, &showlist); - set_cmd_cfunc (set, set_language_command); - set_cmd_cfunc (show, show_language_command); + language_gdbarch_data + = gdbarch_data_register_post_init (language_gdbarch_post_init); + + /* GDB commands for language specific stuff. */ add_prefix_cmd ("check", no_class, set_check, - "Set the status of the type/range checker.", + _("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.", + _("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); - set = add_set_cmd ("type", class_support, var_string_noescape, - (char *) &type, - "Set type checking. (on/warn/off/auto)", - &setchecklist); - show = add_show_from_set (set, &showchecklist); - set_cmd_cfunc (set, set_type_command); - set_cmd_cfunc (show, show_type_command); - - set = add_set_cmd ("range", class_support, var_string_noescape, - (char *) &range, - "Set range checking. (on/warn/off/auto)", - &setchecklist); - show = add_show_from_set (set, &showchecklist); - set_cmd_cfunc (set, set_range_command); - set_cmd_cfunc (show, show_range_command); - - set = add_set_cmd ("case-sensitive", class_support, var_string_noescape, - (char *) &case_sensitive, - "Set case sensitivity in name search. (on/off/auto)\n\ -For Fortran the default is off; for other languages the default is on.", - &setlist); - show = add_show_from_set (set, &showlist); - set_cmd_cfunc (set, set_case_command); - set_cmd_cfunc (show, show_case_command); + 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); - add_language (&unknown_language_defn); - add_language (&local_language_defn); add_language (&auto_language_defn); + add_language (&local_language_defn); + add_language (&unknown_language_defn); - language = savestring ("auto", strlen ("auto")); - type = savestring ("auto", strlen ("auto")); - range = savestring ("auto", strlen ("auto")); - case_sensitive = savestring ("auto",strlen ("auto")); + language = xstrdup ("auto"); + type = xstrdup ("auto"); + range = xstrdup ("auto"); + case_sensitive = xstrdup ("auto"); - /* Have the above take effect */ + /* Have the above take effect. */ set_language (language_auto); }