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.

--
Pierre-Marie de Rodat
>From 702af856454dd74dc23979e488d311ea008981ee Mon Sep 17 00:00:00 2001
From: Pierre-Marie de Rodat <dero...@adacore.com>
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 +++++
 include/dwarf2.def           |  2 ++
 5 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 4a355a3..47a8b1c 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -969,6 +969,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.  */
 
@@ -1268,6 +1278,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 d989264..c38f40f 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3246,7 +3246,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);
@@ -10755,6 +10755,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;
@@ -10805,6 +10806,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:
@@ -10890,6 +10895,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;
@@ -10991,7 +11002,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);
@@ -11012,6 +11024,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;
 }
@@ -11216,7 +11234,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 64ba41f..9dda629 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.  */
diff --git a/include/dwarf2.def b/include/dwarf2.def
index c5b84f2..dd5c8c1 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -409,6 +409,8 @@ DW_AT (DW_AT_GNAT_descriptive_type, 0x2302)
 /* Rational constant extension, not yet specified.  */
 DW_TAG (DW_AT_GNU_numerator, 0x2303)
 DW_TAG (DW_AT_GNU_denominator, 0x2304)
+/* Biased integer extension, not yet specified.  */
+DW_TAG (DW_AT_GNU_bias, 0x2305)
 /* UPC extension.  */
 DW_AT (DW_AT_upc_threads_scaled, 0x3210)
 /* PGI (STMicroelectronics) extensions.  */
-- 
2.4.5

Reply via email to