diff options
author | samuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-05 01:01:12 +0000 |
---|---|---|
committer | samuel <samuel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-09-05 01:01:12 +0000 |
commit | 40e00cb07ea62c37c57ac7a658315b885c711ef3 (patch) | |
tree | 080c4c809c23cab4fbada302cee7e2c74c17d4b4 | |
parent | a084c69e8c419ef18f55fcf217c90d017ac3d37a (diff) | |
download | gcc-40e00cb07ea62c37c57ac7a658315b885c711ef3.tar.gz |
In include:
* dyn-string.h: Adjust formatting.
(dyn_string_insert_char): New macro. New declaration.
In libiberty:
* cp-demangle.c (ANONYMOUS_NAMESPACE_PREFIX): New macro.
(substitution_def): Remove template_parm_number.
(NOT_TEMPLATE_PARM): Remove.
(result_insert_string): New macro.
(result_insert): Likewise.
(result_insert_char): Likewise.
(substitution_add): Remove last parameter. Don't store template
parm number.
(BFT_NO_RETURN_TYPE): Define as NULL.
(demangle_encoding): Adjust call to demangle_bare_function_type.
(demangle_name): Adjust substitution. Adjust call to
substitution_add.
(demangle_prefix): Adjust call to substitution_add.
(demangle_identifier): Handle anonymous namespaces.
(demangle_operator_name): Change demangling of vendor-extended
operator to match ABI changes.
(demangle_type_ptr): Change parameters. Make recursive. Handle
substitutions here.
(demangle_type): Adjust calls to demangle_template_param,
substitution_add, and demangle_type_ptr. Fix substitution of
templated types.
(demangle_function_type): Change parameter to a pointer.
(demangle_bare_function_type): Likewise. Adjust insertion point.
(demangle_template_param): Remove last parameter.
(demangle_expr_primary): Remove unused variable. Adjust call to
demangle_template_param.
(is_mangled_char): Accept `$' and `.'.
* cplus-dem.c (gnu_new_abi_symbol_characters): Add '$' and '.'.
* dyn-string.c (dyn_string_insert_char): New function.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36148 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | include/ChangeLog | 5 | ||||
-rw-r--r-- | include/dyn-string.h | 8 | ||||
-rw-r--r-- | libiberty/ChangeLog | 32 | ||||
-rw-r--r-- | libiberty/cp-demangle.c | 363 | ||||
-rw-r--r-- | libiberty/cplus-dem.c | 2 | ||||
-rw-r--r-- | libiberty/dyn-string.c | 24 |
6 files changed, 286 insertions, 148 deletions
diff --git a/include/ChangeLog b/include/ChangeLog index 6c68319a244..5a541b610bc 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,8 @@ +2000-09-04 Alex Samuel <samuel@codesourcery.com> + + * dyn-string.h: Adjust formatting. + (dyn_string_insert_char): New macro. New declaration. + 2000-08-28 Jason Merrill <jason@redhat.com> * md5.h: New file. diff --git a/include/dyn-string.h b/include/dyn-string.h index 103f9472538..67f7ab7d36e 100644 --- a/include/dyn-string.h +++ b/include/dyn-string.h @@ -59,6 +59,7 @@ typedef struct dyn_string #define dyn_string_prepend_cstr __cxa_dyn_string_prepend_cstr #define dyn_string_insert __cxa_dyn_string_insert #define dyn_string_insert_cstr __cxa_dyn_string_insert_cstr +#define dyn_string_insert_char __cxa_dyn_string_insert_char #define dyn_string_append __cxa_dyn_string_append #define dyn_string_append_cstr __cxa_dyn_string_append_cstr #define dyn_string_append_char __cxa_dyn_string_append_char @@ -82,11 +83,10 @@ extern int dyn_string_insert PARAMS ((dyn_string_t, int, dyn_string_t)); extern int dyn_string_insert_cstr PARAMS ((dyn_string_t, int, const char *)); +extern int dyn_string_insert_char PARAMS ((dyn_string_t, int, int)); extern int dyn_string_append PARAMS ((dyn_string_t, dyn_string_t)); -extern int dyn_string_append_cstr - PARAMS ((dyn_string_t, const char *)); -extern int dyn_string_append_char - PARAMS ((dyn_string_t, int)); +extern int dyn_string_append_cstr PARAMS ((dyn_string_t, const char *)); +extern int dyn_string_append_char PARAMS ((dyn_string_t, int)); extern int dyn_string_substring PARAMS ((dyn_string_t, dyn_string_t, int, int)); extern int dyn_string_eq PARAMS ((dyn_string_t, dyn_string_t)); diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 2a9b32f5ba6..0ee0abfda90 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,35 @@ +2000-09-03 Alex Samuel <samuel@codesourcery.com> + + * cp-demangle.c (ANONYMOUS_NAMESPACE_PREFIX): New macro. + (substitution_def): Remove template_parm_number. + (NOT_TEMPLATE_PARM): Remove. + (result_insert_string): New macro. + (result_insert): Likewise. + (result_insert_char): Likewise. + (substitution_add): Remove last parameter. Don't store template + parm number. + (BFT_NO_RETURN_TYPE): Define as NULL. + (demangle_encoding): Adjust call to demangle_bare_function_type. + (demangle_name): Adjust substitution. Adjust call to + substitution_add. + (demangle_prefix): Adjust call to substitution_add. + (demangle_identifier): Handle anonymous namespaces. + (demangle_operator_name): Change demangling of vendor-extended + operator to match ABI changes. + (demangle_type_ptr): Change parameters. Make recursive. Handle + substitutions here. + (demangle_type): Adjust calls to demangle_template_param, + substitution_add, and demangle_type_ptr. Fix substitution of + templated types. + (demangle_function_type): Change parameter to a pointer. + (demangle_bare_function_type): Likewise. Adjust insertion point. + (demangle_template_param): Remove last parameter. + (demangle_expr_primary): Remove unused variable. Adjust call to + demangle_template_param. + (is_mangled_char): Accept `$' and `.'. + * cplus-dem.c (gnu_new_abi_symbol_characters): Add '$' and '.'. + * dyn-string.c (dyn_string_insert_char): New function. + 2000-08-31 Hans-Peter Nilsson <hp@axis.com> * testsuite/demangle-expected: Add nine tests for diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c index d8c7cedb595..f6e58342ed2 100644 --- a/libiberty/cp-demangle.c +++ b/libiberty/cp-demangle.c @@ -62,6 +62,10 @@ (((CHAR) >= 'a' && (CHAR) <= 'z') \ || ((CHAR) >= 'A' && (CHAR) <= 'Z')) +/* The prefix prepended by GCC to an identifier represnting the + anonymous namespace. */ +#define ANONYMOUS_NAMESPACE_PREFIX "_GLOBAL_" + /* If flag_verbose is zero, some simplifications will be made to the output to make it easier to read and supress details that are generally not of interest to the average C++ programmer. @@ -92,17 +96,10 @@ struct substitution_def /* The demangled text of the substitution. */ dyn_string_t text; - /* The template parameter that this represents, indexed from zero. - If this is not a template paramter number, the value is - NOT_TEMPLATE_PARM. */ - int template_parm_number; - /* Whether this substitution represents a template item. */ int template_p : 1; }; -#define NOT_TEMPLATE_PARM (-1) - /* Data structure representing a template argument list. */ struct template_arg_list_def @@ -206,7 +203,7 @@ static string_list_t result_pop static int substitution_start PARAMS ((demangling_t)); static status_t substitution_add - PARAMS ((demangling_t, int, int, int)); + PARAMS ((demangling_t, int, int)); static dyn_string_t substitution_get PARAMS ((demangling_t, int, int *)); #ifdef CP_DEMANGLE_DEBUG @@ -288,6 +285,22 @@ static void demangling_delete (dyn_string_append_char (&(DM)->result->string, (CHAR)) \ ? STATUS_OK : STATUS_ALLOCATION_FAILED) +/* Inserts a dyn_string_t to the demangled result at position POS. */ +#define result_insert_string(DM, POS, STRING) \ + (dyn_string_insert (&(DM)->result->string, (POS), (STRING)) \ + ? STATUS_OK : STATUS_ALLOCATION_FAILED) + +/* Inserts NUL-terminated string CSTR to the demangled result at + position POS. */ +#define result_insert(DM, POS, CSTR) \ + (dyn_string_insert_cstr (&(DM)->result->string, (POS), (CSTR)) \ + ? STATUS_OK : STATUS_ALLOCATION_FAILED) + +/* Inserts character CHAR to the demangled result at position POS. */ +#define result_insert_char(DM, POS, CHAR) \ + (dyn_string_insert_char (&(DM)->result->string, (POS), (CHAR)) \ + ? STATUS_OK : STATUS_ALLOCATION_FAILED) + /* The length of the current demangled result. */ #define result_length(DM) \ dyn_string_length (&(DM)->result->string) @@ -458,19 +471,13 @@ substitution_start (dm) /* Adds the suffix of the current demangled result of DM starting at START_POSITION as a potential substitution. If TEMPLATE_P is - non-zero, this potential substitution is a template-id. - - If TEMPLATE_PARM_NUMBER is not NOT_TEMPLATE_PARM, the substitution - is for that particular <template-param>, and is distinct from other - otherwise-identical types and other <template-param>s with - different indices. */ + non-zero, this potential substitution is a template-id. */ static status_t -substitution_add (dm, start_position, template_p, template_parm_number) +substitution_add (dm, start_position, template_p) demangling_t dm; int start_position; int template_p; - int template_parm_number; { dyn_string_t result = result_string (dm); dyn_string_t substitution = dyn_string_new (0); @@ -513,7 +520,6 @@ substitution_add (dm, start_position, template_p, template_parm_number) i = dm->num_substitutions++; dm->substitutions[i].text = substitution; dm->substitutions[i].template_p = template_p; - dm->substitutions[i].template_parm_number = template_parm_number; #ifdef CP_DEMANGLE_DEBUG substitutions_print (dm, stderr); @@ -815,7 +821,7 @@ static status_t demangle_special_name static status_t demangle_ctor_dtor_name PARAMS ((demangling_t)); static status_t demangle_type_ptr - PARAMS ((demangling_t)); + PARAMS ((demangling_t, int *, int)); static status_t demangle_type PARAMS ((demangling_t)); static status_t demangle_CV_qualifiers @@ -823,15 +829,15 @@ static status_t demangle_CV_qualifiers static status_t demangle_builtin_type PARAMS ((demangling_t)); static status_t demangle_function_type - PARAMS ((demangling_t, int)); + PARAMS ((demangling_t, int *)); static status_t demangle_bare_function_type - PARAMS ((demangling_t, int)); + PARAMS ((demangling_t, int *)); static status_t demangle_class_enum_type PARAMS ((demangling_t, int *)); static status_t demangle_array_type PARAMS ((demangling_t)); static status_t demangle_template_param - PARAMS ((demangling_t, int *)); + PARAMS ((demangling_t)); static status_t demangle_template_args PARAMS ((demangling_t)); static status_t demangle_literal @@ -859,7 +865,7 @@ static status_t cp_demangle_type /* When passed to demangle_bare_function_type, indicates that the function's return type is not encoded before its parameter types. */ -#define BFT_NO_RETURN_TYPE -1 +#define BFT_NO_RETURN_TYPE NULL /* Check that the next character is C. If so, consume it. If not, return an error. */ @@ -937,7 +943,7 @@ demangle_encoding (dm) /* Template functions have their return type encoded. The return type should be inserted at start_position. */ RETURN_IF_ERROR - (demangle_bare_function_type (dm, start_position)); + (demangle_bare_function_type (dm, &start_position)); else /* Non-template functions don't have their return type encoded. */ @@ -974,6 +980,7 @@ demangle_name (dm, template_p) { int start = substitution_start (dm); char peek = peek_char (dm); + int is_std_substitution = 0; DEMANGLE_TRACE ("name", dm); @@ -998,6 +1005,7 @@ demangle_name (dm, template_p) (void) next_char (dm); RETURN_IF_ERROR (result_append (dm, "std::")); RETURN_IF_ERROR (demangle_unqualified_name (dm)); + is_std_substitution = 1; } else { @@ -1007,11 +1015,11 @@ demangle_name (dm, template_p) If so, then we just demangled an <unqualified-template-name>. */ if (peek_char (dm) == 'I') { - /* The template name is a substitution candidate, unless it - was already a back-substitution. */ - if (peek != 'S') - RETURN_IF_ERROR (substitution_add (dm, start, 0, - NOT_TEMPLATE_PARM)); + /* A template name of the form std::<unqualified-name> is a + substitution candidate. */ + if (is_std_substitution) + RETURN_IF_ERROR (substitution_add (dm, start, 0)); + /* Demangle the <template-args> here. */ RETURN_IF_ERROR (demangle_template_args (dm)); *template_p = 1; } @@ -1029,8 +1037,7 @@ demangle_name (dm, template_p) if (peek_char (dm) == 'I') { /* Add a substitution for the unqualified template name. */ - RETURN_IF_ERROR (substitution_add (dm, start, 0, - NOT_TEMPLATE_PARM)); + RETURN_IF_ERROR (substitution_add (dm, start, 0)); RETURN_IF_ERROR (demangle_template_args (dm)); *template_p = 1; @@ -1185,8 +1192,7 @@ demangle_prefix (dm, template_p) if (peek != 'S' && peek_char (dm) != 'E') /* Add a new substitution for the prefix thus far. */ - RETURN_IF_ERROR (substitution_add (dm, start, *template_p, - NOT_TEMPLATE_PARM)); + RETURN_IF_ERROR (substitution_add (dm, start, *template_p)); } } @@ -1353,6 +1359,29 @@ demangle_identifier (dm, length, identifier) return STATUS_ALLOCATION_FAILED; } + /* GCC encodes anonymous namespaces using a `_GLOBAL_[_.$]N.' + followed by the source file name and some random characters. + Unless we're in strict mode, decipher these names appropriately. */ + if (!flag_strict) + { + char *name = dyn_string_buf (identifier); + int prefix_length = strlen (ANONYMOUS_NAMESPACE_PREFIX); + + /* Compare the first, fixed part. */ + if (strncmp (name, ANONYMOUS_NAMESPACE_PREFIX, prefix_length) == 0) + { + name += prefix_length; + /* The next character might be a period, an underscore, or + dollar sign, depending on the target architecture's + assembler's capabilities. After that comes an `N'. */ + if ((*name == '.' || *name == '_' || *name == '$') + && *(name + 1) == 'N') + /* This looks like the anonymous namespace identifier. + Replace it with something comprehensible. */ + dyn_string_copy_cstr (identifier, "(anonymous namespace)"); + } + } + return STATUS_OK; } @@ -1411,7 +1440,7 @@ demangle_identifier (dm, length, identifier) ::= qu # ? ::= sz # sizeof ::= cv <type> # cast - ::= vx <source-name> # vendor extended operator */ + ::= v [0-9] <source-name> # vendor extended operator */ static status_t demangle_operator_name (dm, short_name, num_args) @@ -1491,10 +1520,10 @@ demangle_operator_name (dm, short_name, num_args) DEMANGLE_TRACE ("operator-name", dm); - /* Is this a vendor extended operator? */ - if (c0 == 'v' && c1 == 'x') + /* Is this a vendor-extended operator? */ + if (c0 == 'v' && IS_DIGIT (c1)) { - RETURN_IF_ERROR (result_append (dm, "operator")); + RETURN_IF_ERROR (result_append (dm, "operator ")); RETURN_IF_ERROR (demangle_source_name (dm)); *num_args = 0; return STATUS_OK; @@ -1832,6 +1861,19 @@ demangle_ctor_dtor_name (dm) a pointer to data or pointer to function to construct the right output syntax. C++'s pointer syntax is hairy. + This function adds substitution candidates for every nested + pointer/reference type it processes, including the outermost, final + type, assuming the substitution starts at SUBSTITUTION_START in the + demangling result. For example, if this function demangles + `PP3Foo', it will add a substitution for `Foo', `Foo*', and + `Foo**', in that order. + + *INSERT_POS is a quantity used internally, when this function calls + itself recursively, to figure out where to insert pointer + punctuation on the way up. On entry to this function, INSERT_POS + should point to a temporary value, but that value need not be + initialized. + <type> ::= P <type> ::= R <type> ::= <pointer-to-member-type> @@ -1839,104 +1881,131 @@ demangle_ctor_dtor_name (dm) <pointer-to-member-type> ::= M </class/ type> </member/ type> */ static status_t -demangle_type_ptr (dm) +demangle_type_ptr (dm, insert_pos, substitution_start) demangling_t dm; + int *insert_pos; + int substitution_start; { char next; status_t status; - - /* Collect pointer symbols into this string. */ - dyn_string_t symbols = dyn_string_new (10); + int is_substitution_candidate = 1; DEMANGLE_TRACE ("type*", dm); - if (symbols == NULL) - return STATUS_ALLOCATION_FAILED; - /* Scan forward, collecting pointers and references into symbols, until we hit something else. Then emit the type. */ - while (1) + next = peek_char (dm); + if (next == 'P') { - next = peek_char (dm); - if (next == 'P') - { - if (!dyn_string_append_char (symbols, '*')) - return STATUS_ALLOCATION_FAILED; - advance_char (dm); - } - else if (next == 'R') - { - if (!dyn_string_append_char (symbols, '&')) - return STATUS_ALLOCATION_FAILED; - advance_char (dm); - } - else if (next == 'M') - { - /* Pointer-to-member. */ - dyn_string_t class_type; - - /* Eat the 'M'. */ - advance_char (dm); - - /* Capture the type of which this is a pointer-to-member. */ - RETURN_IF_ERROR (result_push (dm)); - RETURN_IF_ERROR (demangle_type (dm)); - class_type = (dyn_string_t) result_pop (dm); - - /* Build the pointer-to-member notation. It comes before - other pointer and reference qualifiers -- */ - if (!dyn_string_prepend_cstr (symbols, "::*")) - return STATUS_ALLOCATION_FAILED; - if (!dyn_string_prepend (symbols, class_type)) - return STATUS_ALLOCATION_FAILED; - dyn_string_delete (class_type); - - if (peek_char (dm) == 'F') - continue; - - /* Demangle the type of the pointed-to member. */ + /* A pointer. Snarf the `P'. */ + advance_char (dm); + /* Demangle the underlying type. */ + RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos, + substitution_start)); + /* Insert an asterisk where we're told to; it doesn't + necessarily go at the end. */ + RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '*')); + } + else if (next == 'R') + { + /* A reference. Snarf the `R'. */ + advance_char (dm); + /* Demangle the underlying type. */ + RETURN_IF_ERROR (demangle_type_ptr (dm, insert_pos, + substitution_start)); + /* Insert an ampersand where we're told to; it doesn't + necessarily go at the end. */ + RETURN_IF_ERROR (result_insert_char (dm, *insert_pos, '&')); + } + else if (next == 'M') + { + /* A pointer-to-member. */ + dyn_string_t class_type; + + /* Eat the 'M'. */ + advance_char (dm); + + /* Capture the type of which this is a pointer-to-member. */ + RETURN_IF_ERROR (result_push (dm)); + RETURN_IF_ERROR (demangle_type (dm)); + class_type = (dyn_string_t) result_pop (dm); + + if (peek_char (dm) == 'F') + /* A pointer-to-member function. We want output along the + lines of `void (C::*) (int, int)'. Demangle the function + type, which would in this case give `void () (int, int)' + and set *insert_pos to the spot between the first + parentheses. */ + status = demangle_type_ptr (dm, insert_pos, substitution_start); + else + { + /* A pointer-to-member variable. Demangle the type of the + pointed-to member. */ status = demangle_type (dm); /* Make it pretty. */ if (STATUS_NO_ERROR (status)) status = result_append_space (dm); - /* Add the pointer-to-member syntax, and other pointer and - reference symbols. */ - if (STATUS_NO_ERROR (status)) - status = result_append_string (dm, symbols); - /* Clean up. */ - dyn_string_delete (symbols); - - RETURN_IF_ERROR (status); - return STATUS_OK; + /* The pointer-to-member notation (e.g. `C::*') follows the + member's type. */ + *insert_pos = result_length (dm); } - else if (next == 'F') - { - /* Ooh, tricky, a pointer-to-function. */ - int position = result_length (dm); - status = result_append_char (dm, '('); - if (STATUS_NO_ERROR (status)) - status = result_append_string (dm, symbols); - if (STATUS_NO_ERROR (status)) - status = result_append_char (dm, ')'); - dyn_string_delete (symbols); - RETURN_IF_ERROR (status); - RETURN_IF_ERROR (demangle_function_type (dm, position)); - return STATUS_OK; - } - else - { - /* No more pointer or reference tokens. Finish up. */ - status = demangle_type (dm); + /* Build the pointer-to-member notation. */ + if (STATUS_NO_ERROR (status)) + status = result_insert (dm, *insert_pos, "::*"); + if (STATUS_NO_ERROR (status)) + status = result_insert_string (dm, *insert_pos, class_type); + /* There may be additional levels of (pointer or reference) + indirection in this type. If so, the `*' and `&' should be + added after the pointer-to-member notation (e.g. `C::*&' for + a reference to a pointer-to-member of class C). */ + *insert_pos += dyn_string_length (class_type) + 3; - if (STATUS_NO_ERROR (status)) - status = result_append_string (dm, symbols); - dyn_string_delete (symbols); + /* Clean up. */ + dyn_string_delete (class_type); - RETURN_IF_ERROR (status); - return STATUS_OK; - } + RETURN_IF_ERROR (status); + } + else if (next == 'F') + { + /* Ooh, tricky, a pointer-to-function. When we demangle the + function type, the return type should go at the very + beginning. */ + *insert_pos = result_length (dm); + /* The parentheses indicate this is a function pointer or + reference type. */ + RETURN_IF_ERROR (result_append (dm, "()")); + /* Now demangle the function type. The return type will be + inserted before the `()', and the argument list will go after + it. */ + RETURN_IF_ERROR (demangle_function_type (dm, insert_pos)); + /* We should now have something along the lines of + `void () (int, int)'. The pointer or reference characters + have to inside the first set of parentheses. *insert_pos has + already been updated to point past the end of the return + type. Move it one character over so it points inside the + `()'. */ + ++(*insert_pos); + } + else + { + /* No more pointer or reference tokens; this is therefore a + pointer to data. Finish up by demangling the underlying + type. */ + RETURN_IF_ERROR (demangle_type (dm)); + /* The pointer or reference characters follow the underlying + type, as in `int*&'. */ + *insert_pos = result_length (dm); + /* Because of the production <type> ::= <substitution>, + demangle_type will already have added the underlying type as + a substitution candidate. Don't do it again. */ + is_substitution_candidate = 0; } + + if (is_substitution_candidate) + RETURN_IF_ERROR (substitution_add (dm, substitution_start, 0)); + + return STATUS_OK; } /* Demangles and emits a <type>. @@ -1965,7 +2034,7 @@ demangle_type (dm) char peek_next; int template_p = 0; template_arg_list_t old_arg_list = current_template_arg_list (dm); - int template_parm = NOT_TEMPLATE_PARM; + int insert_pos; /* A <type> can be a <substitution>; therefore, this <type> is a substitution candidate unless a special condition holds (see @@ -2040,7 +2109,7 @@ demangle_type (dm) /* It's either a <template-param> or a <template-template-param>. In either case, demangle the `T' token first. */ - RETURN_IF_ERROR (demangle_template_param (dm, &template_parm)); + RETURN_IF_ERROR (demangle_template_param (dm)); /* Check for a template argument list; if one is found, it's a <template-template-param> ::= <template-param> @@ -2050,8 +2119,7 @@ demangle_type (dm) /* Add a substitution candidate. The template parameter `T' token is a substitution candidate by itself, without the template argument list. */ - RETURN_IF_ERROR (substitution_add (dm, start, template_p, - template_parm)); + RETURN_IF_ERROR (substitution_add (dm, start, template_p)); /* Now demangle the template argument list. */ RETURN_IF_ERROR (demangle_template_args (dm)); @@ -2077,23 +2145,27 @@ demangle_type (dm) them. */ if (peek_char (dm) == 'I') RETURN_IF_ERROR (demangle_template_args (dm)); - - /* A substitution token is not itself a substitution - candidate. */ - is_substitution_candidate = 0; + else + /* A substitution token is not itself a substitution + candidate. (However, if the substituted template is + instantiated, the resulting type is.) */ + is_substitution_candidate = 0; } else /* While the special substitution token itself is not a substitution candidate, the <class-enum-type> is, so don't clear is_substitution_candidate. */ - demangle_class_enum_type (dm, &template_p); + RETURN_IF_ERROR (demangle_class_enum_type (dm, &template_p)); break; case 'P': case 'R': case 'M': - RETURN_IF_ERROR (demangle_type_ptr (dm)); + RETURN_IF_ERROR (demangle_type_ptr (dm, &insert_pos, start)); + /* demangle_type_ptr adds all applicable substitution + candidates. */ + is_substitution_candidate = 0; break; case 'C': @@ -2111,7 +2183,7 @@ demangle_type (dm) break; case 'U': - /* Vendor extended type qualifier. */ + /* Vendor-extended type qualifier. */ advance_char (dm); RETURN_IF_ERROR (demangle_source_name (dm)); RETURN_IF_ERROR (result_append_char (dm, ' ')); @@ -2127,7 +2199,7 @@ demangle_type (dm) <template-param>, pass its index since from the point of substitutions; a <template-param> token is a substitution candidate distinct from the type that is substituted for it. */ - RETURN_IF_ERROR (substitution_add (dm, start, template_p, template_parm)); + RETURN_IF_ERROR (substitution_add (dm, start, template_p)); /* Pop off template argument lists added during mangling of this type. */ @@ -2266,16 +2338,18 @@ demangle_CV_qualifiers (dm, qualifiers) } } -/* Demangles and emits a <function-type> FUNCTION_NAME_POS is the +/* Demangles and emits a <function-type>. *FUNCTION_NAME_POS is the position in the result string of the start of the function - identifier, at which the function's return type will be inserted. + identifier, at which the function's return type will be inserted; + *FUNCTION_NAME_POS is updated to position past the end of the + function's return type. <function-type> ::= F [Y] <bare-function-type> E */ static status_t demangle_function_type (dm, function_name_pos) demangling_t dm; - int function_name_pos; + int *function_name_pos; { DEMANGLE_TRACE ("function-type", dm); RETURN_IF_ERROR (demangle_char (dm, 'F')); @@ -2301,7 +2375,7 @@ demangle_function_type (dm, function_name_pos) static status_t demangle_bare_function_type (dm, return_type_pos) demangling_t dm; - int return_type_pos; + int *return_type_pos; { /* Sequence is the index of the current function parameter, counting from zero. The value -1 denotes the return type. */ @@ -2326,10 +2400,16 @@ demangle_bare_function_type (dm, return_type_pos) /* Add a space to the end of the type. Insert the return type where we've been asked to. */ - if (!dyn_string_append_space (return_type) - || !dyn_string_insert (result_string (dm), return_type_pos, - return_type)) + if (!dyn_string_append_space (return_type)) status = STATUS_ALLOCATION_FAILED; + if (STATUS_NO_ERROR (status)) + { + if (!dyn_string_insert (result_string (dm), *return_type_pos, + return_type)) + status = STATUS_ALLOCATION_FAILED; + else + *return_type_pos += dyn_string_length (return_type); + } dyn_string_delete (return_type); RETURN_IF_ERROR (status); @@ -2436,16 +2516,14 @@ demangle_array_type (dm) return STATUS_OK; } -/* Demangles and emits a <template-param>. The zero-indexed position - in the parameter list is placed in *TEMPLATE_PARM_NUMBER. +/* Demangles and emits a <template-param>. <template-param> ::= T_ # first template parameter ::= T <parameter-2 number> _ */ static status_t -demangle_template_param (dm, template_parm_number) +demangle_template_param (dm) demangling_t dm; - int *template_parm_number; { int parm_number; template_arg_list_t current_arg_list = current_template_arg_list (dm); @@ -2475,7 +2553,6 @@ demangle_template_param (dm, template_parm_number) return "Template parameter number out of bounds."; RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg)); - *template_parm_number = parm_number; return STATUS_OK; } @@ -2784,12 +2861,11 @@ demangle_expr_primary (dm) demangling_t dm; { char peek = peek_char (dm); - int unused; DEMANGLE_TRACE ("expr-primary", dm); if (peek == 'T') - RETURN_IF_ERROR (demangle_template_param (dm, &unused)); + RETURN_IF_ERROR (demangle_template_param (dm)); else if (peek == 'L') { /* Consume the `L'. */ @@ -2826,7 +2902,7 @@ demangle_expr_primary (dm) ::= So # ::std::basic_ostream<char, std::char_traits<char> > ::= Sd # ::std::basic_iostream<char, - std::char_traits<char> > + std::char_traits<char> > */ static status_t @@ -3297,7 +3373,8 @@ static void print_usage /* Non-zero if CHAR is a character than can occur in a mangled name. */ #define is_mangled_char(CHAR) \ - (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) || (CHAR) == '_') + (IS_ALPHA (CHAR) || IS_DIGIT (CHAR) \ + || (CHAR) == '_' || (CHAR) == '.' || (CHAR) == '$') /* The name of this program, as invoked. */ const char* program_name; diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c index 6156303ef1f..e00f787e75c 100644 --- a/libiberty/cplus-dem.c +++ b/libiberty/cplus-dem.c @@ -4853,7 +4853,7 @@ hp_symbol_characters () static const char * gnu_new_abi_symbol_characters () { - return "_"; + return "_$."; } diff --git a/libiberty/dyn-string.c b/libiberty/dyn-string.c index 69897f84c5e..34f88ade96d 100644 --- a/libiberty/dyn-string.c +++ b/libiberty/dyn-string.c @@ -305,6 +305,30 @@ dyn_string_insert_cstr (dest, pos, src) return 1; } +/* Inserts character C into DEST starting at position POS. DEST is + expanded as necessary. Returns 1 on success. On failure, + RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ + +int +dyn_string_insert_char (dest, pos, c) + dyn_string_t dest; + int pos; + int c; +{ + int i; + + if (dyn_string_resize (dest, dest->length + 1) == NULL) + return 0; + /* Make room for the insertion. Be sure to copy the NUL. */ + for (i = dest->length; i >= pos; --i) + dest->s[i + 1] = dest->s[i]; + /* Add the new character. */ + dest->s[pos] = c; + /* Compute the new length. */ + ++dest->length; + return 1; +} + /* Append S to DS, resizing DS if necessary. Returns 1 on success. On failure, if RETURN_ON_ALLOCATION_FAILURE, deletes DEST and returns 0. */ |