From patchwork Thu Dec 16 08:30:23 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 75724 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 31757B6EE8 for ; Thu, 16 Dec 2010 19:30:35 +1100 (EST) Received: (qmail 20822 invoked by alias); 16 Dec 2010 08:30:34 -0000 Received: (qmail 20809 invoked by uid 22791); 16 Dec 2010 08:30:33 -0000 X-SWARE-Spam-Status: No, hits=-5.5 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_BJ, TW_JC, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 16 Dec 2010 08:30:28 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oBG8UQGZ032008 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 16 Dec 2010 03:30:26 -0500 Received: from adjoa.redhat.com (ovpn-113-34.phx2.redhat.com [10.3.113.34]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id oBG8UObM008571; Thu, 16 Dec 2010 03:30:25 -0500 From: Dodji Seketeli To: Jason Merrill Cc: GCC Patches Subject: Fix for PR debug/46955 X-URL: http://www.redhat.com Date: Thu, 16 Dec 2010 09:30:23 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello, Consider this short example: struct S { int f; }; template struct T { }; T<&S::f> v; The DW_TAG_template_value_param DIE created for type T<&S::f> lacks the DW_AT_const_value attribute which value should be the value of the pointer-to-member constant &S::f. The problem is tree_add_const_value_attribute doesn't know how to fold the C++ specific PTRMEM_CST representing &S::f. This patch ensures that template arguments -- especially PTRMEM_CST nodes -- that are retrieved with lang_hooks.get_innermost_generic_args and lang_hooks.types.get_argument_pack_elems are folded enough for the DWARF emitter. Bootstrapped and tested on x86_64-unknown-linux against trunk. diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index ff92666..5e50461 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -38,6 +38,8 @@ static void cp_init_ts (void); static const char * cxx_dwarf_name (tree t, int verbosity); 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); /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h; consequently, there should be very few hooks below. */ @@ -56,13 +58,13 @@ static tree cp_eh_personality (void); get_primary_template_innermost_parameters #undef LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS #define LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS \ - get_template_innermost_arguments + get_template_innermost_arguments_folded #undef LANG_HOOKS_FUNCTION_PARAMETER_PACK_P #define LANG_HOOKS_FUNCTION_PARAMETER_PACK_P \ function_parameter_pack_p #undef LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS #define LANG_HOOKS_GET_ARGUMENT_PACK_ELEMS \ - get_template_argument_pack_elems + get_template_argument_pack_elems_folded #undef LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P #define LANG_HOOKS_GENERIC_GENERIC_PARAMETER_DECL_P \ template_template_parameter_p @@ -165,5 +167,74 @@ cp_eh_personality (void) return cp_eh_personality_decl; } +/* This is a subroutine of fold_cplus_constants. It returns TRUE if T + is a C++ specific constant that needs to be folded further before + being passed to the debug info emitter. */ + +static bool +template_arg_needs_folding (const_tree t) +{ + /* For now only PTRMEM_CST nodes are to be folded further. */ + if (TREE_CODE (t) == PTRMEM_CST) + return true; + return false; +} + +/* Fold the elements of the TREE_VEC C which are C++ specific nodes + which would need folding so that they can be processed by the debug + info emitter. This is a subroutine of + get_template_innermost_arguments_folded and + get_template_argument_pack_elems_folded. */ + +static tree +fold_cplus_constants (const_tree c) +{ + tree folded_elems, elems = CONST_CAST_TREE (c); + int vec_len, i; + + if (elems == NULL_TREE || elems == error_mark_node) + return elems; + + vec_len = TREE_VEC_LENGTH (elems); + + /* First check if there is at least one element that needs + folding. If there is none, we just return ELEMS. Otherwise create + and return a new tree vector that contains the folded versions of + ELEMS. This is to avoid allocating memory if we don't need + to. */ + for (i = 0; i < vec_len; ++i) + { + if (template_arg_needs_folding (TREE_VEC_ELT (elems, i))) + break; + } + if (i == vec_len) + return elems; + + folded_elems = make_tree_vec (vec_len); + for (i = 0; i < vec_len; ++i) + { + TREE_VEC_ELT (folded_elems, i) = + cplus_expand_constant (TREE_VEC_ELT (elems, i)); + } + return folded_elems; +} + +/* The C++ implementation of the LANG_HOOKS_GET_INNERMOST_GENERIC_ARGS + hook. It returns the innermost template arguments of type T, and + makes sure those arguments are folded enough for the debug info + emitter. */ + +static tree +get_template_innermost_arguments_folded (const_tree t) +{ + return fold_cplus_constants (get_template_innermost_arguments (t)); +} + +static tree +get_template_argument_pack_elems_folded (const_tree t) +{ + return fold_cplus_constants (get_template_argument_pack_elems (t)); +} + #include "gt-cp-cp-lang.h" #include "gtype-cp.h" diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/template-params-8.C b/gcc/testsuite/g++.dg/debug/dwarf2/template-params-8.C new file mode 100644 index 0000000..2d4a270 --- /dev/null +++ b/gcc/testsuite/g++.dg/debug/dwarf2/template-params-8.C @@ -0,0 +1,15 @@ +// Origin PR debug/46955 +// { dg-options "-g -dA" } +// { dg-do compile } + +struct S { int f; }; +template struct T { }; +T<&S::f> v; + +// For the type of v, we should have this DWARF generated: +// .uleb128 0x6 # (DIE (0x57) DW_TAG_template_value_param) +// .ascii "MP\0" # DW_AT_name +// .long 0x61 # DW_AT_type +// .byte 0 # DW_AT_const_value +// So let's look for that. +// { dg-final { scan-assembler "\[^\n\r\]*DIE \(\[^\n\r\]*\) DW_TAG_template_value_param\[^\n\r\]*\[\n\r\]{1,2}\[^\n\r\]*DW_AT_name\[\n\r\]{1,2}\[^\n\r\]*DW_AT_type\[\n\r\]{1,2}\[^\n\r\]*DW_AT_const_value\[\n\r\]{1,2}" } }