X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Flanguage.c;h=f761002c4a28371b5220d55d059d9ca6bb9a9dd5;hb=46da9242e8f4e4f85dfb2eb1da5603b89126e78f;hp=d975f2353ba52145f4f995bce2e8694745c79144;hpb=759ef83693911e20efd389b20cbf8f3a8eec30eb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/language.c b/gdb/language.c index d975f2353b..f761002c4a 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -1,7 +1,6 @@ /* Multiple source language support for GDB. - Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 1991-2016 Free Software Foundation, Inc. Contributed by the Department of Computer Science at the State University of New York at Buffalo. @@ -23,7 +22,7 @@ /* 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 @@ -31,31 +30,32 @@ #include "defs.h" #include -#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); @@ -63,11 +63,8 @@ static void unk_lang_emit_char (int c, struct type *type, static void unk_lang_printchar (int c, struct type *type, struct ui_file *stream); -static void unk_lang_print_type (struct type *, char *, struct ui_file *, - int, int); - -static int unk_lang_value_print (struct value *, struct ui_file *, - const struct value_print_options *); +static void unk_lang_value_print (struct value *, struct ui_file *, + const struct value_print_options *); static CORE_ADDR unk_lang_trampoline (struct frame_info *, CORE_ADDR pc); @@ -81,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; @@ -111,20 +106,20 @@ 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 (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, @@ -132,22 +127,29 @@ show_language_command (struct ui_file *file, int from_tty, "\"auto; currently %s\".\n"), current_language->la_name); else - fprintf_filtered (gdb_stdout, _("The current source language is \"%s\".\n"), + 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 command. Change the current working language. */ static void 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++) @@ -160,7 +162,19 @@ set_language_command (char *ignore, int from_tty, struct cmd_list_element *c) /* 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 @@ -173,7 +187,7 @@ set_language_command (char *ignore, int from_tty, struct cmd_list_element *c) /* 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; } @@ -185,81 +199,8 @@ set_language_command (char *ignore, int from_tty, struct cmd_list_element *c) 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. */ + not match the current language. */ static void show_range_command (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) @@ -297,7 +238,7 @@ show_range_command (struct ui_file *file, int from_tty, "does not match the language.\n")); } -/* Set command. Change the setting for range checking. */ +/* Set command. Change the setting for range checking. */ static void set_range_command (char *ignore, int from_tty, struct cmd_list_element *c) { @@ -319,7 +260,7 @@ set_range_command (char *ignore, int from_tty, struct cmd_list_element *c) else if (strcmp (range, "auto") == 0) { range_mode = range_mode_auto; - set_type_range_case (); + set_range_case (); return; } else @@ -333,7 +274,7 @@ set_range_command (char *ignore, int from_tty, struct cmd_list_element *c) } /* Show command. Display a warning if the case sensitivity setting does - not match the current language. */ + not match the current language. */ static void show_case_command (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) @@ -361,7 +302,8 @@ show_case_command (struct ui_file *file, int from_tty, tmp); } else - fprintf_filtered (gdb_stdout, _("Case sensitivity in name search is \"%s\".\n"), + fprintf_filtered (gdb_stdout, + _("Case sensitivity in name search is \"%s\".\n"), value); if (case_sensitivity != current_language->la_case_sensitivity) @@ -387,7 +329,7 @@ set_case_command (char *ignore, int from_tty, struct cmd_list_element *c) else if (strcmp (case_sensitive, "auto") == 0) { case_mode = case_mode_auto; - set_type_range_case (); + set_range_case (); return; } else @@ -405,21 +347,19 @@ set_case_command (char *ignore, int from_tty, struct cmd_list_element *c) /* 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 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) @@ -434,7 +374,7 @@ set_language (enum language lang) if (languages[i]->la_language == lang) { current_language = languages[i]; - set_type_range_case (); + set_range_case (); break; } } @@ -458,8 +398,6 @@ language_info (int quietly) 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); @@ -467,237 +405,8 @@ language_info (int quietly) } } -/* Return the result of a binary operation. */ - -#if 0 /* Currently unused */ - -struct type * -binop_result_type (struct value *v1, struct value *v2) -{ - int size, uns; - struct type *t1 = check_typedef (VALUE_TYPE (v1)); - struct type *t2 = check_typedef (VALUE_TYPE (v2)); - int l1 = TYPE_LENGTH (t1); - int l2 = TYPE_LENGTH (t2); - - switch (current_language->la_language) - { - case language_c: - case language_cplus: - case language_objc: - if (TYPE_CODE (t1) == TYPE_CODE_FLT) - return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ? - VALUE_TYPE (v2) : VALUE_TYPE (v1); - else if (TYPE_CODE (t2) == TYPE_CODE_FLT) - return TYPE_CODE (t1) == TYPE_CODE_FLT && l1 > l2 ? - VALUE_TYPE (v1) : VALUE_TYPE (v2); - else if (TYPE_UNSIGNED (t1) && l1 > l2) - return VALUE_TYPE (v1); - else if (TYPE_UNSIGNED (t2) && l2 > l1) - return VALUE_TYPE (v2); - else /* Both are signed. Result is the longer type */ - return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2); - break; - case language_m2: - /* If we are doing type-checking, l1 should equal l2, so this is - not needed. */ - return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2); - break; - } - internal_error (__FILE__, __LINE__, _("failed internal consistency check")); - return (struct type *) 0; /* For lint */ -} - -#endif /* 0 */ -#if 0 -/* This page contains functions that are used in type/range checking. - They all return zero if the type/range check fails. - - It is hoped that these will make extending GDB to parse different - languages a little easier. These are primarily used in eval.c when - evaluating expressions and making sure that their types are correct. - Instead of having a mess of conjucted/disjuncted expressions in an "if", - the ideas of type can be wrapped up in the following functions. - - Note that some of them are not currently dependent upon which language - is currently being parsed. For example, floats are the same in - C and Modula-2 (ie. the only floating point type has TYPE_CODE of - TYPE_CODE_FLT), while booleans are different. */ - -/* Returns non-zero if its argument is a simple type. This is the same for - both Modula-2 and for C. In the C case, TYPE_CODE_CHAR will never occur, - and thus will never cause the failure of the test. */ -int -simple_type (struct type *type) -{ - CHECK_TYPEDEF (type); - switch (TYPE_CODE (type)) - { - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_ENUM: - case TYPE_CODE_FLT: - case TYPE_CODE_RANGE: - case TYPE_CODE_BOOL: - return 1; - - default: - return 0; - } -} - -/* Returns non-zero if its argument is of an ordered type. - An ordered type is one in which the elements can be tested for the - properties of "greater than", "less than", etc, or for which the - operations "increment" or "decrement" make sense. */ -int -ordered_type (struct type *type) -{ - CHECK_TYPEDEF (type); - switch (TYPE_CODE (type)) - { - case TYPE_CODE_INT: - case TYPE_CODE_CHAR: - case TYPE_CODE_ENUM: - case TYPE_CODE_FLT: - case TYPE_CODE_RANGE: - return 1; - - default: - return 0; - } -} - -/* Returns non-zero if the two types are the same */ -int -same_type (struct type *arg1, struct type *arg2) -{ - CHECK_TYPEDEF (type); - if (structured_type (arg1) ? !structured_type (arg2) : structured_type (arg2)) - /* One is structured and one isn't */ - return 0; - else if (structured_type (arg1) && structured_type (arg2)) - return arg1 == arg2; - else if (numeric_type (arg1) && numeric_type (arg2)) - return (TYPE_CODE (arg2) == TYPE_CODE (arg1)) && - (TYPE_UNSIGNED (arg1) == TYPE_UNSIGNED (arg2)) - ? 1 : 0; - else - return arg1 == arg2; -} - -/* Returns non-zero if the type is integral */ -int -integral_type (struct type *type) -{ - CHECK_TYPEDEF (type); - switch (current_language->la_language) - { - case language_c: - case language_cplus: - case language_objc: - return (TYPE_CODE (type) != TYPE_CODE_INT) && - (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1; - case language_m2: - case language_pascal: - return TYPE_CODE (type) != TYPE_CODE_INT ? 0 : 1; - default: - error (_("Language not supported.")); - } -} - -/* Returns non-zero if the value is numeric */ -int -numeric_type (struct type *type) -{ - CHECK_TYPEDEF (type); - switch (TYPE_CODE (type)) - { - case TYPE_CODE_INT: - case TYPE_CODE_FLT: - return 1; - - default: - return 0; - } -} - -/* Returns non-zero if the value is a character type */ -int -character_type (struct type *type) -{ - CHECK_TYPEDEF (type); - switch (current_language->la_language) - { - case language_m2: - case language_pascal: - return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1; - - case language_c: - case language_cplus: - case language_objc: - return (TYPE_CODE (type) == TYPE_CODE_INT) && - TYPE_LENGTH (type) == sizeof (char) - ? 1 : 0; - default: - return (0); - } -} - -/* Returns non-zero if the value is a string type */ -int -string_type (struct type *type) -{ - CHECK_TYPEDEF (type); - switch (current_language->la_language) - { - case language_m2: - case language_pascal: - return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1; - - case language_c: - case language_cplus: - case language_objc: - /* C does not have distinct string type. */ - return (0); - default: - return (0); - } -} - -/* Returns non-zero if the value is a boolean type */ -int -boolean_type (struct type *type) -{ - CHECK_TYPEDEF (type); - if (TYPE_CODE (type) == TYPE_CODE_BOOL) - return 1; - switch (current_language->la_language) - { - case language_c: - case language_cplus: - case language_objc: - /* Might be more cleanly handled by having a - TYPE_CODE_INT_NOT_BOOL for (the deleted) CHILL and such - languages, or a TYPE_CODE_INT_OR_BOOL for C. */ - if (TYPE_CODE (type) == TYPE_CODE_INT) - return 1; - default: - break; - } - return 0; -} - -/* Returns non-zero if the value is a floating-point type */ -int -float_type (struct type *type) -{ - CHECK_TYPEDEF (type); - return TYPE_CODE (type) == TYPE_CODE_FLT; -} - -/* Returns non-zero if the value is a pointer type */ +/* Returns non-zero if the value is a pointer type. */ int pointer_type (struct type *type) { @@ -705,38 +414,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: - case language_objc: - return (TYPE_CODE (type) == TYPE_CODE_STRUCT) || - (TYPE_CODE (type) == TYPE_CODE_UNION) || - (TYPE_CODE (type) == TYPE_CODE_ARRAY); - case language_pascal: - return (TYPE_CODE(type) == TYPE_CODE_STRUCT) || - (TYPE_CODE(type) == TYPE_CODE_UNION) || - (TYPE_CODE(type) == TYPE_CODE_SET) || - (TYPE_CODE(type) == TYPE_CODE_ARRAY); - case language_m2: - return (TYPE_CODE (type) == TYPE_CODE_STRUCT) || - (TYPE_CODE (type) == TYPE_CODE_SET) || - (TYPE_CODE (type) == TYPE_CODE_ARRAY); - default: - return (0); - } -} -#endif /* 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) { @@ -751,47 +433,20 @@ value_true (struct value *val) /* This page contains functions for the printing out of error messages that occur during type- and range- - checking. */ + checking. */ -/* These are called when a language fails a type- or range-check. The +/* This is called when a language fails a range-check. The first argument should be a printf()-style format string, and the - rest of the arguments should be its arguments. If - [type|range]_check is [type|range]_check_on, an error is printed; - if [type|range]_check_warn, a warning; otherwise just the - message. */ - -void -type_error (const char *string,...) -{ - va_list args; - va_start (args, string); - - switch (type_check) - { - case type_check_warn: - vwarning (string, args); - break; - case type_check_on: - verror (string, args); - break; - case type_check_off: - /* FIXME: cagney/2002-01-30: Should this function print anything - when type error is off? */ - vfprintf_filtered (gdb_stderr, string, args); - fprintf_filtered (gdb_stderr, "\n"); - break; - default: - internal_error (__FILE__, __LINE__, _("bad switch")); - } - va_end (args); -} + rest of the arguments should be its arguments. If range_check is + range_check_on, an error is printed; if range_check_warn, a warning; + otherwise just the message. */ void range_error (const char *string,...) { va_list args; - va_start (args, string); + va_start (args, string); switch (range_check) { case range_check_warn: @@ -813,9 +468,9 @@ range_error (const char *string,...) } -/* 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) @@ -829,7 +484,7 @@ language_enum (char *str) 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) @@ -846,8 +501,8 @@ language_def (enum language lang) return NULL; } -/* Return the language as a string */ -char * +/* Return the language as a string. */ +const char * language_str (enum language lang) { int i; @@ -867,7 +522,7 @@ 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); + help_list (setchecklist, "set check ", all_commands, gdb_stdout); } static void @@ -882,25 +537,26 @@ 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. */ - static char *language_set_doc = NULL; + 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) { 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) { @@ -912,19 +568,30 @@ add_language (const struct language_defn *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 *)); + language_names = XRESIZEVEC (const char *, language_names, + languages_size + 1); + for (i = 0; i < languages_size; ++i) language_names[i] = languages[i]->la_name; language_names[i] = 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 (); - fprintf_unfiltered (tmp_stream, _("\ -Set the current source language.\n\ -The currently understood settings are:\n\n\ -local or auto Automatic setting based on source file\n")); + 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) { @@ -943,18 +610,19 @@ local or auto Automatic setting based on source file\n")); languages[i]->la_name + 1); } - xfree (language_set_doc); 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, + 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 @@ -971,6 +639,7 @@ skip_language_trampoline (struct frame_info *frame, CORE_ADDR pc) if (languages[i]->skip_trampoline) { CORE_ADDR real_pc = (languages[i]->skip_trampoline) (frame, pc); + if (real_pc) return real_pc; } @@ -979,10 +648,10 @@ skip_language_trampoline (struct frame_info *frame, CORE_ADDR pc) return 0; } -/* Return demangled language symbol, or NULL. +/* Return demangled language symbol, or NULL. FIXME: Options are only useful for certain languages and ignored by others, so it would be better to remove them here and have a - more flexible demangler for the languages that need it. + more flexible demangler for the languages that need it. FIXME: Sometimes the demangler is invoked when we don't know the language, so we can't use this everywhere. */ char * @@ -994,13 +663,30 @@ language_demangle (const struct language_defn *current_language, 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 *current_language, +language_class_name_from_physname (const struct language_defn *lang, const char *physname) { - if (current_language != NULL && current_language->la_class_name_from_physname) - return current_language->la_class_name_from_physname (physname); + if (lang != NULL && lang->la_class_name_from_physname) + return lang->la_class_name_from_physname (physname); return NULL; } @@ -1044,7 +730,7 @@ default_print_array_index (struct value *index_value, struct ui_file *stream, void default_get_string (struct value *value, gdb_byte **buffer, int *length, - const char **charset) + struct type **char_type, const char **charset) { error (_("Getting a string is unsupported in this language.")); } @@ -1052,7 +738,7 @@ default_get_string (struct value *value, gdb_byte **buffer, int *length, /* Define the language that is no language. */ static int -unk_lang_parser (void) +unk_lang_parser (struct parser_state *ps) { return 1; } @@ -1067,45 +753,53 @@ static void 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 (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, struct type *type, const gdb_byte *string, unsigned int length, - int force_ellipses, + 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 void -unk_lang_print_type (struct type *type, char *varstring, struct ui_file *stream, - int show, int level) +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_print_type called.")); + error (_("internal error - unimplemented " + "function unk_lang_print_type called.")); } -static int +static void 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_val_print called.")); + error (_("internal error - unimplemented " + "function unk_lang_val_print called.")); } -static int +static void unk_lang_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { - error (_("internal error - unimplemented function unk_lang_value_print called.")); + error (_("internal error - unimplemented " + "function unk_lang_value_print called.")); } static CORE_ADDR unk_lang_trampoline (struct frame_info *frame, CORE_ADDR pc) @@ -1116,7 +810,7 @@ static CORE_ADDR unk_lang_trampoline (struct frame_info *frame, CORE_ADDR pc) /* Unknown languages just use the cplus demangler. */ static char *unk_lang_demangle (const char *mangled, int options) { - return cplus_demangle (mangled, options); + return gdb_demangle (mangled, options); } static char *unk_lang_class_name (const char *mangled) @@ -1142,12 +836,13 @@ unknown_language_arch_info (struct gdbarch *gdbarch, 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, @@ -1159,12 +854,15 @@ const struct language_defn unknown_language_defn = 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 */ - unk_lang_class_name, /* Language specific class_name_from_physname */ + NULL, + unk_lang_class_name, /* Language specific + class_name_from_physname */ unk_op_print_tab, /* expression operators for printing */ 1, /* c-style arrays */ 0, /* String lower bound */ @@ -1174,19 +872,26 @@ const struct language_defn unknown_language_defn = default_print_array_index, default_pass_by_reference, default_get_string, + NULL, /* la_get_symbol_name_cmp */ + iterate_over_symbols, + &default_varobj_ops, + NULL, + NULL, 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", + "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, @@ -1198,12 +903,15 @@ const struct language_defn auto_language_defn = 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 */ - unk_lang_class_name, /* Language specific class_name_from_physname */ + NULL, + unk_lang_class_name, /* Language specific + class_name_from_physname */ unk_op_print_tab, /* expression operators for printing */ 1, /* c-style arrays */ 0, /* String lower bound */ @@ -1213,18 +921,24 @@ const struct language_defn auto_language_defn = default_print_array_index, default_pass_by_reference, 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, @@ -1236,12 +950,15 @@ const struct language_defn local_language_defn = 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 */ - unk_lang_class_name, /* Language specific class_name_from_physname */ + NULL, + unk_lang_class_name, /* Language specific + class_name_from_physname */ unk_op_print_tab, /* expression operators for printing */ 1, /* c-style arrays */ 0, /* String lower bound */ @@ -1251,6 +968,11 @@ const struct language_defn local_language_defn = default_print_array_index, default_pass_by_reference, default_get_string, + NULL, /* la_get_symbol_name_cmp */ + iterate_over_symbols, + &default_varobj_ops, + NULL, + NULL, LANG_MAGIC }; @@ -1286,8 +1008,9 @@ struct type * 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; } @@ -1295,17 +1018,19 @@ struct 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); + if (type && TYPE_CODE (type) == TYPE_CODE_BOOL) return type; } @@ -1314,39 +1039,151 @@ language_bool_type (const struct language_defn *la, 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; - for (p = ld->arch_info[la->la_language].primitive_type_vector; - (*p) != NULL; - p++) + struct type **p; + + for (p = lai->primitive_type_vector; (*p) != NULL; p++) { if (strcmp (TYPE_NAME (*p), name) == 0) - return (*p); + return p; + } + return NULL; +} + +/* 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]); + } + + /* 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; } - 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 */ +/* Initialize the language routines. */ void _initialize_language (void) { - static const char *type_or_range_names[] + static const char *const type_or_range_names[] = { "on", "off", "warn", "auto", NULL }; - static const char *case_sensitive_names[] + static const char *const case_sensitive_names[] = { "on", "off", "auto", NULL }; language_gdbarch_data = gdbarch_data_register_post_init (language_gdbarch_post_init); - /* GDB commands for language specific stuff */ + /* GDB commands for language specific stuff. */ add_prefix_cmd ("check", no_class, set_check, _("Set the status of the type/range checker."), @@ -1360,18 +1197,11 @@ _initialize_language (void) 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)"), _("\ -Show range checking. (on/warn/off/auto)"), NULL, - set_range_command, + &range, + _("Set range checking. (on/warn/off/auto)"), + _("Show range checking. (on/warn/off/auto)"), + NULL, set_range_command, show_range_command, &setchecklist, &showchecklist); @@ -1393,6 +1223,6 @@ For Fortran the default is off; for other languages the default is on."), range = xstrdup ("auto"); case_sensitive = xstrdup ("auto"); - /* Have the above take effect */ + /* Have the above take effect. */ set_language (language_auto); }