From eb7b5ddb8b2325f938424c2b81ea752948dc867a Mon Sep 17 00:00:00 2001 From: DJ Delorie Date: Fri, 6 Jan 2012 22:04:43 +0000 Subject: [PATCH] merge from gcc --- libiberty/ChangeLog | 27 +++ libiberty/configure | 3 - libiberty/cp-demangle.c | 282 ++++++++++++++++++-------- libiberty/testsuite/demangle-expected | 53 ++++- 4 files changed, 282 insertions(+), 83 deletions(-) diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 34d6b6ad8c5..8587ee2eabd 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,30 @@ +2012-01-06 Jason Merrill + + PR c++/6057 + PR c++/48051 + PR c++/50855 + PR c++/51322 + * cp-demangle.c (d_dump): Handle DEMANGLE_COMPONENT_NULLARY and + DEMANGLE_COMPONENT_INITIALIZER_LIST. + (d_make_comp): Likewise. Allow null right arg for + DEMANGLE_COMPONENT_TRINARY_ARG2. + (cplus_demangle_operators): Adjust new/delete; add .*, :: and throw. + (d_template_args, d_template_arg): Handle 'J' for argument packs. + (d_exprlist): Add terminator parm. + (d_expression, d_print_comp): Handle initializer lists, nullary + expressions, prefix/suffix operators, and new. + (d_print_subexpr): Avoid parens around DEMANGLE_COMPONENT_QUAL_NAME + and DEMANGLE_COMPONENT_INITIALIZER_LIST. + * testsuite/demangle-expected: Add tests. + + * cp-demangle.c (cplus_demangle_type): decltype, pack expansion + and vector are substitutable. + (cplus_demangle_operators): Sort. + +2012-01-04 Andreas Krebbel + + * configure: Regenerate. + 2012-01-02 Jakub Jelinek * make-relative-prefix.c (make_relative_prefix_1): Avoid diff --git a/libiberty/configure b/libiberty/configure index 9bdea73f950..b0edb0b2994 100755 --- a/libiberty/configure +++ b/libiberty/configure @@ -4899,9 +4899,6 @@ case "${host}" in m68k-*-*) PICFLAG=-fpic ;; - s390*-*-*) - PICFLAG=-fpic - ;; # FIXME: Override -fPIC default in libgcc only? sh-*-linux* | sh[2346lbe]*-*-linux*) PICFLAG=-fpic diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 0f1166be48c..2dfd67ceb77 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -648,9 +648,15 @@ d_dump (struct demangle_component *dc, int indent) case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST: printf ("template argument list\n"); break; + case DEMANGLE_COMPONENT_INITIALIZER_LIST: + printf ("initializer list\n"); + break; case DEMANGLE_COMPONENT_CAST: printf ("cast\n"); break; + case DEMANGLE_COMPONENT_NULLARY: + printf ("nullary operator\n"); + break; case DEMANGLE_COMPONENT_UNARY: printf ("unary operator\n"); break; @@ -806,7 +812,6 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_BINARY_ARGS: case DEMANGLE_COMPONENT_TRINARY: case DEMANGLE_COMPONENT_TRINARY_ARG1: - case DEMANGLE_COMPONENT_TRINARY_ARG2: case DEMANGLE_COMPONENT_LITERAL: case DEMANGLE_COMPONENT_LITERAL_NEG: case DEMANGLE_COMPONENT_COMPOUND_NAME: @@ -843,6 +848,8 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, case DEMANGLE_COMPONENT_PACK_EXPANSION: case DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS: case DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS: + case DEMANGLE_COMPONENT_NULLARY: + case DEMANGLE_COMPONENT_TRINARY_ARG2: if (left == NULL) return NULL; break; @@ -850,6 +857,7 @@ d_make_comp (struct d_info *di, enum demangle_component_type type, /* This needs a right parameter, but the left parameter can be empty. */ case DEMANGLE_COMPONENT_ARRAY_TYPE: + case DEMANGLE_COMPONENT_INITIALIZER_LIST: if (right == NULL) return NULL; break; @@ -1554,7 +1562,8 @@ d_identifier (struct d_info *di, int len) /* operator_name ::= many different two character encodings. ::= cv ::= v -*/ + + This list is sorted for binary search. */ #define NL(s) s, (sizeof s) - 1 @@ -1566,19 +1575,23 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "aa", NL ("&&"), 2 }, { "ad", NL ("&"), 1 }, { "an", NL ("&"), 2 }, + { "at", NL ("alignof "), 1 }, + { "az", NL ("alignof "), 1 }, { "cl", NL ("()"), 2 }, { "cm", NL (","), 2 }, { "co", NL ("~"), 1 }, { "dV", NL ("/="), 2 }, - { "da", NL ("delete[]"), 1 }, + { "da", NL ("delete[] "), 1 }, { "de", NL ("*"), 1 }, - { "dl", NL ("delete"), 1 }, + { "dl", NL ("delete "), 1 }, + { "ds", NL (".*"), 2 }, { "dt", NL ("."), 2 }, { "dv", NL ("/"), 2 }, { "eO", NL ("^="), 2 }, { "eo", NL ("^"), 2 }, { "eq", NL ("=="), 2 }, { "ge", NL (">="), 2 }, + { "gs", NL ("::"), 1 }, { "gt", NL (">"), 2 }, { "ix", NL ("[]"), 2 }, { "lS", NL ("<<="), 2 }, @@ -1590,11 +1603,11 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "mi", NL ("-"), 2 }, { "ml", NL ("*"), 2 }, { "mm", NL ("--"), 1 }, - { "na", NL ("new[]"), 1 }, + { "na", NL ("new[]"), 3 }, { "ne", NL ("!="), 2 }, { "ng", NL ("-"), 1 }, { "nt", NL ("!"), 1 }, - { "nw", NL ("new"), 1 }, + { "nw", NL ("new"), 3 }, { "oR", NL ("|="), 2 }, { "oo", NL ("||"), 2 }, { "or", NL ("|"), 2 }, @@ -1611,8 +1624,8 @@ const struct demangle_operator_info cplus_demangle_operators[] = { "rs", NL (">>"), 2 }, { "st", NL ("sizeof "), 1 }, { "sz", NL ("sizeof "), 1 }, - { "at", NL ("alignof "), 1 }, - { "az", NL ("alignof "), 1 }, + { "tr", NL ("throw"), 0 }, + { "tw", NL ("throw "), 1 }, { NULL, NULL, 0, 0 } }; @@ -2242,12 +2255,14 @@ cplus_demangle_type (struct d_info *di) d_expression (di), NULL); if (ret && d_next_char (di) != 'E') ret = NULL; + can_subst = 1; break; case 'p': /* Pack expansion. */ ret = d_make_comp (di, DEMANGLE_COMPONENT_PACK_EXPANSION, cplus_demangle_type (di), NULL); + can_subst = 1; break; case 'f': @@ -2298,6 +2313,7 @@ cplus_demangle_type (struct d_info *di) case 'v': ret = d_vector_type (di); + can_subst = 1; break; case 'n': @@ -2675,8 +2691,10 @@ d_template_args (struct d_info *di) constructor or destructor. */ hold_last_name = di->last_name; - if (! d_check_char (di, 'I')) + if (d_peek_char (di) != 'I' + && d_peek_char (di) != 'J') return NULL; + d_advance (di, 1); if (d_peek_char (di) == 'E') { @@ -2735,6 +2753,7 @@ d_template_arg (struct d_info *di) return d_expr_primary (di); case 'I': + case 'J': /* An argument pack. */ return d_template_args (di); @@ -2743,15 +2762,16 @@ d_template_arg (struct d_info *di) } } -/* Subroutine of ::= cl + E */ +/* Parse a sequence of expressions until we hit the terminator + character. */ static struct demangle_component * -d_exprlist (struct d_info *di) +d_exprlist (struct d_info *di, char terminator) { struct demangle_component *list = NULL; struct demangle_component **p = &list; - if (d_peek_char (di) == 'E') + if (d_peek_char (di) == terminator) { d_advance (di, 1); return d_make_comp (di, DEMANGLE_COMPONENT_ARGLIST, NULL, NULL); @@ -2768,7 +2788,7 @@ d_exprlist (struct d_info *di) return NULL; p = &d_right (*p); - if (d_peek_char (di) == 'E') + if (d_peek_char (di) == terminator) { d_advance (di, 1); break; @@ -2859,9 +2879,21 @@ d_expression (struct d_info *di) else return name; } + else if ((peek == 'i' || peek == 't') + && d_peek_next_char (di) == 'l') + { + /* Brace-enclosed initializer list, untyped or typed. */ + struct demangle_component *type = NULL; + if (peek == 't') + type = cplus_demangle_type (di); + d_advance (di, 2); + return d_make_comp (di, DEMANGLE_COMPONENT_INITIALIZER_LIST, + type, d_exprlist (di, 'E')); + } else { struct demangle_component *op; + const char *code = NULL; int args; op = d_operator_name (di); @@ -2869,12 +2901,13 @@ d_expression (struct d_info *di) return NULL; if (op->type == DEMANGLE_COMPONENT_OPERATOR) - di->expansion += op->u.s_operator.op->len - 2; - - if (op->type == DEMANGLE_COMPONENT_OPERATOR - && strcmp (op->u.s_operator.op->code, "st") == 0) - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, - cplus_demangle_type (di)); + { + code = op->u.s_operator.op->code; + di->expansion += op->u.s_operator.op->len - 2; + if (strcmp (code, "st") == 0) + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, + cplus_demangle_type (di)); + } switch (op->type) { @@ -2893,26 +2926,43 @@ d_expression (struct d_info *di) switch (args) { + case 0: + return d_make_comp (di, DEMANGLE_COMPONENT_NULLARY, op, NULL); + case 1: { struct demangle_component *operand; + int suffix = 0; + + if (code && (code[0] == 'p' || code[0] == 'm') + && code[1] == code[0]) + /* pp_ and mm_ are the prefix variants. */ + suffix = !d_check_char (di, '_'); + if (op->type == DEMANGLE_COMPONENT_CAST && d_check_char (di, '_')) - operand = d_exprlist (di); + operand = d_exprlist (di, 'E'); else operand = d_expression (di); - return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, - operand); + + if (suffix) + /* Indicate the suffix variant for d_print_comp. */ + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, + d_make_comp (di, + DEMANGLE_COMPONENT_BINARY_ARGS, + operand, operand)); + else + return d_make_comp (di, DEMANGLE_COMPONENT_UNARY, op, + operand); } case 2: { struct demangle_component *left; struct demangle_component *right; - const char *code = op->u.s_operator.op->code; left = d_expression (di); if (!strcmp (code, "cl")) - right = d_exprlist (di); + right = d_exprlist (di, 'E'); else if (!strcmp (code, "dt") || !strcmp (code, "pt")) { right = d_unqualified_name (di); @@ -2932,17 +2982,50 @@ d_expression (struct d_info *di) { struct demangle_component *first; struct demangle_component *second; + struct demangle_component *third; - first = d_expression (di); - second = d_expression (di); + if (!strcmp (code, "qu")) + { + /* ?: expression. */ + first = d_expression (di); + second = d_expression (di); + third = d_expression (di); + } + else if (code[0] == 'n') + { + /* new-expression. */ + if (code[1] != 'w' && code[1] != 'a') + return NULL; + first = d_exprlist (di, '_'); + second = cplus_demangle_type (di); + if (d_peek_char (di) == 'E') + { + d_advance (di, 1); + third = NULL; + } + else if (d_peek_char (di) == 'p' + && d_peek_next_char (di) == 'i') + { + /* Parenthesized initializer. */ + d_advance (di, 2); + third = d_exprlist (di, 'E'); + } + else if (d_peek_char (di) == 'i' + && d_peek_next_char (di) == 'l') + /* initializer-list. */ + third = d_expression (di); + else + return NULL; + } + else + return NULL; return d_make_comp (di, DEMANGLE_COMPONENT_TRINARY, op, d_make_comp (di, DEMANGLE_COMPONENT_TRINARY_ARG1, first, d_make_comp (di, DEMANGLE_COMPONENT_TRINARY_ARG2, - second, - d_expression (di)))); + second, third))); } default: return NULL; @@ -3662,6 +3745,8 @@ d_print_subexpr (struct d_print_info *dpi, int options, { int simple = 0; if (dc->type == DEMANGLE_COMPONENT_NAME + || dc->type == DEMANGLE_COMPONENT_QUAL_NAME + || dc->type == DEMANGLE_COMPONENT_INITIALIZER_LIST || dc->type == DEMANGLE_COMPONENT_FUNCTION_PARAM) simple = 1; if (!simple) @@ -4257,6 +4342,19 @@ d_print_comp (struct d_print_info *dpi, int options, } return; + case DEMANGLE_COMPONENT_INITIALIZER_LIST: + { + struct demangle_component *type = d_left (dc); + struct demangle_component *list = d_right (dc); + + if (type) + d_print_comp (dpi, options, type); + d_append_char (dpi, '{'); + d_print_comp (dpi, options, list); + d_append_char (dpi, '}'); + } + return; + case DEMANGLE_COMPONENT_OPERATOR: { char c; @@ -4280,55 +4378,59 @@ d_print_comp (struct d_print_info *dpi, int options, d_print_cast (dpi, options, dc); return; + case DEMANGLE_COMPONENT_NULLARY: + d_print_expr_op (dpi, options, d_left (dc)); + return; + case DEMANGLE_COMPONENT_UNARY: - 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)) - - function type ... d_right (d_right (dc)) - argument list - */ - - 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. + { + struct demangle_component *op = d_left (dc); + struct demangle_component *operand = d_right (dc); + const char *code = NULL; - unary operator ... dc - operator & ... d_left (dc) - qualified name ... d_right (dc) - */ + if (op->type == DEMANGLE_COMPONENT_OPERATOR) + { + code = op->u.s_operator.op->code; + if (!strcmp (code, "ad")) + { + /* Don't print the argument list for the address of a + function. */ + if (operand->type == DEMANGLE_COMPONENT_TYPED_NAME + && d_left (operand)->type == DEMANGLE_COMPONENT_QUAL_NAME + && d_right (operand)->type == DEMANGLE_COMPONENT_FUNCTION_TYPE) + operand = d_left (operand); + } + if (operand->type == DEMANGLE_COMPONENT_BINARY_ARGS) + { + /* This indicates a suffix operator. */ + operand = d_left (operand); + d_print_subexpr (dpi, options, operand); + d_print_expr_op (dpi, options, op); + return; + } + } - 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 - { - d_append_char (dpi, '('); - d_print_cast (dpi, options, d_left (dc)); - d_append_char (dpi, ')'); - } - d_print_subexpr (dpi, options, d_right (dc)); + if (op->type != DEMANGLE_COMPONENT_CAST) + d_print_expr_op (dpi, options, op); + else + { + d_append_char (dpi, '('); + d_print_cast (dpi, options, op); + d_append_char (dpi, ')'); + } + if (code && !strcmp (code, "gs")) + /* Avoid parens after '::'. */ + d_print_comp (dpi, options, operand); + else if (code && !strcmp (code, "st")) + /* Always print parens for sizeof (type). */ + { + d_append_char (dpi, '('); + d_print_comp (dpi, options, operand); + d_append_char (dpi, ')'); + } + else + d_print_subexpr (dpi, options, operand); + } return; case DEMANGLE_COMPONENT_BINARY: @@ -4393,11 +4495,33 @@ d_print_comp (struct d_print_info *dpi, int options, d_print_error (dpi); return; } - d_print_subexpr (dpi, options, d_left (d_right (dc))); - d_print_expr_op (dpi, options, d_left (dc)); - d_print_subexpr (dpi, options, d_left (d_right (d_right (dc)))); - d_append_string (dpi, " : "); - d_print_subexpr (dpi, options, d_right (d_right (d_right (dc)))); + { + struct demangle_component *op = d_left (dc); + struct demangle_component *first = d_left (d_right (dc)); + struct demangle_component *second = d_left (d_right (d_right (dc))); + struct demangle_component *third = d_right (d_right (d_right (dc))); + + if (!strcmp (op->u.s_operator.op->code, "qu")) + { + d_print_subexpr (dpi, options, first); + d_print_expr_op (dpi, options, op); + d_print_subexpr (dpi, options, second); + d_append_string (dpi, " : "); + d_print_subexpr (dpi, options, third); + } + else + { + d_append_string (dpi, "new "); + if (d_left (first) != NULL) + { + d_print_subexpr (dpi, options, first); + d_append_char (dpi, ' '); + } + d_print_comp (dpi, options, second); + if (third) + d_print_subexpr (dpi, options, third); + } + } return; case DEMANGLE_COMPONENT_TRINARY_ARG1: diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected index 70abf681ae8..3f3960a4093 100644 --- a/libiberty/testsuite/demangle-expected +++ b/libiberty/testsuite/demangle-expected @@ -3935,7 +3935,7 @@ _Z1tIlEDTplcvT_Li5EclL_Z1qsELi6EEEv decltype (((long)(5))+(q(6))) t() # test for expansion of function parameter pack --format=gnu-v3 -_Z1gIIidEEDTclL_Z1fEspplfp_Li1EEEDpT_ +_Z1gIJidEEDTclL_Z1fEspplfp_Li1EEEDpT_ decltype (f(({parm#1}+(1))...)) g(int, double) # lambda tests --format=gnu-v3 @@ -4018,6 +4018,57 @@ K<1, &S::m>::f() --format=gnu-v3 _ZSt10_ConstructI10CellBorderIS0_EEvPT_DpOT0_ _ZSt10_ConstructI10CellBorderIS0_EEvPT_DpOT0_ +# A pack expansion is substitutable. +--format=gnu-v3 +_Z1fIJiEiEv1AIJDpT_EET0_S4_ +void f(A, int, int) +# So is decltype. +--format=gnu-v3 +_Z1fIiiEDTcvT__EET0_S2_ +decltype ((int)()) f(int, int) +# And vector. +--format=gnu-v3 +_Z1fDv4_iS_ +f(int __vector(4), int __vector(4)) +--format=gnu-v3 +_Z2f1Ii1AEDTdsfp_fp0_ET0_MS2_T_ +decltype ({parm#1}.*{parm#2}) f1(A, int A::*) +--format=gnu-v3 +_Z2f2IiEDTquL_Z1bEfp_trET_ +decltype (b?{parm#1} : (throw)) f2(int) +--format=gnu-v3 +_Z6check1IiEvP6helperIXsznw_T_EEE +void check1(helper*) +--format=gnu-v3 +_Z6check2IiEvP6helperIXszgsnw_T_piEEE +void check2(helper*) +--format=gnu-v3 +_Z6check3IiEvP6helperIXsznwadL_Z1iE_T_piLi1EEEE +void check3(helper*) +--format=gnu-v3 +_Z6check4IiEvP6helperIXszna_A1_T_EEE +void check4(helper*) +--format=gnu-v3 +_Z6check5IiEvP6helperIXszna_A1_T_piEEE +void check5(helper*) +--format=gnu-v3 +_Z1fIiEDTcmgsdlfp_psfp_EPT_ +decltype ((::delete {parm#1}),(+{parm#1})) f(int*) +--format=gnu-v3 +_Z1fIiEDTcmdafp_psfp_EPT_ +decltype ((delete[] {parm#1}),(+{parm#1})) f(int*) +--format=gnu-v3 +_Z2f1IiEDTppfp_ET_ +decltype ({parm#1}++) f1(int) +--format=gnu-v3 +_Z2f1IiEDTpp_fp_ET_ +decltype (++{parm#1}) f1(int) +--format=gnu-v3 +_Z2f1IiEDTcl1gfp_ilEEET_ +decltype (g({parm#1}, {})) f1(int) +--format=gnu-v3 +_Z2f1IiEDTnw_T_ilEES0_ +decltype (new int{}) f1(int) # # Ada (GNAT) tests. # -- 2.30.2