X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Fcp-name-parser.y;h=c6a5c341bfc521065284735b9910b9a0ebd34bfd;hb=484b3c325d8182cd7b7da4ceeaedc238c7f80b5c;hp=889ef9193fe89f26d9f76d9e8f0f3a99ff667a48;hpb=847f5ce8dadda349a73bcc89395d8da272e837f2;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 889ef9193f..c6a5c341bf 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -1,25 +1,23 @@
/* YACC parser for C++ names, for GDB.
- Copyright 2003, 2004, 2005
- Free Software Foundation, Inc.
+ Copyright (C) 2003-2016 Free Software Foundation, Inc.
Parts of the lexer are based on c-exp.y from GDB.
-This file is part of GDB.
+ This file is part of GDB.
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see . */
/* Note that malloc's and realloc's in this file are transformed to
xmalloc and xrealloc respectively by the same sed command in the
@@ -31,14 +29,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
%{
-#include
-#include
-#include
-#include
+#include "defs.h"
+#include
#include "safe-ctype.h"
-#include "libiberty.h"
#include "demangle.h"
+#include "cp-support.h"
/* Bison does not make it easy to create a parser without global
state, unfortunately. Here are all the global variables used
@@ -54,13 +50,37 @@ static const char *lexptr, *prev_lexptr, *error_lexptr, *global_errmsg;
/* The components built by the parser are allocated ahead of time,
and cached in this structure. */
+#define ALLOC_CHUNK 100
+
struct demangle_info {
int used;
- struct demangle_component comps[1];
+ struct demangle_info *next;
+ struct demangle_component comps[ALLOC_CHUNK];
};
static struct demangle_info *demangle_info;
-#define d_grab() (&demangle_info->comps[demangle_info->used++])
+
+static struct demangle_component *
+d_grab (void)
+{
+ struct demangle_info *more;
+
+ if (demangle_info->used >= ALLOC_CHUNK)
+ {
+ if (demangle_info->next == NULL)
+ {
+ more = XNEW (struct demangle_info);
+ more->next = NULL;
+ demangle_info->next = more;
+ }
+ else
+ more = demangle_info->next;
+
+ more->used = 0;
+ demangle_info = more;
+ }
+ return &demangle_info->comps[demangle_info->used++];
+}
/* The parse tree created by the parser is stored here after a successful
parse. */
@@ -144,6 +164,12 @@ static struct demangle_component *d_binary (const char *,
#define yygindex cpname_yygindex
#define yytable cpname_yytable
#define yycheck cpname_yycheck
+#define yyss cpname_yyss
+#define yysslim cpname_yysslim
+#define yyssp cpname_yyssp
+#define yystacksize cpname_yystacksize
+#define yyvs cpname_yyvs
+#define yyvsp cpname_yyvsp
int yyparse (void);
static int yylex (void);
@@ -162,7 +188,11 @@ fill_comp (enum demangle_component_type d_type, struct demangle_component *lhs,
struct demangle_component *rhs)
{
struct demangle_component *ret = d_grab ();
- cplus_demangle_fill_component (ret, d_type, lhs, rhs);
+ int i;
+
+ i = cplus_demangle_fill_component (ret, d_type, lhs, rhs);
+ gdb_assert (i);
+
return ret;
}
@@ -178,7 +208,11 @@ static struct demangle_component *
make_operator (const char *name, int args)
{
struct demangle_component *ret = d_grab ();
- cplus_demangle_fill_operator (ret, name, args);
+ int i;
+
+ i = cplus_demangle_fill_operator (ret, name, args);
+ gdb_assert (i);
+
return ret;
}
@@ -186,7 +220,11 @@ static struct demangle_component *
make_dtor (enum gnu_v3_dtor_kinds kind, struct demangle_component *name)
{
struct demangle_component *ret = d_grab ();
- cplus_demangle_fill_dtor (ret, kind, name);
+ int i;
+
+ i = cplus_demangle_fill_dtor (ret, kind, name);
+ gdb_assert (i);
+
return ret;
}
@@ -194,7 +232,11 @@ static struct demangle_component *
make_builtin_type (const char *name)
{
struct demangle_component *ret = d_grab ();
- cplus_demangle_fill_builtin_type (ret, name);
+ int i;
+
+ i = cplus_demangle_fill_builtin_type (ret, name);
+ gdb_assert (i);
+
return ret;
}
@@ -202,7 +244,11 @@ static struct demangle_component *
make_name (const char *name, int len)
{
struct demangle_component *ret = d_grab ();
- cplus_demangle_fill_name (ret, name, len);
+ int i;
+
+ i = cplus_demangle_fill_name (ret, name, len);
+ gdb_assert (i);
+
return ret;
}
@@ -228,16 +274,12 @@ make_name (const char *name, int len)
int fold_flag;
} abstract;
int lval;
- struct {
- int val;
- struct demangle_component *type;
- } typed_val_int;
const char *opname;
}
-%type exp exp1 type start start_opt operator colon_name
+%type exp exp1 type start start_opt oper colon_name
%type unqualified_name colon_ext_name
-%type template template_arg
+%type templ template_arg
%type builtin_type
%type typespec_2 array_indicator
%type colon_ext_only ext_only_name
@@ -286,14 +328,6 @@ make_name (const char *name, int len)
/* Non-C++ things we get from the demangler. */
%token DEMANGLER_SPECIAL
%token CONSTRUCTION_VTABLE CONSTRUCTION_IN
-%token GLOBAL
-
-%{
-enum {
- GLOBAL_CONSTRUCTORS = DEMANGLE_COMPONENT_LITERAL + 20,
- GLOBAL_DESTRUCTORS = DEMANGLE_COMPONENT_LITERAL + 21
-};
-%}
/* Precedence declarations. */
@@ -398,25 +432,37 @@ function
demangler_special
: DEMANGLER_SPECIAL start
- { $$ = make_empty ($1);
+ { $$ = make_empty ((enum demangle_component_type) $1);
d_left ($$) = $2;
d_right ($$) = NULL; }
| CONSTRUCTION_VTABLE start CONSTRUCTION_IN start
{ $$ = fill_comp (DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, $2, $4); }
- | GLOBAL
- { $$ = make_empty ($1.val);
- d_left ($$) = $1.type;
- d_right ($$) = NULL; }
;
-operator : OPERATOR NEW
- { $$ = make_operator ("new", 1); }
+oper : OPERATOR NEW
+ {
+ /* Match the whitespacing of cplus_demangle_operators.
+ It would abort on unrecognized string otherwise. */
+ $$ = make_operator ("new", 3);
+ }
| OPERATOR DELETE
- { $$ = make_operator ("delete", 1); }
+ {
+ /* Match the whitespacing of cplus_demangle_operators.
+ It would abort on unrecognized string otherwise. */
+ $$ = make_operator ("delete ", 1);
+ }
| OPERATOR NEW '[' ']'
- { $$ = make_operator ("new[]", 1); }
+ {
+ /* Match the whitespacing of cplus_demangle_operators.
+ It would abort on unrecognized string otherwise. */
+ $$ = make_operator ("new[]", 3);
+ }
| OPERATOR DELETE '[' ']'
- { $$ = make_operator ("delete[]", 1); }
+ {
+ /* Match the whitespacing of cplus_demangle_operators.
+ It would abort on unrecognized string otherwise. */
+ $$ = make_operator ("delete[] ", 1);
+ }
| OPERATOR '+'
{ $$ = make_operator ("+", 2); }
| OPERATOR '-'
@@ -472,7 +518,7 @@ operator : OPERATOR NEW
| OPERATOR ARROW
{ $$ = make_operator ("->", 2); }
| OPERATOR '(' ')'
- { $$ = make_operator ("()", 0); }
+ { $$ = make_operator ("()", 2); }
| OPERATOR '[' ']'
{ $$ = make_operator ("[]", 2); }
;
@@ -482,7 +528,7 @@ operator : OPERATOR NEW
since it's not clear that it's parseable. */
conversion_op
: OPERATOR typespec_2
- { $$ = fill_comp (DEMANGLE_COMPONENT_CAST, $2, NULL); }
+ { $$ = fill_comp (DEMANGLE_COMPONENT_CONVERSION, $2, NULL); }
;
conversion_op_name
@@ -508,8 +554,8 @@ conversion_op_name
/* DEMANGLE_COMPONENT_NAME */
/* This accepts certain invalid placements of '~'. */
-unqualified_name: operator
- | operator '<' template_params '>'
+unqualified_name: oper
+ | oper '<' template_params '>'
{ $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
| '~' NAME
{ $$ = make_dtor (gnu_v3_complete_object_dtor, $2); }
@@ -533,9 +579,9 @@ colon_name : name
name : nested_name NAME %prec NAME
{ $$ = $1.comp; d_right ($1.last) = $2; }
| NAME %prec NAME
- | nested_name template %prec NAME
+ | nested_name templ %prec NAME
{ $$ = $1.comp; d_right ($1.last) = $2; }
- | template %prec NAME
+ | templ %prec NAME
;
colon_ext_name : colon_name
@@ -565,13 +611,13 @@ nested_name : NAME COLONCOLON
d_left ($$.last) = $2;
d_right ($$.last) = NULL;
}
- | template COLONCOLON
+ | templ COLONCOLON
{ $$.comp = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
d_left ($$.comp) = $1;
d_right ($$.comp) = NULL;
$$.last = $$.comp;
}
- | nested_name template COLONCOLON
+ | nested_name templ COLONCOLON
{ $$.comp = $1.comp;
d_right ($1.last) = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
$$.last = d_right ($1.last);
@@ -582,7 +628,7 @@ nested_name : NAME COLONCOLON
/* DEMANGLE_COMPONENT_TEMPLATE */
/* DEMANGLE_COMPONENT_TEMPLATE_ARGLIST */
-template : NAME '<' template_params '>'
+templ : NAME '<' template_params '>'
{ $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
;
@@ -986,6 +1032,8 @@ exp1 : exp '>' exp
in parentheses. */
exp1 : '&' start
{ $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $2); }
+ | '&' '(' start ')'
+ { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY, make_operator ("&", 1), $3); }
;
/* Expressions, not including the comma operator. */
@@ -1041,18 +1089,13 @@ exp : REINTERPRET_CAST '<' type '>' '(' exp1 ')' %prec UNARY
}
;
-/* Another form of C++-style cast. "type ( exp1 )" is not allowed (it's too
- ambiguous), but "name ( exp1 )" is. Because we don't need to support
- function types, we can handle this unambiguously (the use of typespec_2
- prevents a silly, harmless conflict with qualifiers_opt). This does not
- appear in demangler output so it's not a great loss if we need to
- disable it. */
-exp : typespec_2 '(' exp1 ')' %prec UNARY
- { $$ = fill_comp (DEMANGLE_COMPONENT_UNARY,
- fill_comp (DEMANGLE_COMPONENT_CAST, $1, NULL),
- $3);
- }
- ;
+/* Another form of C++-style cast is "type ( exp1 )". This creates too many
+ conflicts to support. For a while we supported the simpler
+ "typespec_2 ( exp1 )", but that conflicts with "& ( start )" as a
+ reference, deep within the wilderness of abstract declarators:
+ Qux vs Qux, a shift-reduce conflict at the
+ innermost left parenthesis. So we do not support function-like casts.
+ Fortunately they never appear in demangler output. */
/* TO INVESTIGATE: ._0 style anonymous names; anonymous namespaces */
@@ -1150,7 +1193,11 @@ exp : FLOAT
;
exp : SIZEOF '(' type ')' %prec UNARY
- { $$ = d_unary ("sizeof", $3); }
+ {
+ /* Match the whitespacing of cplus_demangle_operators.
+ It would abort on unrecognized string otherwise. */
+ $$ = d_unary ("sizeof ", $3);
+ }
;
/* C++. */
@@ -1438,7 +1485,7 @@ c_parse_backslash (int host_char, int *target_char)
after the zeros. A value of 0 does not mean end of string. */
static int
-parse_escape (const char **string_ptr)
+cp_parse_escape (const char **string_ptr)
{
int target_char;
int c = *(*string_ptr)++;
@@ -1459,7 +1506,7 @@ parse_escape (const char **string_ptr)
if (c == '?')
return 0177;
else if (c == '\\')
- target_char = parse_escape (string_ptr);
+ target_char = cp_parse_escape (string_ptr);
else
target_char = c;
@@ -1498,7 +1545,7 @@ parse_escape (const char **string_ptr)
return i;
}
default:
- return target_char;
+ return c;
}
}
@@ -1533,7 +1580,7 @@ yylex (void)
{
int c;
int namelen;
- const char *tokstart, *tokptr;
+ const char *tokstart;
retry:
prev_lexptr = lexptr;
@@ -1557,17 +1604,17 @@ yylex (void)
lexptr++;
c = *lexptr++;
if (c == '\\')
- c = parse_escape (&lexptr);
+ c = cp_parse_escape (&lexptr);
else if (c == '\'')
{
- yyerror ("empty character constant");
+ yyerror (_("empty character constant"));
return ERROR;
}
c = *lexptr++;
if (c != '\'')
{
- yyerror ("invalid character constant");
+ yyerror (_("invalid character constant"));
return ERROR;
}
@@ -1691,7 +1738,7 @@ yylex (void)
memcpy (err_copy, tokstart, p - tokstart);
err_copy[p - tokstart] = 0;
- yyerror ("invalid number");
+ yyerror (_("invalid number"));
return ERROR;
}
lexptr = p;
@@ -1767,14 +1814,14 @@ yylex (void)
case '"':
/* These can't occur in C++ names. */
- yyerror ("unexpected string literal");
+ yyerror (_("unexpected string literal"));
return ERROR;
}
if (!(c == '_' || c == '$' || ISALPHA (c)))
{
/* We must have come across a bad character (e.g. ';'). */
- yyerror ("invalid character");
+ yyerror (_("invalid character"));
return ERROR;
}
@@ -1837,23 +1884,23 @@ yylex (void)
{
const char *p;
lexptr = tokstart + 29;
- yylval.typed_val_int.val = GLOBAL_CONSTRUCTORS;
+ yylval.lval = DEMANGLE_COMPONENT_GLOBAL_CONSTRUCTORS;
/* Find the end of the symbol. */
p = symbol_end (lexptr);
- yylval.typed_val_int.type = make_name (lexptr, p - lexptr);
+ yylval.comp = make_name (lexptr, p - lexptr);
lexptr = p;
- return GLOBAL;
+ return DEMANGLER_SPECIAL;
}
if (strncmp (tokstart, "global destructors keyed to ", 28) == 0)
{
const char *p;
lexptr = tokstart + 28;
- yylval.typed_val_int.val = GLOBAL_DESTRUCTORS;
+ yylval.lval = DEMANGLE_COMPONENT_GLOBAL_DESTRUCTORS;
/* Find the end of the symbol. */
p = symbol_end (lexptr);
- yylval.typed_val_int.type = make_name (lexptr, p - lexptr);
+ yylval.comp = make_name (lexptr, p - lexptr);
lexptr = p;
- return GLOBAL;
+ return DEMANGLER_SPECIAL;
}
HANDLE_SPECIAL ("vtable for ", DEMANGLE_COMPONENT_VTABLE);
@@ -1923,19 +1970,18 @@ yyerror (char *msg)
global_errmsg = msg ? msg : "parse error";
}
-/* Allocate all the components we'll need to build a tree. We generally
- allocate too many components, but the extra memory usage doesn't hurt
- because the trees are temporary. If we start keeping the trees for
- a longer lifetime we'll need to be cleverer. */
+/* Allocate a chunk of the components we'll need to build a tree. We
+ generally allocate too many components, but the extra memory usage
+ doesn't hurt because the trees are temporary and the storage is
+ reused. More may be allocated later, by d_grab. */
static struct demangle_info *
-allocate_info (int comps)
+allocate_info (void)
{
- struct demangle_info *ret;
+ struct demangle_info *info = XNEW (struct demangle_info);
- ret = malloc (sizeof (struct demangle_info)
- + sizeof (struct demangle_component) * (comps - 1));
- ret->used = 0;
- return ret;
+ info->next = NULL;
+ info->used = 0;
+ return info;
}
/* Convert RESULT to a string. The return value is allocated
@@ -1947,54 +1993,105 @@ allocate_info (int comps)
char *
cp_comp_to_string (struct demangle_component *result, int estimated_len)
{
- char *str, *prefix = NULL, *buf;
- size_t err = 0;
+ size_t err;
- if (result->type == GLOBAL_DESTRUCTORS)
- {
- result = d_left (result);
- prefix = "global destructors keyed to ";
- }
- else if (result->type == GLOBAL_CONSTRUCTORS)
+ return cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, estimated_len,
+ &err);
+}
+
+/* A convenience function to allocate and initialize a new struct
+ demangled_parse_info. */
+
+struct demangle_parse_info *
+cp_new_demangle_parse_info (void)
+{
+ struct demangle_parse_info *info;
+
+ info = XNEW (struct demangle_parse_info);
+ info->info = NULL;
+ info->tree = NULL;
+ obstack_init (&info->obstack);
+
+ return info;
+}
+
+/* Free any memory associated with the given PARSE_INFO. */
+
+void
+cp_demangled_name_parse_free (struct demangle_parse_info *parse_info)
+{
+ struct demangle_info *info = parse_info->info;
+
+ /* Free any allocated chunks of memory for the parse. */
+ while (info != NULL)
{
- result = d_left (result);
- prefix = "global constructors keyed to ";
+ struct demangle_info *next = info->next;
+
+ free (info);
+ info = next;
}
- str = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, estimated_len, &err);
- if (str == NULL)
- return NULL;
+ /* Free any memory allocated during typedef replacement. */
+ obstack_free (&parse_info->obstack, NULL);
- if (prefix == NULL)
- return str;
+ /* Free the parser info. */
+ free (parse_info);
+}
- buf = malloc (strlen (str) + strlen (prefix) + 1);
- strcpy (buf, prefix);
- strcat (buf, str);
- free (str);
- return (buf);
+/* Merge the two parse trees given by DEST and SRC. The parse tree
+ in SRC is attached to DEST at the node represented by TARGET.
+ SRC is then freed.
+
+ NOTE 1: Since there is no API to merge obstacks, this function does
+ even attempt to try it. Fortunately, we do not (yet?) need this ability.
+ The code will assert if SRC->obstack is not empty.
+
+ NOTE 2: The string from which SRC was parsed must not be freed, since
+ this function will place pointers to that string into DEST. */
+
+void
+cp_merge_demangle_parse_infos (struct demangle_parse_info *dest,
+ struct demangle_component *target,
+ struct demangle_parse_info *src)
+
+{
+ struct demangle_info *di;
+
+ /* Copy the SRC's parse data into DEST. */
+ *target = *src->tree;
+ di = dest->info;
+ while (di->next != NULL)
+ di = di->next;
+ di->next = src->info;
+
+ /* Clear the (pointer to) SRC's parse data so that it is not freed when
+ cp_demangled_parse_info_free is called. */
+ src->info = NULL;
+
+ /* Free SRC. */
+ cp_demangled_name_parse_free (src);
}
-/* Convert a demangled name to a demangle_component tree. *MEMORY is set to the
- block of used memory that should be freed when finished with the
- tree. On error, NULL is returned, and an error message will be
- set in *ERRMSG (which does not need to be freed). */
+/* Convert a demangled name to a demangle_component tree. On success,
+ a structure containing the root of the new tree is returned; it must
+ be freed by calling cp_demangled_name_parse_free. On error, NULL is
+ returned, and an error message will be set in *ERRMSG (which does
+ not need to be freed). */
-struct demangle_component *
-cp_demangled_name_to_comp (const char *demangled_name, void **memory,
- const char **errmsg)
+struct demangle_parse_info *
+cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
{
static char errbuf[60];
- struct demangle_component *result;
+ struct demangle_parse_info *result;
- int len = strlen (demangled_name);
-
- len = len + len / 8;
prev_lexptr = lexptr = demangled_name;
error_lexptr = NULL;
global_errmsg = NULL;
- demangle_info = allocate_info (len);
+ demangle_info = allocate_info ();
+
+ result = cp_new_demangle_parse_info ();
+ result->info = demangle_info;
if (yyparse ())
{
@@ -2005,12 +2102,11 @@ cp_demangled_name_to_comp (const char *demangled_name, void **memory,
strcat (errbuf, "'");
*errmsg = errbuf;
}
- free (demangle_info);
+ cp_demangled_name_parse_free (result);
return NULL;
}
- *memory = demangle_info;
- result = global_result;
+ result->tree = global_result;
global_result = NULL;
return result;
@@ -2024,17 +2120,6 @@ cp_print (struct demangle_component *result)
char *str;
size_t err = 0;
- if (result->type == GLOBAL_DESTRUCTORS)
- {
- result = d_left (result);
- fputs ("global destructors keyed to ", stdout);
- }
- else if (result->type == GLOBAL_CONSTRUCTORS)
- {
- result = d_left (result);
- fputs ("global constructors keyed to ", stdout);
- }
-
str = cplus_demangle_print (DMGL_PARAMS | DMGL_ANSI, result, 64, &err);
if (str == NULL)
return;
@@ -2060,15 +2145,41 @@ trim_chars (char *lexptr, char **extra_chars)
return c;
}
+/* When this file is built as a standalone program, xmalloc comes from
+ libiberty --- in which case we have to provide xfree ourselves. */
+
+void
+xfree (void *ptr)
+{
+ if (ptr != NULL)
+ {
+ /* Literal `free' would get translated back to xfree again. */
+ CONCAT2 (fr,ee) (ptr);
+ }
+}
+
+/* GDB normally defines internal_error itself, but when this file is built
+ as a standalone program, we must also provide an implementation. */
+
+void
+internal_error (const char *file, int line, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start (ap, fmt);
+ fprintf (stderr, "%s:%d: internal error: ", file, line);
+ vfprintf (stderr, fmt, ap);
+ exit (1);
+}
+
int
main (int argc, char **argv)
{
- char *str2, *extra_chars, c;
+ char *str2, *extra_chars = "", c;
char buf[65536];
int arg;
const char *errmsg;
- void *memory;
- struct demangle_component *result;
+ struct demangle_parse_info *result;
arg = 1;
if (argv[arg] && strcmp (argv[arg], "--debug") == 0)
@@ -2087,14 +2198,14 @@ main (int argc, char **argv)
str2 = cplus_demangle (buf, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
if (str2 == NULL)
{
- /* printf ("Demangling error\n"); */
+ printf ("Demangling error\n");
if (c)
printf ("%s%c%s\n", buf, c, extra_chars);
else
printf ("%s\n", buf);
continue;
}
- result = cp_demangled_name_to_comp (str2, &memory, &errmsg);
+ result = cp_demangled_name_to_comp (str2, &errmsg);
if (result == NULL)
{
fputs (errmsg, stderr);
@@ -2102,8 +2213,8 @@ main (int argc, char **argv)
continue;
}
- cp_print (result);
- free (memory);
+ cp_print (result->tree);
+ cp_demangled_name_parse_free (result);
free (str2);
if (c)
@@ -2115,16 +2226,16 @@ main (int argc, char **argv)
}
else
{
- result = cp_demangled_name_to_comp (argv[arg], &memory, &errmsg);
+ result = cp_demangled_name_to_comp (argv[arg], &errmsg);
if (result == NULL)
{
fputs (errmsg, stderr);
fputc ('\n', stderr);
return 0;
}
- cp_print (result);
+ cp_print (result->tree);
+ cp_demangled_name_parse_free (result);
putchar ('\n');
- free (memory);
}
return 0;
}