This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PING] [PATCH] PR debug/28767 (Support pointer-to-member-function)


On Tue, May 3, 2011 at 10:36 PM, Dodji Seketeli <dodji@seketeli.org> wrote:
> FWIW, this was posted to http://gcc.gnu.org/ml/gcc-patches/2011-03/msg00949.html
>
>
>
> ---------- Forwarded message ----------
> From:?Dodji Seketeli <dodji@redhat.com>
> To:?Jason Merrill <jason@redhat.com>
> Date:?Wed, 16 Mar 2011 20:56:37 +0100
> Subject:?[PATCH] PR debug/28767 (Support pointer-to-member-function)
> Hello,
>
> This PR is an enhancement request to emit a DW_TAG_ptr_to_member_type
> DIE for pointer-to-member-function types.
>
> The patch below does add a new language hook to support this and
> adapts the existing code that emits DW_TAG_ptr_to_member_type for
> ponter-to-data-member types to handle pointer-to-member-function types
> as well.
>
> Tested on x86_64-unknown-linux-gnu against trunk.
>
> I am proposing this for 4.7.
>
> --
> ? ? ? ? ? ? ? ?Dodji
>
> From 36d971de3a01c83f8e23c4016262ea73357f6bd6 Mon Sep 17 00:00:00 2001
> From: Dodji Seketeli <dodji@redhat.com>
> Date: Tue, 15 Mar 2011 16:50:30 +0100
> Subject: [PATCH] PR debug/28767 (Support pointer-to-member-function)
>
> gcc/
> ? ? ? ?* langhooks.h (struct lag_hooks_for_type)<is_ptr_to_member>:
> ? ? ? ?Declare New language hook.
> ? ? ? ?* hooks.h (hook_bool_const_tree_treeptr_false): Declare ...
> ? ? ? ?hooks.c (hook_bool_const_tree_treeptr_false): ... new default
> ? ? ? ?hook.
> ? ? ? ?* langhooks-def.h (LANG_HOOKS_IS_PTR_TO_MEMBER): Define new hook
> ? ? ? ?initializer.

Ick.  Can you please instead grab some available bit in TREE_TYPE instead
of using a new langhook which makes it impossible to support this from LTO?

Richard.

> ? ? ? ?(LANG_HOOKS_FOR_TYPES_INITIALIZER): Initialize the
> ? ? ? ?is_ptr_to_member field to LANG_HOOKS_IS_PTR_TO_MEMBER.
> ? ? ? ?* dwarf2out.c (gen_ptr_to_mbr_type_die): Handle
> ? ? ? ?pointer-to-member-function in addition to pointer-to-data-member.
> ? ? ? ?Both using the new language hook.
> ? ? ? ?(gen_type_die_with_usage): Handle pointer-to-member-function and
> ? ? ? ?pointer-to-data-member types with gen_ptr_to_mbr_type_die.
>
> gcc/cp/
>
> ? ? ? ?* cp-lang.c (is_ptr_to_member): New language hook implementation
> ? ? ? ?for C++.
> ? ? ? ?(LANG_HOOKS_IS_PTR_TO_MEMBER): Initialize this language hook for
> ? ? ? ?C++.
>
> gcc/testsuite/
>
> ? ? ? ?* g++.dg/debug/dwarf2/ptrmem-1.C: New test.
> ---
> ?gcc/cp/cp-lang.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? | ? 39 +++++++++++++++++-
> ?gcc/dwarf2out.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 58 ++++++++++++++++----------
> ?gcc/hooks.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?7 +++
> ?gcc/hooks.h ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?gcc/langhooks-def.h ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?2 +
> ?gcc/langhooks.h ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?8 ++++
> ?gcc/testsuite/g++.dg/debug/dwarf2/ptrmem-1.C | ? 20 +++++++++
> ?7 files changed, 112 insertions(+), 23 deletions(-)
> ?create mode 100644 gcc/testsuite/g++.dg/debug/dwarf2/ptrmem-1.C
>
> diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c
> index e5c1c09..62faa1c 100644
> --- a/gcc/cp/cp-lang.c
> +++ b/gcc/cp/cp-lang.c
> @@ -40,7 +40,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 bool is_ptr_to_member (const_tree, tree*);
> ?/* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
> ? ?consequently, there should be very few hooks below. ?*/
>
> @@ -65,6 +65,9 @@ static tree get_template_argument_pack_elems_folded (const_tree);
> ?#undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS
> ?#define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \
> ? ? ? ?get_template_argument_pack_elems_folded
> +#undef LANG_HOOKS_IS_PTR_TO_MEMBER
> +#define LANG_HOOKS_IS_PTR_TO_MEMBER \
> + ? ? ? ?is_ptr_to_member
> ?#undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P
> ?#define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \
> ? ? ? ?template_template_parameter_p
> @@ -238,5 +241,39 @@ get_template_argument_pack_elems_folded (const_tree t)
> ? return fold_cplus_constants (get_template_argument_pack_elems (t));
> ?}
>
> +/* The C++ implementation of LANG_HOOKS_GET_PTRMEM_TYPES.
> +
> + ? Returns TRUE if T is a pointer-to-data-member or
> + ? a pointer-to-member-function.
> +
> + ? If PTRMEM_INFO is non-null and if T is a
> + ? pointer-to-member-function, *PTRMEM_INFO is set to a TREE_LIST
> + ? which TREE_PURPOSE is the METHOD_TYPE of member-function pointed
> + ? to. ?The TREE_VALUE is the class/struct type containing the member
> + ? function. ?If T is a pointer-to-member, *PTRMEM_INFO is set to a
> + ? TREE_LIST which TREE_PURPOSE is the type of the member, and which
> + ? TREE_VALUE is the class/strunct type containing the data member.
> + ? The TREE_TYPE is set to T. ?*/
> +
> +static bool
> +is_ptr_to_member (const_tree t,
> + ? ? ? ? ? ? ? ? tree *ptrmem_info)
> +{
> + ?if (!t || !TYPE_PTR_TO_MEMBER_P (t))
> + ? ?return false;
> +
> + ?if (ptrmem_info != NULL)
> + ? ?{
> + ? ? ?if (TYPE_PTRMEMFUNC_P (t))
> + ? ? ? *ptrmem_info = build_tree_list (TYPE_PTRMEMFUNC_FN_TYPE (t),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TYPE_PTRMEMFUNC_OBJECT_TYPE (t));
> + ? ? ?else
> + ? ? ? *ptrmem_info = build_tree_list (TYPE_PTRMEM_POINTED_TO_TYPE (t),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?TYPE_PTRMEM_CLASS_TYPE (t));
> + ? ? ?TREE_TYPE (*ptrmem_info) = CONST_CAST_TREE (t);
> + ? ?}
> + ?return true;
> +}
> +
> ?#include "gt-cp-cp-lang.h"
> ?#include "gtype-cp.h"
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index 733c849..949c099 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -6520,7 +6520,7 @@ static void gen_label_die (tree, dw_die_ref);
> ?static void gen_lexical_block_die (tree, dw_die_ref, int);
> ?static void gen_inlined_subroutine_die (tree, dw_die_ref, int);
> ?static void gen_field_die (tree, dw_die_ref);
> -static void gen_ptr_to_mbr_type_die (tree, dw_die_ref);
> +static bool gen_ptr_to_mbr_type_die (tree, dw_die_ref);
> ?static dw_die_ref gen_compile_unit_die (const char *);
> ?static void gen_inheritance_die (tree, tree, dw_die_ref);
> ?static void gen_member_die (tree, dw_die_ref);
> @@ -20064,19 +20064,36 @@ gen_reference_type_die (tree type, dw_die_ref context_die)
> ?}
> ?#endif
>
> -/* Generate a DIE for a pointer to a member type. ?*/
> +/* Generate a DIE for a pointer to a member type. ?Return TRUE if the
> + ? DIE was actually generated, false otherwise. ?*/
>
> -static void
> +static bool
> ?gen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die)
> ?{
> - ?dw_die_ref ptr_die
> - ? ?= new_die (DW_TAG_ptr_to_member_type,
> - ? ? ? ? ? ? ?scope_die_for (type, context_die), type);
> + ?dw_die_ref ptr_die;
> + ?tree ptrmem_info = NULL_TREE;
> +
> + ?if (!lang_hooks.types.is_ptr_to_member (type, &ptrmem_info))
> + ? ?return false;
>
> + ?gcc_assert (ptrmem_info != NULL_TREE);
> +
> + ?/* Output the description of the class type containing the
> + ? ? member pointed to. ?*/
> + ?gen_type_die_with_usage (TREE_VALUE (ptrmem_info),
> + ? ? ? ? ? ? ? ? ? ? ? ? ?context_die, DINFO_USAGE_IND_USE);
> + ?/* Output the description of the type of the memeber
> + ? ? pointed to. ?*/
> + ?gen_type_die_with_usage (TREE_PURPOSE (ptrmem_info),
> + ? ? ? ? ? ? ? ? ? ? ? ? ?context_die, DINFO_USAGE_IND_USE);
> + ?/* Now create the DW_TAG_ptr_to_member_type proper. ?*/
> + ?ptr_die = new_die (DW_TAG_ptr_to_member_type,
> + ? ? ? ? ? ? ? ? ? ?scope_die_for (type, context_die), type);
> ? equate_type_number_to_die (type, ptr_die);
> ? add_AT_die_ref (ptr_die, DW_AT_containing_type,
> - ? ? ? ? ? ? ? ? lookup_type_die (TYPE_OFFSET_BASETYPE (type)));
> - ?add_type_attribute (ptr_die, TREE_TYPE (type), 0, 0, context_die);
> + ? ? ? ? ? ? ? ? lookup_type_die (TREE_VALUE (ptrmem_info)));
> + ?add_type_attribute (ptr_die, TREE_PURPOSE (ptrmem_info), 0, 0, context_die);
> + ?return true;
> ?}
>
> ?/* Generate the DIE for the compilation unit. ?*/
> @@ -20603,6 +20620,14 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
> ? ? ? return;
> ? ? }
>
> + ?/* ?If this is a pointer-to-member, handle it here. ?*/
> + ?if (!TREE_ASM_WRITTEN (type)
> + ? ? ?&& gen_ptr_to_mbr_type_die (type, context_die))
> + ? ?{
> + ? ? ?TREE_ASM_WRITTEN (type) = 1;
> + ? ? ?return;
> + ? ?}
> +
> ? /* We are going to output a DIE to represent the unqualified version
> ? ? ?of this type (i.e. without any const or volatile qualifiers) so
> ? ? ?get the main variant (i.e. the unqualified version) of this type
> @@ -20635,19 +20660,9 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
> ? ? ? break;
>
> ? ? case OFFSET_TYPE:
> - ? ? ?/* This code is used for C++ pointer-to-data-member types.
> - ? ? ? ?Output a description of the relevant class type. ?*/
> - ? ? ?gen_type_die_with_usage (TYPE_OFFSET_BASETYPE (type), context_die,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DINFO_USAGE_IND_USE);
> -
> - ? ? ?/* Output a description of the type of the object pointed to. ?*/
> - ? ? ?gen_type_die_with_usage (TREE_TYPE (type), context_die,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DINFO_USAGE_IND_USE);
> -
> - ? ? ?/* Now output a DIE to represent this pointer-to-data-member type
> - ? ? ? ?itself. ?*/
> - ? ? ?gen_ptr_to_mbr_type_die (type, context_die);
> - ? ? ?break;
> + ? ? ?/* This code is used for C++ pointer-to-data-member types, so
> + ? ? ? ?it should have been handled earlier. ?*/
> + ? ? ?gcc_unreachable ();
>
> ? ? case FUNCTION_TYPE:
> ? ? ? /* Force out return type (in case it wasn't forced out already). ?*/
> @@ -21818,7 +21833,6 @@ gen_scheduled_generic_parms_dies (void)
> ? ? gen_generic_params_dies (t);
> ?}
>
> -
> ?/* Replace DW_AT_name for the decl with name. ?*/
>
> ?static void
> diff --git a/gcc/hooks.c b/gcc/hooks.c
> index f859dd9..4a2a9f2 100644
> --- a/gcc/hooks.c
> +++ b/gcc/hooks.c
> @@ -219,6 +219,13 @@ hook_bool_const_tree_true (const_tree a ATTRIBUTE_UNUSED)
> ?}
>
> ?bool
> +hook_bool_const_tree_treeptr_false (const_tree a ATTRIBUTE_UNUSED,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tree *b ATTRIBUTE_UNUSED)
> +{
> + ?return false;
> +}
> +
> +bool
> ?hook_bool_tree_tree_false (tree a ATTRIBUTE_UNUSED, tree b ATTRIBUTE_UNUSED)
> ?{
> ? return false;
> diff --git a/gcc/hooks.h b/gcc/hooks.h
> index 7962fe8..71fe747 100644
> --- a/gcc/hooks.h
> +++ b/gcc/hooks.h
> @@ -38,6 +38,7 @@ extern bool hook_bool_tree_false (tree);
> ?extern bool hook_bool_const_tree_false (const_tree);
> ?extern bool hook_bool_tree_true (tree);
> ?extern bool hook_bool_const_tree_true (const_tree);
> +extern bool hook_bool_const_tree_treeptr_false (const_tree, tree *p);
> ?extern bool hook_bool_const_tree_hwi_hwi_const_tree_false (const_tree,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? HOST_WIDE_INT,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? HOST_WIDE_INT,
> diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
> index 961e929..ab077f8 100644
> --- a/gcc/langhooks-def.h
> +++ b/gcc/langhooks-def.h
> @@ -164,6 +164,7 @@ extern tree lhd_make_node (enum tree_code);
> ?#define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS hook_tree_const_tree_null
> ?#define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P hook_bool_const_tree_false
> ?#define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS hook_tree_const_tree_null
> +#define LANG_HOOKS_IS_PTR_TO_MEMBER hook_bool_const_tree_treeptr_false
> ?#define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P hook_bool_const_tree_false
> ?#define LANG_HOOKS_FUNCTION_PARM_EXPANDED_FROM_PACK_P \
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?hook_bool_tree_tree_false
> @@ -185,6 +186,7 @@ extern tree lhd_make_node (enum tree_code);
> ? LANG_HOOKS_TYPE_FOR_SIZE, \
> ? LANG_HOOKS_GENERIC_TYPE_P, \
> ? LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS, \
> + ?LANG_HOOKS_IS_PTR_TO_MEMBER, ? ? ?\
> ? LANG_HOOKS_TYPE_PROMOTES_TO, \
> ? LANG_HOOKS_REGISTER_BUILTIN_TYPE, \
> ? LANG_HOOKS_INCOMPLETE_TYPE_ERROR, \
> diff --git a/gcc/langhooks.h b/gcc/langhooks.h
> index a994729..97758d6 100644
> --- a/gcc/langhooks.h
> +++ b/gcc/langhooks.h
> @@ -90,6 +90,14 @@ struct lang_hooks_for_types
> ? /* Returns the TREE_VEC of elements of a given generic argument pack. ?*/
> ? tree (*get_argument_pack_elems) (const_tree);
>
> + ?/* If the first parameter is a pointer-to-data-member or a
> + ? ? pointer-to-function-member, return TRUE. ?If the second parameter
> + ? ? is non-null, set it to a TREE_LIST. ?The TREE_PURPOSE is the type
> + ? ? of the member pointed to. ?The TREE_VALUE is the type of the
> + ? ? class containing the member. ?The TREE_TYPE is set to the first
> + ? ? parameter. ?*/
> + ?bool (*is_ptr_to_member) (const_tree, tree*);
> +
> ? /* Given a type, apply default promotions to unnamed function
> ? ? ?arguments and return the new type. ?Return the same type if no
> ? ? ?change. ?Required by any language that supports variadic
> diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/ptrmem-1.C b/gcc/testsuite/g++.dg/debug/dwarf2/ptrmem-1.C
> new file mode 100644
> index 0000000..c232165
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/debug/dwarf2/ptrmem-1.C
> @@ -0,0 +1,20 @@
> +// Origin PR debug/28767
> +// { dg-options "-g -dA -fno-merge-debug-strings" }
> +
> +struct A
> +{
> + ? ?int func(void);
> + ? ?char data;
> +};
> +
> +int (A::*ptr) (void) = &A::func;
> +char A::* d = &A::data;
> +
> +// For the code abobe we want to test that we have two sequences
> +// ressembling:
> +//
> +// ? ? ?.uleb128 0x9 ? # (DIE (0x7f) DW_TAG_ptr_to_member_type)
> +// ? ? .long ? 0x2d ? ?# DW_AT_containing_type
> +// ? ? .long ? 0x88 ? ?# DW_AT_type
> +//
> +// { dg-final { scan-assembler-times "DIE \\(\[^\n\r\]+\\) DW_TAG_ptr_to_member_type\\)\[\n\r\]{1,2}\[^\n\r\]+DW_AT_containing_type\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]+DW_AT_type\[^\n\r\]*\[\n\r\]{1,2}" ?2 } }
> --
> 1.7.3.4
>
>
>
>
> --
> ? ? ? ? ? ? ? ?Dodji
>
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]