On 06/29/2011 05:15 PM, Jason Merrill wrote:
This patch adds support for use of 'this' (implicitly or explicitly) in the trailing-return-type of a member function.
The above patch wasn't enough, though. The following patch fixes some issues that arose with real uses, including mangling.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit ef43a979a3f46150f383b9deab70dd412d66f96b Author: Jason Merrill <ja...@redhat.com> Date: Sun Jul 3 17:14:56 2011 -0400 DR 1207 PR c++/49589 * mangle.c (write_expression): Handle 'this'. * parser.c (cp_parser_postfix_dot_deref_expression): Allow incomplete *this. * semantics.c (potential_constant_expression_1): Check that DECL_CONTEXT is set on 'this'. diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 134c9ea..81b772f 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -2495,6 +2495,11 @@ write_expression (tree expr) else if (TREE_CODE_CLASS (code) == tcc_constant || (abi_version_at_least (2) && code == CONST_DECL)) write_template_arg_literal (expr); + else if (code == PARM_DECL && DECL_ARTIFICIAL (expr)) + { + gcc_assert (!strcmp ("this", IDENTIFIER_POINTER (DECL_NAME (expr)))); + write_string ("fpT"); + } else if (code == PARM_DECL) { /* A function parameter used in a late-specified return type. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index d79326d..6bb15ed 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5281,7 +5281,11 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser, postfix_expression); scope = NULL_TREE; } - else + /* Unlike the object expression in other contexts, *this is not + required to be of complete type for purposes of class member + access (5.2.5) outside the member function body. */ + else if (scope != current_class_ref + && !(processing_template_decl && scope == current_class_type)) scope = complete_type_or_else (scope, NULL_TREE); /* Let the name lookup machinery know that we are processing a class member access expression. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index e29705c..619c058 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -7791,7 +7791,8 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) STRIP_NOPS (x); if (is_this_parameter (x)) { - if (DECL_CONSTRUCTOR_P (DECL_CONTEXT (x)) && want_rval) + if (want_rval && DECL_CONTEXT (x) + && DECL_CONSTRUCTOR_P (DECL_CONTEXT (x))) { if (flags & tf_error) sorry ("use of the value of the object being constructed " diff --git a/gcc/testsuite/g++.dg/abi/mangle48.C b/gcc/testsuite/g++.dg/abi/mangle48.C new file mode 100644 index 0000000..dc9c492 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/mangle48.C @@ -0,0 +1,23 @@ +// Testcase for 'this' mangling +// { dg-options -std=c++0x } + +struct B +{ + template <class U> U f(); +}; + +struct A +{ + B b; + // { dg-final { scan-assembler "_ZN1A1fIiEEDTcldtdtdefpT1b1fIT_EEEv" } } + template <class U> auto f() -> decltype (b.f<U>()); + // { dg-final { scan-assembler "_ZN1A1gIiEEDTcldtptfpT1b1fIT_EEEv" } } + template <class U> auto g() -> decltype (this->b.f<U>()); +}; + +int main() +{ + A a; + a.f<int>(); + a.g<int>(); +}
commit acbc60694bf95f13f9088ed4d5b3d18780aaf754 Author: Jason Merrill <ja...@redhat.com> Date: Mon Jul 4 10:44:29 2011 -0400 * cp-demangle.c (d_expression): Handle 'this'. (d_print_comp) [DEMANGLE_COMPONENT_FUNCTION_PARAM]: Likewise. diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index f136322..29badbb 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -2738,10 +2738,18 @@ d_expression (struct d_info *di) /* Function parameter used in a late-specified return type. */ int index; d_advance (di, 2); - index = d_compact_number (di); - if (index < 0) - return NULL; - + if (d_peek_char (di) == 'T') + { + /* 'this' parameter. */ + d_advance (di, 1); + index = 0; + } + else + { + index = d_compact_number (di) + 1; + if (index == 0) + return NULL; + } return d_make_function_param (di, index); } else if (IS_DIGIT (peek) @@ -4400,9 +4408,17 @@ d_print_comp (struct d_print_info *dpi, int options, return; case DEMANGLE_COMPONENT_FUNCTION_PARAM: - d_append_string (dpi, "{parm#"); - d_append_num (dpi, dc->u.s_number.number + 1); - d_append_char (dpi, '}'); + { + long num = dc->u.s_number.number; + if (num == 0) + d_append_string (dpi, "this"); + else + { + d_append_string (dpi, "{parm#"); + d_append_num (dpi, num); + d_append_char (dpi, '}'); + } + } return; case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 4980cf1..2dc74be 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3905,6 +3905,10 @@ decltype ({parm#1}+{parm#2}) add<int, double>(int, double) --format=gnu-v3 _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_ decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double) +# 'this' test +--format=gnu-v3 +_ZN1A1fIiEEDTcldtdtdefpT1b1fIT_EEEv +decltype ((((*this).b).(f<int>))()) A::f<int>() # new (2008) built in types test --format=gnu-v3 _Z1fDfDdDeDhDsDi