From 3c0ac253df32662c894913b8fc633447a0b1861c Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Thu, 8 Jan 2015 11:07:06 +0100 Subject: [PATCH 7/8] 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. include/ChangeLog: * dwarf2.def (DW_AT_GNU_bias): New attribute. 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. --- gcc/ada/gcc-interface/misc.c | 12 ++++++++++++ gcc/dwarf2out.c | 27 ++++++++++++++++++++++++--- gcc/langhooks-def.h | 2 ++ gcc/langhooks.h | 5 +++++ 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index 891ca3f..269960f 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 6d4d60f..251a405 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -3293,7 +3293,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); @@ -10848,6 +10848,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; @@ -10898,6 +10899,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: @@ -10982,6 +10987,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; @@ -11083,7 +11094,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); @@ -11104,6 +11116,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; } @@ -11318,7 +11336,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 2d02bf6..db96e91 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 f84bdf6..95d5840 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. */ -- 2.6.2