diff options
Diffstat (limited to 'libiberty/cp-demangle.c')
-rw-r--r-- | libiberty/cp-demangle.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index 4a91700..162aafca 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -898,7 +898,7 @@ static status_t demangle_number_literally static status_t demangle_identifier PARAMS ((demangling_t, int, dyn_string_t)); static status_t demangle_operator_name - PARAMS ((demangling_t, int, int *)); + PARAMS ((demangling_t, int, int *, int *)); static status_t demangle_nv_offset PARAMS ((demangling_t)); static status_t demangle_v_offset @@ -1325,7 +1325,7 @@ demangle_unqualified_name (dm, suppress_return_type) if (peek == 'c' && peek_char_next (dm) == 'v') *suppress_return_type = 1; - RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args)); + RETURN_IF_ERROR (demangle_operator_name (dm, 0, &num_args, NULL)); } else if (peek == 'C' || peek == 'D') { @@ -1501,7 +1501,9 @@ demangle_identifier (dm, length, identifier) /* Demangles and emits an <operator-name>. If SHORT_NAME is non-zero, the short form is emitted; otherwise the full source form (`operator +' etc.) is emitted. *NUM_ARGS is set to the number of - operands that the operator takes. + operands that the operator takes. If TYPE_ARG is non-NULL, + *TYPE_ARG is set to 1 if the first argument is a type and 0 + otherwise. <operator-name> ::= nw # new @@ -1551,15 +1553,17 @@ demangle_identifier (dm, length, identifier) ::= cl # () ::= ix # [] ::= qu # ? - ::= sz # sizeof + ::= st # sizeof (a type) + ::= sz # sizeof (an expression) ::= cv <type> # cast ::= v [0-9] <source-name> # vendor extended operator */ static status_t -demangle_operator_name (dm, short_name, num_args) +demangle_operator_name (dm, short_name, num_args, type_arg) demangling_t dm; int short_name; int *num_args; + int *type_arg; { struct operator_code { @@ -1633,6 +1637,10 @@ demangle_operator_name (dm, short_name, num_args) DEMANGLE_TRACE ("operator-name", dm); + /* Assume the first argument is not a type. */ + if (type_arg) + *type_arg = 0; + /* Is this a vendor-extended operator? */ if (c0 == 'v' && IS_DIGIT (c1)) { @@ -1652,6 +1660,16 @@ demangle_operator_name (dm, short_name, num_args) return STATUS_OK; } + /* Is it the sizeof variant that takes a type? */ + if (c0 == 's' && c1 == 't') + { + RETURN_IF_ERROR (result_add (dm, " sizeof")); + *num_args = 1; + if (type_arg) + *type_arg = 1; + return STATUS_OK; + } + /* Perform a binary search for the operator code. */ while (1) { @@ -3154,6 +3172,7 @@ demangle_expression (dm) /* An operator expression. */ { int num_args; + int type_arg; status_t status = STATUS_OK; dyn_string_t operator_name; @@ -3161,7 +3180,8 @@ demangle_expression (dm) operations in infix notation, capture the operator name first. */ RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args)); + RETURN_IF_ERROR (demangle_operator_name (dm, 1, &num_args, + &type_arg)); operator_name = (dyn_string_t) result_pop (dm); /* If it's binary, do an operand first. */ @@ -3182,7 +3202,10 @@ demangle_expression (dm) /* Emit its second (if binary) or only (if unary) operand. */ RETURN_IF_ERROR (result_add_char (dm, '(')); - RETURN_IF_ERROR (demangle_expression (dm)); + if (type_arg) + RETURN_IF_ERROR (demangle_type (dm)); + else + RETURN_IF_ERROR (demangle_expression (dm)); RETURN_IF_ERROR (result_add_char (dm, ')')); /* The ternary operator takes a third operand. */ |