Add constructor and destructor to demangle_parse_info

This adds a constructor and destructor to demangle_parse_info, and
then changes all the users to use them.  This removes
make_cleanup_cp_demangled_name_parse_free and its single use.

2017-01-10  Tom Tromey  <tom@tromey.com>

	* python/py-type.c (typy_legacy_template_argument): Update.
	* cp-support.h (struct demangle_parse_info) (demangle_parse_info,
	~demangle_parse_info): Declare new members.
	(cp_demangled_name_to_comp): Return unique_ptr.
	(cp_demangled_name_parse_free)
	(make_cleanup_cp_demangled_name_parse_free)
	(cp_new_demangle_parse_info): Remove.
	* cp-support.c (do_demangled_name_parse_free_cleanup)
	(make_cleanup_cp_demangled_name_parse_free): Remove.
	(inspect_type, cp_canonicalize_string_full)
	(cp_canonicalize_string): Update.
	(mangled_name_to_comp): Change return type.
	(cp_class_name_from_physname, method_name_from_physname)
	(cp_func_name, cp_remove_params): Update.
	* cp-name-parser.y (demangle_parse_info): New constructor, from
	cp_new_demangle_parse_info.
	(~demangle_parse_info): New destructor, from
	cp_demangled_name_parse_free.
	(cp_merge_demangle_parse_infos): Update.
	(cp_demangled_name_to_comp): Change return type.
This commit is contained in:
Tom Tromey 2016-11-28 21:39:47 -07:00
parent 1ac32117f7
commit c8b23b3f89
5 changed files with 52 additions and 79 deletions

View file

@ -1,3 +1,26 @@
2017-01-10 Tom Tromey <tom@tromey.com>
* python/py-type.c (typy_legacy_template_argument): Update.
* cp-support.h (struct demangle_parse_info) (demangle_parse_info,
~demangle_parse_info): Declare new members.
(cp_demangled_name_to_comp): Return unique_ptr.
(cp_demangled_name_parse_free)
(make_cleanup_cp_demangled_name_parse_free)
(cp_new_demangle_parse_info): Remove.
* cp-support.c (do_demangled_name_parse_free_cleanup)
(make_cleanup_cp_demangled_name_parse_free): Remove.
(inspect_type, cp_canonicalize_string_full)
(cp_canonicalize_string): Update.
(mangled_name_to_comp): Change return type.
(cp_class_name_from_physname, method_name_from_physname)
(cp_func_name, cp_remove_params): Update.
* cp-name-parser.y (demangle_parse_info): New constructor, from
cp_new_demangle_parse_info.
(~demangle_parse_info): New destructor, from
cp_demangled_name_parse_free.
(cp_merge_demangle_parse_infos): Update.
(cp_demangled_name_to_comp): Change return type.
2017-01-10 Tom Tromey <tom@tromey.com> 2017-01-10 Tom Tromey <tom@tromey.com>
* top.c (prevent_dont_repeat): Change return type. * top.c (prevent_dont_repeat): Change return type.

View file

@ -1999,29 +1999,19 @@ cp_comp_to_string (struct demangle_component *result, int estimated_len)
&err); &err);
} }
/* A convenience function to allocate and initialize a new struct /* Constructor for demangle_parse_info. */
demangled_parse_info. */
struct demangle_parse_info * demangle_parse_info::demangle_parse_info ()
cp_new_demangle_parse_info (void) : info (NULL),
tree (NULL)
{ {
struct demangle_parse_info *info; obstack_init (&obstack);
info = XNEW (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. */ /* Destructor for demangle_parse_info. */
void demangle_parse_info::~demangle_parse_info ()
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. */ /* Free any allocated chunks of memory for the parse. */
while (info != NULL) while (info != NULL)
{ {
@ -2032,15 +2022,11 @@ cp_demangled_name_parse_free (struct demangle_parse_info *parse_info)
} }
/* Free any memory allocated during typedef replacement. */ /* Free any memory allocated during typedef replacement. */
obstack_free (&parse_info->obstack, NULL); obstack_free (&obstack, NULL);
/* Free the parser info. */
free (parse_info);
} }
/* Merge the two parse trees given by DEST and SRC. The parse tree /* 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. 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 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. even attempt to try it. Fortunately, we do not (yet?) need this ability.
@ -2067,9 +2053,6 @@ cp_merge_demangle_parse_infos (struct demangle_parse_info *dest,
/* Clear the (pointer to) SRC's parse data so that it is not freed when /* Clear the (pointer to) SRC's parse data so that it is not freed when
cp_demangled_parse_info_free is called. */ cp_demangled_parse_info_free is called. */
src->info = NULL; src->info = NULL;
/* Free SRC. */
cp_demangled_name_parse_free (src);
} }
/* Convert a demangled name to a demangle_component tree. On success, /* Convert a demangled name to a demangle_component tree. On success,
@ -2078,11 +2061,10 @@ cp_merge_demangle_parse_infos (struct demangle_parse_info *dest,
returned, and an error message will be set in *ERRMSG (which does returned, and an error message will be set in *ERRMSG (which does
not need to be freed). */ 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) cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
{ {
static char errbuf[60]; static char errbuf[60];
struct demangle_parse_info *result;
prev_lexptr = lexptr = demangled_name; prev_lexptr = lexptr = demangled_name;
error_lexptr = NULL; error_lexptr = NULL;
@ -2090,7 +2072,7 @@ cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
demangle_info = allocate_info (); 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; result->info = demangle_info;
if (yyparse ()) if (yyparse ())
@ -2102,7 +2084,6 @@ cp_demangled_name_to_comp (const char *demangled_name, const char **errmsg)
strcat (errbuf, "'"); strcat (errbuf, "'");
*errmsg = errbuf; *errmsg = errbuf;
} }
cp_demangled_name_parse_free (result);
return NULL; return NULL;
} }

View file

@ -95,24 +95,6 @@ copy_string_to_obstack (struct obstack *obstack, const char *string,
return (char *) obstack_copy (obstack, string, *len); return (char *) obstack_copy (obstack, string, *len);
} }
/* A cleanup wrapper for cp_demangled_name_parse_free. */
static void
do_demangled_name_parse_free_cleanup (void *data)
{
struct demangle_parse_info *info = (struct demangle_parse_info *) data;
cp_demangled_name_parse_free (info);
}
/* Create a cleanup for C++ name parsing. */
struct cleanup *
make_cleanup_cp_demangled_name_parse_free (struct demangle_parse_info *info)
{
return make_cleanup (do_demangled_name_parse_free_cleanup, info);
}
/* Return 1 if STRING is clearly already in canonical form. This /* Return 1 if STRING is clearly already in canonical form. This
function is conservative; things which it does not recognize are function is conservative; things which it does not recognize are
assumed to be non-canonical, and the parser will sort them out assumed to be non-canonical, and the parser will sort them out
@ -209,7 +191,7 @@ inspect_type (struct demangle_parse_info *info,
long len; long len;
int is_anon; int is_anon;
struct type *type; struct type *type;
struct demangle_parse_info *i; std::unique_ptr<demangle_parse_info> i;
struct ui_file *buf; struct ui_file *buf;
/* Get the real type of the typedef. */ /* Get the real type of the typedef. */
@ -272,7 +254,7 @@ inspect_type (struct demangle_parse_info *info,
if (i != NULL) if (i != NULL)
{ {
/* Merge the two trees. */ /* Merge the two trees. */
cp_merge_demangle_parse_infos (info, ret_comp, i); cp_merge_demangle_parse_infos (info, ret_comp, i.get ());
/* Replace any newly introduced typedefs -- but not /* Replace any newly introduced typedefs -- but not
if the type is anonymous (that would lead to infinite if the type is anonymous (that would lead to infinite
@ -540,22 +522,19 @@ cp_canonicalize_string_full (const char *string,
{ {
std::string ret; std::string ret;
unsigned int estimated_len; unsigned int estimated_len;
struct demangle_parse_info *info; std::unique_ptr<demangle_parse_info> info;
estimated_len = strlen (string) * 2; estimated_len = strlen (string) * 2;
info = cp_demangled_name_to_comp (string, NULL); info = cp_demangled_name_to_comp (string, NULL);
if (info != NULL) if (info != NULL)
{ {
/* Replace all the typedefs in the tree. */ /* Replace all the typedefs in the tree. */
replace_typedefs (info, info->tree, finder, data); replace_typedefs (info.get (), info->tree, finder, data);
/* Convert the tree back into a string. */ /* Convert the tree back into a string. */
ret = cp_comp_to_string (info->tree, estimated_len); ret = cp_comp_to_string (info->tree, estimated_len);
gdb_assert (!ret.empty ()); gdb_assert (!ret.empty ());
/* Free the parse information. */
cp_demangled_name_parse_free (info);
/* Finally, compare the original string with the computed /* Finally, compare the original string with the computed
name, returning NULL if they are the same. */ name, returning NULL if they are the same. */
if (ret == string) if (ret == string)
@ -581,7 +560,7 @@ cp_canonicalize_string_no_typedefs (const char *string)
std::string std::string
cp_canonicalize_string (const char *string) cp_canonicalize_string (const char *string)
{ {
struct demangle_parse_info *info; std::unique_ptr<demangle_parse_info> info;
unsigned int estimated_len; unsigned int estimated_len;
if (cp_already_canonical (string)) if (cp_already_canonical (string))
@ -593,7 +572,6 @@ cp_canonicalize_string (const char *string)
estimated_len = strlen (string) * 2; estimated_len = strlen (string) * 2;
std::string ret = cp_comp_to_string (info->tree, estimated_len); std::string ret = cp_comp_to_string (info->tree, estimated_len);
cp_demangled_name_parse_free (info);
if (ret.empty ()) if (ret.empty ())
{ {
@ -614,12 +592,11 @@ cp_canonicalize_string (const char *string)
freed when finished with the tree, or NULL if none was needed. freed when finished with the tree, or NULL if none was needed.
OPTIONS will be passed to the demangler. */ OPTIONS will be passed to the demangler. */
static struct demangle_parse_info * static std::unique_ptr<demangle_parse_info>
mangled_name_to_comp (const char *mangled_name, int options, mangled_name_to_comp (const char *mangled_name, int options,
void **memory, char **demangled_p) void **memory, char **demangled_p)
{ {
char *demangled_name; char *demangled_name;
struct demangle_parse_info *info;
/* If it looks like a v3 mangled name, then try to go directly /* If it looks like a v3 mangled name, then try to go directly
to trees. */ to trees. */
@ -631,7 +608,7 @@ mangled_name_to_comp (const char *mangled_name, int options,
options, memory); options, memory);
if (ret) if (ret)
{ {
info = cp_new_demangle_parse_info (); std::unique_ptr<demangle_parse_info> info (new demangle_parse_info);
info->tree = ret; info->tree = ret;
*demangled_p = NULL; *demangled_p = NULL;
return info; return info;
@ -646,7 +623,8 @@ mangled_name_to_comp (const char *mangled_name, int options,
/* If we could demangle the name, parse it to build the component /* If we could demangle the name, parse it to build the component
tree. */ tree. */
info = cp_demangled_name_to_comp (demangled_name, NULL); std::unique_ptr<demangle_parse_info> info
= cp_demangled_name_to_comp (demangled_name, NULL);
if (info == NULL) if (info == NULL)
{ {
@ -666,7 +644,7 @@ cp_class_name_from_physname (const char *physname)
void *storage = NULL; void *storage = NULL;
char *demangled_name = NULL, *ret; char *demangled_name = NULL, *ret;
struct demangle_component *ret_comp, *prev_comp, *cur_comp; struct demangle_component *ret_comp, *prev_comp, *cur_comp;
struct demangle_parse_info *info; std::unique_ptr<demangle_parse_info> info;
int done; int done;
info = mangled_name_to_comp (physname, DMGL_ANSI, info = mangled_name_to_comp (physname, DMGL_ANSI,
@ -745,7 +723,6 @@ cp_class_name_from_physname (const char *physname)
xfree (storage); xfree (storage);
xfree (demangled_name); xfree (demangled_name);
cp_demangled_name_parse_free (info);
return ret; return ret;
} }
@ -815,7 +792,7 @@ method_name_from_physname (const char *physname)
void *storage = NULL; void *storage = NULL;
char *demangled_name = NULL, *ret; char *demangled_name = NULL, *ret;
struct demangle_component *ret_comp; struct demangle_component *ret_comp;
struct demangle_parse_info *info; std::unique_ptr<demangle_parse_info> info;
info = mangled_name_to_comp (physname, DMGL_ANSI, info = mangled_name_to_comp (physname, DMGL_ANSI,
&storage, &demangled_name); &storage, &demangled_name);
@ -832,7 +809,6 @@ method_name_from_physname (const char *physname)
xfree (storage); xfree (storage);
xfree (demangled_name); xfree (demangled_name);
cp_demangled_name_parse_free (info);
return ret; return ret;
} }
@ -847,7 +823,7 @@ cp_func_name (const char *full_name)
{ {
char *ret; char *ret;
struct demangle_component *ret_comp; struct demangle_component *ret_comp;
struct demangle_parse_info *info; std::unique_ptr<demangle_parse_info> info;
info = cp_demangled_name_to_comp (full_name, NULL); info = cp_demangled_name_to_comp (full_name, NULL);
if (!info) if (!info)
@ -859,7 +835,6 @@ cp_func_name (const char *full_name)
if (ret_comp != NULL) if (ret_comp != NULL)
ret = cp_comp_to_string (ret_comp, 10); ret = cp_comp_to_string (ret_comp, 10);
cp_demangled_name_parse_free (info);
return ret; return ret;
} }
@ -872,7 +847,7 @@ cp_remove_params (const char *demangled_name)
{ {
int done = 0; int done = 0;
struct demangle_component *ret_comp; struct demangle_component *ret_comp;
struct demangle_parse_info *info; std::unique_ptr<demangle_parse_info> info;
char *ret = NULL; char *ret = NULL;
if (demangled_name == NULL) if (demangled_name == NULL)
@ -905,7 +880,6 @@ cp_remove_params (const char *demangled_name)
if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME) if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
ret = cp_comp_to_string (d_left (ret_comp), 10); ret = cp_comp_to_string (d_left (ret_comp), 10);
cp_demangled_name_parse_free (info);
return ret; return ret;
} }

View file

@ -50,6 +50,10 @@ struct using_direct;
struct demangle_parse_info struct demangle_parse_info
{ {
demangle_parse_info ();
~demangle_parse_info ();
/* The memory used during the parse. */ /* The memory used during the parse. */
struct demangle_info *info; struct demangle_info *info;
@ -135,21 +139,16 @@ struct type *cp_find_type_baseclass_by_name (struct type *parent_type,
/* Functions from cp-name-parser.y. */ /* Functions from cp-name-parser.y. */
extern struct demangle_parse_info *cp_demangled_name_to_comp extern std::unique_ptr<demangle_parse_info> cp_demangled_name_to_comp
(const char *demangled_name, const char **errmsg); (const char *demangled_name, const char **errmsg);
extern char *cp_comp_to_string (struct demangle_component *result, extern char *cp_comp_to_string (struct demangle_component *result,
int estimated_len); int estimated_len);
extern void cp_demangled_name_parse_free (struct demangle_parse_info *);
extern struct cleanup *make_cleanup_cp_demangled_name_parse_free
(struct demangle_parse_info *);
extern void cp_merge_demangle_parse_infos (struct demangle_parse_info *, extern void cp_merge_demangle_parse_infos (struct demangle_parse_info *,
struct demangle_component *, struct demangle_component *,
struct demangle_parse_info *); struct demangle_parse_info *);
extern struct demangle_parse_info *cp_new_demangle_parse_info (void);
/* The list of "maint cplus" commands. */ /* The list of "maint cplus" commands. */
extern struct cmd_list_element *maint_cplus_cmd_list; extern struct cmd_list_element *maint_cplus_cmd_list;

View file

@ -832,7 +832,7 @@ typy_legacy_template_argument (struct type *type, const struct block *block,
{ {
int i; int i;
struct demangle_component *demangled; struct demangle_component *demangled;
struct demangle_parse_info *info = NULL; std::unique_ptr<demangle_parse_info> info;
const char *err; const char *err;
struct type *argtype; struct type *argtype;
struct cleanup *cleanup; struct cleanup *cleanup;
@ -860,7 +860,6 @@ typy_legacy_template_argument (struct type *type, const struct block *block,
return NULL; return NULL;
} }
demangled = info->tree; demangled = info->tree;
cleanup = make_cleanup_cp_demangled_name_parse_free (info);
/* Strip off component names. */ /* Strip off component names. */
while (demangled->type == DEMANGLE_COMPONENT_QUAL_NAME while (demangled->type == DEMANGLE_COMPONENT_QUAL_NAME
@ -869,7 +868,6 @@ typy_legacy_template_argument (struct type *type, const struct block *block,
if (demangled->type != DEMANGLE_COMPONENT_TEMPLATE) if (demangled->type != DEMANGLE_COMPONENT_TEMPLATE)
{ {
do_cleanups (cleanup);
PyErr_SetString (PyExc_RuntimeError, _("Type is not a template.")); PyErr_SetString (PyExc_RuntimeError, _("Type is not a template."));
return NULL; return NULL;
} }
@ -882,14 +880,12 @@ typy_legacy_template_argument (struct type *type, const struct block *block,
if (! demangled) if (! demangled)
{ {
do_cleanups (cleanup);
PyErr_Format (PyExc_RuntimeError, _("No argument %d in template."), PyErr_Format (PyExc_RuntimeError, _("No argument %d in template."),
argno); argno);
return NULL; return NULL;
} }
argtype = typy_lookup_type (demangled->u.s_binary.left, block); argtype = typy_lookup_type (demangled->u.s_binary.left, block);
do_cleanups (cleanup);
if (! argtype) if (! argtype)
return NULL; return NULL;