X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ff-lang.c;h=1b545b27b3b9273cb217bdd102189202d731dd88;hb=1bf9c36374d9c758bc49dc18dca7acf0719e290d;hp=749214963b5402240177007c99dbc1ac5e591009;hpb=49c4e619f81a66545e2332dc218d9bf31bbb51ad;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/f-lang.c b/gdb/f-lang.c index 749214963b..1b545b27b3 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -1,7 +1,6 @@ /* Fortran language support routines for GDB, the GNU debugger. - Copyright (C) 1993-1996, 1998-2005, 2007-2012 Free Software - Foundation, Inc. + Copyright (C) 1993-2020 Free Software Foundation, Inc. Contributed by Motorola. Adapted from the C parser by Farooq Butt (fmbutt@engage.sps.mot.com). @@ -22,58 +21,26 @@ along with this program. If not, see . */ #include "defs.h" -#include "gdb_string.h" #include "symtab.h" #include "gdbtypes.h" #include "expression.h" #include "parser-defs.h" #include "language.h" +#include "varobj.h" +#include "gdbcore.h" #include "f-lang.h" #include "valprint.h" #include "value.h" #include "cp-support.h" #include "charset.h" #include "c-lang.h" +#include "target-float.h" +#include "gdbarch.h" - -/* Following is dubious stuff that had been in the xcoff reader. */ - -struct saved_fcn - { - long line_offset; /* Line offset for function. */ - struct saved_fcn *next; - }; - - -struct saved_bf_symnum - { - long symnum_fcn; /* Symnum of function (i.e. .function - directive). */ - long symnum_bf; /* Symnum of .bf for this function. */ - struct saved_bf_symnum *next; - }; - -typedef struct saved_fcn SAVED_FUNCTION, *SAVED_FUNCTION_PTR; -typedef struct saved_bf_symnum SAVED_BF, *SAVED_BF_PTR; +#include /* Local functions */ -extern void _initialize_f_language (void); -#if 0 -static void clear_function_list (void); -static long get_bf_for_fcn (long); -static void clear_bf_list (void); -static void patch_all_commons_by_name (char *, CORE_ADDR, int); -static SAVED_F77_COMMON_PTR find_first_common_named (char *); -static void add_common_entry (struct symbol *); -static void add_common_block (char *, CORE_ADDR, int, char *); -static SAVED_FUNCTION *allocate_saved_function_node (void); -static SAVED_BF_PTR allocate_saved_bf_node (void); -static COMMON_ENTRY_PTR allocate_common_entry_node (void); -static SAVED_F77_COMMON_PTR allocate_saved_f77_common_node (void); -static void patch_common_entries (SAVED_F77_COMMON_PTR, CORE_ADDR, int); -#endif - static void f_printchar (int c, struct type *type, struct ui_file * stream); static void f_emit_char (int c, struct type *type, struct ui_file * stream, int quoter); @@ -92,7 +59,7 @@ f_get_encoding (struct type *type) encoding = target_charset (get_type_arch (type)); break; case 4: - if (gdbarch_byte_order (get_type_arch (type)) == BFD_ENDIAN_BIG) + if (type_byte_order (type) == BFD_ENDIAN_BIG) encoding = "UTF-32BE"; else encoding = "UTF-32LE"; @@ -178,7 +145,7 @@ static const struct op_print f_op_print_tab[] = {".LT.", BINOP_LESS, PREC_ORDER, 0}, {"**", UNOP_IND, PREC_PREFIX, 0}, {"@", BINOP_REPEAT, PREC_REPEAT, 0}, - {NULL, 0, 0, 0} + {NULL, OP_NULL, PREC_REPEAT, 0} }; enum f_primitive_types { @@ -198,581 +165,694 @@ enum f_primitive_types { nr_f_primitive_types }; -static void -f_language_arch_info (struct gdbarch *gdbarch, - struct language_arch_info *lai) -{ - const struct builtin_f_type *builtin = builtin_f_type (gdbarch); - - lai->string_char_type = builtin->builtin_character; - lai->primitive_type_vector - = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_f_primitive_types + 1, - struct type *); - - lai->primitive_type_vector [f_primitive_type_character] - = builtin->builtin_character; - lai->primitive_type_vector [f_primitive_type_logical] - = builtin->builtin_logical; - lai->primitive_type_vector [f_primitive_type_logical_s1] - = builtin->builtin_logical_s1; - lai->primitive_type_vector [f_primitive_type_logical_s2] - = builtin->builtin_logical_s2; - lai->primitive_type_vector [f_primitive_type_logical_s8] - = builtin->builtin_logical_s8; - lai->primitive_type_vector [f_primitive_type_real] - = builtin->builtin_real; - lai->primitive_type_vector [f_primitive_type_real_s8] - = builtin->builtin_real_s8; - lai->primitive_type_vector [f_primitive_type_real_s16] - = builtin->builtin_real_s16; - lai->primitive_type_vector [f_primitive_type_complex_s8] - = builtin->builtin_complex_s8; - lai->primitive_type_vector [f_primitive_type_complex_s16] - = builtin->builtin_complex_s16; - lai->primitive_type_vector [f_primitive_type_void] - = builtin->builtin_void; - - lai->bool_type_symbol = "logical"; - lai->bool_type_default = builtin->builtin_logical_s2; -} +/* Special expression evaluation cases for Fortran. */ -/* Remove the modules separator :: from the default break list. */ - -static char * -f_word_break_characters (void) +static struct value * +evaluate_subexp_f (struct type *expect_type, struct expression *exp, + int *pos, enum noside noside) { - static char *retval; + struct value *arg1 = NULL, *arg2 = NULL; + enum exp_opcode op; + int pc; + struct type *type; - if (!retval) - { - char *s; + pc = *pos; + *pos += 1; + op = exp->elts[pc].opcode; - retval = xstrdup (default_word_break_characters ()); - s = strchr (retval, ':'); - if (s) + switch (op) + { + default: + *pos -= 1; + return evaluate_subexp_standard (expect_type, exp, pos, noside); + + case UNOP_ABS: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + type = value_type (arg1); + switch (type->code ()) { - char *last_char = &s[strlen (s) - 1]; - - *s = *last_char; - *last_char = 0; + case TYPE_CODE_FLT: + { + double d + = fabs (target_float_to_host_double (value_contents (arg1), + value_type (arg1))); + return value_from_host_double (type, d); + } + case TYPE_CODE_INT: + { + LONGEST l = value_as_long (arg1); + l = llabs (l); + return value_from_longest (type, l); + } } - } - return retval; -} - -/* Consider the modules separator :: as a valid symbol name character - class. */ - -static VEC (char_ptr) * -f_make_symbol_completion_list (char *text, char *word) -{ - return default_make_symbol_completion_list_break_on (text, word, ":"); -} - -const struct language_defn f_language_defn = -{ - "fortran", - language_fortran, - range_check_on, - type_check_on, - case_sensitive_off, - array_column_major, - macro_expansion_no, - &exp_descriptor_standard, - f_parse, /* parser */ - f_error, /* parser error function */ - null_post_parser, - f_printchar, /* Print character constant */ - f_printstr, /* function to print string constant */ - f_emit_char, /* Function to print a single character */ - f_print_type, /* Print a type using appropriate syntax */ - default_print_typedef, /* Print a typedef using appropriate syntax */ - f_val_print, /* Print a value using appropriate syntax */ - c_value_print, /* FIXME */ - default_read_var_value, /* la_read_var_value */ - NULL, /* Language specific skip_trampoline */ - NULL, /* name_of_this */ - cp_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */ - basic_lookup_transparent_type,/* lookup_transparent_type */ - NULL, /* Language specific symbol demangler */ - NULL, /* Language specific - class_name_from_physname */ - f_op_print_tab, /* expression operators for printing */ - 0, /* arrays are first-class (not c-style) */ - 1, /* String lower bound */ - f_word_break_characters, - f_make_symbol_completion_list, - f_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 -}; - -static void * -build_fortran_types (struct gdbarch *gdbarch) -{ - struct builtin_f_type *builtin_f_type - = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_f_type); - - builtin_f_type->builtin_void - = arch_type (gdbarch, TYPE_CODE_VOID, 1, "VOID"); - - builtin_f_type->builtin_character - = arch_integer_type (gdbarch, TARGET_CHAR_BIT, 0, "character"); - - builtin_f_type->builtin_logical_s1 - = arch_boolean_type (gdbarch, TARGET_CHAR_BIT, 1, "logical*1"); - - builtin_f_type->builtin_integer_s2 - = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch), 0, - "integer*2"); - - builtin_f_type->builtin_logical_s2 - = arch_boolean_type (gdbarch, gdbarch_short_bit (gdbarch), 1, - "logical*2"); - - builtin_f_type->builtin_logical_s8 - = arch_boolean_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1, - "logical*8"); + error (_("ABS of type %s not supported"), TYPE_SAFE_NAME (type)); + + case BINOP_MOD: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + type = value_type (arg1); + if (type->code () != value_type (arg2)->code ()) + error (_("non-matching types for parameters to MOD ()")); + switch (type->code ()) + { + case TYPE_CODE_FLT: + { + double d1 + = target_float_to_host_double (value_contents (arg1), + value_type (arg1)); + double d2 + = target_float_to_host_double (value_contents (arg2), + value_type (arg2)); + double d3 = fmod (d1, d2); + return value_from_host_double (type, d3); + } + case TYPE_CODE_INT: + { + LONGEST v1 = value_as_long (arg1); + LONGEST v2 = value_as_long (arg2); + if (v2 == 0) + error (_("calling MOD (N, 0) is undefined")); + LONGEST v3 = v1 - (v1 / v2) * v2; + return value_from_longest (value_type (arg1), v3); + } + } + error (_("MOD of type %s not supported"), TYPE_SAFE_NAME (type)); - builtin_f_type->builtin_integer - = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, - "integer"); + case UNOP_FORTRAN_CEILING: + { + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + type = value_type (arg1); + if (type->code () != TYPE_CODE_FLT) + error (_("argument to CEILING must be of type float")); + double val + = target_float_to_host_double (value_contents (arg1), + value_type (arg1)); + val = ceil (val); + return value_from_host_double (type, val); + } - builtin_f_type->builtin_logical - = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1, - "logical*4"); + case UNOP_FORTRAN_FLOOR: + { + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + type = value_type (arg1); + if (type->code () != TYPE_CODE_FLT) + error (_("argument to FLOOR must be of type float")); + double val + = target_float_to_host_double (value_contents (arg1), + value_type (arg1)); + val = floor (val); + return value_from_host_double (type, val); + } - builtin_f_type->builtin_real - = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch), - "real", NULL); - builtin_f_type->builtin_real_s8 - = arch_float_type (gdbarch, gdbarch_double_bit (gdbarch), - "real*8", NULL); - builtin_f_type->builtin_real_s16 - = arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch), - "real*16", NULL); + case BINOP_FORTRAN_MODULO: + { + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + type = value_type (arg1); + if (type->code () != value_type (arg2)->code ()) + error (_("non-matching types for parameters to MODULO ()")); + /* MODULO(A, P) = A - FLOOR (A / P) * P */ + switch (type->code ()) + { + case TYPE_CODE_INT: + { + LONGEST a = value_as_long (arg1); + LONGEST p = value_as_long (arg2); + LONGEST result = a - (a / p) * p; + if (result != 0 && (a < 0) != (p < 0)) + result += p; + return value_from_longest (value_type (arg1), result); + } + case TYPE_CODE_FLT: + { + double a + = target_float_to_host_double (value_contents (arg1), + value_type (arg1)); + double p + = target_float_to_host_double (value_contents (arg2), + value_type (arg2)); + double result = fmod (a, p); + if (result != 0 && (a < 0.0) != (p < 0.0)) + result += p; + return value_from_host_double (type, result); + } + } + error (_("MODULO of type %s not supported"), TYPE_SAFE_NAME (type)); + } - builtin_f_type->builtin_complex_s8 - = arch_complex_type (gdbarch, "complex*8", - builtin_f_type->builtin_real); - builtin_f_type->builtin_complex_s16 - = arch_complex_type (gdbarch, "complex*16", - builtin_f_type->builtin_real_s8); - builtin_f_type->builtin_complex_s32 - = arch_complex_type (gdbarch, "complex*32", - builtin_f_type->builtin_real_s16); + case BINOP_FORTRAN_CMPLX: + arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); + arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + type = builtin_f_type(exp->gdbarch)->builtin_complex_s16; + return value_literal_complex (arg1, arg2, type); + + case UNOP_FORTRAN_KIND: + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS); + type = value_type (arg1); + + switch (type->code ()) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_MODULE: + case TYPE_CODE_FUNC: + error (_("argument to kind must be an intrinsic type")); + } + + if (!TYPE_TARGET_TYPE (type)) + return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, + TYPE_LENGTH (type)); + return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, + TYPE_LENGTH (TYPE_TARGET_TYPE (type))); + } - return builtin_f_type; + /* Should be unreachable. */ + return nullptr; } -static struct gdbarch_data *f_type_data; +/* Return true if TYPE is a string. */ -const struct builtin_f_type * -builtin_f_type (struct gdbarch *gdbarch) +static bool +f_is_string_type_p (struct type *type) { - return gdbarch_data (gdbarch, f_type_data); + type = check_typedef (type); + return (type->code () == TYPE_CODE_STRING + || (type->code () == TYPE_CODE_ARRAY + && TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_CHAR)); } -void -_initialize_f_language (void) -{ - f_type_data = gdbarch_data_register_post_init (build_fortran_types); - - add_language (&f_language_defn); -} +/* Special expression lengths for Fortran. */ -#if 0 -static SAVED_BF_PTR -allocate_saved_bf_node (void) +static void +operator_length_f (const struct expression *exp, int pc, int *oplenp, + int *argsp) { - SAVED_BF_PTR new; + int oplen = 1; + int args = 0; - new = (SAVED_BF_PTR) xmalloc (sizeof (SAVED_BF)); - return (new); -} + switch (exp->elts[pc - 1].opcode) + { + default: + operator_length_standard (exp, pc, oplenp, argsp); + return; + + case UNOP_FORTRAN_KIND: + case UNOP_FORTRAN_FLOOR: + case UNOP_FORTRAN_CEILING: + oplen = 1; + args = 1; + break; -static SAVED_FUNCTION * -allocate_saved_function_node (void) -{ - SAVED_FUNCTION *new; + case BINOP_FORTRAN_CMPLX: + case BINOP_FORTRAN_MODULO: + oplen = 1; + args = 2; + break; + } - new = (SAVED_FUNCTION *) xmalloc (sizeof (SAVED_FUNCTION)); - return (new); + *oplenp = oplen; + *argsp = args; } -static SAVED_F77_COMMON_PTR -allocate_saved_f77_common_node (void) -{ - SAVED_F77_COMMON_PTR new; - - new = (SAVED_F77_COMMON_PTR) xmalloc (sizeof (SAVED_F77_COMMON)); - return (new); -} +/* Helper for PRINT_SUBEXP_F. Arguments are as for PRINT_SUBEXP_F, except + the extra argument NAME which is the text that should be printed as the + name of this operation. */ -static COMMON_ENTRY_PTR -allocate_common_entry_node (void) +static void +print_unop_subexp_f (struct expression *exp, int *pos, + struct ui_file *stream, enum precedence prec, + const char *name) { - COMMON_ENTRY_PTR new; - - new = (COMMON_ENTRY_PTR) xmalloc (sizeof (COMMON_ENTRY)); - return (new); + (*pos)++; + fprintf_filtered (stream, "%s(", name); + print_subexp (exp, pos, stream, PREC_SUFFIX); + fputs_filtered (")", stream); } -#endif -SAVED_F77_COMMON_PTR head_common_list = NULL; /* Ptr to 1st saved COMMON */ -SAVED_F77_COMMON_PTR tail_common_list = NULL; /* Ptr to last saved COMMON */ -SAVED_F77_COMMON_PTR current_common = NULL; /* Ptr to current COMMON */ +/* Helper for PRINT_SUBEXP_F. Arguments are as for PRINT_SUBEXP_F, except + the extra argument NAME which is the text that should be printed as the + name of this operation. */ -#if 0 -static SAVED_BF_PTR saved_bf_list = NULL; /* Ptr to (.bf,function) - list */ -static SAVED_BF_PTR saved_bf_list_end = NULL; /* Ptr to above list's end */ -static SAVED_BF_PTR current_head_bf_list = NULL; /* Current head of - above list. */ - -static SAVED_BF_PTR tmp_bf_ptr; /* Generic temporary for use - in macros. */ +static void +print_binop_subexp_f (struct expression *exp, int *pos, + struct ui_file *stream, enum precedence prec, + const char *name) +{ + (*pos)++; + fprintf_filtered (stream, "%s(", name); + print_subexp (exp, pos, stream, PREC_SUFFIX); + fputs_filtered (",", stream); + print_subexp (exp, pos, stream, PREC_SUFFIX); + fputs_filtered (")", stream); +} -/* The following function simply enters a given common block onto - the global common block chain. */ +/* Special expression printing for Fortran. */ static void -add_common_block (char *name, CORE_ADDR offset, int secnum, char *func_stab) +print_subexp_f (struct expression *exp, int *pos, + struct ui_file *stream, enum precedence prec) { - SAVED_F77_COMMON_PTR tmp; - char *c, *local_copy_func_stab; + int pc = *pos; + enum exp_opcode op = exp->elts[pc].opcode; - /* If the COMMON block we are trying to add has a blank - name (i.e. "#BLNK_COM") then we set it to __BLANK - because the darn "#" character makes GDB's input - parser have fits. */ + switch (op) + { + default: + print_subexp_standard (exp, pos, stream, prec); + return; + case UNOP_FORTRAN_KIND: + print_unop_subexp_f (exp, pos, stream, prec, "KIND"); + return; - if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 - || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) - { + case UNOP_FORTRAN_FLOOR: + print_unop_subexp_f (exp, pos, stream, prec, "FLOOR"); + return; - xfree (name); - name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1); - strcpy (name, BLANK_COMMON_NAME_LOCAL); - } + case UNOP_FORTRAN_CEILING: + print_unop_subexp_f (exp, pos, stream, prec, "CEILING"); + return; - tmp = allocate_saved_f77_common_node (); + case BINOP_FORTRAN_CMPLX: + print_binop_subexp_f (exp, pos, stream, prec, "CMPLX"); + return; - local_copy_func_stab = xmalloc (strlen (func_stab) + 1); - strcpy (local_copy_func_stab, func_stab); + case BINOP_FORTRAN_MODULO: + print_binop_subexp_f (exp, pos, stream, prec, "MODULO"); + return; + } +} - tmp->name = xmalloc (strlen (name) + 1); +/* Special expression names for Fortran. */ - /* local_copy_func_stab is a stabstring, let us first extract the - function name from the stab by NULLing out the ':' character. */ +static const char * +op_name_f (enum exp_opcode opcode) +{ + switch (opcode) + { + default: + return op_name_standard (opcode); +#define OP(name) \ + case name: \ + return #name ; +#include "fortran-operator.def" +#undef OP + } +} - c = NULL; - c = strchr (local_copy_func_stab, ':'); +/* Special expression dumping for Fortran. */ - if (c) - *c = '\0'; - else - error (_("Malformed function STAB found in add_common_block()")); +static int +dump_subexp_body_f (struct expression *exp, + struct ui_file *stream, int elt) +{ + int opcode = exp->elts[elt].opcode; + int oplen, nargs, i; + switch (opcode) + { + default: + return dump_subexp_body_standard (exp, stream, elt); + + case UNOP_FORTRAN_KIND: + case UNOP_FORTRAN_FLOOR: + case UNOP_FORTRAN_CEILING: + case BINOP_FORTRAN_CMPLX: + case BINOP_FORTRAN_MODULO: + operator_length_f (exp, (elt + 1), &oplen, &nargs); + break; + } - tmp->owning_function = xmalloc (strlen (local_copy_func_stab) + 1); + elt += oplen; + for (i = 0; i < nargs; i += 1) + elt = dump_subexp (exp, stream, elt); - strcpy (tmp->owning_function, local_copy_func_stab); + return elt; +} - strcpy (tmp->name, name); - tmp->offset = offset; - tmp->next = NULL; - tmp->entries = NULL; - tmp->secnum = secnum; +/* Special expression checking for Fortran. */ - current_common = tmp; +static int +operator_check_f (struct expression *exp, int pos, + int (*objfile_func) (struct objfile *objfile, + void *data), + void *data) +{ + const union exp_element *const elts = exp->elts; - if (head_common_list == NULL) + switch (elts[pos].opcode) { - head_common_list = tail_common_list = tmp; - } - else - { - tail_common_list->next = tmp; - tail_common_list = tmp; + case UNOP_FORTRAN_KIND: + case UNOP_FORTRAN_FLOOR: + case UNOP_FORTRAN_CEILING: + case BINOP_FORTRAN_CMPLX: + case BINOP_FORTRAN_MODULO: + /* Any references to objfiles are held in the arguments to this + expression, not within the expression itself, so no additional + checking is required here, the outer expression iteration code + will take care of checking each argument. */ + break; + + default: + return operator_check_standard (exp, pos, objfile_func, data); } -} -#endif -/* The following function simply enters a given common entry onto - the "current_common" block that has been saved away. */ + return 0; +} -#if 0 -static void -add_common_entry (struct symbol *entry_sym_ptr) +static const char *f_extensions[] = { - COMMON_ENTRY_PTR tmp; - + ".f", ".F", ".for", ".FOR", ".ftn", ".FTN", ".fpp", ".FPP", + ".f90", ".F90", ".f95", ".F95", ".f03", ".F03", ".f08", ".F08", + NULL +}; +/* Expression processing for Fortran. */ +static const struct exp_descriptor exp_descriptor_f = +{ + print_subexp_f, + operator_length_f, + operator_check_f, + op_name_f, + dump_subexp_body_f, + evaluate_subexp_f +}; - /* The order of this list is important, since - we expect the entries to appear in decl. - order when we later issue "info common" calls. */ +/* Constant data that describes the Fortran language. */ - tmp = allocate_common_entry_node (); +extern const struct language_data f_language_data = +{ + "fortran", + "Fortran", + language_fortran, + range_check_on, + case_sensitive_off, + array_column_major, + macro_expansion_no, + f_extensions, + &exp_descriptor_f, + f_printchar, /* Print character constant */ + f_printstr, /* function to print string constant */ + f_emit_char, /* Function to print a single character */ + f_print_typedef, /* Print a typedef using appropriate syntax */ + NULL, /* name_of_this */ + false, /* la_store_sym_names_in_linkage_form_p */ + f_op_print_tab, /* expression operators for printing */ + 0, /* arrays are first-class (not c-style) */ + 1, /* String lower bound */ + &default_varobj_ops, + f_is_string_type_p, + "(...)" /* la_struct_too_deep_ellipsis */ +}; - tmp->next = NULL; - tmp->symbol = entry_sym_ptr; +/* Class representing the Fortran language. */ - if (current_common == NULL) - error (_("Attempt to add COMMON entry with no block open!")); - else - { - if (current_common->entries == NULL) - { - current_common->entries = tmp; - current_common->end_of_entries = tmp; - } - else - { - current_common->end_of_entries->next = tmp; - current_common->end_of_entries = tmp; - } - } -} -#endif +class f_language : public language_defn +{ +public: + f_language () + : language_defn (language_fortran, f_language_data) + { /* Nothing. */ } + + /* See language.h. */ + void language_arch_info (struct gdbarch *gdbarch, + struct language_arch_info *lai) const override + { + const struct builtin_f_type *builtin = builtin_f_type (gdbarch); + + lai->string_char_type = builtin->builtin_character; + lai->primitive_type_vector + = GDBARCH_OBSTACK_CALLOC (gdbarch, nr_f_primitive_types + 1, + struct type *); + + lai->primitive_type_vector [f_primitive_type_character] + = builtin->builtin_character; + lai->primitive_type_vector [f_primitive_type_logical] + = builtin->builtin_logical; + lai->primitive_type_vector [f_primitive_type_logical_s1] + = builtin->builtin_logical_s1; + lai->primitive_type_vector [f_primitive_type_logical_s2] + = builtin->builtin_logical_s2; + lai->primitive_type_vector [f_primitive_type_logical_s8] + = builtin->builtin_logical_s8; + lai->primitive_type_vector [f_primitive_type_real] + = builtin->builtin_real; + lai->primitive_type_vector [f_primitive_type_real_s8] + = builtin->builtin_real_s8; + lai->primitive_type_vector [f_primitive_type_real_s16] + = builtin->builtin_real_s16; + lai->primitive_type_vector [f_primitive_type_complex_s8] + = builtin->builtin_complex_s8; + lai->primitive_type_vector [f_primitive_type_complex_s16] + = builtin->builtin_complex_s16; + lai->primitive_type_vector [f_primitive_type_void] + = builtin->builtin_void; + + lai->bool_type_symbol = "logical"; + lai->bool_type_default = builtin->builtin_logical_s2; + } + + /* See language.h. */ + unsigned int search_name_hash (const char *name) const override + { + return cp_search_name_hash (name); + } -/* This routine finds the first encountred COMMON block named "name". */ + /* See language.h. */ -#if 0 -static SAVED_F77_COMMON_PTR -find_first_common_named (char *name) -{ + char *demangle (const char *mangled, int options) const override + { + /* We could support demangling here to provide module namespaces + also for inferiors with only minimal symbol table (ELF symbols). + Just the mangling standard is not standardized across compilers + and there is no DW_AT_producer available for inferiors with only + the ELF symbols to check the mangling kind. */ + return nullptr; + } + + /* See language.h. */ + + void print_type (struct type *type, const char *varstring, + struct ui_file *stream, int show, int level, + const struct type_print_options *flags) const override + { + f_print_type (type, varstring, stream, show, level, flags); + } - SAVED_F77_COMMON_PTR tmp; + /* See language.h. This just returns default set of word break + characters but with the modules separator `::' removed. */ - tmp = head_common_list; + const char *word_break_characters (void) const override + { + static char *retval; - while (tmp != NULL) - { - if (strcmp (tmp->name, name) == 0) - return (tmp); - else - tmp = tmp->next; - } - return (NULL); -} -#endif + if (!retval) + { + char *s; -/* This routine finds the first encountred COMMON block named "name" - that belongs to function funcname. */ + retval = xstrdup (language_defn::word_break_characters ()); + s = strchr (retval, ':'); + if (s) + { + char *last_char = &s[strlen (s) - 1]; -SAVED_F77_COMMON_PTR -find_common_for_function (const char *name, const char *funcname) -{ + *s = *last_char; + *last_char = 0; + } + } + return retval; + } - SAVED_F77_COMMON_PTR tmp; - tmp = head_common_list; + /* See language.h. */ - while (tmp != NULL) - { - if (strcmp (tmp->name, name) == 0 - && strcmp (tmp->owning_function, funcname) == 0) - return (tmp); - else - tmp = tmp->next; - } - return (NULL); -} + void collect_symbol_completion_matches (completion_tracker &tracker, + complete_symbol_mode mode, + symbol_name_match_type name_match_type, + const char *text, const char *word, + enum type_code code) const override + { + /* Consider the modules separator :: as a valid symbol name character + class. */ + default_collect_symbol_completion_matches_break_on (tracker, mode, + name_match_type, + text, word, ":", + code); + } + + /* See language.h. */ + + void value_print_inner + (struct value *val, struct ui_file *stream, int recurse, + const struct value_print_options *options) const override + { + return f_value_print_inner (val, stream, recurse, options); + } + /* See language.h. */ -#if 0 + struct block_symbol lookup_symbol_nonlocal + (const char *name, const struct block *block, + const domain_enum domain) const override + { + return cp_lookup_symbol_nonlocal (this, name, block, domain); + } -/* The following function is called to patch up the offsets - for the statics contained in the COMMON block named - "name." */ + /* See language.h. */ -static void -patch_common_entries (SAVED_F77_COMMON_PTR blk, CORE_ADDR offset, int secnum) -{ - COMMON_ENTRY_PTR entry; + int parser (struct parser_state *ps) const override + { + return f_parse (ps); + } - blk->offset = offset; /* Keep this around for future use. */ +protected: - entry = blk->entries; + /* See language.h. */ - while (entry != NULL) - { - SYMBOL_VALUE (entry->symbol) += offset; - SYMBOL_SECTION (entry->symbol) = secnum; + symbol_name_matcher_ftype *get_symbol_name_matcher_inner + (const lookup_name_info &lookup_name) const override + { + return cp_get_symbol_name_matcher (lookup_name); + } +}; - entry = entry->next; - } - blk->secnum = secnum; -} +/* Single instance of the Fortran language class. */ -/* Patch all commons named "name" that need patching.Since COMMON - blocks occur with relative infrequency, we simply do a linear scan on - the name. Eventually, the best way to do this will be a - hashed-lookup. Secnum is the section number for the .bss section - (which is where common data lives). */ +static f_language f_language_defn; -static void -patch_all_commons_by_name (char *name, CORE_ADDR offset, int secnum) +static void * +build_fortran_types (struct gdbarch *gdbarch) { + struct builtin_f_type *builtin_f_type + = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct builtin_f_type); - SAVED_F77_COMMON_PTR tmp; + builtin_f_type->builtin_void + = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT, "void"); - /* For blank common blocks, change the canonical reprsentation - of a blank name */ + builtin_f_type->builtin_character + = arch_type (gdbarch, TYPE_CODE_CHAR, TARGET_CHAR_BIT, "character"); - if (strcmp (name, BLANK_COMMON_NAME_ORIGINAL) == 0 - || strcmp (name, BLANK_COMMON_NAME_MF77) == 0) - { - xfree (name); - name = alloca (strlen (BLANK_COMMON_NAME_LOCAL) + 1); - strcpy (name, BLANK_COMMON_NAME_LOCAL); - } + builtin_f_type->builtin_logical_s1 + = arch_boolean_type (gdbarch, TARGET_CHAR_BIT, 1, "logical*1"); - tmp = head_common_list; + builtin_f_type->builtin_integer_s2 + = arch_integer_type (gdbarch, gdbarch_short_bit (gdbarch), 0, + "integer*2"); - while (tmp != NULL) - { - if (COMMON_NEEDS_PATCHING (tmp)) - if (strcmp (tmp->name, name) == 0) - patch_common_entries (tmp, offset, secnum); + builtin_f_type->builtin_integer_s8 + = arch_integer_type (gdbarch, gdbarch_long_long_bit (gdbarch), 0, + "integer*8"); - tmp = tmp->next; - } -} -#endif - -/* This macro adds the symbol-number for the start of the function - (the symbol number of the .bf) referenced by symnum_fcn to a - list. This list, in reality should be a FIFO queue but since - #line pragmas sometimes cause line ranges to get messed up - we simply create a linear list. This list can then be searched - first by a queueing algorithm and upon failure fall back to - a linear scan. */ - -#if 0 -#define ADD_BF_SYMNUM(bf_sym,fcn_sym) \ - \ - if (saved_bf_list == NULL) \ -{ \ - tmp_bf_ptr = allocate_saved_bf_node(); \ - \ - tmp_bf_ptr->symnum_bf = (bf_sym); \ - tmp_bf_ptr->symnum_fcn = (fcn_sym); \ - tmp_bf_ptr->next = NULL; \ - \ - current_head_bf_list = saved_bf_list = tmp_bf_ptr; \ - saved_bf_list_end = tmp_bf_ptr; \ - } \ -else \ -{ \ - tmp_bf_ptr = allocate_saved_bf_node(); \ - \ - tmp_bf_ptr->symnum_bf = (bf_sym); \ - tmp_bf_ptr->symnum_fcn = (fcn_sym); \ - tmp_bf_ptr->next = NULL; \ - \ - saved_bf_list_end->next = tmp_bf_ptr; \ - saved_bf_list_end = tmp_bf_ptr; \ - } -#endif - -/* This function frees the entire (.bf,function) list. */ - -#if 0 -static void -clear_bf_list (void) -{ + builtin_f_type->builtin_logical_s2 + = arch_boolean_type (gdbarch, gdbarch_short_bit (gdbarch), 1, + "logical*2"); - SAVED_BF_PTR tmp = saved_bf_list; - SAVED_BF_PTR next = NULL; + builtin_f_type->builtin_logical_s8 + = arch_boolean_type (gdbarch, gdbarch_long_long_bit (gdbarch), 1, + "logical*8"); - while (tmp != NULL) - { - next = tmp->next; - xfree (tmp); - tmp = next; - } - saved_bf_list = NULL; -} -#endif + builtin_f_type->builtin_integer + = arch_integer_type (gdbarch, gdbarch_int_bit (gdbarch), 0, + "integer"); -int global_remote_debug; + builtin_f_type->builtin_logical + = arch_boolean_type (gdbarch, gdbarch_int_bit (gdbarch), 1, + "logical*4"); -#if 0 + builtin_f_type->builtin_real + = arch_float_type (gdbarch, gdbarch_float_bit (gdbarch), + "real", gdbarch_float_format (gdbarch)); + builtin_f_type->builtin_real_s8 + = arch_float_type (gdbarch, gdbarch_double_bit (gdbarch), + "real*8", gdbarch_double_format (gdbarch)); + auto fmt = gdbarch_floatformat_for_type (gdbarch, "real(kind=16)", 128); + if (fmt != nullptr) + builtin_f_type->builtin_real_s16 + = arch_float_type (gdbarch, 128, "real*16", fmt); + else if (gdbarch_long_double_bit (gdbarch) == 128) + builtin_f_type->builtin_real_s16 + = arch_float_type (gdbarch, gdbarch_long_double_bit (gdbarch), + "real*16", gdbarch_long_double_format (gdbarch)); + else + builtin_f_type->builtin_real_s16 + = arch_type (gdbarch, TYPE_CODE_ERROR, 128, "real*16"); -static long -get_bf_for_fcn (long the_function) -{ - SAVED_BF_PTR tmp; - int nprobes = 0; + builtin_f_type->builtin_complex_s8 + = init_complex_type ("complex*8", builtin_f_type->builtin_real); + builtin_f_type->builtin_complex_s16 + = init_complex_type ("complex*16", builtin_f_type->builtin_real_s8); - /* First use a simple queuing algorithm (i.e. look and see if the - item at the head of the queue is the one you want). */ + if (builtin_f_type->builtin_real_s16->code () == TYPE_CODE_ERROR) + builtin_f_type->builtin_complex_s32 + = arch_type (gdbarch, TYPE_CODE_ERROR, 256, "complex*32"); + else + builtin_f_type->builtin_complex_s32 + = init_complex_type ("complex*32", builtin_f_type->builtin_real_s16); - if (saved_bf_list == NULL) - internal_error (__FILE__, __LINE__, - _("cannot get .bf node off empty list")); + return builtin_f_type; +} - if (current_head_bf_list != NULL) - if (current_head_bf_list->symnum_fcn == the_function) - { - if (global_remote_debug) - fprintf_unfiltered (gdb_stderr, "*"); +static struct gdbarch_data *f_type_data; - tmp = current_head_bf_list; - current_head_bf_list = current_head_bf_list->next; - return (tmp->symnum_bf); - } +const struct builtin_f_type * +builtin_f_type (struct gdbarch *gdbarch) +{ + return (const struct builtin_f_type *) gdbarch_data (gdbarch, f_type_data); +} - /* If the above did not work (probably because #line directives were - used in the sourcefile and they messed up our internal tables) we now do - the ugly linear scan. */ +void _initialize_f_language (); +void +_initialize_f_language () +{ + f_type_data = gdbarch_data_register_post_init (build_fortran_types); +} - if (global_remote_debug) - fprintf_unfiltered (gdb_stderr, "\ndefaulting to linear scan\n"); +/* See f-lang.h. */ - nprobes = 0; - tmp = saved_bf_list; - while (tmp != NULL) +struct value * +fortran_argument_convert (struct value *value, bool is_artificial) +{ + if (!is_artificial) { - nprobes++; - if (tmp->symnum_fcn == the_function) + /* If the value is not in the inferior e.g. registers values, + convenience variables and user input. */ + if (VALUE_LVAL (value) != lval_memory) { - if (global_remote_debug) - fprintf_unfiltered (gdb_stderr, "Found in %d probes\n", nprobes); - current_head_bf_list = tmp->next; - return (tmp->symnum_bf); + struct type *type = value_type (value); + const int length = TYPE_LENGTH (type); + const CORE_ADDR addr + = value_as_long (value_allocate_space_in_inferior (length)); + write_memory (addr, value_contents (value), length); + struct value *val + = value_from_contents_and_address (type, value_contents (value), + addr); + return value_addr (val); } - tmp = tmp->next; + else + return value_addr (value); /* Program variables, e.g. arrays. */ } - - return (-1); + return value; } -static SAVED_FUNCTION_PTR saved_function_list = NULL; -static SAVED_FUNCTION_PTR saved_function_list_end = NULL; +/* See f-lang.h. */ -static void -clear_function_list (void) +struct type * +fortran_preserve_arg_pointer (struct value *arg, struct type *type) { - SAVED_FUNCTION_PTR tmp = saved_function_list; - SAVED_FUNCTION_PTR next = NULL; - - while (tmp != NULL) - { - next = tmp->next; - xfree (tmp); - tmp = next; - } - - saved_function_list = NULL; + if (value_type (arg)->code () == TYPE_CODE_PTR) + return value_type (arg); + return type; } -#endif