Commit 0870bfd6 by Alex Samuel Committed by Alex Samuel

cp-demangle.c (string_list_def): Add caret_position and comments.

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

From-SVN: r37011
parent ae4bd622
2000-10-20 Alex Samuel <samuel@codesourcery.com>
* 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.
2000-10-01 Mark Mitchell <mark@codesourcery.com> 2000-10-01 Mark Mitchell <mark@codesourcery.com>
* splay-tree.c (splay_tree_insert): Fix formatting. * splay-tree.c (splay_tree_insert): Fix formatting.
......
...@@ -79,13 +79,22 @@ static int flag_verbose; ...@@ -79,13 +79,22 @@ static int flag_verbose;
specification -- don't demangle special g++ manglings. */ specification -- don't demangle special g++ manglings. */
static int flag_strict; static int flag_strict;
/* String_list_t is an extended form of dyn_string_t which provides a link /* String_list_t is an extended form of dyn_string_t which provides a
field. A string_list_t may safely be cast to and used as a link field and a caret position for additions to the string. A
dyn_string_t. */ string_list_t may safely be cast to and used as a dyn_string_t. */
struct string_list_def struct string_list_def
{ {
/* The dyn_string; must be first. */
struct dyn_string string; 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; struct string_list_def *next;
}; };
...@@ -272,19 +281,28 @@ static void demangling_delete ...@@ -272,19 +281,28 @@ static void demangling_delete
/* Returns the string containing the current demangled result. */ /* Returns the string containing the current demangled result. */
#define result_string(DM) (&(DM)->result->string) #define result_string(DM) (&(DM)->result->string)
/* Appends a dyn_string_t to the demangled result. */ /* Returns the position at which new text is inserted into the
#define result_append_string(DM, STRING) \ demangled result. */
(dyn_string_append (&(DM)->result->string, (STRING)) \ #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) ? STATUS_OK : STATUS_ALLOCATION_FAILED)
/* Appends NUL-terminated string CSTR to the demangled result. */ /* Adds NUL-terminated string CSTR to the demangled result. */
#define result_append(DM, CSTR) \ #define result_add(DM, CSTR) \
(dyn_string_append_cstr (&(DM)->result->string, (CSTR)) \ (dyn_string_insert_cstr (&(DM)->result->string, \
result_caret_pos (DM), (CSTR)) \
? STATUS_OK : STATUS_ALLOCATION_FAILED) ? STATUS_OK : STATUS_ALLOCATION_FAILED)
/* Appends character CHAR to the demangled result. */ /* Adds character CHAR to the demangled result. */
#define result_append_char(DM, CHAR) \ #define result_add_char(DM, CHAR) \
(dyn_string_append_char (&(DM)->result->string, (CHAR)) \ (dyn_string_insert_char (&(DM)->result->string, \
result_caret_pos (DM), (CHAR)) \
? STATUS_OK : STATUS_ALLOCATION_FAILED) ? STATUS_OK : STATUS_ALLOCATION_FAILED)
/* Inserts a dyn_string_t to the demangled result at position POS. */ /* Inserts a dyn_string_t to the demangled result at position POS. */
...@@ -307,12 +325,6 @@ static void demangling_delete ...@@ -307,12 +325,6 @@ static void demangling_delete
#define result_length(DM) \ #define result_length(DM) \
dyn_string_length (&(DM)->result->string) 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 /* Appends a (less-than, greater-than) character to the result in DM
to (open, close) a template argument or parameter list. Appends a to (open, close) a template argument or parameter list. Appends a
space first if necessary to prevent spurious elision of angle space first if necessary to prevent spurious elision of angle
...@@ -380,6 +392,7 @@ string_list_new (length) ...@@ -380,6 +392,7 @@ string_list_new (length)
int length; int length;
{ {
string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def)); string_list_t s = (string_list_t) malloc (sizeof (struct string_list_def));
s->caret_position = 0;
if (s == NULL) if (s == NULL)
return NULL; return NULL;
if (!dyn_string_init ((dyn_string_t) s, length)) if (!dyn_string_init ((dyn_string_t) s, length))
...@@ -409,20 +422,15 @@ result_add_separated_char (dm, character) ...@@ -409,20 +422,15 @@ result_add_separated_char (dm, character)
demangling_t dm; demangling_t dm;
int character; int character;
{ {
dyn_string_t s = &dm->result->string; char *result = dyn_string_buf (result_string (dm));
int caret_pos = result_caret_pos (dm);
/* Add a space if the last character is already a closing angle /* Add a space if the last character is already the character we
bracket, so that a nested template arg list doesn't look like want to add. */
it's closed with a right-shift operator. */ if (caret_pos > 0 && result[caret_pos - 1] == character)
if (dyn_string_last_char (s) == character) RETURN_IF_ERROR (result_add_char (dm, ' '));
{ /* Add the character. */
if (!dyn_string_append_char (s, ' ')) RETURN_IF_ERROR (result_add_char (dm, character));
return STATUS_ALLOCATION_FAILED;
}
/* Add closing angle brackets. */
if (!dyn_string_append_char (s, character))
return STATUS_ALLOCATION_FAILED;
return STATUS_OK; return STATUS_OK;
} }
...@@ -460,6 +468,51 @@ result_pop (dm) ...@@ -460,6 +468,51 @@ result_pop (dm)
return top; 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 /* Returns the start position of a fragment of the demangled result
that will be a substitution candidate. Should be called at the that will be a substitution candidate. Should be called at the
start of productions that can add substitutions. */ start of productions that can add substitutions. */
...@@ -468,7 +521,7 @@ static int ...@@ -468,7 +521,7 @@ static int
substitution_start (dm) substitution_start (dm)
demangling_t dm; demangling_t dm;
{ {
return result_length (dm); return result_caret_pos (dm);
} }
/* Adds the suffix of the current demangled result of DM starting at /* Adds the suffix of the current demangled result of DM starting at
...@@ -491,7 +544,7 @@ substitution_add (dm, start_position, template_p) ...@@ -491,7 +544,7 @@ substitution_add (dm, start_position, template_p)
/* Extract the substring of the current demangling result that /* Extract the substring of the current demangling result that
represents the subsitution candidate. */ represents the subsitution candidate. */
if (!dyn_string_substring (substitution, if (!dyn_string_substring (substitution,
result, start_position, result_length (dm))) result, start_position, result_caret_pos (dm)))
{ {
dyn_string_delete (substitution); dyn_string_delete (substitution);
return STATUS_ALLOCATION_FAILED; return STATUS_ALLOCATION_FAILED;
...@@ -843,7 +896,7 @@ static status_t demangle_bare_function_type ...@@ -843,7 +896,7 @@ static status_t demangle_bare_function_type
static status_t demangle_class_enum_type static status_t demangle_class_enum_type
PARAMS ((demangling_t, int *)); PARAMS ((demangling_t, int *));
static status_t demangle_array_type static status_t demangle_array_type
PARAMS ((demangling_t)); PARAMS ((demangling_t, int *));
static status_t demangle_template_param static status_t demangle_template_param
PARAMS ((demangling_t)); PARAMS ((demangling_t));
static status_t demangle_template_args static status_t demangle_template_args
...@@ -933,7 +986,7 @@ demangle_encoding (dm) ...@@ -933,7 +986,7 @@ demangle_encoding (dm)
/* Remember where the name starts. If it turns out to be a template /* Remember where the name starts. If it turns out to be a template
function, we'll have to insert the return type here. */ function, we'll have to insert the return type here. */
start_position = result_length (dm); start_position = result_caret_pos (dm);
if (peek == 'G' || peek == 'T') if (peek == 'G' || peek == 'T')
RETURN_IF_ERROR (demangle_special_name (dm)); RETURN_IF_ERROR (demangle_special_name (dm));
...@@ -943,7 +996,7 @@ demangle_encoding (dm) ...@@ -943,7 +996,7 @@ demangle_encoding (dm)
RETURN_IF_ERROR (demangle_name (dm, &encode_return_type)); RETURN_IF_ERROR (demangle_name (dm, &encode_return_type));
/* If there's anything left, the name was a function name, with /* If there's anything left, the name was a function name, with
maybe its return type, and its parameters types, following. */ maybe its return type, and its parameter types, following. */
if (!end_of_name_p (dm) if (!end_of_name_p (dm)
&& peek_char (dm) != 'E') && peek_char (dm) != 'E')
{ {
...@@ -1017,7 +1070,7 @@ demangle_name (dm, encode_return_type) ...@@ -1017,7 +1070,7 @@ demangle_name (dm, encode_return_type)
{ {
(void) next_char (dm); (void) next_char (dm);
(void) next_char (dm); (void) next_char (dm);
RETURN_IF_ERROR (result_append (dm, "std::")); RETURN_IF_ERROR (result_add (dm, "std::"));
RETURN_IF_ERROR RETURN_IF_ERROR
(demangle_unqualified_name (dm, &suppress_return_type)); (demangle_unqualified_name (dm, &suppress_return_type));
is_std_substitution = 1; is_std_substitution = 1;
...@@ -1082,20 +1135,30 @@ demangle_nested_name (dm, encode_return_type) ...@@ -1082,20 +1135,30 @@ demangle_nested_name (dm, encode_return_type)
peek = peek_char (dm); peek = peek_char (dm);
if (peek == 'r' || peek == 'V' || peek == 'K') if (peek == 'r' || peek == 'V' || peek == 'K')
{ {
dyn_string_t cv_qualifiers;
status_t status; status_t status;
/* Snarf up and emit CV qualifiers. */ /* Snarf up CV qualifiers. */
dyn_string_t cv_qualifiers = dyn_string_new (24); cv_qualifiers = dyn_string_new (24);
if (cv_qualifiers == NULL) if (cv_qualifiers == NULL)
return STATUS_ALLOCATION_FAILED; return STATUS_ALLOCATION_FAILED;
demangle_CV_qualifiers (dm, cv_qualifiers); demangle_CV_qualifiers (dm, cv_qualifiers);
status = result_append_string (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); dyn_string_delete (cv_qualifiers);
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
RETURN_IF_ERROR (result_append_space (dm));
} }
RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type)); RETURN_IF_ERROR (demangle_prefix (dm, encode_return_type));
/* No need to demangle the final <unqualified-name>; demangle_prefix /* No need to demangle the final <unqualified-name>; demangle_prefix
will handle it. */ will handle it. */
...@@ -1159,7 +1222,7 @@ demangle_prefix (dm, encode_return_type) ...@@ -1159,7 +1222,7 @@ demangle_prefix (dm, encode_return_type)
{ {
/* We have another level of scope qualification. */ /* We have another level of scope qualification. */
if (nested) if (nested)
RETURN_IF_ERROR (result_append (dm, "::")); RETURN_IF_ERROR (result_add (dm, "::"));
else else
nested = 1; nested = 1;
...@@ -1275,7 +1338,7 @@ demangle_source_name (dm) ...@@ -1275,7 +1338,7 @@ demangle_source_name (dm)
dm->last_source_name)); dm->last_source_name));
/* Emit it. */ /* Emit it. */
RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name)); RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
return STATUS_OK; return STATUS_OK;
} }
...@@ -1547,7 +1610,7 @@ demangle_operator_name (dm, short_name, num_args) ...@@ -1547,7 +1610,7 @@ demangle_operator_name (dm, short_name, num_args)
/* Is this a vendor-extended operator? */ /* Is this a vendor-extended operator? */
if (c0 == 'v' && IS_DIGIT (c1)) if (c0 == 'v' && IS_DIGIT (c1))
{ {
RETURN_IF_ERROR (result_append (dm, "operator ")); RETURN_IF_ERROR (result_add (dm, "operator "));
RETURN_IF_ERROR (demangle_source_name (dm)); RETURN_IF_ERROR (demangle_source_name (dm));
*num_args = 0; *num_args = 0;
return STATUS_OK; return STATUS_OK;
...@@ -1556,7 +1619,7 @@ demangle_operator_name (dm, short_name, num_args) ...@@ -1556,7 +1619,7 @@ demangle_operator_name (dm, short_name, num_args)
/* Is this a conversion operator? */ /* Is this a conversion operator? */
if (c0 == 'c' && c1 == 'v') if (c0 == 'c' && c1 == 'v')
{ {
RETURN_IF_ERROR (result_append (dm, "operator ")); RETURN_IF_ERROR (result_add (dm, "operator "));
/* Demangle the converted-to type. */ /* Demangle the converted-to type. */
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
*num_args = 0; *num_args = 0;
...@@ -1574,8 +1637,8 @@ demangle_operator_name (dm, short_name, num_args) ...@@ -1574,8 +1637,8 @@ demangle_operator_name (dm, short_name, num_args)
/* Found it. */ /* Found it. */
{ {
if (!short_name) if (!short_name)
RETURN_IF_ERROR (result_append (dm, "operator")); RETURN_IF_ERROR (result_add (dm, "operator"));
RETURN_IF_ERROR (result_append (dm, p->name)); RETURN_IF_ERROR (result_add (dm, p->name));
*num_args = p->num_args; *num_args = p->num_args;
return STATUS_OK; return STATUS_OK;
...@@ -1615,11 +1678,11 @@ demangle_nv_offset (dm) ...@@ -1615,11 +1678,11 @@ demangle_nv_offset (dm)
/* Don't display the offset unless in verbose mode. */ /* Don't display the offset unless in verbose mode. */
if (flag_verbose) if (flag_verbose)
{ {
status = result_append (dm, " [nv:"); status = result_add (dm, " [nv:");
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_string (dm, number); status = result_add_string (dm, number);
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_char (dm, ']'); status = result_add_char (dm, ']');
} }
/* Clean up. */ /* Clean up. */
...@@ -1651,11 +1714,11 @@ demangle_v_offset (dm) ...@@ -1651,11 +1714,11 @@ demangle_v_offset (dm)
/* Don't display the offset unless in verbose mode. */ /* Don't display the offset unless in verbose mode. */
if (flag_verbose) if (flag_verbose)
{ {
status = result_append (dm, " [v:"); status = result_add (dm, " [v:");
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_string (dm, number); status = result_add_string (dm, number);
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
result_append_char (dm, ','); result_add_char (dm, ',');
} }
dyn_string_delete (number); dyn_string_delete (number);
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
...@@ -1672,9 +1735,9 @@ demangle_v_offset (dm) ...@@ -1672,9 +1735,9 @@ demangle_v_offset (dm)
/* Don't display the vcall offset unless in verbose mode. */ /* Don't display the vcall offset unless in verbose mode. */
if (flag_verbose) if (flag_verbose)
{ {
status = result_append_string (dm, number); status = result_add_string (dm, number);
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_char (dm, ']'); status = result_add_char (dm, ']');
} }
dyn_string_delete (number); dyn_string_delete (number);
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
...@@ -1763,7 +1826,7 @@ demangle_special_name (dm) ...@@ -1763,7 +1826,7 @@ demangle_special_name (dm)
/* A guard variable name. Consume the G. */ /* A guard variable name. Consume the G. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (demangle_char (dm, 'V')); RETURN_IF_ERROR (demangle_char (dm, 'V'));
RETURN_IF_ERROR (result_append (dm, "guard variable for ")); RETURN_IF_ERROR (result_add (dm, "guard variable for "));
RETURN_IF_ERROR (demangle_name (dm, &unused)); RETURN_IF_ERROR (demangle_name (dm, &unused));
} }
else if (peek == 'T') else if (peek == 'T')
...@@ -1778,77 +1841,77 @@ demangle_special_name (dm) ...@@ -1778,77 +1841,77 @@ demangle_special_name (dm)
case 'V': case 'V':
/* Virtual table. */ /* Virtual table. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "vtable for ")); RETURN_IF_ERROR (result_add (dm, "vtable for "));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
case 'T': case 'T':
/* VTT structure. */ /* VTT structure. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "VTT for ")); RETURN_IF_ERROR (result_add (dm, "VTT for "));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
case 'I': case 'I':
/* Typeinfo structure. */ /* Typeinfo structure. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "typeinfo for ")); RETURN_IF_ERROR (result_add (dm, "typeinfo for "));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
case 'F': case 'F':
/* Typeinfo function. Used only in old ABI with new mangling. */ /* Typeinfo function. Used only in old ABI with new mangling. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "typeinfo fn for ")); RETURN_IF_ERROR (result_add (dm, "typeinfo fn for "));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
case 'S': case 'S':
/* Character string containing type name, used in typeinfo. */ /* Character string containing type name, used in typeinfo. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "typeinfo name for ")); RETURN_IF_ERROR (result_add (dm, "typeinfo name for "));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
case 'J': case 'J':
/* The java Class variable corresponding to a C++ class. */ /* The java Class variable corresponding to a C++ class. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "java Class for ")); RETURN_IF_ERROR (result_add (dm, "java Class for "));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
case 'h': case 'h':
/* Non-virtual thunk. */ /* Non-virtual thunk. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "non-virtual thunk")); RETURN_IF_ERROR (result_add (dm, "non-virtual thunk"));
RETURN_IF_ERROR (demangle_nv_offset (dm)); RETURN_IF_ERROR (demangle_nv_offset (dm));
/* Demangle the separator. */ /* Demangle the separator. */
RETURN_IF_ERROR (demangle_char (dm, '_')); RETURN_IF_ERROR (demangle_char (dm, '_'));
/* Demangle and emit the target name and function type. */ /* Demangle and emit the target name and function type. */
RETURN_IF_ERROR (result_append (dm, " to ")); RETURN_IF_ERROR (result_add (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm)); RETURN_IF_ERROR (demangle_encoding (dm));
break; break;
case 'v': case 'v':
/* Virtual thunk. */ /* Virtual thunk. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "virtual thunk")); RETURN_IF_ERROR (result_add (dm, "virtual thunk"));
RETURN_IF_ERROR (demangle_v_offset (dm)); RETURN_IF_ERROR (demangle_v_offset (dm));
/* Demangle the separator. */ /* Demangle the separator. */
RETURN_IF_ERROR (demangle_char (dm, '_')); RETURN_IF_ERROR (demangle_char (dm, '_'));
/* Demangle and emit the target function. */ /* Demangle and emit the target function. */
RETURN_IF_ERROR (result_append (dm, " to ")); RETURN_IF_ERROR (result_add (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm)); RETURN_IF_ERROR (demangle_encoding (dm));
break; break;
case 'c': case 'c':
/* Covariant return thunk. */ /* Covariant return thunk. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "covariant return thunk")); RETURN_IF_ERROR (result_add (dm, "covariant return thunk"));
RETURN_IF_ERROR (demangle_call_offset (dm)); RETURN_IF_ERROR (demangle_call_offset (dm));
RETURN_IF_ERROR (demangle_call_offset (dm)); RETURN_IF_ERROR (demangle_call_offset (dm));
/* Demangle and emit the target function. */ /* Demangle and emit the target function. */
RETURN_IF_ERROR (result_append (dm, " to ")); RETURN_IF_ERROR (result_add (dm, " to "));
RETURN_IF_ERROR (demangle_encoding (dm)); RETURN_IF_ERROR (demangle_encoding (dm));
break; break;
...@@ -1859,7 +1922,7 @@ demangle_special_name (dm) ...@@ -1859,7 +1922,7 @@ demangle_special_name (dm)
dyn_string_t derived_type; dyn_string_t derived_type;
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (result_append (dm, "construction vtable for ")); RETURN_IF_ERROR (result_add (dm, "construction vtable for "));
/* Demangle the derived type off to the side. */ /* Demangle the derived type off to the side. */
RETURN_IF_ERROR (result_push (dm)); RETURN_IF_ERROR (result_push (dm));
...@@ -1883,17 +1946,17 @@ demangle_special_name (dm) ...@@ -1883,17 +1946,17 @@ demangle_special_name (dm)
/* Emit the derived type. */ /* Emit the derived type. */
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append (dm, "-in-"); status = result_add (dm, "-in-");
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_string (dm, derived_type); status = result_add_string (dm, derived_type);
dyn_string_delete (derived_type); dyn_string_delete (derived_type);
/* Don't display the offset unless in verbose mode. */ /* Don't display the offset unless in verbose mode. */
if (flag_verbose) if (flag_verbose)
{ {
status = result_append_char (dm, ' '); status = result_add_char (dm, ' ');
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
result_append_string (dm, number); result_add_string (dm, number);
} }
dyn_string_delete (number); dyn_string_delete (number);
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
...@@ -1949,14 +2012,14 @@ demangle_ctor_dtor_name (dm) ...@@ -1949,14 +2012,14 @@ demangle_ctor_dtor_name (dm)
advance_char (dm); advance_char (dm);
if (peek_char (dm) < '1' || peek_char (dm) > '3') if (peek_char (dm) < '1' || peek_char (dm) > '3')
return "Unrecognized constructor."; return "Unrecognized constructor.";
RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name)); RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
/* Print the flavor of the constructor if in verbose mode. */ /* Print the flavor of the constructor if in verbose mode. */
flavor = next_char (dm) - '1'; flavor = next_char (dm) - '1';
if (flag_verbose) if (flag_verbose)
{ {
RETURN_IF_ERROR (result_append (dm, "[")); RETURN_IF_ERROR (result_add (dm, "["));
RETURN_IF_ERROR (result_append (dm, ctor_flavors[flavor])); RETURN_IF_ERROR (result_add (dm, ctor_flavors[flavor]));
RETURN_IF_ERROR (result_append_char (dm, ']')); RETURN_IF_ERROR (result_add_char (dm, ']'));
} }
} }
else if (peek == 'D') else if (peek == 'D')
...@@ -1965,15 +2028,15 @@ demangle_ctor_dtor_name (dm) ...@@ -1965,15 +2028,15 @@ demangle_ctor_dtor_name (dm)
advance_char (dm); advance_char (dm);
if (peek_char (dm) < '0' || peek_char (dm) > '2') if (peek_char (dm) < '0' || peek_char (dm) > '2')
return "Unrecognized destructor."; return "Unrecognized destructor.";
RETURN_IF_ERROR (result_append_char (dm, '~')); RETURN_IF_ERROR (result_add_char (dm, '~'));
RETURN_IF_ERROR (result_append_string (dm, dm->last_source_name)); RETURN_IF_ERROR (result_add_string (dm, dm->last_source_name));
/* Print the flavor of the destructor if in verbose mode. */ /* Print the flavor of the destructor if in verbose mode. */
flavor = next_char (dm) - '0'; flavor = next_char (dm) - '0';
if (flag_verbose) if (flag_verbose)
{ {
RETURN_IF_ERROR (result_append (dm, " [")); RETURN_IF_ERROR (result_add (dm, " ["));
RETURN_IF_ERROR (result_append (dm, dtor_flavors[flavor])); RETURN_IF_ERROR (result_add (dm, dtor_flavors[flavor]));
RETURN_IF_ERROR (result_append_char (dm, ']')); RETURN_IF_ERROR (result_add_char (dm, ']'));
} }
} }
else else
...@@ -2014,7 +2077,6 @@ demangle_type_ptr (dm, insert_pos, substitution_start) ...@@ -2014,7 +2077,6 @@ demangle_type_ptr (dm, insert_pos, substitution_start)
int *insert_pos; int *insert_pos;
int substitution_start; int substitution_start;
{ {
char next;
status_t status; status_t status;
int is_substitution_candidate = 1; int is_substitution_candidate = 1;
...@@ -2022,9 +2084,9 @@ demangle_type_ptr (dm, insert_pos, substitution_start) ...@@ -2022,9 +2084,9 @@ demangle_type_ptr (dm, insert_pos, substitution_start)
/* Scan forward, collecting pointers and references into symbols, /* Scan forward, collecting pointers and references into symbols,
until we hit something else. Then emit the type. */ until we hit something else. Then emit the type. */
next = peek_char (dm); switch (peek_char (dm))
if (next == 'P')
{ {
case 'P':
/* A pointer. Snarf the `P'. */ /* A pointer. Snarf the `P'. */
advance_char (dm); advance_char (dm);
/* Demangle the underlying type. */ /* Demangle the underlying type. */
...@@ -2036,9 +2098,9 @@ demangle_type_ptr (dm, insert_pos, substitution_start) ...@@ -2036,9 +2098,9 @@ demangle_type_ptr (dm, insert_pos, substitution_start)
/* The next (outermost) pointer or reference character should go /* The next (outermost) pointer or reference character should go
after this one. */ after this one. */
++(*insert_pos); ++(*insert_pos);
} break;
else if (next == 'R')
{ case 'R':
/* A reference. Snarf the `R'. */ /* A reference. Snarf the `R'. */
advance_char (dm); advance_char (dm);
/* Demangle the underlying type. */ /* Demangle the underlying type. */
...@@ -2050,8 +2112,9 @@ demangle_type_ptr (dm, insert_pos, substitution_start) ...@@ -2050,8 +2112,9 @@ demangle_type_ptr (dm, insert_pos, substitution_start)
/* The next (outermost) pointer or reference character should go /* The next (outermost) pointer or reference character should go
after this one. */ after this one. */
++(*insert_pos); ++(*insert_pos);
} break;
else if (next == 'M')
case 'M':
{ {
/* A pointer-to-member. */ /* A pointer-to-member. */
dyn_string_t class_type; dyn_string_t class_type;
...@@ -2071,17 +2134,24 @@ demangle_type_ptr (dm, insert_pos, substitution_start) ...@@ -2071,17 +2134,24 @@ demangle_type_ptr (dm, insert_pos, substitution_start)
and set *insert_pos to the spot between the first and set *insert_pos to the spot between the first
parentheses. */ parentheses. */
status = demangle_type_ptr (dm, insert_pos, substitution_start); 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 else
{ {
/* A pointer-to-member variable. Demangle the type of the /* A pointer-to-member variable. Demangle the type of the
pointed-to member. */ pointed-to member. */
status = demangle_type (dm); status = demangle_type (dm);
/* Make it pretty. */ /* Make it pretty. */
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status)
status = result_append_space (dm); && !result_previous_char_is_space (dm))
status = result_add_char (dm, ' ');
/* The pointer-to-member notation (e.g. `C::*') follows the /* The pointer-to-member notation (e.g. `C::*') follows the
member's type. */ member's type. */
*insert_pos = result_length (dm); *insert_pos = result_caret_pos (dm);
} }
/* Build the pointer-to-member notation. */ /* Build the pointer-to-member notation. */
...@@ -2100,15 +2170,16 @@ demangle_type_ptr (dm, insert_pos, substitution_start) ...@@ -2100,15 +2170,16 @@ demangle_type_ptr (dm, insert_pos, substitution_start)
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
} }
else if (next == 'F') break;
{
case 'F':
/* Ooh, tricky, a pointer-to-function. When we demangle the /* Ooh, tricky, a pointer-to-function. When we demangle the
function type, the return type should go at the very function type, the return type should go at the very
beginning. */ beginning. */
*insert_pos = result_length (dm); *insert_pos = result_caret_pos (dm);
/* The parentheses indicate this is a function pointer or /* The parentheses indicate this is a function pointer or
reference type. */ reference type. */
RETURN_IF_ERROR (result_append (dm, "()")); RETURN_IF_ERROR (result_add (dm, "()"));
/* Now demangle the function type. The return type will be /* Now demangle the function type. The return type will be
inserted before the `()', and the argument list will go after inserted before the `()', and the argument list will go after
it. */ it. */
...@@ -2120,20 +2191,27 @@ demangle_type_ptr (dm, insert_pos, substitution_start) ...@@ -2120,20 +2191,27 @@ demangle_type_ptr (dm, insert_pos, substitution_start)
type. Move it one character over so it points inside the type. Move it one character over so it points inside the
`()'. */ `()'. */
++(*insert_pos); ++(*insert_pos);
} break;
else
{ 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 /* No more pointer or reference tokens; this is therefore a
pointer to data. Finish up by demangling the underlying pointer to data. Finish up by demangling the underlying
type. */ type. */
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
/* The pointer or reference characters follow the underlying /* The pointer or reference characters follow the underlying
type, as in `int*&'. */ type, as in `int*&'. */
*insert_pos = result_length (dm); *insert_pos = result_caret_pos (dm);
/* Because of the production <type> ::= <substitution>, /* Because of the production <type> ::= <substitution>,
demangle_type will already have added the underlying type as demangle_type will already have added the underlying type as
a substitution candidate. Don't do it again. */ a substitution candidate. Don't do it again. */
is_substitution_candidate = 0; is_substitution_candidate = 0;
break;
} }
if (is_substitution_candidate) if (is_substitution_candidate)
...@@ -2201,34 +2279,30 @@ demangle_type (dm) ...@@ -2201,34 +2279,30 @@ demangle_type (dm)
{ {
status_t status; status_t status;
dyn_string_t cv_qualifiers = dyn_string_new (24); dyn_string_t cv_qualifiers = dyn_string_new (24);
int old_caret_position = result_get_caret (dm);
if (cv_qualifiers == NULL) if (cv_qualifiers == NULL)
return STATUS_ALLOCATION_FAILED; return STATUS_ALLOCATION_FAILED;
/* Decode all adjacent CV qualifiers. */
demangle_CV_qualifiers (dm, cv_qualifiers); demangle_CV_qualifiers (dm, cv_qualifiers);
/* Emit them, and shift the caret left so that the
/* If the qualifiers apply to a pointer or reference, they underlying type will be emitted before the qualifiers. */
need to come after the whole qualified type. */ status = result_add_string (dm, cv_qualifiers);
if (peek_char (dm) == 'P' || peek_char (dm) == 'R') result_shift_caret (dm, -dyn_string_length (cv_qualifiers));
{ /* Clean up. */
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); dyn_string_delete (cv_qualifiers);
RETURN_IF_ERROR (status); 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; break;
...@@ -2236,7 +2310,7 @@ demangle_type (dm) ...@@ -2236,7 +2310,7 @@ demangle_type (dm)
return "Non-pointer or -reference function type."; return "Non-pointer or -reference function type.";
case 'A': case 'A':
RETURN_IF_ERROR (demangle_array_type (dm)); RETURN_IF_ERROR (demangle_array_type (dm, NULL));
break; break;
case 'T': case 'T':
...@@ -2325,14 +2399,14 @@ demangle_type (dm) ...@@ -2325,14 +2399,14 @@ demangle_type (dm)
case 'C': case 'C':
/* A C99 complex type. */ /* A C99 complex type. */
RETURN_IF_ERROR (result_append (dm, "complex ")); RETURN_IF_ERROR (result_add (dm, "complex "));
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
case 'G': case 'G':
/* A C99 imaginary type. */ /* A C99 imaginary type. */
RETURN_IF_ERROR (result_append (dm, "imaginary ")); RETURN_IF_ERROR (result_add (dm, "imaginary "));
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
...@@ -2341,7 +2415,7 @@ demangle_type (dm) ...@@ -2341,7 +2415,7 @@ demangle_type (dm)
/* Vendor-extended type qualifier. */ /* Vendor-extended type qualifier. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (demangle_source_name (dm)); RETURN_IF_ERROR (demangle_source_name (dm));
RETURN_IF_ERROR (result_append_char (dm, ' ')); RETURN_IF_ERROR (result_add_char (dm, ' '));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
break; break;
...@@ -2441,7 +2515,7 @@ demangle_builtin_type (dm) ...@@ -2441,7 +2515,7 @@ demangle_builtin_type (dm)
if (type_name == NULL) if (type_name == NULL)
return "Unrecognized <builtin-type> code."; return "Unrecognized <builtin-type> code.";
RETURN_IF_ERROR (result_append (dm, type_name)); RETURN_IF_ERROR (result_add (dm, type_name));
advance_char (dm); advance_char (dm);
return STATUS_OK; return STATUS_OK;
} }
...@@ -2512,7 +2586,7 @@ demangle_function_type (dm, function_name_pos) ...@@ -2512,7 +2586,7 @@ demangle_function_type (dm, function_name_pos)
{ {
/* Indicate this function has C linkage if in verbose mode. */ /* Indicate this function has C linkage if in verbose mode. */
if (flag_verbose) if (flag_verbose)
RETURN_IF_ERROR (result_append (dm, " [extern \"C\"] ")); RETURN_IF_ERROR (result_add (dm, " [extern \"C\"] "));
advance_char (dm); advance_char (dm);
} }
RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos)); RETURN_IF_ERROR (demangle_bare_function_type (dm, function_name_pos));
...@@ -2539,7 +2613,7 @@ demangle_bare_function_type (dm, return_type_pos) ...@@ -2539,7 +2613,7 @@ demangle_bare_function_type (dm, return_type_pos)
DEMANGLE_TRACE ("bare-function-type", dm); DEMANGLE_TRACE ("bare-function-type", dm);
RETURN_IF_ERROR (result_append_char (dm, '(')); RETURN_IF_ERROR (result_add_char (dm, '('));
while (!end_of_name_p (dm) && peek_char (dm) != 'E') while (!end_of_name_p (dm) && peek_char (dm) != 'E')
{ {
if (sequence == -1) if (sequence == -1)
...@@ -2581,7 +2655,7 @@ demangle_bare_function_type (dm, return_type_pos) ...@@ -2581,7 +2655,7 @@ demangle_bare_function_type (dm, return_type_pos)
{ {
/* Separate parameter types by commas. */ /* Separate parameter types by commas. */
if (sequence > 0) if (sequence > 0)
RETURN_IF_ERROR (result_append (dm, ", ")); RETURN_IF_ERROR (result_add (dm, ", "));
/* Demangle the type. */ /* Demangle the type. */
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
} }
...@@ -2589,7 +2663,7 @@ demangle_bare_function_type (dm, return_type_pos) ...@@ -2589,7 +2663,7 @@ demangle_bare_function_type (dm, return_type_pos)
++sequence; ++sequence;
} }
RETURN_IF_ERROR (result_append_char (dm, ')')); RETURN_IF_ERROR (result_add_char (dm, ')'));
/* We should have demangled at least one parameter type (which would /* We should have demangled at least one parameter type (which would
be void, for a function that takes no parameters), plus the be void, for a function that takes no parameters), plus the
...@@ -2620,17 +2694,32 @@ demangle_class_enum_type (dm, encode_return_type) ...@@ -2620,17 +2694,32 @@ demangle_class_enum_type (dm, encode_return_type)
/* Demangles and emits an <array-type>. /* 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> <array-type> ::= A [<dimension number>] _ <element type>
::= A <dimension expression> _ <element type> */ ::= A <dimension expression> _ <element type> */
static status_t static status_t
demangle_array_type (dm) demangle_array_type (dm, ptr_insert_pos)
demangling_t dm; demangling_t dm;
int *ptr_insert_pos;
{ {
status_t status = STATUS_OK; status_t status = STATUS_OK;
dyn_string_t array_size = NULL; dyn_string_t array_size = NULL;
char peek; char peek;
DEMANGLE_TRACE ("array-type", dm);
RETURN_IF_ERROR (demangle_char (dm, 'A')); RETURN_IF_ERROR (demangle_char (dm, 'A'));
/* Demangle the array size into array_size. */ /* Demangle the array size into array_size. */
...@@ -2664,13 +2753,24 @@ demangle_array_type (dm) ...@@ -2664,13 +2753,24 @@ demangle_array_type (dm)
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = demangle_type (dm); 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. */ /* Emit the array dimension syntax. */
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_char (dm, '['); status = result_add_char (dm, '[');
if (STATUS_NO_ERROR (status) && array_size != NULL) if (STATUS_NO_ERROR (status) && array_size != NULL)
status = result_append_string (dm, array_size); status = result_add_string (dm, array_size);
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_char (dm, ']'); status = result_add_char (dm, ']');
if (array_size != NULL) if (array_size != NULL)
dyn_string_delete (array_size); dyn_string_delete (array_size);
...@@ -2714,7 +2814,7 @@ demangle_template_param (dm) ...@@ -2714,7 +2814,7 @@ demangle_template_param (dm)
/* parm_number exceeded the number of arguments in the current /* parm_number exceeded the number of arguments in the current
template argument list. */ template argument list. */
return "Template parameter number out of bounds."; return "Template parameter number out of bounds.";
RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg)); RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
return STATUS_OK; return STATUS_OK;
} }
...@@ -2752,7 +2852,7 @@ demangle_template_args (dm) ...@@ -2752,7 +2852,7 @@ demangle_template_args (dm)
if (first) if (first)
first = 0; first = 0;
else else
RETURN_IF_ERROR (result_append (dm, ", ")); RETURN_IF_ERROR (result_add (dm, ", "));
/* Capture the template arg. */ /* Capture the template arg. */
RETURN_IF_ERROR (result_push (dm)); RETURN_IF_ERROR (result_push (dm));
...@@ -2760,7 +2860,7 @@ demangle_template_args (dm) ...@@ -2760,7 +2860,7 @@ demangle_template_args (dm)
arg = result_pop (dm); arg = result_pop (dm);
/* Emit it in the demangled name. */ /* Emit it in the demangled name. */
RETURN_IF_ERROR (result_append_string (dm, (dyn_string_t) arg)); RETURN_IF_ERROR (result_add_string (dm, (dyn_string_t) arg));
/* Save it for use in expanding <template-param>s. */ /* Save it for use in expanding <template-param>s. */
template_arg_list_add_arg (arg_list, arg); template_arg_list_add_arg (arg_list, arg);
...@@ -2836,9 +2936,9 @@ demangle_literal (dm) ...@@ -2836,9 +2936,9 @@ demangle_literal (dm)
corresponding to false or true, respectively. */ corresponding to false or true, respectively. */
value = peek_char (dm); value = peek_char (dm);
if (value == '0') if (value == '0')
RETURN_IF_ERROR (result_append (dm, "false")); RETURN_IF_ERROR (result_add (dm, "false"));
else if (value == '1') else if (value == '1')
RETURN_IF_ERROR (result_append (dm, "true")); RETURN_IF_ERROR (result_add (dm, "true"));
else else
return "Unrecognized bool constant."; return "Unrecognized bool constant.";
/* Consume the 0 or 1. */ /* Consume the 0 or 1. */
...@@ -2856,10 +2956,10 @@ demangle_literal (dm) ...@@ -2856,10 +2956,10 @@ demangle_literal (dm)
value_string = dyn_string_new (0); value_string = dyn_string_new (0);
status = demangle_number_literally (dm, value_string, 10, 1); status = demangle_number_literally (dm, value_string, 10, 1);
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_string (dm, value_string); status = result_add_string (dm, value_string);
/* For long integers, append an l. */ /* For long integers, append an l. */
if (code == 'l' && STATUS_NO_ERROR (status)) if (code == 'l' && STATUS_NO_ERROR (status))
status = result_append_char (dm, code); status = result_add_char (dm, code);
dyn_string_delete (value_string); dyn_string_delete (value_string);
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
...@@ -2869,9 +2969,9 @@ demangle_literal (dm) ...@@ -2869,9 +2969,9 @@ demangle_literal (dm)
literal's type explicitly using cast syntax. */ literal's type explicitly using cast syntax. */
} }
RETURN_IF_ERROR (result_append_char (dm, '(')); RETURN_IF_ERROR (result_add_char (dm, '('));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
RETURN_IF_ERROR (result_append_char (dm, ')')); RETURN_IF_ERROR (result_add_char (dm, ')'));
value_string = dyn_string_new (0); value_string = dyn_string_new (0);
if (value_string == NULL) if (value_string == NULL)
...@@ -2879,7 +2979,7 @@ demangle_literal (dm) ...@@ -2879,7 +2979,7 @@ demangle_literal (dm)
status = demangle_number_literally (dm, value_string, 10, 1); status = demangle_number_literally (dm, value_string, 10, 1);
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_string (dm, value_string); status = result_add_string (dm, value_string);
dyn_string_delete (value_string); dyn_string_delete (value_string);
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
...@@ -2967,30 +3067,30 @@ demangle_expression (dm) ...@@ -2967,30 +3067,30 @@ demangle_expression (dm)
/* If it's binary, do an operand first. */ /* If it's binary, do an operand first. */
if (num_args > 1) if (num_args > 1)
{ {
status = result_append_char (dm, '('); status = result_add_char (dm, '(');
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = demangle_expression (dm); status = demangle_expression (dm);
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_char (dm, ')'); status = result_add_char (dm, ')');
} }
/* Emit the operator. */ /* Emit the operator. */
if (STATUS_NO_ERROR (status)) if (STATUS_NO_ERROR (status))
status = result_append_string (dm, operator_name); status = result_add_string (dm, operator_name);
dyn_string_delete (operator_name); dyn_string_delete (operator_name);
RETURN_IF_ERROR (status); RETURN_IF_ERROR (status);
/* Emit its second (if binary) or only (if unary) operand. */ /* Emit its second (if binary) or only (if unary) operand. */
RETURN_IF_ERROR (result_append_char (dm, '(')); RETURN_IF_ERROR (result_add_char (dm, '('));
RETURN_IF_ERROR (demangle_expression (dm)); RETURN_IF_ERROR (demangle_expression (dm));
RETURN_IF_ERROR (result_append_char (dm, ')')); RETURN_IF_ERROR (result_add_char (dm, ')'));
/* The ternary operator takes a third operand. */ /* The ternary operator takes a third operand. */
if (num_args == 3) if (num_args == 3)
{ {
RETURN_IF_ERROR (result_append (dm, ":(")); RETURN_IF_ERROR (result_add (dm, ":("));
RETURN_IF_ERROR (demangle_expression (dm)); RETURN_IF_ERROR (demangle_expression (dm));
RETURN_IF_ERROR (result_append_char (dm, ')')); RETURN_IF_ERROR (result_add_char (dm, ')'));
} }
} }
...@@ -3009,7 +3109,7 @@ demangle_scope_expression (dm) ...@@ -3009,7 +3109,7 @@ demangle_scope_expression (dm)
RETURN_IF_ERROR (demangle_char (dm, 's')); RETURN_IF_ERROR (demangle_char (dm, 's'));
RETURN_IF_ERROR (demangle_char (dm, 'r')); RETURN_IF_ERROR (demangle_char (dm, 'r'));
RETURN_IF_ERROR (demangle_type (dm)); RETURN_IF_ERROR (demangle_type (dm));
RETURN_IF_ERROR (result_append (dm, "::")); RETURN_IF_ERROR (result_add (dm, "::"));
RETURN_IF_ERROR (demangle_encoding (dm)); RETURN_IF_ERROR (demangle_encoding (dm));
return STATUS_OK; return STATUS_OK;
} }
...@@ -3100,17 +3200,17 @@ demangle_substitution (dm, template_p) ...@@ -3100,17 +3200,17 @@ demangle_substitution (dm, template_p)
switch (peek) switch (peek)
{ {
case 't': case 't':
RETURN_IF_ERROR (result_append (dm, "std")); RETURN_IF_ERROR (result_add (dm, "std"));
break; break;
case 'a': case 'a':
RETURN_IF_ERROR (result_append (dm, "std::allocator")); RETURN_IF_ERROR (result_add (dm, "std::allocator"));
new_last_source_name = "allocator"; new_last_source_name = "allocator";
*template_p = 1; *template_p = 1;
break; break;
case 'b': case 'b':
RETURN_IF_ERROR (result_append (dm, "std::basic_string")); RETURN_IF_ERROR (result_add (dm, "std::basic_string"));
new_last_source_name = "basic_string"; new_last_source_name = "basic_string";
*template_p = 1; *template_p = 1;
break; break;
...@@ -3118,12 +3218,12 @@ demangle_substitution (dm, template_p) ...@@ -3118,12 +3218,12 @@ demangle_substitution (dm, template_p)
case 's': case 's':
if (!flag_verbose) if (!flag_verbose)
{ {
RETURN_IF_ERROR (result_append (dm, "std::string")); RETURN_IF_ERROR (result_add (dm, "std::string"));
new_last_source_name = "string"; new_last_source_name = "string";
} }
else else
{ {
RETURN_IF_ERROR (result_append (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >")); RETURN_IF_ERROR (result_add (dm, "std::basic_string<char, std::char_traits<char>, std::allocator<char> >"));
new_last_source_name = "basic_string"; new_last_source_name = "basic_string";
} }
*template_p = 0; *template_p = 0;
...@@ -3132,12 +3232,12 @@ demangle_substitution (dm, template_p) ...@@ -3132,12 +3232,12 @@ demangle_substitution (dm, template_p)
case 'i': case 'i':
if (!flag_verbose) if (!flag_verbose)
{ {
RETURN_IF_ERROR (result_append (dm, "std::istream")); RETURN_IF_ERROR (result_add (dm, "std::istream"));
new_last_source_name = "istream"; new_last_source_name = "istream";
} }
else else
{ {
RETURN_IF_ERROR (result_append (dm, "std::basic_istream<char, std::char_traints<char> >")); RETURN_IF_ERROR (result_add (dm, "std::basic_istream<char, std::char_traints<char> >"));
new_last_source_name = "basic_istream"; new_last_source_name = "basic_istream";
} }
*template_p = 0; *template_p = 0;
...@@ -3146,12 +3246,12 @@ demangle_substitution (dm, template_p) ...@@ -3146,12 +3246,12 @@ demangle_substitution (dm, template_p)
case 'o': case 'o':
if (!flag_verbose) if (!flag_verbose)
{ {
RETURN_IF_ERROR (result_append (dm, "std::ostream")); RETURN_IF_ERROR (result_add (dm, "std::ostream"));
new_last_source_name = "ostream"; new_last_source_name = "ostream";
} }
else else
{ {
RETURN_IF_ERROR (result_append (dm, "std::basic_ostream<char, std::char_traits<char> >")); RETURN_IF_ERROR (result_add (dm, "std::basic_ostream<char, std::char_traits<char> >"));
new_last_source_name = "basic_ostream"; new_last_source_name = "basic_ostream";
} }
*template_p = 0; *template_p = 0;
...@@ -3160,12 +3260,12 @@ demangle_substitution (dm, template_p) ...@@ -3160,12 +3260,12 @@ demangle_substitution (dm, template_p)
case 'd': case 'd':
if (!flag_verbose) if (!flag_verbose)
{ {
RETURN_IF_ERROR (result_append (dm, "std::iostream")); RETURN_IF_ERROR (result_add (dm, "std::iostream"));
new_last_source_name = "iostream"; new_last_source_name = "iostream";
} }
else else
{ {
RETURN_IF_ERROR (result_append (dm, "std::basic_iostream<char, std::char_traits<char> >")); RETURN_IF_ERROR (result_add (dm, "std::basic_iostream<char, std::char_traits<char> >"));
new_last_source_name = "basic_iostream"; new_last_source_name = "basic_iostream";
} }
*template_p = 0; *template_p = 0;
...@@ -3196,7 +3296,7 @@ demangle_substitution (dm, template_p) ...@@ -3196,7 +3296,7 @@ demangle_substitution (dm, template_p)
return "Substitution number out of range."; return "Substitution number out of range.";
/* Emit the substitution text. */ /* Emit the substitution text. */
RETURN_IF_ERROR (result_append_string (dm, text)); RETURN_IF_ERROR (result_add_string (dm, text));
RETURN_IF_ERROR (demangle_char (dm, '_')); RETURN_IF_ERROR (demangle_char (dm, '_'));
return STATUS_OK; return STATUS_OK;
...@@ -3216,12 +3316,12 @@ demangle_local_name (dm) ...@@ -3216,12 +3316,12 @@ demangle_local_name (dm)
RETURN_IF_ERROR (demangle_char (dm, 'Z')); RETURN_IF_ERROR (demangle_char (dm, 'Z'));
RETURN_IF_ERROR (demangle_encoding (dm)); RETURN_IF_ERROR (demangle_encoding (dm));
RETURN_IF_ERROR (demangle_char (dm, 'E')); RETURN_IF_ERROR (demangle_char (dm, 'E'));
RETURN_IF_ERROR (result_append (dm, "::")); RETURN_IF_ERROR (result_add (dm, "::"));
if (peek_char (dm) == 's') if (peek_char (dm) == 's')
{ {
/* Local character string literal. */ /* Local character string literal. */
RETURN_IF_ERROR (result_append (dm, "string literal")); RETURN_IF_ERROR (result_add (dm, "string literal"));
/* Consume the s. */ /* Consume the s. */
advance_char (dm); advance_char (dm);
RETURN_IF_ERROR (demangle_discriminator (dm, 0)); RETURN_IF_ERROR (demangle_discriminator (dm, 0));
...@@ -3258,7 +3358,7 @@ demangle_discriminator (dm, suppress_first) ...@@ -3258,7 +3358,7 @@ demangle_discriminator (dm, suppress_first)
/* Consume the underscore. */ /* Consume the underscore. */
advance_char (dm); advance_char (dm);
if (flag_verbose) if (flag_verbose)
RETURN_IF_ERROR (result_append (dm, " [#")); RETURN_IF_ERROR (result_add (dm, " [#"));
/* Check if there's a number following the underscore. */ /* Check if there's a number following the underscore. */
if (IS_DIGIT ((unsigned char) peek_char (dm))) if (IS_DIGIT ((unsigned char) peek_char (dm)))
{ {
...@@ -3276,15 +3376,15 @@ demangle_discriminator (dm, suppress_first) ...@@ -3276,15 +3376,15 @@ demangle_discriminator (dm, suppress_first)
{ {
if (flag_verbose) if (flag_verbose)
/* A missing digit correspond to one. */ /* A missing digit correspond to one. */
RETURN_IF_ERROR (result_append_char (dm, '1')); RETURN_IF_ERROR (result_add_char (dm, '1'));
} }
if (flag_verbose) if (flag_verbose)
RETURN_IF_ERROR (result_append_char (dm, ']')); RETURN_IF_ERROR (result_add_char (dm, ']'));
} }
else if (!suppress_first) else if (!suppress_first)
{ {
if (flag_verbose) if (flag_verbose)
RETURN_IF_ERROR (result_append (dm, " [#0]")); RETURN_IF_ERROR (result_add (dm, " [#0]"));
} }
return STATUS_OK; return STATUS_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment