/* YACC parser for C++ names, for GDB.
- Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Copyright (C) 2003-2017 Free Software Foundation, Inc.
Parts of the lexer are based on c-exp.y from GDB.
#include "defs.h"
#include <unistd.h>
-#include <string.h>
-
#include "safe-ctype.h"
#include "demangle.h"
#include "cp-support.h"
-#include "gdb_assert.h"
/* Bison does not make it easy to create a parser without global
state, unfortunately. Here are all the global variables used
{
if (demangle_info->next == NULL)
{
- more = malloc (sizeof (struct demangle_info));
+ more = XNEW (struct demangle_info);
more->next = NULL;
demangle_info->next = more;
}
{
struct demangle_component *ret = d_grab ();
ret->type = d_type;
+ ret->d_printing = 0;
return ret;
}
const char *opname;
}
-%type <comp> exp exp1 type start start_opt operator colon_name
+%type <comp> exp exp1 type start start_opt oper colon_name
%type <comp> unqualified_name colon_ext_name
-%type <comp> template template_arg
+%type <comp> templ template_arg
%type <comp> builtin_type
%type <comp> typespec_2 array_indicator
%type <comp> colon_ext_only ext_only_name
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); }
;
-operator : OPERATOR NEW
+oper : OPERATOR NEW
{
/* Match the whitespacing of cplus_demangle_operators.
It would abort on unrecognized string otherwise. */
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
/* 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); }
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
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);
/* DEMANGLE_COMPONENT_TEMPLATE */
/* DEMANGLE_COMPONENT_TEMPLATE_ARGLIST */
-template : NAME '<' template_params '>'
+templ : NAME '<' template_params '>'
{ $$ = fill_comp (DEMANGLE_COMPONENT_TEMPLATE, $1, $3.comp); }
;
{ $$.comp = make_empty (DEMANGLE_COMPONENT_REFERENCE);
$$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
$$.last = &d_left ($$.comp); }
+ | ANDAND
+ { $$.comp = make_empty (DEMANGLE_COMPONENT_RVALUE_REFERENCE);
+ $$.comp->u.s_binary.left = $$.comp->u.s_binary.right = NULL;
+ $$.last = &d_left ($$.comp); }
| nested_name '*' qualifiers_opt
{ $$.comp = make_empty (DEMANGLE_COMPONENT_PTRMEM_TYPE);
$$.comp->u.s_binary.left = $1.comp;
static struct demangle_info *
allocate_info (void)
{
- struct demangle_info *info = malloc (sizeof (struct demangle_info));
+ struct demangle_info *info = XNEW (struct demangle_info);
info->next = NULL;
info->used = 0;
&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 = malloc (sizeof (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;