aboutsummaryrefslogtreecommitdiff
path: root/gdb/cp-name-parser.y
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2011-08-18 16:17:39 +0000
committerKeith Seitz <keiths@redhat.com>2011-08-18 16:17:39 +0000
commit3a93a0c2ef1629add02bfdb6efe81015819acd35 (patch)
tree40d5b97e7a1d2698688510f6cb66c831daac5da2 /gdb/cp-name-parser.y
parent7230378dfd17300cd58e07acda312299f6bd1936 (diff)
downloadbinutils-3a93a0c2ef1629add02bfdb6efe81015819acd35.zip
binutils-3a93a0c2ef1629add02bfdb6efe81015819acd35.tar.gz
binutils-3a93a0c2ef1629add02bfdb6efe81015819acd35.tar.bz2
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.
Diffstat (limited to 'gdb/cp-name-parser.y')
-rw-r--r--gdb/cp-name-parser.y134
1 files changed, 112 insertions, 22 deletions
diff --git a/gdb/cp-name-parser.y b/gdb/cp-name-parser.y
index 286bbb4..f257370 100644
--- a/gdb/cp-name-parser.y
+++ b/gdb/cp-name-parser.y
@@ -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;