From: Pierre-Marie de Rodat Date: Thu, 17 Dec 2015 14:10:24 +0000 (+0000) Subject: DWARF: add a language hook for scalar biased types X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=69c5f9d7b57c82797154bdc199e69326ac981101;p=gcc.git DWARF: add a language hook for scalar biased types Front-ends like GNAT for Ada sometimes use biased encodings for integral types. This change creates a new language hook so that the bias information can make it into the debugging information back-end and introduces an experimental DWARF attribute to hold it. gcc/ada/ChangeLog: * gcc-interface/misc.c (gnat_get_type_bias): New. (LANG_HOOKS_GET_TYPE_BIAS): Redefine macro to implement the get_type_bias language hook. gcc/ChangeLog: * langhooks.h (struct lang_hooks_for_types): New get_bias_field. * langhooks-def.h (LANG_HOOKS_GET_TYPE_BIAS): New. (LANG_HOOKS_FOR_TYPES_INITIALIZER): Initialize the get_bias_field. * dwarf2out.c (base_type_die): In non-strict DWARF mode, invoke the get_type_bias language hook for INTEGER_TYPE nodes. If it returns a bias, emit an attribute for it. (subrange_type_die): Change signature to handle bias. If non-strict DWARF mode, emit an attribute for it, if one passed. (modified_type_die): For subrange types, invoke the get_type_bias langage hook and pass the bias to subrange_type_die. From-SVN: r231767 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9736786df31..405d8b0e5a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2015-12-17 Pierre-Marie de Rodat + + * langhooks.h (struct lang_hooks_for_types): New get_bias_field. + * langhooks-def.h (LANG_HOOKS_GET_TYPE_BIAS): New. + (LANG_HOOKS_FOR_TYPES_INITIALIZER): Initialize the + get_bias_field. + * dwarf2out.c + (base_type_die): In non-strict DWARF mode, invoke the + get_type_bias language hook for INTEGER_TYPE nodes. If it + returns a bias, emit an attribute for it. + (subrange_type_die): Change signature to handle bias. If + non-strict DWARF mode, emit an attribute for it, if one passed. + (modified_type_die): For subrange types, invoke the + get_type_bias langage hook and pass the bias to + subrange_type_die. + 2015-12-17 Pierre-Marie de Rodat * dwarf2out.h (DWARF2OUT_ARRAY_DESCR_INFO_MAX_DIMEN): New macro. diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index eb1092380bf..80c5a39d803 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,9 @@ +2015-12-17 Pierre-Marie de Rodat + + * gcc-interface/misc.c (gnat_get_type_bias): New. + (LANG_HOOKS_GET_TYPE_BIAS): Redefine macro to implement the + get_type_bias language hook. + 2015-12-17 Pierre-Marie de Rodat * gcc-interface/misc.c (gnat_get_array_descr_info): When the diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 891ca3f338c..269960f917d 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -977,6 +977,16 @@ gnat_get_subrange_bounds (const_tree gnu_type, tree *lowval, tree *highval) *highval = TYPE_MAX_VALUE (gnu_type); } +static tree +gnat_get_type_bias (const_tree gnu_type) +{ + if (TREE_CODE (gnu_type) == INTEGER_TYPE + && TYPE_BIASED_REPRESENTATION_P (gnu_type) + && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL) + return TYPE_RM_MIN_VALUE(gnu_type); + return NULL_TREE; +} + /* GNU_TYPE is the type of a subprogram parameter. Determine if it should be passed by reference by default. */ @@ -1276,6 +1286,8 @@ get_lang_specific (tree node) #define LANG_HOOKS_GET_ARRAY_DESCR_INFO gnat_get_array_descr_info #undef LANG_HOOKS_GET_SUBRANGE_BOUNDS #define LANG_HOOKS_GET_SUBRANGE_BOUNDS gnat_get_subrange_bounds +#undef LANG_HOOKS_GET_TYPE_BIAS +#define LANG_HOOKS_GET_TYPE_BIAS gnat_get_type_bias #undef LANG_HOOKS_DESCRIPTIVE_TYPE #define LANG_HOOKS_DESCRIPTIVE_TYPE gnat_descriptive_type #undef LANG_HOOKS_GET_DEBUG_TYPE diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 98528c7e062..067c4f23892 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3288,7 +3288,7 @@ static void output_line_info (bool); static void output_file_names (void); static dw_die_ref base_type_die (tree); static int is_base_type (tree); -static dw_die_ref subrange_type_die (tree, tree, tree, dw_die_ref); +static dw_die_ref subrange_type_die (tree, tree, tree, tree, dw_die_ref); static int decl_quals (const_tree); static dw_die_ref modified_type_die (tree, int, dw_die_ref); static dw_die_ref generic_parameter_die (tree, tree, bool, dw_die_ref); @@ -10809,6 +10809,7 @@ base_type_die (tree type) enum dwarf_type encoding; bool fpt_used = false; struct fixed_point_type_info fpt_info; + tree type_bias = NULL_TREE; if (TREE_CODE (type) == ERROR_MARK || TREE_CODE (type) == VOID_TYPE) return 0; @@ -10859,6 +10860,10 @@ base_type_die (tree type) encoding = DW_ATE_unsigned; else encoding = DW_ATE_signed; + + if (!dwarf_strict + && lang_hooks.types.get_type_bias) + type_bias = lang_hooks.types.get_type_bias (type); break; case REAL_TYPE: @@ -10943,6 +10948,12 @@ base_type_die (tree type) gcc_unreachable (); } } + if (type_bias != NULL) + add_scalar_info (base_type_result, DW_AT_GNU_bias, type_bias, + dw_scalar_form_constant + | dw_scalar_form_exprloc + | dw_scalar_form_reference, + NULL); add_pubtype (type, base_type_result); return base_type_result; @@ -11044,7 +11055,8 @@ offset_int_type_size_in_bits (const_tree type) to a DIE that describes the given type. */ static dw_die_ref -subrange_type_die (tree type, tree low, tree high, dw_die_ref context_die) +subrange_type_die (tree type, tree low, tree high, tree bias, + dw_die_ref context_die) { dw_die_ref subrange_die; const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type); @@ -11065,6 +11077,12 @@ subrange_type_die (tree type, tree low, tree high, dw_die_ref context_die) add_bound_info (subrange_die, DW_AT_lower_bound, low, NULL); if (high) add_bound_info (subrange_die, DW_AT_upper_bound, high, NULL); + if (bias && !dwarf_strict) + add_scalar_info (subrange_die, DW_AT_GNU_bias, bias, + dw_scalar_form_constant + | dw_scalar_form_exprloc + | dw_scalar_form_reference, + NULL); return subrange_die; } @@ -11279,7 +11297,10 @@ modified_type_die (tree type, int cv_quals, dw_die_ref context_die) && TREE_TYPE (type) != NULL_TREE && subrange_type_for_debug_p (type, &low, &high)) { - mod_type_die = subrange_type_die (type, low, high, context_die); + tree bias = NULL_TREE; + if (lang_hooks.types.get_type_bias) + bias = lang_hooks.types.get_type_bias (type); + mod_type_die = subrange_type_die (type, low, high, bias, context_die); item_type = TREE_TYPE (type); } else if (is_base_type (type)) diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 2d02bf631d0..db96e916bc4 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -173,6 +173,7 @@ extern tree lhd_make_node (enum tree_code); #define LANG_HOOKS_TYPE_HASH_EQ NULL #define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL #define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL +#define LANG_HOOKS_GET_TYPE_BIAS NULL #define LANG_HOOKS_DESCRIPTIVE_TYPE NULL #define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type #define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE lhd_enum_underlying_base_type @@ -195,6 +196,7 @@ extern tree lhd_make_node (enum tree_code); LANG_HOOKS_TYPE_HASH_EQ, \ LANG_HOOKS_GET_ARRAY_DESCR_INFO, \ LANG_HOOKS_GET_SUBRANGE_BOUNDS, \ + LANG_HOOKS_GET_TYPE_BIAS, \ LANG_HOOKS_DESCRIPTIVE_TYPE, \ LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \ LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE, \ diff --git a/gcc/langhooks.h b/gcc/langhooks.h index f84bdf64bf4..95d5840d0a9 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -127,6 +127,11 @@ struct lang_hooks_for_types /* Fill in information for the debugger about the bounds of TYPE. */ void (*get_subrange_bounds) (const_tree, tree *, tree *); + /* Called on INTEGER_TYPEs. Return NULL_TREE for non-biased types. For + biased types, return as an INTEGER_CST node the value that is represented + by a physical zero. */ + tree (*get_type_bias) (const_tree); + /* A type descriptive of TYPE's complex layout generated to help the debugger to decode variable-length or self-referential constructs. This is only used for the AT_GNAT_descriptive_type DWARF attribute. */