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:
Keith Seitz
2011-08-18 16:17:39 +00:00
parent 7230378dfd
commit 3a93a0c2ef
6 changed files with 665 additions and 62 deletions

View File

@@ -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;