X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ff-typeprint.c;h=65ec93af9f419c03674bc6aa6e9bf4057934d656;hb=3dcc261cf8dfbf60075cc4617cec0b1aaab8896f;hp=7dbe093a7fcafd12353189207f1ded02f20989ff;hpb=2123df0ebfc7ade46784ef412226490d59f8ce05;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index 7dbe093a7f..65ec93af9f 100644 --- a/gdb/f-typeprint.c +++ b/gdb/f-typeprint.c @@ -1,6 +1,6 @@ /* Support for printing Fortran types for GDB, the GNU debugger. - Copyright (C) 1986-2017 Free Software Foundation, Inc. + Copyright (C) 1986-2020 Free Software Foundation, Inc. Contributed by Motorola. Adapted from the C version by Farooq Butt (fmbutt@engage.sps.mot.com). @@ -31,13 +31,14 @@ #include "target.h" #include "f-lang.h" #include "typeprint.h" +#include "cli/cli-style.h" #if 0 /* Currently unused. */ static void f_type_print_args (struct type *, struct ui_file *); #endif static void f_type_print_varspec_suffix (struct type *, struct ui_file *, int, - int, int, int); + int, int, int, bool); void f_type_print_varspec_prefix (struct type *, struct ui_file *, int, int); @@ -45,6 +46,16 @@ void f_type_print_varspec_prefix (struct type *, struct ui_file *, void f_type_print_base (struct type *, struct ui_file *, int, int); +/* See documentation in f-lang.h. */ + +void +f_print_typedef (struct type *type, struct symbol *new_symbol, + struct ui_file *stream) +{ + type = check_typedef (type); + f_print_type (type, "", stream, 0, 0, &type_print_raw_options); +} + /* LEVEL is the depth to indent lines by. */ void @@ -53,28 +64,23 @@ f_print_type (struct type *type, const char *varstring, struct ui_file *stream, { enum type_code code; - if (type_not_associated (type)) - { - val_print_not_associated (stream); - return; - } - - if (type_not_allocated (type)) - { - val_print_not_allocated (stream); - return; - } - f_type_print_base (type, stream, show, level); - code = TYPE_CODE (type); + code = type->code (); if ((varstring != NULL && *varstring != '\0') - /* Need a space if going to print stars or brackets; - but not if we will print just a type name. */ - || ((show > 0 || TYPE_NAME (type) == 0) - && (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC + /* Need a space if going to print stars or brackets; but not if we + will print just a type name. */ + || ((show > 0 + || type->name () == 0) + && (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD || code == TYPE_CODE_ARRAY - || code == TYPE_CODE_REF))) + || ((code == TYPE_CODE_PTR + || code == TYPE_CODE_REF) + && (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_FUNC + || (TYPE_TARGET_TYPE (type)->code () + == TYPE_CODE_METHOD) + || (TYPE_TARGET_TYPE (type)->code () + == TYPE_CODE_ARRAY)))))) fputs_filtered (" ", stream); f_type_print_varspec_prefix (type, stream, show, 0); @@ -89,7 +95,7 @@ f_print_type (struct type *type, const char *varstring, struct ui_file *stream, demangled_args = (*varstring != '\0' && varstring[strlen (varstring) - 1] == ')'); - f_type_print_varspec_suffix (type, stream, show, 0, demangled_args, 0); + f_type_print_varspec_suffix (type, stream, show, 0, demangled_args, 0, false); } } @@ -108,12 +114,12 @@ f_type_print_varspec_prefix (struct type *type, struct ui_file *stream, if (type == 0) return; - if (TYPE_NAME (type) && show <= 0) + if (type->name () && show <= 0) return; QUIT; - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_PTR: f_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); @@ -154,27 +160,30 @@ f_type_print_varspec_prefix (struct type *type, struct ui_file *stream, /* Print any array sizes, function arguments or close parentheses needed after the variable name (to describe its type). - Args work like c_type_print_varspec_prefix. */ + Args work like c_type_print_varspec_prefix. + + PRINT_RANK_ONLY is true when TYPE is an array which should be printed + without the upper and lower bounds being specified, this will occur + when the array is not allocated or not associated and so there are no + known upper or lower bounds. */ static void f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr, int demangled_args, - int arrayprint_recurse_level) + int arrayprint_recurse_level, bool print_rank_only) { - int upper_bound, lower_bound; - /* No static variables are permitted as an error call may occur during execution of this function. */ if (type == 0) return; - if (TYPE_NAME (type) && show <= 0) + if (type->name () && show <= 0) return; QUIT; - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_ARRAY: arrayprint_recurse_level++; @@ -183,34 +192,52 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, fprintf_filtered (stream, "("); if (type_not_associated (type)) - val_print_not_associated (stream); + print_rank_only = true; else if (type_not_allocated (type)) - val_print_not_allocated (stream); + print_rank_only = true; + else if ((TYPE_ASSOCIATED_PROP (type) + && PROP_CONST != TYPE_DYN_PROP_KIND (TYPE_ASSOCIATED_PROP (type))) + || (TYPE_ALLOCATED_PROP (type) + && PROP_CONST != TYPE_DYN_PROP_KIND (TYPE_ALLOCATED_PROP (type))) + || (TYPE_DATA_LOCATION (type) + && PROP_CONST != TYPE_DYN_PROP_KIND (TYPE_DATA_LOCATION (type)))) + { + /* This case exist when we ptype a typename which has the dynamic + properties but cannot be resolved as there is no object. */ + print_rank_only = true; + } + + if (TYPE_TARGET_TYPE (type)->code () == TYPE_CODE_ARRAY) + f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, + 0, 0, arrayprint_recurse_level, + print_rank_only); + + if (print_rank_only) + fprintf_filtered (stream, ":"); else - { - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY) - f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - 0, 0, arrayprint_recurse_level); - - lower_bound = f77_get_lowerbound (type); - if (lower_bound != 1) /* Not the default. */ - fprintf_filtered (stream, "%d:", lower_bound); - - /* Make sure that, if we have an assumed size array, we - print out a warning and print the upperbound as '*'. */ - - if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) - fprintf_filtered (stream, "*"); - else - { - upper_bound = f77_get_upperbound (type); - fprintf_filtered (stream, "%d", upper_bound); - } - - if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_ARRAY) - f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - 0, 0, arrayprint_recurse_level); - } + { + LONGEST lower_bound = f77_get_lowerbound (type); + if (lower_bound != 1) /* Not the default. */ + fprintf_filtered (stream, "%s:", plongest (lower_bound)); + + /* Make sure that, if we have an assumed size array, we + print out a warning and print the upperbound as '*'. */ + + if (type->bounds ()->high.kind () == PROP_UNDEFINED) + fprintf_filtered (stream, "*"); + else + { + LONGEST upper_bound = f77_get_upperbound (type); + + fputs_filtered (plongest (upper_bound), stream); + } + } + + if (TYPE_TARGET_TYPE (type)->code () != TYPE_CODE_ARRAY) + f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, + 0, 0, arrayprint_recurse_level, + print_rank_only); + if (arrayprint_recurse_level == 1) fprintf_filtered (stream, ")"); else @@ -221,17 +248,35 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, case TYPE_CODE_PTR: case TYPE_CODE_REF: f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0, - arrayprint_recurse_level); - fprintf_filtered (stream, ")"); + arrayprint_recurse_level, false); + fprintf_filtered (stream, " )"); break; case TYPE_CODE_FUNC: - f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - passed_a_ptr, 0, arrayprint_recurse_level); - if (passed_a_ptr) + { + int i, nfields = type->num_fields (); + + f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, + passed_a_ptr, 0, + arrayprint_recurse_level, false); + if (passed_a_ptr) + fprintf_filtered (stream, ") "); + fprintf_filtered (stream, "("); + if (nfields == 0 && TYPE_PROTOTYPED (type)) + f_print_type (builtin_f_type (get_type_arch (type))->builtin_void, + "", stream, -1, 0, 0); + else + for (i = 0; i < nfields; i++) + { + if (i > 0) + { + fputs_filtered (", ", stream); + wrap_here (" "); + } + f_print_type (type->field (i).type (), "", stream, -1, 0, 0); + } fprintf_filtered (stream, ")"); - - fprintf_filtered (stream, "()"); + } break; case TYPE_CODE_UNDEF: @@ -273,7 +318,6 @@ void f_type_print_base (struct type *type, struct ui_file *stream, int show, int level) { - int upper_bound; int index; QUIT; @@ -281,45 +325,59 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show, wrap_here (" "); if (type == NULL) { - fputs_filtered ("", stream); + fputs_styled ("", metadata_style.style (), stream); return; } /* When SHOW is zero or less, and there is a valid type name, then always just print the type name directly from the type. */ - if ((show <= 0) && (TYPE_NAME (type) != NULL)) + if ((show <= 0) && (type->name () != NULL)) { - fprintfi_filtered (level, stream, "%s", TYPE_NAME (type)); + const char *prefix = ""; + if (type->code () == TYPE_CODE_UNION) + prefix = "Type, C_Union :: "; + else if (type->code () == TYPE_CODE_STRUCT) + prefix = "Type "; + fprintfi_filtered (level, stream, "%s%s", prefix, type->name ()); return; } - if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF) + if (type->code () != TYPE_CODE_TYPEDEF) type = check_typedef (type); - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_TYPEDEF: f_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level); break; case TYPE_CODE_ARRAY: - case TYPE_CODE_FUNC: f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); break; + case TYPE_CODE_FUNC: + if (TYPE_TARGET_TYPE (type) == NULL) + type_print_unknown_return_type (stream); + else + f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); + break; case TYPE_CODE_PTR: - fprintf_filtered (stream, "PTR TO -> ( "); - f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); + fprintfi_filtered (level, stream, "PTR TO -> ( "); + f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0); break; case TYPE_CODE_REF: - fprintf_filtered (stream, "REF TO -> ( "); - f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); + fprintfi_filtered (level, stream, "REF TO -> ( "); + f_type_print_base (TYPE_TARGET_TYPE (type), stream, show, 0); break; case TYPE_CODE_VOID: - fprintfi_filtered (level, stream, "VOID"); + { + gdbarch *gdbarch = get_type_arch (type); + struct type *void_type = builtin_f_type (gdbarch)->builtin_void; + fprintfi_filtered (level, stream, "%s", void_type->name ()); + } break; case TYPE_CODE_UNDEF: @@ -341,53 +399,59 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show, through as TYPE_CODE_INT since dbxstclass.h is so C-oriented, we must change these to "character" from "char". */ - if (strcmp (TYPE_NAME (type), "char") == 0) + if (strcmp (type->name (), "char") == 0) fprintfi_filtered (level, stream, "character"); else goto default_case; break; case TYPE_CODE_STRING: - /* Strings may have dynamic upperbounds (lengths) like arrays. */ + /* Strings may have dynamic upperbounds (lengths) like arrays. We + check specifically for the PROP_CONST case to indicate that the + dynamic type has been resolved. If we arrive here having been + asked to print the type of a value with a dynamic type then the + bounds will not have been resolved. */ - if (TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) - fprintfi_filtered (level, stream, "character*(*)"); - else + if (type->bounds ()->high.kind () == PROP_CONST) { - upper_bound = f77_get_upperbound (type); - fprintf_filtered (stream, "character*%d", upper_bound); + LONGEST upper_bound = f77_get_upperbound (type); + + fprintf_filtered (stream, "character*%s", pulongest (upper_bound)); } + else + fprintfi_filtered (level, stream, "character*(*)"); break; case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - if (TYPE_CODE (type) == TYPE_CODE_UNION) + if (type->code () == TYPE_CODE_UNION) fprintfi_filtered (level, stream, "Type, C_Union :: "); else fprintfi_filtered (level, stream, "Type "); - fputs_filtered (TYPE_TAG_NAME (type), stream); + fputs_filtered (type->name (), stream); /* According to the definition, we only print structure elements in case show > 0. */ if (show > 0) { fputs_filtered ("\n", stream); - for (index = 0; index < TYPE_NFIELDS (type); index++) + for (index = 0; index < type->num_fields (); index++) { - f_type_print_base (TYPE_FIELD_TYPE (type, index), stream, + f_type_print_base (type->field (index).type (), stream, show - 1, level + 4); fputs_filtered (" :: ", stream); - fputs_filtered (TYPE_FIELD_NAME (type, index), stream); - f_type_print_varspec_suffix (TYPE_FIELD_TYPE (type, index), - stream, show - 1, 0, 0, 0); + fputs_styled (TYPE_FIELD_NAME (type, index), + variable_name_style.style (), stream); + f_type_print_varspec_suffix (type->field (index).type (), + stream, show - 1, 0, 0, 0, false); fputs_filtered ("\n", stream); } fprintfi_filtered (level, stream, "End Type "); - fputs_filtered (TYPE_TAG_NAME (type), stream); + fputs_filtered (type->name (), stream); } break; case TYPE_CODE_MODULE: - fprintfi_filtered (level, stream, "module %s", TYPE_TAG_NAME (type)); + fprintfi_filtered (level, stream, "module %s", type->name ()); break; default_case: @@ -396,10 +460,13 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show, such as fundamental types. For these, just print whatever the type name is, as recorded in the type itself. If there is no type name, then complain. */ - if (TYPE_NAME (type) != NULL) - fprintfi_filtered (level, stream, "%s", TYPE_NAME (type)); + if (type->name () != NULL) + fprintfi_filtered (level, stream, "%s", type->name ()); else - error (_("Invalid type code (%d) in symbol table."), TYPE_CODE (type)); + error (_("Invalid type code (%d) in symbol table."), type->code ()); break; } + + if (TYPE_IS_ALLOCATABLE (type)) + fprintf_filtered (stream, ", allocatable"); }