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.

From-SVN: r36148
This commit is contained in:
Alex Samuel 2000-09-05 01:01:12 +00:00 committed by Alex Samuel
parent c9672d45dc
commit 31e0ab1f76
6 changed files with 286 additions and 148 deletions

View File

@ -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.

View File

@ -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));

View File

@ -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

View File

@ -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;

View File

@ -4853,7 +4853,7 @@ hp_symbol_characters ()
static const char *
gnu_new_abi_symbol_characters ()
{
return "_";
return "_$.";
}

View File

@ -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. */