On Mon, 27 Jun 2011 20:00:24 +0200, Jason Merrill wrote: > They should be supressed whenever the function appears in an > expression context, either as a pointer to member function (i.e. the > operand of '&')
Done, therefore it is no longer restricted only to templates as before. > or as the function being called in a call expression. I implemented it in the patch below but I do not agree + understand it. The call expression is in libiberty/testsuite/demangle-expected modified by this patch as: # decltype/fn call test --format=gnu-v3 _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_ -decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double) +decltype (g) add3<int, double>(int, double) I agree it is sufficient to determine the return type just from the function type as return type cannot be overloaded by the function parameters. But it no longer matches a valid C++ source code now: char g (int x, double y) { return 0; } template <typename T, typename U> decltype (g((T) 0, (U) 0)) add3 (T x, U y) { return 'z'; } // error: ‘add3’ declared as function returning a function // decltype (g) add3 (T x, U y) { return 'z'; } int main () { add3<int, double> (1, 2.0); } g++ -Wall -g -std=c++0x g++ (GCC) 4.7.0 20110629 (experimental) (Regression testing underway.) Thanks, Jan libiberty/ 2011-06-29 Jan Kratochvil <jan.kratoch...@redhat.com> * cp-demangle.c (d_print_comp): Suppress argument list for function references by the '&' unary operator. Keep also already processed variant without the argument list. Suppress argument list also for function call used in an expression. * testsuite/demangle-expected: Remove parameters from function call expressions of 6 testcases. Create 3 new testcases for function references by the '&' unary operator.. --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -4139,7 +4169,46 @@ d_print_comp (struct d_print_info *dpi, int options, return; case DEMANGLE_COMPONENT_UNARY: - if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST) + if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR + && d_left (dc)->u.s_operator.op->len == 1 + && d_left (dc)->u.s_operator.op->name[0] == '&' + && d_right (dc)->type == DEMANGLE_COMPONENT_TYPED_NAME + && d_left (d_right (dc))->type == DEMANGLE_COMPONENT_QUAL_NAME + && d_right (d_right (dc))->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) + { + /* Address of a function (therefore in an expression context) must + have its argument list suppressed. + + unary operator ... dc + operator & ... d_left (dc) + typed name ... d_right (dc) + qualified name ... d_left (d_right (dc)) + <names> + function type ... d_right (d_right (dc)) + argument list + <arguments> */ + + d_print_expr_op (dpi, options, d_left (dc)); + d_print_comp (dpi, options, d_left (d_right (dc))); + return; + } + else if (d_left (dc)->type == DEMANGLE_COMPONENT_OPERATOR + && d_left (dc)->u.s_operator.op->len == 1 + && d_left (dc)->u.s_operator.op->name[0] == '&' + && d_right (dc)->type == DEMANGLE_COMPONENT_QUAL_NAME) + { + /* Keep also already processed variant without the argument list. + + unary operator ... dc + operator & ... d_left (dc) + qualified name ... d_right (dc) + <names> */ + + d_print_expr_op (dpi, options, d_left (dc)); + d_print_comp (dpi, options, d_right (dc)); + return; + } + else if (d_left (dc)->type != DEMANGLE_COMPONENT_CAST) d_print_expr_op (dpi, options, d_left (dc)); else { @@ -4172,10 +4241,11 @@ d_print_comp (struct d_print_info *dpi, int options, d_print_comp (dpi, options, d_right (d_right (dc))); d_append_char (dpi, ']'); } - else + /* Function call used in an expression should not have the argument list + printed. */ + else if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0) { - if (strcmp (d_left (dc)->u.s_operator.op->code, "cl") != 0) - d_print_expr_op (dpi, options, d_left (dc)); + d_print_expr_op (dpi, options, d_left (dc)); d_print_subexpr (dpi, options, d_right (d_right (dc))); } diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index bbd418c..da87282 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3904,7 +3904,7 @@ decltype ({parm#1}+{parm#2}) add<int, double>(int, double) # decltype/fn call test --format=gnu-v3 _Z4add3IidEDTclL_Z1gEfp_fp0_EET_T0_ -decltype (g({parm#1}, {parm#2})) add3<int, double>(int, double) +decltype (g) add3<int, double>(int, double) # new (2008) built in types test --format=gnu-v3 _Z1fDfDdDeDhDsDi @@ -3916,15 +3916,15 @@ void f<int*, float*, double*>(int*, float*, double*) # '.' test --format=gnu-v3 _Z1hI1AIiEdEDTcldtfp_1gIT0_EEET_S2_ -decltype (({parm#1}.(g<double>))()) h<A<int>, double>(A<int>, double) +decltype (({parm#1}.(g<double>))) h<A<int>, double>(A<int>, double) # test for typed function in decltype --format=gnu-v3 _ZN1AIiE1jIiEEDTplfp_clL_Z1xvEEET_ -decltype ({parm#1}+((x())())) A<int>::j<int>(int) +decltype ({parm#1}+((x()))) A<int>::j<int>(int) # test for expansion of function parameter pack --format=gnu-v3 _Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_ -decltype (f(({parm#1}+(1))...)) g<int, double>(int, double) +decltype (f) g<int, double>(int, double) # lambda tests --format=gnu-v3 _ZZ1giENKUlvE_clEv @@ -3949,10 +3949,10 @@ _Z1fIfLi4EEvDv_T0__T_ void f<float, 4>(float __vector(4)) --format=gnu-v3 _Z1fI1AEDTclonplfp_fp_EET_ -decltype ((operator+)({parm#1}, {parm#1})) f<A>(A) +decltype ((operator+)) f<A>(A) --format=gnu-v3 _Z1hI1AEDTcldtfp_miEET_ -decltype (({parm#1}.(operator-))()) h<A>(A) +decltype (({parm#1}.(operator-))) h<A>(A) --format=gnu-v3 _Z1fDn f(decltype(nullptr)) @@ -3990,6 +3990,18 @@ outer(short (*)(int), long) _Z6outer2IsEPFilES1_ outer2<short>(int (*)(long)) # +--format=gnu-v3 --no-params +_ZN1KIXadL_ZN1S1mEiEEE1fEv +K<&S::m>::f() +K<&S::m>::f +--format=gnu-v3 +_ZN1KILi1EXadL_ZN1S1mEiEEE1fEv +K<1, &S::m>::f() +# Here the `(int)' argument list of `S::m' is already removed. +--format=gnu-v3 +_ZN1KILi1EXadL_ZN1S1mEEEE1fEv +K<1, &S::m>::f() +# # Ada (GNAT) tests. # # Simple test.