/* YACC parser for C++ names, for GDB.
- Copyright (C) 2003-2015 Free Software Foundation, Inc.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
Parts of the lexer are based on c-exp.y from GDB.
int yyparse (void);
static int yylex (void);
-static void yyerror (char *);
+static void yyerror (const char *);
/* Enable yydebug for the stand-alone parser. */
#ifdef TEST_CPNAMES
return ret;
}
-static struct demangle_component *
-make_empty (enum demangle_component_type d_type)
-{
- struct demangle_component *ret = d_grab ();
- ret->type = d_type;
- return ret;
-}
-
static struct demangle_component *
make_operator (const char *name, int args)
{
demangler_special
: DEMANGLER_SPECIAL start
- { $$ = make_empty ((enum demangle_component_type) $1);
- d_left ($$) = $2;
- d_right ($$) = NULL; }
+ { $$ = fill_comp ((enum demangle_component_type) $1, $2, NULL); }
| CONSTRUCTION_VTABLE start CONSTRUCTION_IN start
{ $$ = fill_comp (DEMANGLE_COMPONENT_CONSTRUCTION_VTABLE, $2, $4); }
;
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
;
nested_name : NAME COLONCOLON
- { $$.comp = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
- d_left ($$.comp) = $1;
- d_right ($$.comp) = NULL;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $1, NULL);
$$.last = $$.comp;
}
| nested_name NAME COLONCOLON
{ $$.comp = $1.comp;
- d_right ($1.last) = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
+ d_right ($1.last) = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $2, NULL);
$$.last = d_right ($1.last);
- d_left ($$.last) = $2;
- d_right ($$.last) = NULL;
}
| templ COLONCOLON
- { $$.comp = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
- d_left ($$.comp) = $1;
- d_right ($$.comp) = NULL;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $1, NULL);
$$.last = $$.comp;
}
| nested_name templ COLONCOLON
{ $$.comp = $1.comp;
- d_right ($1.last) = make_empty (DEMANGLE_COMPONENT_QUAL_NAME);
+ d_right ($1.last) = fill_comp (DEMANGLE_COMPONENT_QUAL_NAME, $2, NULL);
$$.last = d_right ($1.last);
- d_left ($$.last) = $2;
- d_right ($$.last) = NULL;
}
;
;
ptr_operator : '*' qualifiers_opt
- { $$.comp = make_empty (DEMANGLE_COMPONENT_POINTER);
- $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_POINTER, NULL, NULL);
$$.last = &d_left ($$.comp);
$$.comp = d_qualify ($$.comp, $2, 0); }
/* g++ seems to allow qualifiers after the reference? */
| '&'
- { $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
- $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_REFERENCE, NULL, NULL);
+ $$.last = &d_left ($$.comp); }
+ | ANDAND
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_RVALUE_REFERENCE, NULL, NULL);
$$.last = &d_left ($$.comp); }
| nested_name '*' qualifiers_opt
- { $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
- $$.comp->u.s_binary.left = $1.comp;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_PTRMEM_TYPE, $1.comp, NULL);
/* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME. */
*$1.last = *d_left ($1.last);
- $$.comp->u.s_binary.right = NULL;
$$.last = &d_right ($$.comp);
$$.comp = d_qualify ($$.comp, $3, 0); }
| COLONCOLON nested_name '*' qualifiers_opt
- { $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
- $$.comp->u.s_binary.left = $2.comp;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_PTRMEM_TYPE, $2.comp, NULL);
/* Convert the innermost DEMANGLE_COMPONENT_QUAL_NAME to a DEMANGLE_COMPONENT_NAME. */
*$2.last = *d_left ($2.last);
- $$.comp->u.s_binary.right = NULL;
$$.last = &d_right ($$.comp);
$$.comp = d_qualify ($$.comp, $4, 0); }
;
array_indicator : '[' ']'
- { $$ = make_empty (DEMANGLE_COMPONENT_ARRAY_TYPE);
- d_left ($$) = NULL;
- }
+ { $$ = fill_comp (DEMANGLE_COMPONENT_ARRAY_TYPE, NULL, NULL); }
| '[' INT ']'
- { $$ = make_empty (DEMANGLE_COMPONENT_ARRAY_TYPE);
- d_left ($$) = $2;
- }
+ { $$ = fill_comp (DEMANGLE_COMPONENT_ARRAY_TYPE, $2, NULL); }
;
/* Details of this approach inspired by the G++ < 3.4 parser. */
$$.last = &d_right ($2);
}
| colon_ext_name
- { $$.comp = make_empty (DEMANGLE_COMPONENT_TYPED_NAME);
- d_left ($$.comp) = $1;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, NULL);
$$.last = &d_right ($$.comp);
}
;
$$.last = $1.last;
*$2.last = $1.comp; }
| colon_ext_name
- { $$.comp = make_empty (DEMANGLE_COMPONENT_TYPED_NAME);
- d_left ($$.comp) = $1;
+ { $$.comp = fill_comp (DEMANGLE_COMPONENT_TYPED_NAME, $1, NULL);
$$.last = &d_right ($$.comp);
}
| direct_declarator_1
}
static void
-yyerror (char *msg)
+yyerror (const char *msg)
{
if (global_errmsg)
return;
&err);
}
-/* A convenience function to allocate and initialize a new struct
- demangled_parse_info. */
+/* Constructor for demangle_parse_info. */
-struct demangle_parse_info *
-cp_new_demangle_parse_info (void)
+demangle_parse_info::demangle_parse_info ()
+: info (NULL),
+ tree (NULL)
{
- struct demangle_parse_info *info;
-
- info = XNEW (struct demangle_parse_info);
- info->info = NULL;
- info->tree = NULL;
- obstack_init (&info->obstack);
-
- return info;
+ obstack_init (&obstack);
}
-/* Free any memory associated with the given PARSE_INFO. */
+/* Destructor for demangle_parse_info. */
-void
-cp_demangled_name_parse_free (struct demangle_parse_info *parse_info)
+demangle_parse_info::~demangle_parse_info ()
{
- struct demangle_info *info = parse_info->info;
-
/* Free any allocated chunks of memory for the parse. */
while (info != NULL)
{
}
/* Free any memory allocated during typedef replacement. */
- obstack_free (&parse_info->obstack, NULL);
-
- /* Free the parser info. */
- free (parse_info);
+ obstack_free (&obstack, NULL);
}
/* 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.
/* 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. 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). */
+ a structure containing the root of the new tree is returned. On
+ error, NULL is returned, and an error message will be set in
+ *ERRMSG (which does not need to be freed). */
-struct demangle_parse_info *
+struct std::unique_ptr<demangle_parse_info>
cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
{
static char errbuf[60];
- struct demangle_parse_info *result;
prev_lexptr = lexptr = demangled_name;
error_lexptr = NULL;
demangle_info = allocate_info ();
- result = cp_new_demangle_parse_info ();
+ std::unique_ptr<demangle_parse_info> result (new demangle_parse_info);
result->info = demangle_info;
if (yyparse ())
strcat (errbuf, "'");
*errmsg = errbuf;
}
- cp_demangled_name_parse_free (result);
return NULL;
}
char buf[65536];
int arg;
const char *errmsg;
- struct demangle_parse_info *result;
arg = 1;
if (argv[arg] && strcmp (argv[arg], "--debug") == 0)
printf ("%s\n", buf);
continue;
}
- result = cp_demangled_name_to_comp (str2, &errmsg);
+
+ std::unique_ptr<demangle_parse_info> result
+ = cp_demangled_name_to_comp (str2, &errmsg);
if (result == NULL)
{
fputs (errmsg, stderr);
}
cp_print (result->tree);
- cp_demangled_name_parse_free (result);
free (str2);
if (c)
}
else
{
- result = cp_demangled_name_to_comp (argv[arg], &errmsg);
+ std::unique_ptr<demangle_parse_info> result
+ = cp_demangled_name_to_comp (argv[arg], &errmsg);
if (result == NULL)
{
fputs (errmsg, stderr);
return 0;
}
cp_print (result->tree);
- cp_demangled_name_parse_free (result);
putchar ('\n');
}
return 0;