diff mbox

PR debug/16063. Add DW_AT_type to DW_TAG_enumeration.

Message ID 1395573501-21296-1-git-send-email-mjw@redhat.com
State New
Headers show

Commit Message

Mark Wielaard March 23, 2014, 11:18 a.m. UTC
Add a new lang-hook that provides the underlying base type of an
ENUMERAL_TYPE. Including implementations for C and C++. Use this
enum_underlying_base_type lang-hook in dwarf2out.c to add a DW_AT_type
base type reference to a DW_TAG_enumeration.

gcc/
	* dwarf2out.c (gen_enumeration_type_die): Add DW_AT_type if
	enum_underlying_base_type defined and DWARF version > 3.
	* langhooks.h (struct lang_hooks_for_types): Add
	enum_underlying_base_type.
	* langhooks-def.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): New define.
	(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add new lang hook.

gcc/c-family/
	* c-common.c (c_enum_underlying_base_type): New function.
	* c-common.h (c_enum_underlying_base_type): Add declaration.

gcc/c/
	* c-objc-common.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): Define.

gcc/cp/
	* dwarf2out.c (gen_enumeration_type_die): Add DW_AT_type if
	enum_underlying_base_type defined and DWARF version > 3.
	* langhooks.h (struct lang_hooks_for_types): Add
	enum_underlying_base_type.
	* langhooks-def.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): New define.
	(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add new lang hook.
---
 gcc/ChangeLog           |   10 ++++++++++
 gcc/c-family/ChangeLog  |    6 ++++++
 gcc/c-family/c-common.c |    8 ++++++++
 gcc/c-family/c-common.h |    1 +
 gcc/c/ChangeLog         |    5 +++++
 gcc/c/c-objc-common.h   |    2 ++
 gcc/cp/ChangeLog        |    6 ++++++
 gcc/cp/cp-lang.c        |   18 ++++++++++++++++++
 gcc/dwarf2out.c         |    7 +++++++
 gcc/langhooks-def.h     |    4 +++-
 gcc/langhooks.h         |    2 ++
 11 files changed, 68 insertions(+), 1 deletions(-)

Comments

Richard Biener March 24, 2014, 9:26 a.m. UTC | #1
On Sun, Mar 23, 2014 at 12:18 PM, Mark Wielaard <mjw@redhat.com> wrote:
> Add a new lang-hook that provides the underlying base type of an
> ENUMERAL_TYPE. Including implementations for C and C++. Use this
> enum_underlying_base_type lang-hook in dwarf2out.c to add a DW_AT_type
> base type reference to a DW_TAG_enumeration.

Don't we have TREE_TYPE (enum-type) as that type?  Thus, can we avoid
adding the new langhook?

Thanks,
Richard.

> gcc/
>         * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_type if
>         enum_underlying_base_type defined and DWARF version > 3.
>         * langhooks.h (struct lang_hooks_for_types): Add
>         enum_underlying_base_type.
>         * langhooks-def.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): New define.
>         (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add new lang hook.
>
> gcc/c-family/
>         * c-common.c (c_enum_underlying_base_type): New function.
>         * c-common.h (c_enum_underlying_base_type): Add declaration.
>
> gcc/c/
>         * c-objc-common.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): Define.
>
> gcc/cp/
>         * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_type if
>         enum_underlying_base_type defined and DWARF version > 3.
>         * langhooks.h (struct lang_hooks_for_types): Add
>         enum_underlying_base_type.
>         * langhooks-def.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): New define.
>         (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add new lang hook.
> ---
>  gcc/ChangeLog           |   10 ++++++++++
>  gcc/c-family/ChangeLog  |    6 ++++++
>  gcc/c-family/c-common.c |    8 ++++++++
>  gcc/c-family/c-common.h |    1 +
>  gcc/c/ChangeLog         |    5 +++++
>  gcc/c/c-objc-common.h   |    2 ++
>  gcc/cp/ChangeLog        |    6 ++++++
>  gcc/cp/cp-lang.c        |   18 ++++++++++++++++++
>  gcc/dwarf2out.c         |    7 +++++++
>  gcc/langhooks-def.h     |    4 +++-
>  gcc/langhooks.h         |    2 ++
>  11 files changed, 68 insertions(+), 1 deletions(-)
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index f3b4f2d..e90ea6e 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,5 +1,15 @@
>  2014-03-21  Mark Wielaard  <mjw@redhat.com>
>
> +       PR debug/16063
> +       * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_type if
> +       enum_underlying_base_type defined and DWARF version > 3.
> +       * langhooks.h (struct lang_hooks_for_types): Add
> +       enum_underlying_base_type.
> +       * langhooks-def.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): New define.
> +       (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add new lang hook.
> +
> +2014-03-21  Mark Wielaard  <mjw@redhat.com>
> +
>         * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_const_value
>         as unsigned or int depending on type and value used.
>
> diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
> index 4e5aea4..90b688b 100644
> --- a/gcc/c-family/ChangeLog
> +++ b/gcc/c-family/ChangeLog
> @@ -1,3 +1,9 @@
> +2014-03-21  Mark Wielaard  <mjw@redhat.com>
> +
> +       PR debug/16063
> +       * c-common.c (c_enum_underlying_base_type): New function.
> +       * c-common.h (c_enum_underlying_base_type): Add declaration.
> +
>  2014-03-13  Jakub Jelinek  <jakub@redhat.com>
>
>         PR middle-end/36282
> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> index abd96fb..55ebbcc 100644
> --- a/gcc/c-family/c-common.c
> +++ b/gcc/c-family/c-common.c
> @@ -3902,6 +3902,14 @@ c_register_builtin_type (tree type, const char* name)
>
>    registered_builtin_types = tree_cons (0, type, registered_builtin_types);
>  }
> +
> +/* The C version of the enum_underlying_base_type langhook.  */
> +tree
> +c_enum_underlying_base_type (const_tree type)
> +{
> +  return c_common_type_for_size (TYPE_PRECISION (type), TYPE_UNSIGNED (type));
> +}
> +
>
>  /* Print an error message for invalid operands to arith operation
>     CODE with TYPE0 for operand 0, and TYPE1 for operand 1.
> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
> index 1099b10..e378b44 100644
> --- a/gcc/c-family/c-common.h
> +++ b/gcc/c-family/c-common.h
> @@ -832,6 +832,7 @@ extern void c_common_finish (void);
>  extern void c_common_parse_file (void);
>  extern alias_set_type c_common_get_alias_set (tree);
>  extern void c_register_builtin_type (tree, const char*);
> +extern tree c_enum_underlying_base_type (const_tree);
>  extern bool c_promoting_integer_type_p (const_tree);
>  extern int self_promoting_args_p (const_tree);
>  extern tree strip_pointer_operator (tree);
> diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
> index b39b7d6..9ab6eab 100644
> --- a/gcc/c/ChangeLog
> +++ b/gcc/c/ChangeLog
> @@ -1,3 +1,8 @@
> +2014-03-21  Mark Wielaard  <mjw@redhat.com>
> +
> +       PR debug/16063
> +       * c-objc-common.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): Define.
> +
>  2014-03-18  Manuel López-Ibáñez  <manu@gcc.gnu.org>
>
>         PR c/55383
> diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
> index 92cf60f..0651db7 100644
> --- a/gcc/c/c-objc-common.h
> +++ b/gcc/c/c-objc-common.h
> @@ -84,6 +84,8 @@ along with GCC; see the file COPYING3.  If not see
>  #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
>  #undef LANG_HOOKS_EXPR_TO_DECL
>  #define LANG_HOOKS_EXPR_TO_DECL c_expr_to_decl
> +#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
> +#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE c_enum_underlying_base_type
>
>  /* The C front end's scoping structure is very different from
>     that expected by the language-independent code; it is best
> diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
> index 3cf6858..8e6508e 100644
> --- a/gcc/cp/ChangeLog
> +++ b/gcc/cp/ChangeLog
> @@ -1,3 +1,9 @@
> +2014-03-21  Mark Wielaard  <mjw@redhat.com>
> +
> +       PR debug/16063
> +       * cp-lang.c (cxx_enum_underlying_base_type): New function.
> +       (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): Define.
> +
>  2014-03-17  Adam Butcher  <adam@jessamine.co.uk>
>
>         PR c++/60390
> diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
> index c28c07a..6a40d29 100644
> --- a/gcc/cp/cp-lang.c
> +++ b/gcc/cp/cp-lang.c
> @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "coretypes.h"
>  #include "tm.h"
>  #include "tree.h"
> +#include "stor-layout.h"
>  #include "cp-tree.h"
>  #include "c-family/c-common.h"
>  #include "langhooks.h"
> @@ -40,6 +41,7 @@ static enum classify_record cp_classify_record (tree type);
>  static tree cp_eh_personality (void);
>  static tree get_template_innermost_arguments_folded (const_tree);
>  static tree get_template_argument_pack_elems_folded (const_tree);
> +static tree cxx_enum_underlying_base_type (const_tree);
>
>  /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
>     consequently, there should be very few hooks below.  */
> @@ -81,6 +83,8 @@ static tree get_template_argument_pack_elems_folded (const_tree);
>  #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
>  #undef LANG_HOOKS_EH_RUNTIME_TYPE
>  #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
> +#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
> +#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE cxx_enum_underlying_base_type
>
>  /* Each front end provides its own lang hook initializer.  */
>  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
> @@ -219,5 +223,19 @@ get_template_argument_pack_elems_folded (const_tree t)
>    return fold_cplus_constants (get_template_argument_pack_elems (t));
>  }
>
> +/* The C++ version of the enum_underlying_base_type langhook.
> +   See also cp/semantics.c (finish_underlying_type).  */
> +static tree cxx_enum_underlying_base_type (const_tree type)
> +{
> +  tree underlying_type = ENUM_UNDERLYING_TYPE (type);
> +
> +  if (! ENUM_FIXED_UNDERLYING_TYPE_P (type))
> +    underlying_type
> +      = c_common_type_for_mode (TYPE_MODE (underlying_type),
> +                                TYPE_UNSIGNED (underlying_type));
> +
> +  return underlying_type;
> +}
> +
>  #include "gt-cp-cp-lang.h"
>  #include "gtype-cp.h"
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index af97408..554f787 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -17339,6 +17339,13 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die)
>
>        TREE_ASM_WRITTEN (type) = 1;
>        add_byte_size_attribute (type_die, type);
> +      if (lang_hooks.types.enum_underlying_base_type != NULL
> +         && (dwarf_version >= 3 || !dwarf_strict))
> +       {
> +         tree underlying = lang_hooks.types.enum_underlying_base_type (type);
> +         dw_die_ref underlying_die = base_type_die (underlying);
> +         add_AT_die_ref (type_die, DW_AT_type, underlying_die);
> +       }
>        if (TYPE_STUB_DECL (type) != NULL_TREE)
>         {
>           add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
> diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
> index 95bd379..b8e0d97 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_GET_SUBRANGE_BOUNDS NULL
>  #define LANG_HOOKS_DESCRIPTIVE_TYPE    NULL
>  #define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type
> +#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE NULL
>
>  #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
>    LANG_HOOKS_MAKE_TYPE, \
> @@ -191,7 +192,8 @@ extern tree lhd_make_node (enum tree_code);
>    LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
>    LANG_HOOKS_GET_SUBRANGE_BOUNDS, \
>    LANG_HOOKS_DESCRIPTIVE_TYPE, \
> -  LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE \
> +  LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \
> +  LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE \
>  }
>
>  /* Declaration hooks.  */
> diff --git a/gcc/langhooks.h b/gcc/langhooks.h
> index c848b0c..667298b 100644
> --- a/gcc/langhooks.h
> +++ b/gcc/langhooks.h
> @@ -137,6 +137,8 @@ struct lang_hooks_for_types
>       return values from functions.  The argument TYPE is the top of the
>       chain, and BOTTOM is the new type which we will point to.  */
>    tree (*reconstruct_complex_type) (tree, tree);
> +
> +  tree (*enum_underlying_base_type) (const_tree);
>  };
>
>  /* Language hooks related to decls and the symbol table.  */
> --
> 1.7.1
>
Mark Wielaard March 24, 2014, 10:46 a.m. UTC | #2
On Mon, 2014-03-24 at 10:26 +0100, Richard Biener wrote:
> On Sun, Mar 23, 2014 at 12:18 PM, Mark Wielaard <mjw@redhat.com> wrote:
> > Add a new lang-hook that provides the underlying base type of an
> > ENUMERAL_TYPE. Including implementations for C and C++. Use this
> > enum_underlying_base_type lang-hook in dwarf2out.c to add a DW_AT_type
> > base type reference to a DW_TAG_enumeration.
> 
> Don't we have TREE_TYPE (enum-type) as that type?  Thus, can we avoid
> adding the new langhook?

The underlying type is the integral base type of the enum, which, at
least for C++, can be different from the tree type of the enum. See also
cp/semantics.c (finish_underlying_type) which calculates it in the C++
case.

Cheers,

Mark
Cary Coutant March 24, 2014, 4:57 p.m. UTC | #3
> gcc/cp/
>         * dwarf2out.c (gen_enumeration_type_die): Add DW_AT_type if
>         enum_underlying_base_type defined and DWARF version > 3.
>         * langhooks.h (struct lang_hooks_for_types): Add
>         enum_underlying_base_type.
>         * langhooks-def.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): New define.
>         (LANG_HOOKS_FOR_TYPES_INITIALIZER): Add new lang hook.

This should be the ChangeLog entry for cp/cp-lang.c.

-cary
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f3b4f2d..e90ea6e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@ 
 2014-03-21  Mark Wielaard  <mjw@redhat.com>
 
+	PR debug/16063
+	* dwarf2out.c (gen_enumeration_type_die): Add DW_AT_type if
+	enum_underlying_base_type defined and DWARF version > 3.
+	* langhooks.h (struct lang_hooks_for_types): Add
+	enum_underlying_base_type.
+	* langhooks-def.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): New define.
+	(LANG_HOOKS_FOR_TYPES_INITIALIZER): Add new lang hook.
+
+2014-03-21  Mark Wielaard  <mjw@redhat.com>
+
 	* dwarf2out.c (gen_enumeration_type_die): Add DW_AT_const_value
 	as unsigned or int depending on type and value used.
 
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 4e5aea4..90b688b 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@ 
+2014-03-21  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/16063
+	* c-common.c (c_enum_underlying_base_type): New function.
+	* c-common.h (c_enum_underlying_base_type): Add declaration.
+
 2014-03-13  Jakub Jelinek  <jakub@redhat.com>
 
 	PR middle-end/36282
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index abd96fb..55ebbcc 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -3902,6 +3902,14 @@  c_register_builtin_type (tree type, const char* name)
 
   registered_builtin_types = tree_cons (0, type, registered_builtin_types);
 }
+
+/* The C version of the enum_underlying_base_type langhook.  */
+tree
+c_enum_underlying_base_type (const_tree type)
+{
+  return c_common_type_for_size (TYPE_PRECISION (type), TYPE_UNSIGNED (type));
+}
+
 
 /* Print an error message for invalid operands to arith operation
    CODE with TYPE0 for operand 0, and TYPE1 for operand 1.
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 1099b10..e378b44 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -832,6 +832,7 @@  extern void c_common_finish (void);
 extern void c_common_parse_file (void);
 extern alias_set_type c_common_get_alias_set (tree);
 extern void c_register_builtin_type (tree, const char*);
+extern tree c_enum_underlying_base_type (const_tree);
 extern bool c_promoting_integer_type_p (const_tree);
 extern int self_promoting_args_p (const_tree);
 extern tree strip_pointer_operator (tree);
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index b39b7d6..9ab6eab 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,8 @@ 
+2014-03-21  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/16063
+	* c-objc-common.h (LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): Define.
+
 2014-03-18  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
 	PR c/55383
diff --git a/gcc/c/c-objc-common.h b/gcc/c/c-objc-common.h
index 92cf60f..0651db7 100644
--- a/gcc/c/c-objc-common.h
+++ b/gcc/c/c-objc-common.h
@@ -84,6 +84,8 @@  along with GCC; see the file COPYING3.  If not see
 #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
 #undef LANG_HOOKS_EXPR_TO_DECL
 #define LANG_HOOKS_EXPR_TO_DECL c_expr_to_decl
+#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
+#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE c_enum_underlying_base_type
 
 /* The C front end's scoping structure is very different from
    that expected by the language-independent code; it is best
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3cf6858..8e6508e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@ 
+2014-03-21  Mark Wielaard  <mjw@redhat.com>
+
+	PR debug/16063
+	* cp-lang.c (cxx_enum_underlying_base_type): New function.
+	(LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE): Define.
+
 2014-03-17  Adam Butcher  <adam@jessamine.co.uk>
 
 	PR c++/60390
diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
index c28c07a..6a40d29 100644
--- a/gcc/cp/cp-lang.c
+++ b/gcc/cp/cp-lang.c
@@ -23,6 +23,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
+#include "stor-layout.h"
 #include "cp-tree.h"
 #include "c-family/c-common.h"
 #include "langhooks.h"
@@ -40,6 +41,7 @@  static enum classify_record cp_classify_record (tree type);
 static tree cp_eh_personality (void);
 static tree get_template_innermost_arguments_folded (const_tree);
 static tree get_template_argument_pack_elems_folded (const_tree);
+static tree cxx_enum_underlying_base_type (const_tree);
 
 /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
    consequently, there should be very few hooks below.  */
@@ -81,6 +83,8 @@  static tree get_template_argument_pack_elems_folded (const_tree);
 #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
 #undef LANG_HOOKS_EH_RUNTIME_TYPE
 #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
+#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
+#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE cxx_enum_underlying_base_type
 
 /* Each front end provides its own lang hook initializer.  */
 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -219,5 +223,19 @@  get_template_argument_pack_elems_folded (const_tree t)
   return fold_cplus_constants (get_template_argument_pack_elems (t));
 }
 
+/* The C++ version of the enum_underlying_base_type langhook.
+   See also cp/semantics.c (finish_underlying_type).  */
+static tree cxx_enum_underlying_base_type (const_tree type)
+{
+  tree underlying_type = ENUM_UNDERLYING_TYPE (type);
+
+  if (! ENUM_FIXED_UNDERLYING_TYPE_P (type))
+    underlying_type
+      = c_common_type_for_mode (TYPE_MODE (underlying_type),
+                                TYPE_UNSIGNED (underlying_type));
+
+  return underlying_type;
+}
+
 #include "gt-cp-cp-lang.h"
 #include "gtype-cp.h"
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index af97408..554f787 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -17339,6 +17339,13 @@  gen_enumeration_type_die (tree type, dw_die_ref context_die)
 
       TREE_ASM_WRITTEN (type) = 1;
       add_byte_size_attribute (type_die, type);
+      if (lang_hooks.types.enum_underlying_base_type != NULL
+	  && (dwarf_version >= 3 || !dwarf_strict))
+	{
+	  tree underlying = lang_hooks.types.enum_underlying_base_type (type);
+	  dw_die_ref underlying_die = base_type_die (underlying);
+	  add_AT_die_ref (type_die, DW_AT_type, underlying_die);
+	}
       if (TYPE_STUB_DECL (type) != NULL_TREE)
 	{
 	  add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index 95bd379..b8e0d97 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_GET_SUBRANGE_BOUNDS	NULL
 #define LANG_HOOKS_DESCRIPTIVE_TYPE	NULL
 #define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type
+#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE NULL
 
 #define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
   LANG_HOOKS_MAKE_TYPE, \
@@ -191,7 +192,8 @@  extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
   LANG_HOOKS_GET_SUBRANGE_BOUNDS, \
   LANG_HOOKS_DESCRIPTIVE_TYPE, \
-  LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE \
+  LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \
+  LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE \
 }
 
 /* Declaration hooks.  */
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index c848b0c..667298b 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -137,6 +137,8 @@  struct lang_hooks_for_types
      return values from functions.  The argument TYPE is the top of the
      chain, and BOTTOM is the new type which we will point to.  */
   tree (*reconstruct_complex_type) (tree, tree);
+
+  tree (*enum_underlying_base_type) (const_tree);
 };
 
 /* Language hooks related to decls and the symbol table.  */