From patchwork Wed Feb 23 01:55:01 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 84044 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 2C3BEB70DB for ; Wed, 23 Feb 2011 12:55:23 +1100 (EST) Received: (qmail 18386 invoked by alias); 23 Feb 2011 01:55:21 -0000 Received: (qmail 18263 invoked by uid 22791); 23 Feb 2011 01:55:19 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, 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; Wed, 23 Feb 2011 01:55:14 +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.14.4/8.14.4) with ESMTP id p1N1t5uf006270 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 22 Feb 2011 20:55:05 -0500 Received: from [127.0.0.1] (ovpn-113-77.phx2.redhat.com [10.3.113.77]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p1N1t43K003300; Tue, 22 Feb 2011 20:55:04 -0500 Message-ID: <4D6468F5.7080108@redhat.com> Date: Tue, 22 Feb 2011 20:55:01 -0500 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101209 Fedora/3.1.7-0.35.b3pre.fc14 Lightning/1.0b2 Thunderbird/3.1.7 MIME-Version: 1.0 To: gcc-patches List CC: Mark Mitchell Subject: RFC: C++0x ABI PATCH to function parameter mangling References: <4D64677A.5020105@redhat.com> In-Reply-To: <4D64677A.5020105@redhat.com> 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 And this patch implements the change to function parameter mangling that Daveed proposed on the ABI list. Uses in trailing return types, which are the interesting case, are unaffected; use of one parameter in the declaration of another parameter do change mangling. I think that's all the changes we need to make for code that we currently accept. Tested x86_64-pc-linux-gnu. commit 3c16f729dcb34c970f06beddac2a4a266fe1f0c4 Author: Jason Merrill Date: Mon Feb 21 22:41:34 2011 -0500 * cp-tree.h (DECL_PARM_LEVEL): New. (struct lang_decl_parm): Add level field. * name-lookup.c (function_parm_depth): New fn. * name-lookup.h: Declare it. * parser.c (cp_parser_parameter_declaration_list): Use it. * mangle.c (struct globals): Add parm_depth field. (write_bare_function_type): Adjust it. (write_expression): Include the level delta in PARM_DECL mangling. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 238d0cf..ee72322 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1914,6 +1914,7 @@ struct GTY(()) lang_decl_ns { struct GTY(()) lang_decl_parm { struct lang_decl_base base; + int level; int index; }; @@ -2108,6 +2109,13 @@ struct GTY((variable_size)) lang_decl { #define DECL_PARM_INDEX(NODE) \ (LANG_DECL_PARM_CHECK (NODE)->index) +/* The level of a user-declared parameter in its function, starting at 1. + A parameter of the function will have level 1; a parameter of the first + nested function declarator (i.e. t in void f (void (*p)(T t))) will have + level 2. */ +#define DECL_PARM_LEVEL(NODE) \ + (LANG_DECL_PARM_CHECK (NODE)->level) + /* Nonzero if the VTT parm has been added to NODE. */ #define DECL_HAS_VTT_PARM_P(NODE) \ (LANG_DECL_FN_CHECK (NODE)->has_vtt_parm_p) diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 4d2ace6..a949681 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -96,6 +96,9 @@ typedef struct GTY(()) globals { /* The entity that is being mangled. */ tree GTY ((skip)) entity; + /* How many parameter scopes we are inside. */ + int parm_depth; + /* True if the mangling will be different in a future version of the ABI. */ bool need_abi_warning; @@ -2270,9 +2273,11 @@ write_bare_function_type (const tree type, const int include_return_type_p, write_type (TREE_TYPE (type)); /* Now mangle the types of the arguments. */ + ++G.parm_depth; write_method_parms (TYPE_ARG_TYPES (type), TREE_CODE (type) == METHOD_TYPE, decl); + --G.parm_depth; } /* Write the mangled representation of a method parameter list of @@ -2458,8 +2463,23 @@ write_expression (tree expr) { /* A function parameter used in a late-specified return type. */ int index = DECL_PARM_INDEX (expr); + int level = DECL_PARM_LEVEL (expr); + int delta = G.parm_depth - level + 1; gcc_assert (index >= 1); - write_string ("fp"); + write_char ('f'); + if (delta != 0) + { + /* Let L be the number of function prototype scopes from the + innermost one (in which the parameter reference occurs) up to + (and including) the one containing the declaration of the + referenced parameter. If the parameter declaration clause of + the innermost function prototype scope has been completely + seen, it is not counted (in that case -- which is perhaps the + most common -- L can be zero). */ + write_char ('L'); + write_unsigned_number (delta - 1); + } + write_char ('p'); write_compact_number (index - 1); } else if (DECL_P (expr)) diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e2e5450..4117202 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -1635,6 +1635,22 @@ getdecls (void) return current_binding_level->names; } +/* Return how many function prototypes we are currently nested inside. */ + +int +function_parm_depth (void) +{ + int level = 0; + struct cp_binding_level *b; + + for (b = current_binding_level; + b->kind == sk_function_parms; + b = b->level_chain) + ++level; + + return level; +} + /* For debugging. */ static int no_print_functions = 0; static int no_print_builtins = 0; diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h index f81a565..bfcac69 100644 --- a/gcc/cp/name-lookup.h +++ b/gcc/cp/name-lookup.h @@ -333,6 +333,7 @@ extern bool pushdecl_class_level (tree); extern tree pushdecl_namespace_level (tree, bool); extern bool push_class_level_binding (tree, tree); extern tree getdecls (void); +extern int function_parm_depth (void); extern tree cp_namespace_decls (tree); extern void set_decl_namespace (tree, tree, bool); extern void push_decl_namespace (tree); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8f4a121..5a2806f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15942,6 +15942,7 @@ cp_parser_parameter_declaration_list (cp_parser* parser, bool *is_error) { retrofit_lang_decl (decl); DECL_PARM_INDEX (decl) = ++index; + DECL_PARM_LEVEL (decl) = function_parm_depth (); } /* Add the new parameter to the list. */ diff --git a/gcc/testsuite/g++.dg/abi/mangle39.C b/gcc/testsuite/g++.dg/abi/mangle39.C index 30a08b0..272385b 100644 --- a/gcc/testsuite/g++.dg/abi/mangle39.C +++ b/gcc/testsuite/g++.dg/abi/mangle39.C @@ -1,7 +1,7 @@ // PR c++/42338 // { dg-options "-std=c++0x" } // { dg-final { scan-assembler "_Z1fIPiEDTcmppfp_Li0EET_" } } -// { dg-final { scan-assembler "_Z1gIiEvRK1AIT_EDTixfp_Li0EE" } } +// { dg-final { scan-assembler "_Z1gIiEvRK1AIT_EDTixfL0p_Li0EE" } } template auto f(T t) -> decltype(++t, 0) diff --git a/gcc/testsuite/g++.dg/abi/mangle45.C b/gcc/testsuite/g++.dg/abi/mangle45.C new file mode 100644 index 0000000..48ae57d --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle45.C @@ -0,0 +1,25 @@ +// Testcase for mangling of parameters used other than in a trailing return type +// { dg-options -std=c++0x } + +template void f(T p, decltype(p)); // L = 1 +template void g(T p, decltype(p) (*)()); // L = 1 +// G++ incorrectly rejects these currently. +// template void h(T p, auto (*)()->decltype(p)); // L = 1 +// template void i(T p, auto (*)(T q)->decltype(q)); // L = 0 +// template void j(T p, auto (*)(decltype(p))->T); // L = 2 +template void k(T p, int (*(*)(T* p))[sizeof(p)]); // L = 1 + +int garg(); +int (*karg (int*))[sizeof(int)]; +int main() +{ + // { dg-final { scan-assembler "_Z1fIiEvT_DtfL0p_E" } } + f (1,0); + // { dg-final { scan-assembler "_Z1gIiEvT_PFDtfL0p_EvE" } } + g (1,garg); + // h (1,0); + // i (1,0); + // j (1,0); + // { dg-final { scan-assembler "_Z1kIiEvT_PFPAszfL0p__iPS0_E" } } + k (1,karg); +}