C++ PATCH: new-ABI demangler fixes
Alex Samuel
samuel@codesourcery.com
Sun Oct 22 16:58:00 GMT 2000
This patch fixes some problems with the incorrect generation of
demangled names of
- array pointer and reference types
- const member functions
- CV-qualified pointers and pointers-to-member
in libiberty:
* cp-demangle.c (string_list_def): Add caret_position and comments.
(result_caret_pos): New macro.
(result_append_string): Rename to...
(result_add_string): ... this, and insert at caret position.
Rename throughout.
(result_append): Rename to...
(result_add): ... this, and insert at caret position. Rename
throughout.
(result_append_char): Rename to...
(result_add_char): ... this, and insert at caret position. Rename
throughout.
(result_append_space): Remove.
(string_list_new): Initialize caret position.
(result_add_separated_char): Use caret position.
(result_get_caret): New funtion.
(result_set_caret): Likewise.
(result_shift_caret): Likewise.
(result_previous_char_is_space): Likewise.
(substitution_start): Use caret position.
(substitution_add): Likewise.
(demangling_new): Initialize caret position.
(demangle_encoding): Use caret position.
(demanglin_nested_name): Put CV qualifiers after name.
(demangle_type_ptr): Use switch statement. Handle pointers to
arrays. Don't use result_append_space. Use caret position.
(demangle_type): Emit CV qualifiers after underlying type. Adjust
call to demangle_array_type.
(demangle_array_type): Add parameter to handle pointers to arrays.
Index: cp-demangle.c
===================================================================
RCS file: /cvs/gcc/egcs/libiberty/cp-demangle.c,v
retrieving revision 1.23
diff -c -p -r1.23 cp-demangle.c
*** cp-demangle.c 2000/09/08 17:50:54 1.23
--- cp-demangle.c 2000/10/22 23:52:44
*************** static int flag_verbose;
*** 79,91 ****
specification -- don't demangle special g++ manglings. */
static int flag_strict;
! /* String_list_t is an extended form of dyn_string_t which provides a link
! field. A string_list_t may safely be cast to and used as a
! dyn_string_t. */
struct string_list_def
{
struct dyn_string string;
struct string_list_def *next;
};
--- 79,100 ----
specification -- don't demangle special g++ manglings. */
static int flag_strict;
! /* String_list_t is an extended form of dyn_string_t which provides a
! link field and a caret position for additions to the string. A
! string_list_t may safely be cast to and used as a dyn_string_t. */
struct string_list_def
{
+ /* The dyn_string; must be first. */
struct dyn_string string;
+
+ /* The position at which additional text is added to this string
+ (using the result_add* macros). This value is an offset from the
+ end of the string, not the beginning (and should be
+ non-positive). */
+ int caret_position;
+
+ /* The next string in the list. */
struct string_list_def *next;
};
*************** static void demangling_delete
*** 272,290 ****
/* Returns the string containing the current demangled result. */
#define result_string(DM) (&(DM)->result->string)
! /* Appends a dyn_string_t to the demangled result. */
! #define result_append_string(DM, STRING) \
! (dyn_string_append (&(DM)->result->string, (STRING)) \
? STATUS_OK : STATUS_ALLOCATION_FAILED)
! /* Appends NUL-terminated string CSTR to the demangled result. */
! #define result_append(DM, CSTR) \
! (dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \
? STATUS_OK : STATUS_ALLOCATION_FAILED)
! /* Appends character CHAR to the demangled result. */
! #define result_append_char(DM, CHAR) \
! (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. */
--- 281,308 ----
/* Returns the string containing the current demangled result. */
#define result_string(DM) (&(DM)->result->string)
! /* Returns the position at which new text is inserted into the
! demangled result. */
! #define result_caret_pos(DM) \
! (result_length (DM) + \
! ((string_list_t) result_string (DM))->caret_position)
!
! /* Adds a dyn_string_t to the demangled result. */
! #define result_add_string(DM, STRING) \
! (dyn_string_insert (&(DM)->result->string, \
! result_caret_pos (DM), (STRING)) \
? STATUS_OK : STATUS_ALLOCATION_FAILED)
! /* Adds NUL-terminated string CSTR to the demangled result. */
! #define result_add(DM, CSTR) \
! (dyn_string_insert_cstr (&(DM)->result->string, \
! result_caret_pos (DM), (CSTR)) \
? STATUS_OK : STATUS_ALLOCATION_FAILED)
! /* Adds character CHAR to the demangled result. */
! #define result_add_char(DM, CHAR) \
! (dyn_string_insert_char (&(DM)->result->string, \
! result_caret_pos (DM), (CHAR)) \
? STATUS_OK : STATUS_ALLOCATION_FAILED)
/* Inserts a dyn_string_t to the demangled result at position POS. */
*************** static void demangling_delete
*** 307,318 ****
#define result_length(DM) \
dyn_string_length (&(DM)->result->string)
- /* Appends a space to the demangled result if the last character is
- not a space. */
- #define result_append_space(DM) \
- (dyn_string_append_space (&(DM)->result->string) \
- ? STATUS_OK : STATUS_ALLOCATION_FAILED)
-
/* Appends a (less-than, greater-than) character to the result in DM
to (open, close) a template argument or parameter list. Appends a
space first if necessary to prevent spurious elision of angle
--- 325,330 ----
*************** string_list_new (length)
*** 380,385 ****
--- 392,398 ----
int length;
{
string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
+ s->caret_position = 0;
if (s == NULL)
return NULL;
if (!dyn_string_init ((dyn_string_t) s, length))
*************** result_add_separated_char (dm, character
*** 409,428 ****
demangling_t dm;
int character;
{
! dyn_string_t s = &dm->result->string;
!
! /* Add a space if the last character is already a closing angle
! bracket, so that a nested template arg list doesn't look like
! it's closed with a right-shift operator. */
! if (dyn_string_last_char (s) == character)
! {
! if (!dyn_string_append_char (s, ' '))
! return STATUS_ALLOCATION_FAILED;
! }
! /* Add closing angle brackets. */
! if (!dyn_string_append_char (s, character))
! return STATUS_ALLOCATION_FAILED;
return STATUS_OK;
}
--- 422,436 ----
demangling_t dm;
int character;
{
! char *result = dyn_string_buf (result_string (dm));
! int caret_pos = result_caret_pos (dm);
! /* Add a space if the last character is already the character we
! want to add. */
! if (caret_pos > 0 && result[caret_pos - 1] == character)
! RETURN_IF_ERROR (result_add_char (dm, ' '));
! /* Add the character. */
! RETURN_IF_ERROR (result_add_char (dm, character));
return STATUS_OK;
}
*************** result_pop (dm)
*** 460,465 ****
--- 468,518 ----
return top;
}
+ /* Returns the current value of the caret for the result string. The
+ value is an offet from the end of the result string. */
+
+ static int
+ result_get_caret (dm)
+ demangling_t dm;
+ {
+ return ((string_list_t) result_string (dm))->caret_position;
+ }
+
+ /* Sets the value of the caret for the result string, counted as an
+ offet from the end of the result string. */
+
+ static void
+ result_set_caret (dm, position)
+ demangling_t dm;
+ int position;
+ {
+ ((string_list_t) result_string (dm))->caret_position = position;
+ }
+
+ /* Shifts the position of the next addition to the result by
+ POSITION_OFFSET. A negative value shifts the caret to the left. */
+
+ static void
+ result_shift_caret (dm, position_offset)
+ demangling_t dm;
+ int position_offset;
+ {
+ ((string_list_t) result_string (dm))->caret_position += position_offset;
+ }
+
+ /* Returns non-zero if the character that comes right before the place
+ where text will be added to the result is a space. In this case,
+ the caller should supress adding another space. */
+
+ static int
+ result_previous_char_is_space (dm)
+ demangling_t dm;
+ {
+ char *result = dyn_string_buf (result_string (dm));
+ int pos = result_caret_pos (dm);
+ return pos > 0 && result[pos - 1] == ' ';
+ }
+
/* Returns the start position of a fragment of the demangled result
that will be a substitution candidate. Should be called at the
start of productions that can add substitutions. */
*************** static int
*** 468,474 ****
substitution_start (dm)
demangling_t dm;
{
! return result_length (dm);
}
/* Adds the suffix of the current demangled result of DM starting at
--- 521,527 ----
substitution_start (dm)
demangling_t dm;
{
! return result_caret_pos (dm);
}
/* Adds the suffix of the current demangled result of DM starting at
*************** substitution_add (dm, start_position, te
*** 491,497 ****
/* Extract the substring of the current demangling result that
represents the subsitution candidate. */
if (!dyn_string_substring (substitution,
! result, start_position, result_length (dm)))
{
dyn_string_delete (substitution);
return STATUS_ALLOCATION_FAILED;
--- 544,550 ----
/* Extract the substring of the current demangling result that
represents the subsitution candidate. */
if (!dyn_string_substring (substitution,
! result, start_position, result_caret_pos (dm)))
{
dyn_string_delete (substitution);
return STATUS_ALLOCATION_FAILED;
*************** static status_t demangle_bare_function_t
*** 843,849 ****
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));
static status_t demangle_template_args
--- 896,902 ----
static status_t demangle_class_enum_type
PARAMS ((demangling_t, int *));
static status_t demangle_array_type
! PARAMS ((demangling_t, int *));
static status_t demangle_template_param
PARAMS ((demangling_t));
static status_t demangle_template_args
*************** demangle_encoding (dm)
*** 933,939 ****
/* Remember where the name starts. If it turns out to be a template
function, we'll have to insert the return type here. */
! start_position = result_length (dm);
if (peek == 'G' || peek == 'T')
RETURN_IF_ERROR (demangle_special_name (dm));
--- 986,992 ----
/* Remember where the name starts. If it turns out to be a template
function, we'll have to insert the return type here. */
! start_position = result_caret_pos (dm);
if (peek == 'G' || peek == 'T')
RETURN_IF_ERROR (demangle_special_name (dm));
*************** demangle_encoding (dm)
*** 943,949 ****
RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
/* If there's anything left, the name was a function name, with
! maybe its return type, and its parameters types, following. */
if (!end_of_name_p (dm)
&& peek_char (dm) != 'E')
{
--- 996,1002 ----
RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
/* If there's anything left, the name was a function name, with
! maybe its return type, and its parameter types, following. */
if (!end_of_name_p (dm)
&& peek_char (dm) != 'E')
{
*************** demangle_name (dm, encode_return_type)
*** 1017,1023 ****
{
(void) next_char (dm);
(void) next_char (dm);
! RETURN_IF_ERROR (result_append (dm, "std::"));
RETURN_IF_ERROR
(demangle_unqualified_name (dm, &suppress_return_type));
is_std_substitution = 1;
--- 1070,1076 ----
{
(void) next_char (dm);
(void) next_char (dm);
! RETURN_IF_ERROR (result_add (dm, "std::"));
RETURN_IF_ERROR
(demangle_unqualified_name (dm, &suppress_return_type));
is_std_substitution = 1;
*************** demangle_nested_name (dm, encode_return_
*** 1082,1101 ****
peek = peek_char (dm);
if (peek == 'r' || peek == 'V' || peek == 'K')
{
status_t status;
! /* Snarf up and emit CV qualifiers. */
! dyn_string_t cv_qualifiers = dyn_string_new (24);
if (cv_qualifiers == NULL)
return STATUS_ALLOCATION_FAILED;
-
demangle_CV_qualifiers (dm, cv_qualifiers);
! status = result_append_string (dm, cv_qualifiers);
dyn_string_delete (cv_qualifiers);
RETURN_IF_ERROR (status);
- RETURN_IF_ERROR (result_append_space (dm));
}
!
RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
/* No need to demangle the final <unqualified-name>; demangle_prefix
will handle it. */
--- 1135,1164 ----
peek = peek_char (dm);
if (peek == 'r' || peek == 'V' || peek == 'K')
{
+ dyn_string_t cv_qualifiers;
status_t status;
! /* Snarf up CV qualifiers. */
! cv_qualifiers = dyn_string_new (24);
if (cv_qualifiers == NULL)
return STATUS_ALLOCATION_FAILED;
demangle_CV_qualifiers (dm, cv_qualifiers);
!
! /* Emit them, preceded by a space. */
! status = result_add_char (dm, ' ');
! if (STATUS_NO_ERROR (status))
! status = result_add_string (dm, cv_qualifiers);
! /* The CV qualifiers that occur in a <nested-name> will be
! qualifiers for member functions. These are placed at the end
! of the function. Therefore, shift the caret to the left by
! the length of the qualifiers, so other text is inserted
! before them and they stay at the end. */
! result_shift_caret (dm, -dyn_string_length (cv_qualifiers) - 1);
! /* Clean up. */
dyn_string_delete (cv_qualifiers);
RETURN_IF_ERROR (status);
}
!
RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
/* No need to demangle the final <unqualified-name>; demangle_prefix
will handle it. */
*************** demangle_prefix (dm, encode_return_type)
*** 1159,1165 ****
{
/* We have another level of scope qualification. */
if (nested)
! RETURN_IF_ERROR (result_append (dm, "::"));
else
nested = 1;
--- 1222,1228 ----
{
/* We have another level of scope qualification. */
if (nested)
! RETURN_IF_ERROR (result_add (dm, "::"));
else
nested = 1;
*************** demangle_source_name (dm)
*** 1275,1281 ****
dm->last_source_name));
/* Emit it. */
! RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
return STATUS_OK;
}
--- 1338,1344 ----
dm->last_source_name));
/* Emit it. */
! RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
return STATUS_OK;
}
*************** demangle_operator_name (dm, short_name,
*** 1547,1553 ****
/* Is this a vendor-extended operator? */
if (c0 == 'v' && IS_DIGIT (c1))
{
! RETURN_IF_ERROR (result_append (dm, "operator "));
RETURN_IF_ERROR (demangle_source_name (dm));
*num_args = 0;
return STATUS_OK;
--- 1610,1616 ----
/* Is this a vendor-extended operator? */
if (c0 == 'v' && IS_DIGIT (c1))
{
! RETURN_IF_ERROR (result_add (dm, "operator "));
RETURN_IF_ERROR (demangle_source_name (dm));
*num_args = 0;
return STATUS_OK;
*************** demangle_operator_name (dm, short_name,
*** 1556,1562 ****
/* Is this a conversion operator? */
if (c0 == 'c' && c1 == 'v')
{
! RETURN_IF_ERROR (result_append (dm, "operator "));
/* Demangle the converted-to type. */
RETURN_IF_ERROR (demangle_type (dm));
*num_args = 0;
--- 1619,1625 ----
/* Is this a conversion operator? */
if (c0 == 'c' && c1 == 'v')
{
! RETURN_IF_ERROR (result_add (dm, "operator "));
/* Demangle the converted-to type. */
RETURN_IF_ERROR (demangle_type (dm));
*num_args = 0;
*************** demangle_operator_name (dm, short_name,
*** 1574,1581 ****
/* Found it. */
{
if (!short_name)
! RETURN_IF_ERROR (result_append (dm, "operator"));
! RETURN_IF_ERROR (result_append (dm, p->name));
*num_args = p->num_args;
return STATUS_OK;
--- 1637,1644 ----
/* Found it. */
{
if (!short_name)
! RETURN_IF_ERROR (result_add (dm, "operator"));
! RETURN_IF_ERROR (result_add (dm, p->name));
*num_args = p->num_args;
return STATUS_OK;
*************** demangle_nv_offset (dm)
*** 1615,1625 ****
/* Don't display the offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_append (dm, " [nv:");
if (STATUS_NO_ERROR (status))
! status = result_append_string (dm, number);
if (STATUS_NO_ERROR (status))
! status = result_append_char (dm, ']');
}
/* Clean up. */
--- 1678,1688 ----
/* Don't display the offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_add (dm, " [nv:");
if (STATUS_NO_ERROR (status))
! status = result_add_string (dm, number);
if (STATUS_NO_ERROR (status))
! status = result_add_char (dm, ']');
}
/* Clean up. */
*************** demangle_v_offset (dm)
*** 1651,1661 ****
/* Don't display the offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_append (dm, " [v:");
if (STATUS_NO_ERROR (status))
! status = result_append_string (dm, number);
if (STATUS_NO_ERROR (status))
! result_append_char (dm, ',');
}
dyn_string_delete (number);
RETURN_IF_ERROR (status);
--- 1714,1724 ----
/* Don't display the offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_add (dm, " [v:");
if (STATUS_NO_ERROR (status))
! status = result_add_string (dm, number);
if (STATUS_NO_ERROR (status))
! result_add_char (dm, ',');
}
dyn_string_delete (number);
RETURN_IF_ERROR (status);
*************** demangle_v_offset (dm)
*** 1672,1680 ****
/* Don't display the vcall offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_append_string (dm, number);
if (STATUS_NO_ERROR (status))
! status = result_append_char (dm, ']');
}
dyn_string_delete (number);
RETURN_IF_ERROR (status);
--- 1735,1743 ----
/* Don't display the vcall offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_add_string (dm, number);
if (STATUS_NO_ERROR (status))
! status = result_add_char (dm, ']');
}
dyn_string_delete (number);
RETURN_IF_ERROR (status);
*************** demangle_special_name (dm)
*** 1763,1769 ****
/* A guard variable name. Consume the G. */
advance_char (dm);
RETURN_IF_ERROR (demangle_char (dm, 'V'));
! RETURN_IF_ERROR (result_append (dm, "guard variable for "));
RETURN_IF_ERROR (demangle_name (dm, &unused));
}
else if (peek == 'T')
--- 1826,1832 ----
/* A guard variable name. Consume the G. */
advance_char (dm);
RETURN_IF_ERROR (demangle_char (dm, 'V'));
! RETURN_IF_ERROR (result_add (dm, "guard variable for "));
RETURN_IF_ERROR (demangle_name (dm, &unused));
}
else if (peek == 'T')
*************** demangle_special_name (dm)
*** 1778,1854 ****
case 'V':
/* Virtual table. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "vtable for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'T':
/* VTT structure. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "VTT for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'I':
/* Typeinfo structure. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "typeinfo for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'F':
/* Typeinfo function. Used only in old ABI with new mangling. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "typeinfo fn for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'S':
/* Character string containing type name, used in typeinfo. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "typeinfo name for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'J':
/* The java Class variable corresponding to a C++ class. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "java Class for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'h':
/* Non-virtual thunk. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "non-virtual thunk"));
RETURN_IF_ERROR (demangle_nv_offset (dm));
/* Demangle the separator. */
RETURN_IF_ERROR (demangle_char (dm, '_'));
/* Demangle and emit the target name and function type. */
! RETURN_IF_ERROR (result_append (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm));
break;
case 'v':
/* Virtual thunk. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "virtual thunk"));
RETURN_IF_ERROR (demangle_v_offset (dm));
/* Demangle the separator. */
RETURN_IF_ERROR (demangle_char (dm, '_'));
/* Demangle and emit the target function. */
! RETURN_IF_ERROR (result_append (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm));
break;
case 'c':
/* Covariant return thunk. */
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "covariant return thunk"));
RETURN_IF_ERROR (demangle_call_offset (dm));
RETURN_IF_ERROR (demangle_call_offset (dm));
/* Demangle and emit the target function. */
! RETURN_IF_ERROR (result_append (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm));
break;
--- 1841,1917 ----
case 'V':
/* Virtual table. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "vtable for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'T':
/* VTT structure. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "VTT for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'I':
/* Typeinfo structure. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "typeinfo for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'F':
/* Typeinfo function. Used only in old ABI with new mangling. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "typeinfo fn for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'S':
/* Character string containing type name, used in typeinfo. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "typeinfo name for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'J':
/* The java Class variable corresponding to a C++ class. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "java Class for "));
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'h':
/* Non-virtual thunk. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "non-virtual thunk"));
RETURN_IF_ERROR (demangle_nv_offset (dm));
/* Demangle the separator. */
RETURN_IF_ERROR (demangle_char (dm, '_'));
/* Demangle and emit the target name and function type. */
! RETURN_IF_ERROR (result_add (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm));
break;
case 'v':
/* Virtual thunk. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "virtual thunk"));
RETURN_IF_ERROR (demangle_v_offset (dm));
/* Demangle the separator. */
RETURN_IF_ERROR (demangle_char (dm, '_'));
/* Demangle and emit the target function. */
! RETURN_IF_ERROR (result_add (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm));
break;
case 'c':
/* Covariant return thunk. */
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "covariant return thunk"));
RETURN_IF_ERROR (demangle_call_offset (dm));
RETURN_IF_ERROR (demangle_call_offset (dm));
/* Demangle and emit the target function. */
! RETURN_IF_ERROR (result_add (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm));
break;
*************** demangle_special_name (dm)
*** 1859,1865 ****
dyn_string_t derived_type;
advance_char (dm);
! RETURN_IF_ERROR (result_append (dm, "construction vtable for "));
/* Demangle the derived type off to the side. */
RETURN_IF_ERROR (result_push (dm));
--- 1922,1928 ----
dyn_string_t derived_type;
advance_char (dm);
! RETURN_IF_ERROR (result_add (dm, "construction vtable for "));
/* Demangle the derived type off to the side. */
RETURN_IF_ERROR (result_push (dm));
*************** demangle_special_name (dm)
*** 1883,1899 ****
/* Emit the derived type. */
if (STATUS_NO_ERROR (status))
! status = result_append (dm, "-in-");
if (STATUS_NO_ERROR (status))
! status = result_append_string (dm, derived_type);
dyn_string_delete (derived_type);
/* Don't display the offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_append_char (dm, ' ');
if (STATUS_NO_ERROR (status))
! result_append_string (dm, number);
}
dyn_string_delete (number);
RETURN_IF_ERROR (status);
--- 1946,1962 ----
/* Emit the derived type. */
if (STATUS_NO_ERROR (status))
! status = result_add (dm, "-in-");
if (STATUS_NO_ERROR (status))
! status = result_add_string (dm, derived_type);
dyn_string_delete (derived_type);
/* Don't display the offset unless in verbose mode. */
if (flag_verbose)
{
! status = result_add_char (dm, ' ');
if (STATUS_NO_ERROR (status))
! result_add_string (dm, number);
}
dyn_string_delete (number);
RETURN_IF_ERROR (status);
*************** demangle_ctor_dtor_name (dm)
*** 1949,1962 ****
advance_char (dm);
if (peek_char (dm) < '1' || peek_char (dm) > '3')
return "Unrecognized constructor.";
! RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
/* Print the flavor of the constructor if in verbose mode. */
flavor = next_char (dm) - '1';
if (flag_verbose)
{
! RETURN_IF_ERROR (result_append (dm, "["));
! RETURN_IF_ERROR (result_append (dm, ctor_flavors[flavor]));
! RETURN_IF_ERROR (result_append_char (dm, ']'));
}
}
else if (peek == 'D')
--- 2012,2025 ----
advance_char (dm);
if (peek_char (dm) < '1' || peek_char (dm) > '3')
return "Unrecognized constructor.";
! RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
/* Print the flavor of the constructor if in verbose mode. */
flavor = next_char (dm) - '1';
if (flag_verbose)
{
! RETURN_IF_ERROR (result_add (dm, "["));
! RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor]));
! RETURN_IF_ERROR (result_add_char (dm, ']'));
}
}
else if (peek == 'D')
*************** demangle_ctor_dtor_name (dm)
*** 1965,1979 ****
advance_char (dm);
if (peek_char (dm) < '0' || peek_char (dm) > '2')
return "Unrecognized destructor.";
! RETURN_IF_ERROR (result_append_char (dm, '~'));
! RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name));
/* Print the flavor of the destructor if in verbose mode. */
flavor = next_char (dm) - '0';
if (flag_verbose)
{
! RETURN_IF_ERROR (result_append (dm, " ["));
! RETURN_IF_ERROR (result_append (dm, dtor_flavors[flavor]));
! RETURN_IF_ERROR (result_append_char (dm, ']'));
}
}
else
--- 2028,2042 ----
advance_char (dm);
if (peek_char (dm) < '0' || peek_char (dm) > '2')
return "Unrecognized destructor.";
! RETURN_IF_ERROR (result_add_char (dm, '~'));
! RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
/* Print the flavor of the destructor if in verbose mode. */
flavor = next_char (dm) - '0';
if (flag_verbose)
{
! RETURN_IF_ERROR (result_add (dm, " ["));
! RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor]));
! RETURN_IF_ERROR (result_add_char (dm, ']'));
}
}
else
*************** demangle_type_ptr (dm, insert_pos, subst
*** 2014,2020 ****
int *insert_pos;
int substitution_start;
{
- char next;
status_t status;
int is_substitution_candidate = 1;
--- 2077,2082 ----
*************** demangle_type_ptr (dm, insert_pos, subst
*** 2022,2030 ****
/* Scan forward, collecting pointers and references into symbols,
until we hit something else. Then emit the type. */
! next = peek_char (dm);
! if (next == 'P')
{
/* A pointer. Snarf the `P'. */
advance_char (dm);
/* Demangle the underlying type. */
--- 2084,2092 ----
/* Scan forward, collecting pointers and references into symbols,
until we hit something else. Then emit the type. */
! switch (peek_char (dm))
{
+ case 'P':
/* A pointer. Snarf the `P'. */
advance_char (dm);
/* Demangle the underlying type. */
*************** demangle_type_ptr (dm, insert_pos, subst
*** 2036,2044 ****
/* The next (outermost) pointer or reference character should go
after this one. */
++(*insert_pos);
! }
! else if (next == 'R')
! {
/* A reference. Snarf the `R'. */
advance_char (dm);
/* Demangle the underlying type. */
--- 2098,2106 ----
/* The next (outermost) pointer or reference character should go
after this one. */
++(*insert_pos);
! break;
!
! case 'R':
/* A reference. Snarf the `R'. */
advance_char (dm);
/* Demangle the underlying type. */
*************** demangle_type_ptr (dm, insert_pos, subst
*** 2050,2057 ****
/* The next (outermost) pointer or reference character should go
after this one. */
++(*insert_pos);
! }
! else if (next == 'M')
{
/* A pointer-to-member. */
dyn_string_t class_type;
--- 2112,2120 ----
/* The next (outermost) pointer or reference character should go
after this one. */
++(*insert_pos);
! break;
!
! case 'M':
{
/* A pointer-to-member. */
dyn_string_t class_type;
*************** demangle_type_ptr (dm, insert_pos, subst
*** 2071,2087 ****
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);
/* The pointer-to-member notation (e.g. `C::*') follows the
member's type. */
! *insert_pos = result_length (dm);
}
/* Build the pointer-to-member notation. */
--- 2134,2157 ----
and set *insert_pos to the spot between the first
parentheses. */
status = demangle_type_ptr (dm, insert_pos, substitution_start);
+ else if (peek_char (dm) == 'A')
+ /* A pointer-to-member array variable. We want output that
+ looks like `int (Klass::*) [10]'. Demangle the array type
+ as `int () [10]', and set *insert_pos to the spot between
+ the parentheses. */
+ status = demangle_array_type (dm, insert_pos);
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)
! && !result_previous_char_is_space (dm))
! status = result_add_char (dm, ' ');
/* The pointer-to-member notation (e.g. `C::*') follows the
member's type. */
! *insert_pos = result_caret_pos (dm);
}
/* Build the pointer-to-member notation. */
*************** demangle_type_ptr (dm, insert_pos, subst
*** 2100,2114 ****
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. */
--- 2170,2185 ----
RETURN_IF_ERROR (status);
}
! break;
!
! case '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_caret_pos (dm);
/* The parentheses indicate this is a function pointer or
reference type. */
! RETURN_IF_ERROR (result_add (dm, "()"));
/* Now demangle the function type. The return type will be
inserted before the `()', and the argument list will go after
it. */
*************** demangle_type_ptr (dm, insert_pos, subst
*** 2120,2139 ****
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)
--- 2191,2217 ----
type. Move it one character over so it points inside the
`()'. */
++(*insert_pos);
! break;
!
! case 'A':
! /* An array pointer or reference. demangle_array_type will figure
! out where the asterisks and ampersands go. */
! RETURN_IF_ERROR (demangle_array_type (dm, insert_pos));
! break;
!
! default:
/* 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_caret_pos (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;
+ break;
}
if (is_substitution_candidate)
*************** demangle_type (dm)
*** 2201,2234 ****
{
status_t status;
dyn_string_t cv_qualifiers = dyn_string_new (24);
if (cv_qualifiers == NULL)
return STATUS_ALLOCATION_FAILED;
demangle_CV_qualifiers (dm, cv_qualifiers);
!
! /* If the qualifiers apply to a pointer or reference, they
! need to come after the whole qualified type. */
! if (peek_char (dm) == 'P' || peek_char (dm) == 'R')
! {
! status = demangle_type (dm);
! if (STATUS_NO_ERROR (status))
! status = result_append_space (dm);
! if (STATUS_NO_ERROR (status))
! status = result_append_string (dm, cv_qualifiers);
! }
! /* Otherwise, the qualifiers come first. */
! else
! {
! status = result_append_string (dm, cv_qualifiers);
! if (STATUS_NO_ERROR (status))
! status = result_append_space (dm);
! if (STATUS_NO_ERROR (status))
! status = demangle_type (dm);
! }
!
dyn_string_delete (cv_qualifiers);
RETURN_IF_ERROR (status);
}
break;
--- 2279,2308 ----
{
status_t status;
dyn_string_t cv_qualifiers = dyn_string_new (24);
+ int old_caret_position = result_get_caret (dm);
if (cv_qualifiers == NULL)
return STATUS_ALLOCATION_FAILED;
+ /* Decode all adjacent CV qualifiers. */
demangle_CV_qualifiers (dm, cv_qualifiers);
! /* Emit them, and shift the caret left so that the
! underlying type will be emitted before the qualifiers. */
! status = result_add_string (dm, cv_qualifiers);
! result_shift_caret (dm, -dyn_string_length (cv_qualifiers));
! /* Clean up. */
dyn_string_delete (cv_qualifiers);
RETURN_IF_ERROR (status);
+ /* Also prepend a blank, if needed. */
+ RETURN_IF_ERROR (result_add_char (dm, ' '));
+ result_shift_caret (dm, -1);
+
+ /* Demangle the underlying type. It will be emitted before
+ the CV qualifiers, since we moved the caret. */
+ RETURN_IF_ERROR (demangle_type (dm));
+
+ /* Put the caret back where it was previously. */
+ result_set_caret (dm, old_caret_position);
}
break;
*************** demangle_type (dm)
*** 2236,2242 ****
return "Non-pointer or -reference function type.";
case 'A':
! RETURN_IF_ERROR (demangle_array_type (dm));
break;
case 'T':
--- 2310,2316 ----
return "Non-pointer or -reference function type.";
case 'A':
! RETURN_IF_ERROR (demangle_array_type (dm, NULL));
break;
case 'T':
*************** demangle_type (dm)
*** 2325,2338 ****
case 'C':
/* A C99 complex type. */
! RETURN_IF_ERROR (result_append (dm, "complex "));
advance_char (dm);
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'G':
/* A C99 imaginary type. */
! RETURN_IF_ERROR (result_append (dm, "imaginary "));
advance_char (dm);
RETURN_IF_ERROR (demangle_type (dm));
break;
--- 2399,2412 ----
case 'C':
/* A C99 complex type. */
! RETURN_IF_ERROR (result_add (dm, "complex "));
advance_char (dm);
RETURN_IF_ERROR (demangle_type (dm));
break;
case 'G':
/* A C99 imaginary type. */
! RETURN_IF_ERROR (result_add (dm, "imaginary "));
advance_char (dm);
RETURN_IF_ERROR (demangle_type (dm));
break;
*************** demangle_type (dm)
*** 2341,2347 ****
/* Vendor-extended type qualifier. */
advance_char (dm);
RETURN_IF_ERROR (demangle_source_name (dm));
! RETURN_IF_ERROR (result_append_char (dm, ' '));
RETURN_IF_ERROR (demangle_type (dm));
break;
--- 2415,2421 ----
/* Vendor-extended type qualifier. */
advance_char (dm);
RETURN_IF_ERROR (demangle_source_name (dm));
! RETURN_IF_ERROR (result_add_char (dm, ' '));
RETURN_IF_ERROR (demangle_type (dm));
break;
*************** demangle_builtin_type (dm)
*** 2441,2447 ****
if (type_name == NULL)
return "Unrecognized <builtin-type> code.";
! RETURN_IF_ERROR (result_append (dm, type_name));
advance_char (dm);
return STATUS_OK;
}
--- 2515,2521 ----
if (type_name == NULL)
return "Unrecognized <builtin-type> code.";
! RETURN_IF_ERROR (result_add (dm, type_name));
advance_char (dm);
return STATUS_OK;
}
*************** demangle_function_type (dm, function_nam
*** 2512,2518 ****
{
/* Indicate this function has C linkage if in verbose mode. */
if (flag_verbose)
! RETURN_IF_ERROR (result_append (dm, " [extern \"C\"] "));
advance_char (dm);
}
RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
--- 2586,2592 ----
{
/* Indicate this function has C linkage if in verbose mode. */
if (flag_verbose)
! RETURN_IF_ERROR (result_add (dm, " [extern \"C\"] "));
advance_char (dm);
}
RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
*************** demangle_bare_function_type (dm, return_
*** 2539,2545 ****
DEMANGLE_TRACE ("bare-function-type", dm);
! RETURN_IF_ERROR (result_append_char (dm, '('));
while (!end_of_name_p (dm) && peek_char (dm) != 'E')
{
if (sequence == -1)
--- 2613,2619 ----
DEMANGLE_TRACE ("bare-function-type", dm);
! RETURN_IF_ERROR (result_add_char (dm, '('));
while (!end_of_name_p (dm) && peek_char (dm) != 'E')
{
if (sequence == -1)
*************** demangle_bare_function_type (dm, return_
*** 2581,2587 ****
{
/* Separate parameter types by commas. */
if (sequence > 0)
! RETURN_IF_ERROR (result_append (dm, ", "));
/* Demangle the type. */
RETURN_IF_ERROR (demangle_type (dm));
}
--- 2655,2661 ----
{
/* Separate parameter types by commas. */
if (sequence > 0)
! RETURN_IF_ERROR (result_add (dm, ", "));
/* Demangle the type. */
RETURN_IF_ERROR (demangle_type (dm));
}
*************** demangle_bare_function_type (dm, return_
*** 2589,2595 ****
++sequence;
}
! RETURN_IF_ERROR (result_append_char (dm, ')'));
/* We should have demangled at least one parameter type (which would
be void, for a function that takes no parameters), plus the
--- 2663,2669 ----
++sequence;
}
! RETURN_IF_ERROR (result_add_char (dm, ')'));
/* We should have demangled at least one parameter type (which would
be void, for a function that takes no parameters), plus the
*************** demangle_class_enum_type (dm, encode_ret
*** 2620,2636 ****
/* Demangles and emits an <array-type>.
<array-type> ::= A [<dimension number>] _ <element type>
::= A <dimension expression> _ <element type> */
static status_t
! demangle_array_type (dm)
demangling_t dm;
{
status_t status = STATUS_OK;
dyn_string_t array_size = NULL;
char peek;
RETURN_IF_ERROR (demangle_char (dm, 'A'));
/* Demangle the array size into array_size. */
--- 2694,2725 ----
/* Demangles and emits an <array-type>.
+ If PTR_INSERT_POS is not NULL, the array type is formatted as a
+ pointer or reference to an array, except that asterisk and
+ ampersand punctuation is omitted (since it's not know at this
+ point). *PTR_INSERT_POS is set to the position in the demangled
+ name at which this punctuation should be inserted. For example,
+ `A10_i' is demangled to `int () [10]' and *PTR_INSERT_POS points
+ between the parentheses.
+
+ If PTR_INSERT_POS is NULL, the array type is assumed not to be
+ pointer- or reference-qualified. Then, for example, `A10_i' is
+ demangled simply as `int[10]'.
+
<array-type> ::= A [<dimension number>] _ <element type>
::= A <dimension expression> _ <element type> */
static status_t
! demangle_array_type (dm, ptr_insert_pos)
demangling_t dm;
+ int *ptr_insert_pos;
{
status_t status = STATUS_OK;
dyn_string_t array_size = NULL;
char peek;
+ DEMANGLE_TRACE ("array-type", dm);
+
RETURN_IF_ERROR (demangle_char (dm, 'A'));
/* Demangle the array size into array_size. */
*************** demangle_array_type (dm)
*** 2664,2676 ****
if (STATUS_NO_ERROR (status))
status = demangle_type (dm);
/* Emit the array dimension syntax. */
if (STATUS_NO_ERROR (status))
! status = result_append_char (dm, '[');
if (STATUS_NO_ERROR (status) && array_size != NULL)
! status = result_append_string (dm, array_size);
if (STATUS_NO_ERROR (status))
! status = result_append_char (dm, ']');
if (array_size != NULL)
dyn_string_delete (array_size);
--- 2753,2776 ----
if (STATUS_NO_ERROR (status))
status = demangle_type (dm);
+ if (ptr_insert_pos != NULL)
+ {
+ /* This array is actually part of an pointer- or
+ reference-to-array type. Format appropriately, except we
+ don't know which and how much punctuation to use. */
+ if (STATUS_NO_ERROR (status))
+ status = result_add (dm, " () ");
+ /* Let the caller know where to insert the punctuation. */
+ *ptr_insert_pos = result_caret_pos (dm) - 2;
+ }
+
/* Emit the array dimension syntax. */
if (STATUS_NO_ERROR (status))
! status = result_add_char (dm, '[');
if (STATUS_NO_ERROR (status) && array_size != NULL)
! status = result_add_string (dm, array_size);
if (STATUS_NO_ERROR (status))
! status = result_add_char (dm, ']');
if (array_size != NULL)
dyn_string_delete (array_size);
*************** demangle_template_param (dm)
*** 2714,2720 ****
/* parm_number exceeded the number of arguments in the current
template argument list. */
return "Template parameter number out of bounds.";
! RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
return STATUS_OK;
}
--- 2814,2820 ----
/* parm_number exceeded the number of arguments in the current
template argument list. */
return "Template parameter number out of bounds.";
! RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
return STATUS_OK;
}
*************** demangle_template_args (dm)
*** 2752,2758 ****
if (first)
first = 0;
else
! RETURN_IF_ERROR (result_append (dm, ", "));
/* Capture the template arg. */
RETURN_IF_ERROR (result_push (dm));
--- 2852,2858 ----
if (first)
first = 0;
else
! RETURN_IF_ERROR (result_add (dm, ", "));
/* Capture the template arg. */
RETURN_IF_ERROR (result_push (dm));
*************** demangle_template_args (dm)
*** 2760,2766 ****
arg = result_pop (dm);
/* Emit it in the demangled name. */
! RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg));
/* Save it for use in expanding <template-param>s. */
template_arg_list_add_arg (arg_list, arg);
--- 2860,2866 ----
arg = result_pop (dm);
/* Emit it in the demangled name. */
! RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
/* Save it for use in expanding <template-param>s. */
template_arg_list_add_arg (arg_list, arg);
*************** demangle_literal (dm)
*** 2836,2844 ****
corresponding to false or true, respectively. */
value = peek_char (dm);
if (value == '0')
! RETURN_IF_ERROR (result_append (dm, "false"));
else if (value == '1')
! RETURN_IF_ERROR (result_append (dm, "true"));
else
return "Unrecognized bool constant.";
/* Consume the 0 or 1. */
--- 2936,2944 ----
corresponding to false or true, respectively. */
value = peek_char (dm);
if (value == '0')
! RETURN_IF_ERROR (result_add (dm, "false"));
else if (value == '1')
! RETURN_IF_ERROR (result_add (dm, "true"));
else
return "Unrecognized bool constant.";
/* Consume the 0 or 1. */
*************** demangle_literal (dm)
*** 2856,2865 ****
value_string = dyn_string_new (0);
status = demangle_number_literally (dm, value_string, 10, 1);
if (STATUS_NO_ERROR (status))
! status = result_append_string (dm, value_string);
/* For long integers, append an l. */
if (code == 'l' && STATUS_NO_ERROR (status))
! status = result_append_char (dm, code);
dyn_string_delete (value_string);
RETURN_IF_ERROR (status);
--- 2956,2965 ----
value_string = dyn_string_new (0);
status = demangle_number_literally (dm, value_string, 10, 1);
if (STATUS_NO_ERROR (status))
! status = result_add_string (dm, value_string);
/* For long integers, append an l. */
if (code == 'l' && STATUS_NO_ERROR (status))
! status = result_add_char (dm, code);
dyn_string_delete (value_string);
RETURN_IF_ERROR (status);
*************** demangle_literal (dm)
*** 2869,2877 ****
literal's type explicitly using cast syntax. */
}
! RETURN_IF_ERROR (result_append_char (dm, '('));
RETURN_IF_ERROR (demangle_type (dm));
! RETURN_IF_ERROR (result_append_char (dm, ')'));
value_string = dyn_string_new (0);
if (value_string == NULL)
--- 2969,2977 ----
literal's type explicitly using cast syntax. */
}
! RETURN_IF_ERROR (result_add_char (dm, '('));
RETURN_IF_ERROR (demangle_type (dm));
! RETURN_IF_ERROR (result_add_char (dm, ')'));
value_string = dyn_string_new (0);
if (value_string == NULL)
*************** demangle_literal (dm)
*** 2879,2885 ****
status = demangle_number_literally (dm, value_string, 10, 1);
if (STATUS_NO_ERROR (status))
! status = result_append_string (dm, value_string);
dyn_string_delete (value_string);
RETURN_IF_ERROR (status);
--- 2979,2985 ----
status = demangle_number_literally (dm, value_string, 10, 1);
if (STATUS_NO_ERROR (status))
! status = result_add_string (dm, value_string);
dyn_string_delete (value_string);
RETURN_IF_ERROR (status);
*************** demangle_expression (dm)
*** 2967,2996 ****
/* If it's binary, do an operand first. */
if (num_args > 1)
{
! status = result_append_char (dm, '(');
if (STATUS_NO_ERROR (status))
status = demangle_expression (dm);
if (STATUS_NO_ERROR (status))
! status = result_append_char (dm, ')');
}
/* Emit the operator. */
if (STATUS_NO_ERROR (status))
! status = result_append_string (dm, operator_name);
dyn_string_delete (operator_name);
RETURN_IF_ERROR (status);
/* Emit its second (if binary) or only (if unary) operand. */
! RETURN_IF_ERROR (result_append_char (dm, '('));
RETURN_IF_ERROR (demangle_expression (dm));
! RETURN_IF_ERROR (result_append_char (dm, ')'));
/* The ternary operator takes a third operand. */
if (num_args == 3)
{
! RETURN_IF_ERROR (result_append (dm, ":("));
RETURN_IF_ERROR (demangle_expression (dm));
! RETURN_IF_ERROR (result_append_char (dm, ')'));
}
}
--- 3067,3096 ----
/* If it's binary, do an operand first. */
if (num_args > 1)
{
! status = result_add_char (dm, '(');
if (STATUS_NO_ERROR (status))
status = demangle_expression (dm);
if (STATUS_NO_ERROR (status))
! status = result_add_char (dm, ')');
}
/* Emit the operator. */
if (STATUS_NO_ERROR (status))
! status = result_add_string (dm, operator_name);
dyn_string_delete (operator_name);
RETURN_IF_ERROR (status);
/* Emit its second (if binary) or only (if unary) operand. */
! RETURN_IF_ERROR (result_add_char (dm, '('));
RETURN_IF_ERROR (demangle_expression (dm));
! RETURN_IF_ERROR (result_add_char (dm, ')'));
/* The ternary operator takes a third operand. */
if (num_args == 3)
{
! RETURN_IF_ERROR (result_add (dm, ":("));
RETURN_IF_ERROR (demangle_expression (dm));
! RETURN_IF_ERROR (result_add_char (dm, ')'));
}
}
*************** demangle_scope_expression (dm)
*** 3009,3015 ****
RETURN_IF_ERROR (demangle_char (dm, 's'));
RETURN_IF_ERROR (demangle_char (dm, 'r'));
RETURN_IF_ERROR (demangle_type (dm));
! RETURN_IF_ERROR (result_append (dm, "::"));
RETURN_IF_ERROR (demangle_encoding (dm));
return STATUS_OK;
}
--- 3109,3115 ----
RETURN_IF_ERROR (demangle_char (dm, 's'));
RETURN_IF_ERROR (demangle_char (dm, 'r'));
RETURN_IF_ERROR (demangle_type (dm));
! RETURN_IF_ERROR (result_add (dm, "::"));
RETURN_IF_ERROR (demangle_encoding (dm));
return STATUS_OK;
}
*************** demangle_substitution (dm, template_p)
*** 3100,3116 ****
switch (peek)
{
case 't':
! RETURN_IF_ERROR (result_append (dm, "std"));
break;
case 'a':
! RETURN_IF_ERROR (result_append (dm, "std::allocator"));
new_last_source_name = "allocator";
*template_p = 1;
break;
case 'b':
! RETURN_IF_ERROR (result_append (dm, "std::basic_string"));
new_last_source_name = "basic_string";
*template_p = 1;
break;
--- 3200,3216 ----
switch (peek)
{
case 't':
! RETURN_IF_ERROR (result_add (dm, "std"));
break;
case 'a':
! RETURN_IF_ERROR (result_add (dm, "std::allocator"));
new_last_source_name = "allocator";
*template_p = 1;
break;
case 'b':
! RETURN_IF_ERROR (result_add (dm, "std::basic_string"));
new_last_source_name = "basic_string";
*template_p = 1;
break;
*************** demangle_substitution (dm, template_p)
*** 3118,3129 ****
case 's':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_append (dm, "std::string"));
new_last_source_name = "string";
}
else
{
! RETURN_IF_ERROR (result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
new_last_source_name = "basic_string";
}
*template_p = 0;
--- 3218,3229 ----
case 's':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_add (dm, "std::string"));
new_last_source_name = "string";
}
else
{
! RETURN_IF_ERROR (result_add (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
new_last_source_name = "basic_string";
}
*template_p = 0;
*************** demangle_substitution (dm, template_p)
*** 3132,3143 ****
case 'i':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_append (dm, "std::istream"));
new_last_source_name = "istream";
}
else
{
! RETURN_IF_ERROR (result_append (dm, "std::basic_istream<char, std::char_traints<char> >"));
new_last_source_name = "basic_istream";
}
*template_p = 0;
--- 3232,3243 ----
case 'i':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_add (dm, "std::istream"));
new_last_source_name = "istream";
}
else
{
! RETURN_IF_ERROR (result_add (dm, "std::basic_istream<char, std::char_traints<char> >"));
new_last_source_name = "basic_istream";
}
*template_p = 0;
*************** demangle_substitution (dm, template_p)
*** 3146,3157 ****
case 'o':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_append (dm, "std::ostream"));
new_last_source_name = "ostream";
}
else
{
! RETURN_IF_ERROR (result_append (dm, "std::basic_ostream<char, std::char_traits<char> >"));
new_last_source_name = "basic_ostream";
}
*template_p = 0;
--- 3246,3257 ----
case 'o':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_add (dm, "std::ostream"));
new_last_source_name = "ostream";
}
else
{
! RETURN_IF_ERROR (result_add (dm, "std::basic_ostream<char, std::char_traits<char> >"));
new_last_source_name = "basic_ostream";
}
*template_p = 0;
*************** demangle_substitution (dm, template_p)
*** 3160,3171 ****
case 'd':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_append (dm, "std::iostream"));
new_last_source_name = "iostream";
}
else
{
! RETURN_IF_ERROR (result_append (dm, "std::basic_iostream<char, std::char_traits<char> >"));
new_last_source_name = "basic_iostream";
}
*template_p = 0;
--- 3260,3271 ----
case 'd':
if (!flag_verbose)
{
! RETURN_IF_ERROR (result_add (dm, "std::iostream"));
new_last_source_name = "iostream";
}
else
{
! RETURN_IF_ERROR (result_add (dm, "std::basic_iostream<char, std::char_traits<char> >"));
new_last_source_name = "basic_iostream";
}
*template_p = 0;
*************** demangle_substitution (dm, template_p)
*** 3196,3202 ****
return "Substitution number out of range.";
/* Emit the substitution text. */
! RETURN_IF_ERROR (result_append_string (dm, text));
RETURN_IF_ERROR (demangle_char (dm, '_'));
return STATUS_OK;
--- 3296,3302 ----
return "Substitution number out of range.";
/* Emit the substitution text. */
! RETURN_IF_ERROR (result_add_string (dm, text));
RETURN_IF_ERROR (demangle_char (dm, '_'));
return STATUS_OK;
*************** demangle_local_name (dm)
*** 3216,3227 ****
RETURN_IF_ERROR (demangle_char (dm, 'Z'));
RETURN_IF_ERROR (demangle_encoding (dm));
RETURN_IF_ERROR (demangle_char (dm, 'E'));
! RETURN_IF_ERROR (result_append (dm, "::"));
if (peek_char (dm) == 's')
{
/* Local character string literal. */
! RETURN_IF_ERROR (result_append (dm, "string literal"));
/* Consume the s. */
advance_char (dm);
RETURN_IF_ERROR (demangle_discriminator (dm, 0));
--- 3316,3327 ----
RETURN_IF_ERROR (demangle_char (dm, 'Z'));
RETURN_IF_ERROR (demangle_encoding (dm));
RETURN_IF_ERROR (demangle_char (dm, 'E'));
! RETURN_IF_ERROR (result_add (dm, "::"));
if (peek_char (dm) == 's')
{
/* Local character string literal. */
! RETURN_IF_ERROR (result_add (dm, "string literal"));
/* Consume the s. */
advance_char (dm);
RETURN_IF_ERROR (demangle_discriminator (dm, 0));
*************** demangle_discriminator (dm, suppress_fir
*** 3258,3264 ****
/* Consume the underscore. */
advance_char (dm);
if (flag_verbose)
! RETURN_IF_ERROR (result_append (dm, " [#"));
/* Check if there's a number following the underscore. */
if (IS_DIGIT ((unsigned char) peek_char (dm)))
{
--- 3358,3364 ----
/* Consume the underscore. */
advance_char (dm);
if (flag_verbose)
! RETURN_IF_ERROR (result_add (dm, " [#"));
/* Check if there's a number following the underscore. */
if (IS_DIGIT ((unsigned char) peek_char (dm)))
{
*************** demangle_discriminator (dm, suppress_fir
*** 3276,3290 ****
{
if (flag_verbose)
/* A missing digit correspond to one. */
! RETURN_IF_ERROR (result_append_char (dm, '1'));
}
if (flag_verbose)
! RETURN_IF_ERROR (result_append_char (dm, ']'));
}
else if (!suppress_first)
{
if (flag_verbose)
! RETURN_IF_ERROR (result_append (dm, " [#0]"));
}
return STATUS_OK;
--- 3376,3390 ----
{
if (flag_verbose)
/* A missing digit correspond to one. */
! RETURN_IF_ERROR (result_add_char (dm, '1'));
}
if (flag_verbose)
! RETURN_IF_ERROR (result_add_char (dm, ']'));
}
else if (!suppress_first)
{
if (flag_verbose)
! RETURN_IF_ERROR (result_add (dm, " [#0]"));
}
return STATUS_OK;
More information about the Gcc-patches
mailing list