forked from Imagelibrary/binutils-gdb
PR c++/12266
* cp-name-parser.y (struct demangle_info): Remove unused member PREV. (d_grab): Likewise. (allocate_info): Change return type to struct demangle_info *. Always allocate a new demangle_info. Remove unused PREV pointer. (cp_new_demangle_parse_info): New function. (cp_demangled_name_parse_free): New function. (do_demangled_name_parse_free_cleanup): New function. (make_cleanup_cp_demangled_name_parse_free): New function. (cp_demangled_name_to_comp): Change return type to struct demangle_parse_info *. Allocate a new storage for each call. (main): Update usage for cp_demangled_name_to_comp API change. * cp-support.h (struct demangle_parse_info): New structure. (cp_demangled_name_to_comp): Update API change for return type. (cp_new_demangle_parse_info): Declare. (make_cleanup_cp_demangled_name_parse_free): New declaration. (cp_demangled_name_parse_free): Declare. * cp-support.c (cp_canonicalize_string): Update API change for cp_demangled_name_to_comp. (mangled_name_to_comp): Likewise. Return struct demangle_parse_info, too. (cp_class_name_from_physname): Update mangled_name_to_comp API change. (method_name_from_physname): Likewise. (cp_func_name): Update API change for cp_demangled_name_to_comp. (cp_remove_params): Likewise. * python/py-type.c (typy_legacy_template_argument): Likewise. * cp-support.h (cp_canonicalize_string_no_typedefs): Declare. (cp_merge_demangle_parse_infos): Declare. * cp-support.c (ignore_typedefs): New file global. (copy_string_to_obstack): New function. (inspect_type): New function. (replace_typedefs): New function. (replace_typedefs_qualified_name): New function. (cp_canonicalize_string_no_typedefs): New function. * cp-name-parser.y (cp_merge_demangle_parse_infos): New function. (cp_new_demangle__parse_info): Allocate and initialize the obstack. * linespec.c (find_methods): Use cp_canonicalize_string_no_typedefs instead of cp_canonicalize_string. (find_method): Likewise. (decode_compound): Before looking up the name, call cp_canonicalize_string_no_typedefs. (decode_variable): Likewise.
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
#include "libiberty.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
|
||||
@@ -60,7 +61,7 @@ static const char *lexptr, *prev_lexptr, *error_lexptr, *global_errmsg;
|
||||
|
||||
struct demangle_info {
|
||||
int used;
|
||||
struct demangle_info *prev, *next;
|
||||
struct demangle_info *next;
|
||||
struct demangle_component comps[ALLOC_CHUNK];
|
||||
};
|
||||
|
||||
@@ -76,7 +77,6 @@ d_grab (void)
|
||||
if (demangle_info->next == NULL)
|
||||
{
|
||||
more = malloc (sizeof (struct demangle_info));
|
||||
more->prev = demangle_info;
|
||||
more->next = NULL;
|
||||
demangle_info->next = more;
|
||||
}
|
||||
@@ -1935,20 +1935,14 @@ yyerror (char *msg)
|
||||
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 void
|
||||
static struct demangle_info *
|
||||
allocate_info (void)
|
||||
{
|
||||
if (demangle_info == NULL)
|
||||
{
|
||||
demangle_info = malloc (sizeof (struct demangle_info));
|
||||
demangle_info->prev = NULL;
|
||||
demangle_info->next = NULL;
|
||||
}
|
||||
else
|
||||
while (demangle_info->prev)
|
||||
demangle_info = demangle_info->prev;
|
||||
struct demangle_info *info = malloc (sizeof (struct demangle_info));
|
||||
|
||||
demangle_info->used = 0;
|
||||
info->next = NULL;
|
||||
info->used = 0;
|
||||
return info;
|
||||
}
|
||||
|
||||
/* Convert RESULT to a string. The return value is allocated
|
||||
@@ -1966,23 +1960,102 @@ cp_comp_to_string (struct demangle_component *result, int 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 = malloc (sizeof (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)
|
||||
{
|
||||
struct demangle_info *next = info->next;
|
||||
|
||||
free (info);
|
||||
info = next;
|
||||
}
|
||||
|
||||
/* Free any memory allocated during typedef replacement. */
|
||||
obstack_free (&parse_info->obstack, NULL);
|
||||
|
||||
/* Free the parser info. */
|
||||
free (parse_info);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
/* Assert if the SRC obstack is not empty. */
|
||||
gdb_assert (obstack_empty_p (&src->obstack));
|
||||
|
||||
/* Free SRC. */
|
||||
cp_demangled_name_parse_free (src);
|
||||
}
|
||||
|
||||
/* Convert a demangled name to a demangle_component tree. On success,
|
||||
the root of the new tree is returned; it is valid until the next
|
||||
call to this function and should not be freed. On error, NULL is
|
||||
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 *
|
||||
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;
|
||||
|
||||
prev_lexptr = lexptr = demangled_name;
|
||||
error_lexptr = NULL;
|
||||
global_errmsg = NULL;
|
||||
|
||||
allocate_info ();
|
||||
demangle_info = allocate_info ();
|
||||
|
||||
result = cp_new_demangle_parse_info ();
|
||||
result->info = demangle_info;
|
||||
|
||||
if (yyparse ())
|
||||
{
|
||||
@@ -1993,10 +2066,11 @@ cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
|
||||
strcat (errbuf, "'");
|
||||
*errmsg = errbuf;
|
||||
}
|
||||
cp_demangled_name_parse_free (result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = global_result;
|
||||
result->tree = global_result;
|
||||
global_result = NULL;
|
||||
|
||||
return result;
|
||||
@@ -2048,6 +2122,20 @@ xfree (void *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)
|
||||
{
|
||||
@@ -2055,7 +2143,7 @@ main (int argc, char **argv)
|
||||
char buf[65536];
|
||||
int arg;
|
||||
const char *errmsg;
|
||||
struct demangle_component *result;
|
||||
struct demangle_parse_info *result;
|
||||
|
||||
arg = 1;
|
||||
if (argv[arg] && strcmp (argv[arg], "--debug") == 0)
|
||||
@@ -2089,7 +2177,8 @@ main (int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
|
||||
cp_print (result);
|
||||
cp_print (result->tree);
|
||||
cp_demangled_name_parse_free (result);
|
||||
|
||||
free (str2);
|
||||
if (c)
|
||||
@@ -2108,7 +2197,8 @@ main (int argc, char **argv)
|
||||
fputc ('\n', stderr);
|
||||
return 0;
|
||||
}
|
||||
cp_print (result);
|
||||
cp_print (result->tree);
|
||||
cp_demangled_name_parse_free (result);
|
||||
putchar ('\n');
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user