This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Use ui_file_as_string throughout more


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2f408ecb929bd56613e94cf1e84ace4692c78257

commit 2f408ecb929bd56613e94cf1e84ace4692c78257
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Nov 8 15:26:47 2016 +0000

    Use ui_file_as_string throughout more
    
    This replaces most of the remaining ui_file_xstrdup calls with
    ui_file_as_string calls.  Whenever a call was replaced, that led to a
    cascade of other necessary adjustments throughout, to make the code
    use std::string instead of raw pointers.  And then whenever I added a
    std::string as member of a struct, I needed to adjust
    allocation/destruction of said struct to use new/delete instead of
    xmalloc/xfree.
    
    The stopping point was once gdb built again.  These doesn't seem to be
    a way to reasonably split this out further.
    
    Maybe-not-obvious changes:
    
     - demangle_for_lookup returns a cleanup today.  To get rid of that,
       and avoid unnecessary string dupping/copying, this introduces a
       demangle_result_storage type that the caller instantiates and
       passes to demangle_for_lookup.
    
     - Many methods returned a "char *" to indicate that the caller owns
       the memory and must free it.  Those are switched to return a
       std::string instead.  Methods that return a "view" into some
       internal string return a "const char *" instead.  I.e., we only
       copy/allocate when necessary.
    
    gdb/ChangeLog:
    2016-11-08  Pedro Alves  <palves@redhat.com>
    
    	* ada-lang.c (ada_name_for_lookup, type_as_string): Use and return
    	std::string.
    	(type_as_string_and_cleanup): Delete.
    	(ada_lookup_struct_elt_type): Use type_as_string.
    	* ada-lang.h (ada_name_for_lookup): Now returns std::string.
    	* ada-varobj.c (ada_varobj_scalar_image): Return a std::string.
    	(ada_varobj_describe_child): Make 'child_name' and
    	'child_path_expr' parameters std::string pointers.
    	(ada_varobj_describe_struct_child, ada_varobj_describe_ptr_child):
    	Likewise, and use string_printf.
    	(ada_varobj_describe_simple_array_child)
    	(ada_varobj_describe_child): Likewise.
    	(ada_varobj_get_name_of_child, ada_varobj_get_path_expr_of_child)
    	(ada_varobj_get_value_image)
    	(ada_varobj_get_value_of_array_variable)
    	(ada_varobj_get_value_of_variable, ada_name_of_variable)
    	(ada_name_of_child, ada_path_expr_of_child)
    	(ada_value_of_variable): Now returns std::string.  Use
    	string_printf.
    	(ada_value_of_child): Adjust.
    	* break-catch-throw.c (check_status_exception_catchpoint): Adjust
    	to use std::string.
    	* breakpoint.c (watch_command_1): Adjust to use std::string.
    	* c-lang.c (c_get_string): Adjust to use std::string.
    	* c-typeprint.c (print_name_maybe_canonical): Use std::string.
    	* c-varobj.c (varobj_is_anonymous_child): Use ==/!= std::string
    	operators.
    	(c_name_of_variable): Now returns a std::string.
    	(c_describe_child): The 'cname' and 'cfull_expression' output
    	parameters are now std::string pointers.  Adjust.
    	(c_name_of_child, c_path_expr_of_child, c_value_of_variable)
    	(cplus_number_of_children): Adjust to use std::string and
    	string_printf.
    	(cplus_name_of_variable): Now returns a std::string.
    	(cplus_describe_child): The 'cname' and 'cfull_expression' output
    	parameters are now std::string pointers.  Adjust.
    	(cplus_name_of_child, cplus_path_expr_of_child)
    	(cplus_value_of_variable): Now returns a std::string.
    	* cp-abi.c (cplus_typename_from_type_info): Return std::string.
    	* cp-abi.h (cplus_typename_from_type_info): Return std::string.
    	(struct cp_abi_ops) <get_typename_from_type_info>: Return
    	std::string.
    	* cp-support.c (inspect_type): Use std::string.
    	(cp_canonicalize_string_full, cp_canonicalize_string_no_typedefs)
    	(cp_canonicalize_string): Return std::string and adjust.
    	* cp-support.h (cp_canonicalize_string)
    	(cp_canonicalize_string_no_typedefs, cp_canonicalize_string_full):
    	Return std::string.
    	* dbxread.c (read_dbx_symtab): Use std::string.
    	* dwarf2read.c (dwarf2_canonicalize_name): Adjust to use std::string.
    	* gdbcmd.h (lookup_struct_elt_type): Adjust to use std::string.
    	* gnu-v3-abi.c (gnuv3_get_typeid): Use std::string.
    	(gnuv3_get_typename_from_type_info): Return a std::string and
    	adjust.
    	(gnuv3_get_type_from_type_info): Adjust to use std::string.
    	* guile/guile.c (gdbscm_execute_gdb_command): Adjust to use
    	std::string.
    	* infcmd.c (print_return_value_1): Adjust to use std::string.
    	* linespec.c (find_linespec_symbols): Adjust to
    	demangle_for_lookup API change.  Use std::string.
    	* mi/mi-cmd-var.c (print_varobj, mi_cmd_var_set_format)
    	(mi_cmd_var_info_type, mi_cmd_var_info_path_expression)
    	(mi_cmd_var_info_expression, mi_cmd_var_evaluate_expression)
    	(mi_cmd_var_assign, varobj_update_one): Adjust to use std::string.
    	* minsyms.c (lookup_minimal_symbol): Use std::string.
    	* python/py-varobj.c (py_varobj_iter_next): Use new instead of
    	XNEW.  vitem->name is a std::string now, adjust.
    	* rust-exp.y (convert_ast_to_type, convert_name): Adjust to use
    	std::string.
    	* stabsread.c (define_symbol): Adjust to use std::string.
    	* symtab.c (demangle_for_lookup): Now returns 'const char *'.  Add
    	a demangle_result_storage parameter.  Use it for storage.
    	(lookup_symbol_in_language)
    	(lookup_symbol_in_objfile_from_linkage_name): Adjust to new
    	demangle_for_lookup API.
    	* symtab.h (struct demangle_result_storage): New type.
    	(demangle_for_lookup): Now returns 'const char *'.  Add a
    	demangle_result_storage parameter.
    	* typeprint.c (type_to_string): Return std::string and use
    	ui_file_as_string.
    	* value.h (type_to_string): Change return type to std::string.
    	* varobj-iter.h (struct varobj_item) <name>: Now a std::string.
    	(varobj_iter_delete): Use delete instead of xfree.
    	* varobj.c (create_child): Return std::string instead of char * in
    	output parameter.
    	(name_of_variable, name_of_child, my_value_of_variable): Return
    	std::string instead of char *.
    	(varobj_create, varobj_get_handle): Constify 'objname' parameter.
    	Adjust to std::string fields.
    	(varobj_get_objname): Return a const char * instead of a char *.
    	(varobj_get_expression): Return a std::string.
    	(varobj_list_children): Adjust to use std::string.
    	(varobj_get_type): Return a std::string.
    	(varobj_get_path_expr): Return a const char * instead of a char *.
    	Adjust to std::string fields.
    	(varobj_get_formatted_value, varobj_get_value): Return a
    	std::string.
    	(varobj_set_value): Change type of 'expression' parameter to
    	std::string.  Use std::string.
    	(install_new_value): Use std::string.
    	(delete_variable_1): Adjust to use std::string.
    	(create_child): Change the 'name' parameter to a std::string
    	reference.  Swap it into the new item's name.
    	(create_child_with_value): Swap item's name into the new child's
    	name.  Use string_printf.
    	(new_variable): Use new instead of XNEW.
    	(free_variable): Don't xfree fields that are now std::string.
    	(name_of_variable, name_of_child): Now returns std::string.
    	(value_of_root): Adjust to use std::string.
    	(my_value_of_variable, varobj_value_get_print_value): Return
    	and use std::string.
    	(varobj_value_get_print_value): Adjust to use ui_file_as_string
    	and std::string.
    	* varobj.h (struct varobj) <name, path_expr, obj_name,
    	print_value>: Now std::string's.
    	<name_of_variable, name_of_child, path_expr_of_child,
    	value_of_variable>: Return std::string.
    	(varobj_create, varobj_get_handle): Constify 'objname' parameter.
    	(varobj_get_objname): Return a const char * instead of a char *.
    	(varobj_get_expression, varobj_get_type): Return a std::string.
    	(varobj_get_path_expr): Return a const char * instead of a char *.
    	(varobj_get_formatted_value, varobj_get_value): Return a
    	std::string.
    	(varobj_set_value): Constify 'expression' parameter.
    	(varobj_value_get_print_value): Return a std::string.

Diff:
---
 gdb/ChangeLog           | 128 ++++++++++++++++++++++++++++++++
 gdb/ada-lang.c          |  15 +---
 gdb/ada-lang.h          |   2 +-
 gdb/ada-varobj.c        | 130 ++++++++++++++-------------------
 gdb/break-catch-throw.c |  19 ++---
 gdb/breakpoint.c        |   7 +-
 gdb/c-lang.c            |   9 +--
 gdb/c-typeprint.c       |   5 +-
 gdb/c-varobj.c          | 142 +++++++++++++++++-------------------
 gdb/cp-abi.c            |   2 +-
 gdb/cp-abi.h            |   7 +-
 gdb/cp-support.c        |  60 +++++++--------
 gdb/cp-support.h        |  10 +--
 gdb/dbxread.c           |  22 +++---
 gdb/dwarf2read.c        |  12 +--
 gdb/gdbtypes.c          |  12 ++-
 gdb/gnu-v3-abi.c        |  55 +++++---------
 gdb/infcmd.c            |   9 +--
 gdb/linespec.c          |  53 ++++++--------
 gdb/mi/mi-cmd-var.c     |  70 +++++++-----------
 gdb/minsyms.c           |  17 ++---
 gdb/python/py-varobj.c  |   4 +-
 gdb/rust-exp.y          |  11 +--
 gdb/stabsread.c         |  21 +++---
 gdb/symtab.c            |  87 ++++++++--------------
 gdb/symtab.h            |  39 +++++++++-
 gdb/typeprint.c         |   7 +-
 gdb/value.h             |   2 +-
 gdb/varobj-iter.h       |   4 +-
 gdb/varobj.c            | 190 ++++++++++++++++++++++--------------------------
 gdb/varobj.h            |  70 +++++++++---------
 31 files changed, 607 insertions(+), 614 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ed6f160..b19a07f 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,133 @@
 2016-11-08  Pedro Alves  <palves@redhat.com>
 
+	* ada-lang.c (ada_name_for_lookup, type_as_string): Use and return
+	std::string.
+	(type_as_string_and_cleanup): Delete.
+	(ada_lookup_struct_elt_type): Use type_as_string.
+	* ada-lang.h (ada_name_for_lookup): Now returns std::string.
+	* ada-varobj.c (ada_varobj_scalar_image): Return a std::string.
+	(ada_varobj_describe_child): Make 'child_name' and
+	'child_path_expr' parameters std::string pointers.
+	(ada_varobj_describe_struct_child, ada_varobj_describe_ptr_child):
+	Likewise, and use string_printf.
+	(ada_varobj_describe_simple_array_child)
+	(ada_varobj_describe_child): Likewise.
+	(ada_varobj_get_name_of_child, ada_varobj_get_path_expr_of_child)
+	(ada_varobj_get_value_image)
+	(ada_varobj_get_value_of_array_variable)
+	(ada_varobj_get_value_of_variable, ada_name_of_variable)
+	(ada_name_of_child, ada_path_expr_of_child)
+	(ada_value_of_variable): Now returns std::string.  Use
+	string_printf.
+	(ada_value_of_child): Adjust.
+	* break-catch-throw.c (check_status_exception_catchpoint): Adjust
+	to use std::string.
+	* breakpoint.c (watch_command_1): Adjust to use std::string.
+	* c-lang.c (c_get_string): Adjust to use std::string.
+	* c-typeprint.c (print_name_maybe_canonical): Use std::string.
+	* c-varobj.c (varobj_is_anonymous_child): Use ==/!= std::string
+	operators.
+	(c_name_of_variable): Now returns a std::string.
+	(c_describe_child): The 'cname' and 'cfull_expression' output
+	parameters are now std::string pointers.  Adjust.
+	(c_name_of_child, c_path_expr_of_child, c_value_of_variable)
+	(cplus_number_of_children): Adjust to use std::string and
+	string_printf.
+	(cplus_name_of_variable): Now returns a std::string.
+	(cplus_describe_child): The 'cname' and 'cfull_expression' output
+	parameters are now std::string pointers.  Adjust.
+	(cplus_name_of_child, cplus_path_expr_of_child)
+	(cplus_value_of_variable): Now returns a std::string.
+	* cp-abi.c (cplus_typename_from_type_info): Return std::string.
+	* cp-abi.h (cplus_typename_from_type_info): Return std::string.
+	(struct cp_abi_ops) <get_typename_from_type_info>: Return
+	std::string.
+	* cp-support.c (inspect_type): Use std::string.
+	(cp_canonicalize_string_full, cp_canonicalize_string_no_typedefs)
+	(cp_canonicalize_string): Return std::string and adjust.
+	* cp-support.h (cp_canonicalize_string)
+	(cp_canonicalize_string_no_typedefs, cp_canonicalize_string_full):
+	Return std::string.
+	* dbxread.c (read_dbx_symtab): Use std::string.
+	* dwarf2read.c (dwarf2_canonicalize_name): Adjust to use std::string.
+	* gdbcmd.h (lookup_struct_elt_type): Adjust to use std::string.
+	* gnu-v3-abi.c (gnuv3_get_typeid): Use std::string.
+	(gnuv3_get_typename_from_type_info): Return a std::string and
+	adjust.
+	(gnuv3_get_type_from_type_info): Adjust to use std::string.
+	* guile/guile.c (gdbscm_execute_gdb_command): Adjust to use
+	std::string.
+	* infcmd.c (print_return_value_1): Adjust to use std::string.
+	* linespec.c (find_linespec_symbols): Adjust to
+	demangle_for_lookup API change.  Use std::string.
+	* mi/mi-cmd-var.c (print_varobj, mi_cmd_var_set_format)
+	(mi_cmd_var_info_type, mi_cmd_var_info_path_expression)
+	(mi_cmd_var_info_expression, mi_cmd_var_evaluate_expression)
+	(mi_cmd_var_assign, varobj_update_one): Adjust to use std::string.
+	* minsyms.c (lookup_minimal_symbol): Use std::string.
+	* python/py-varobj.c (py_varobj_iter_next): Use new instead of
+	XNEW.  vitem->name is a std::string now, adjust.
+	* rust-exp.y (convert_ast_to_type, convert_name): Adjust to use
+	std::string.
+	* stabsread.c (define_symbol): Adjust to use std::string.
+	* symtab.c (demangle_for_lookup): Now returns 'const char *'.  Add
+	a demangle_result_storage parameter.  Use it for storage.
+	(lookup_symbol_in_language)
+	(lookup_symbol_in_objfile_from_linkage_name): Adjust to new
+	demangle_for_lookup API.
+	* symtab.h (struct demangle_result_storage): New type.
+	(demangle_for_lookup): Now returns 'const char *'.  Add a
+	demangle_result_storage parameter.
+	* typeprint.c (type_to_string): Return std::string and use
+	ui_file_as_string.
+	* value.h (type_to_string): Change return type to std::string.
+	* varobj-iter.h (struct varobj_item) <name>: Now a std::string.
+	(varobj_iter_delete): Use delete instead of xfree.
+	* varobj.c (create_child): Return std::string instead of char * in
+	output parameter.
+	(name_of_variable, name_of_child, my_value_of_variable): Return
+	std::string instead of char *.
+	(varobj_create, varobj_get_handle): Constify 'objname' parameter.
+	Adjust to std::string fields.
+	(varobj_get_objname): Return a const char * instead of a char *.
+	(varobj_get_expression): Return a std::string.
+	(varobj_list_children): Adjust to use std::string.
+	(varobj_get_type): Return a std::string.
+	(varobj_get_path_expr): Return a const char * instead of a char *.
+	Adjust to std::string fields.
+	(varobj_get_formatted_value, varobj_get_value): Return a
+	std::string.
+	(varobj_set_value): Change type of 'expression' parameter to
+	std::string.  Use std::string.
+	(install_new_value): Use std::string.
+	(delete_variable_1): Adjust to use std::string.
+	(create_child): Change the 'name' parameter to a std::string
+	reference.  Swap it into the new item's name.
+	(create_child_with_value): Swap item's name into the new child's
+	name.  Use string_printf.
+	(new_variable): Use new instead of XNEW.
+	(free_variable): Don't xfree fields that are now std::string.
+	(name_of_variable, name_of_child): Now returns std::string.
+	(value_of_root): Adjust to use std::string.
+	(my_value_of_variable, varobj_value_get_print_value): Return
+	and use std::string.
+	(varobj_value_get_print_value): Adjust to use ui_file_as_string
+	and std::string.
+	* varobj.h (struct varobj) <name, path_expr, obj_name,
+	print_value>: Now std::string's.
+	<name_of_variable, name_of_child, path_expr_of_child,
+	value_of_variable>: Return std::string.
+	(varobj_create, varobj_get_handle): Constify 'objname' parameter.
+	(varobj_get_objname): Return a const char * instead of a char *.
+	(varobj_get_expression, varobj_get_type): Return a std::string.
+	(varobj_get_path_expr): Return a const char * instead of a char *.
+	(varobj_get_formatted_value, varobj_get_value): Return a
+	std::string.
+	(varobj_set_value): Constify 'expression' parameter.
+	(varobj_value_get_print_value): Return a std::string.
+
+2016-11-08  Pedro Alves  <palves@redhat.com>
+
 	* language.c (add_language): Use ui_file_as_string and adjust to
 	use std::string.
 
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 3c04554..d9b46c6 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -5871,28 +5871,21 @@ ada_iterate_over_symbols (const struct block *block,
 }
 
 /* If NAME is the name of an entity, return a string that should
-   be used to look that entity up in Ada units.  This string should
-   be deallocated after use using xfree.
+   be used to look that entity up in Ada units.
 
    NAME can have any form that the "break" or "print" commands might
    recognize.  In other words, it does not have to be the "natural"
    name, or the "encoded" name.  */
 
-char *
+std::string
 ada_name_for_lookup (const char *name)
 {
-  char *canon;
   int nlen = strlen (name);
 
   if (name[0] == '<' && name[nlen - 1] == '>')
-    {
-      canon = (char *) xmalloc (nlen - 1);
-      memcpy (canon, name + 1, nlen - 2);
-      canon[nlen - 2] = '\0';
-    }
+    return std::string (name + 1, nlen - 2);
   else
-    canon = xstrdup (ada_encode (ada_fold_name (name)));
-  return canon;
+    return ada_encode (ada_fold_name (name));
 }
 
 /* The result is as for ada_lookup_symbol_list with FULL_SEARCH set
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 7de71eb..189d696 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -370,7 +370,7 @@ extern char *ada_breakpoint_rewrite (char *, int *);
 
 extern char *ada_main_name (void);
 
-extern char *ada_name_for_lookup (const char *name);
+extern std::string ada_name_for_lookup (const char *name);
 
 extern void create_ada_exception_catchpoint
   (struct gdbarch *gdbarch, enum ada_exception_catchpoint_kind ex_kind,
diff --git a/gdb/ada-varobj.c b/gdb/ada-varobj.c
index 1902890..ae46ca2 100644
--- a/gdb/ada-varobj.c
+++ b/gdb/ada-varobj.c
@@ -74,19 +74,16 @@ ada_varobj_decode_var (struct value **value_ptr, struct type **type_ptr)
 /* Return a string containing an image of the given scalar value.
    VAL is the numeric value, while TYPE is the value's type.
    This is useful for plain integers, of course, but even more
-   so for enumerated types.
+   so for enumerated types.  */
 
-   The result should be deallocated by xfree after use.  */
-
-static char *
+static std::string
 ada_varobj_scalar_image (struct type *type, LONGEST val)
 {
   struct ui_file *buf = mem_fileopen ();
   struct cleanup *cleanups = make_cleanup_ui_file_delete (buf);
-  char *result;
 
   ada_print_scalar (type, val, buf);
-  result = ui_file_xstrdup (buf, NULL);
+  std::string result = ui_file_as_string (buf);
   do_cleanups (cleanups);
 
   return result;
@@ -404,10 +401,10 @@ static void ada_varobj_describe_child (struct value *parent_value,
 				       const char *parent_name,
 				       const char *parent_path_expr,
 				       int child_index,
-				       char **child_name,
+				       std::string *child_name,
 				       struct value **child_value,
 				       struct type **child_type,
-				       char **child_path_expr);
+				       std::string *child_path_expr);
 
 /* Same as ada_varobj_describe_child, but limited to struct/union
    objects.  */
@@ -418,10 +415,10 @@ ada_varobj_describe_struct_child (struct value *parent_value,
 				  const char *parent_name,
 				  const char *parent_path_expr,
 				  int child_index,
-				  char **child_name,
+				  std::string *child_name,
 				  struct value **child_value,
 				  struct type **child_type,
-				  char **child_path_expr)
+				  std::string *child_path_expr)
 {
   int fieldno;
   int childno = 0;
@@ -506,7 +503,7 @@ ada_varobj_describe_struct_child (struct value *parent_value,
 	      const char *field_name = TYPE_FIELD_NAME (parent_type, fieldno);
 	      int child_name_len = ada_name_prefix_len (field_name);
 
-	      *child_name = xstrprintf ("%.*s", child_name_len, field_name);
+	      *child_name = string_printf ("%.*s", child_name_len, field_name);
 	    }
 
 	  if (child_value && parent_value)
@@ -527,8 +524,8 @@ ada_varobj_describe_struct_child (struct value *parent_value,
 	      int child_name_len = ada_name_prefix_len (field_name);
 
 	      *child_path_expr =
-		xstrprintf ("(%s).%.*s", parent_path_expr,
-			    child_name_len, field_name);
+		string_printf ("(%s).%.*s", parent_path_expr,
+			       child_name_len, field_name);
 	    }
 
 	  return;
@@ -556,13 +553,13 @@ ada_varobj_describe_ptr_child (struct value *parent_value,
 			       const char *parent_name,
 			       const char *parent_path_expr,
 			       int child_index,
-			       char **child_name,
+			       std::string *child_name,
 			       struct value **child_value,
 			       struct type **child_type,
-			       char **child_path_expr)
+			       std::string *child_path_expr)
 {
   if (child_name)
-    *child_name = xstrprintf ("%s.all", parent_name);
+    *child_name = string_printf ("%s.all", parent_name);
 
   if (child_value && parent_value)
     ada_varobj_ind (parent_value, parent_type, child_value, NULL);
@@ -571,7 +568,7 @@ ada_varobj_describe_ptr_child (struct value *parent_value,
     ada_varobj_ind (parent_value, parent_type, NULL, child_type);
 
   if (child_path_expr)
-    *child_path_expr = xstrprintf ("(%s).all", parent_path_expr);
+    *child_path_expr = string_printf ("(%s).all", parent_path_expr);
 }
 
 /* Same as ada_varobj_describe_child, limited to simple array objects
@@ -586,10 +583,10 @@ ada_varobj_describe_simple_array_child (struct value *parent_value,
 					const char *parent_name,
 					const char *parent_path_expr,
 					int child_index,
-					char **child_name,
+					std::string *child_name,
 					struct value **child_value,
 					struct type **child_type,
-					char **child_path_expr)
+					std::string *child_path_expr)
 {
   struct type *index_type;
   int real_index;
@@ -612,8 +609,7 @@ ada_varobj_describe_simple_array_child (struct value *parent_value,
 
   if (child_path_expr)
     {
-      char *index_img = ada_varobj_scalar_image (index_type, real_index);
-      struct cleanup *cleanups = make_cleanup (xfree, index_img);
+      std::string index_img = ada_varobj_scalar_image (index_type, real_index);
 
       /* Enumeration litterals by themselves are potentially ambiguous.
 	 For instance, consider the following package spec:
@@ -647,13 +643,12 @@ ada_varobj_describe_simple_array_child (struct value *parent_value,
 
       if (index_type_name != NULL)
 	*child_path_expr =
-	  xstrprintf ("(%s)(%.*s'(%s))", parent_path_expr,
-		      ada_name_prefix_len (index_type_name),
-		      index_type_name, index_img);
+	  string_printf ("(%s)(%.*s'(%s))", parent_path_expr,
+			 ada_name_prefix_len (index_type_name),
+			 index_type_name, index_img.c_str ());
       else
 	*child_path_expr =
-	  xstrprintf ("(%s)(%s)", parent_path_expr, index_img);
-      do_cleanups (cleanups);
+	  string_printf ("(%s)(%s)", parent_path_expr, index_img.c_str ());
     }
 }
 
@@ -665,10 +660,10 @@ ada_varobj_describe_child (struct value *parent_value,
 			   const char *parent_name,
 			   const char *parent_path_expr,
 			   int child_index,
-			   char **child_name,
+			   std::string *child_name,
 			   struct value **child_value,
 			   struct type **child_type,
-			   char **child_path_expr)
+			   std::string *child_path_expr)
 {
   /* We cannot compute the child's path expression without
      the parent's path expression.  This is a pre-condition
@@ -680,13 +675,13 @@ ada_varobj_describe_child (struct value *parent_value,
   ada_varobj_adjust_for_child_access (&parent_value, &parent_type);
 
   if (child_name)
-    *child_name = NULL;
+    *child_name = std::string ();
   if (child_value)
     *child_value = NULL;
   if (child_type)
     *child_type = NULL;
   if (child_path_expr)
-    *child_path_expr = NULL;
+    *child_path_expr = std::string ();
 
   if (ada_is_array_descriptor_type (parent_type)
       && TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
@@ -731,20 +726,18 @@ ada_varobj_describe_child (struct value *parent_value,
   /* It should never happen.  But rather than crash, report dummy names
      and return a NULL child_value.  */
   if (child_name)
-    *child_name = xstrdup ("???");
+    *child_name = "???";
 }
 
 /* Return the name of the child number CHILD_INDEX of the (PARENT_VALUE,
-   PARENT_TYPE) pair.  PARENT_NAME is the name of the PARENT.
-
-   The result should be deallocated after use with xfree.  */
+   PARENT_TYPE) pair.  PARENT_NAME is the name of the PARENT.  */
 
-static char *
+static std::string
 ada_varobj_get_name_of_child (struct value *parent_value,
 			      struct type *parent_type,
 			      const char *parent_name, int child_index)
 {
-  char *child_name;
+  std::string child_name;
 
   ada_varobj_describe_child (parent_value, parent_type, parent_name,
 			     NULL, child_index, &child_name, NULL,
@@ -755,18 +748,16 @@ ada_varobj_get_name_of_child (struct value *parent_value,
 /* Return the path expression of the child number CHILD_INDEX of
    the (PARENT_VALUE, PARENT_TYPE) pair.  PARENT_NAME is the name
    of the parent, and PARENT_PATH_EXPR is the parent's path expression.
-   Both must be non-NULL.
+   Both must be non-NULL.  */
 
-   The result must be deallocated after use with xfree.  */
-
-static char *
+static std::string
 ada_varobj_get_path_expr_of_child (struct value *parent_value,
 				   struct type *parent_type,
 				   const char *parent_name,
 				   const char *parent_path_expr,
 				   int child_index)
 {
-  char *child_path_expr;
+  std::string child_path_expr;
 
   ada_varobj_describe_child (parent_value, parent_type, parent_name,
 			     parent_path_expr, child_index, NULL,
@@ -813,11 +804,10 @@ ada_varobj_get_type_of_child (struct value *parent_value,
 
    The resulting string must be deallocated after use with xfree.  */
 
-static char *
+static std::string
 ada_varobj_get_value_image (struct value *value,
 			    struct value_print_options *opts)
 {
-  char *result;
   struct ui_file *buffer;
   struct cleanup *old_chain;
 
@@ -825,7 +815,7 @@ ada_varobj_get_value_image (struct value *value,
   old_chain = make_cleanup_ui_file_delete (buffer);
 
   common_val_print (value, buffer, 0, opts, current_language);
-  result = ui_file_xstrdup (buffer, NULL);
+  std::string result = ui_file_as_string (buffer);
 
   do_cleanups (old_chain);
   return result;
@@ -841,7 +831,7 @@ ada_varobj_get_value_image (struct value *value,
 
    The result should be deallocated after use using xfree.  */
 
-static char *
+static std::string
 ada_varobj_get_value_of_array_variable (struct value *value,
 					struct type *type,
 					struct value_print_options *opts)
@@ -857,50 +847,36 @@ ada_varobj_get_value_of_array_variable (struct value *value,
       && ada_is_string_type (type)
       && (opts->format == 0 || opts->format == 's'))
     {
-      char *str;
-      struct cleanup *old_chain;
-
-      str = ada_varobj_get_value_image (value, opts);
-      old_chain = make_cleanup (xfree, str);
-      result = xstrprintf ("[%d] %s", numchild, str);
-      do_cleanups (old_chain);
+      std::string str = ada_varobj_get_value_image (value, opts);
+      return string_printf ("[%d] %s", numchild, str.c_str ());
     }
   else
-    result = xstrprintf ("[%d]", numchild);
-
-  return result;
+    return string_printf ("[%d]", numchild);
 }
 
 /* Return a string representation of the (VALUE, TYPE) pair, using
    the given print options OPTS as our formatting options.  */
 
-static char *
+static std::string
 ada_varobj_get_value_of_variable (struct value *value,
 				  struct type *type,
 				  struct value_print_options *opts)
 {
-  char *result = NULL;
-
   ada_varobj_decode_var (&value, &type);
 
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
-      result = xstrdup ("{...}");
-      break;
+      return "{...}";
     case TYPE_CODE_ARRAY:
-      result = ada_varobj_get_value_of_array_variable (value, type, opts);
-      break;
+      return ada_varobj_get_value_of_array_variable (value, type, opts);
     default:
       if (!value)
-	result = xstrdup ("");
+	return "";
       else
-	result = ada_varobj_get_value_image (value, opts);
-      break;
+	return ada_varobj_get_value_image (value, opts);
     }
-
-  return result;
 }
 
 /* Ada specific callbacks for VAROBJs.  */
@@ -911,20 +887,20 @@ ada_number_of_children (const struct varobj *var)
   return ada_varobj_get_number_of_children (var->value, var->type);
 }
 
-static char *
+static std::string
 ada_name_of_variable (const struct varobj *parent)
 {
   return c_varobj_ops.name_of_variable (parent);
 }
 
-static char *
+static std::string
 ada_name_of_child (const struct varobj *parent, int index)
 {
   return ada_varobj_get_name_of_child (parent->value, parent->type,
-				       parent->name, index);
+				       parent->name.c_str (), index);
 }
 
-static char*
+static std::string
 ada_path_expr_of_child (const struct varobj *child)
 {
   const struct varobj *parent = child->parent;
@@ -932,7 +908,7 @@ ada_path_expr_of_child (const struct varobj *child)
 
   return ada_varobj_get_path_expr_of_child (parent->value,
 					    parent->type,
-					    parent->name,
+					    parent->name.c_str (),
 					    parent_path_expr,
 					    child->index);
 }
@@ -941,7 +917,7 @@ static struct value *
 ada_value_of_child (const struct varobj *parent, int index)
 {
   return ada_varobj_get_value_of_child (parent->value, parent->type,
-					parent->name, index);
+					parent->name.c_str (), index);
 }
 
 static struct type *
@@ -951,7 +927,7 @@ ada_type_of_child (const struct varobj *parent, int index)
 				       index);
 }
 
-static char *
+static std::string
 ada_value_of_variable (const struct varobj *var,
 		       enum varobj_display_formats format)
 {
@@ -1019,9 +995,9 @@ ada_value_has_mutated (const struct varobj *var, struct value *new_val,
 
   varobj_restrict_range (var->children, &from, &to);
   for (i = from; i < to; i++)
-    if (strcmp (ada_varobj_get_name_of_child (new_val, new_type,
-					      var->name, i),
-		VEC_index (varobj_p, var->children, i)->name) != 0)
+    if (ada_varobj_get_name_of_child (new_val, new_type,
+				      var->name.c_str (), i)
+	!= VEC_index (varobj_p, var->children, i)->name)
       return 1;
 
   return 0;
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c
index cfec33b..6136a57 100644
--- a/gdb/break-catch-throw.c
+++ b/gdb/break-catch-throw.c
@@ -162,7 +162,7 @@ check_status_exception_catchpoint (struct bpstats *bs)
 {
   struct exception_catchpoint *self
     = (struct exception_catchpoint *) bs->breakpoint_at;
-  char *type_name = NULL;
+  std::string type_name;
 
   bkpt_breakpoint_ops.check_status (bs);
   if (bs->stop == 0)
@@ -174,17 +174,14 @@ check_status_exception_catchpoint (struct bpstats *bs)
   TRY
     {
       struct value *typeinfo_arg;
-      char *canon;
+      std::string canon;
 
       fetch_probe_arguments (NULL, &typeinfo_arg);
       type_name = cplus_typename_from_type_info (typeinfo_arg);
 
-      canon = cp_canonicalize_string (type_name);
-      if (canon != NULL)
-	{
-	  xfree (type_name);
-	  type_name = canon;
-	}
+      canon = cp_canonicalize_string (type_name.c_str ());
+      if (!canon.empty ())
+	std::swap (type_name, canon);
     }
   CATCH (e, RETURN_MASK_ERROR)
     {
@@ -192,12 +189,10 @@ check_status_exception_catchpoint (struct bpstats *bs)
     }
   END_CATCH
 
-  if (type_name != NULL)
+  if (!type_name.empty ())
     {
-      if (regexec (self->pattern, type_name, 0, NULL, 0) != 0)
+      if (regexec (self->pattern, type_name.c_str (), 0, NULL, 0) != 0)
 	bs->stop = 0;
-
-      xfree (type_name);
     }
 }
 
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 101f230..45f00d1 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -11390,14 +11390,13 @@ watch_command_1 (const char *arg, int accessflag, int from_tty,
     {
       struct type *t = value_type (val);
       CORE_ADDR addr = value_as_address (val);
-      char *name;
 
       t = check_typedef (TYPE_TARGET_TYPE (check_typedef (t)));
-      name = type_to_string (t);
 
-      w->exp_string_reparse = xstrprintf ("* (%s *) %s", name,
+      std::string name = type_to_string (t);
+
+      w->exp_string_reparse = xstrprintf ("* (%s *) %s", name.c_str (),
 					  core_addr_to_string (addr));
-      xfree (name);
 
       w->exp_string = xstrprintf ("-location %.*s",
 				  (int) (exp_end - exp_start), exp_start);
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index d24b0c8..ecc1e79 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -356,14 +356,11 @@ c_get_string (struct value *value, gdb_byte **buffer,
 
  error:
   {
-    char *type_str;
-
-    type_str = type_to_string (type);
-    if (type_str)
+    std::string type_str = type_to_string (type);
+    if (!type_str.empty ())
       {
-	make_cleanup (xfree, type_str);
 	error (_("Trying to read string with inappropriate type `%s'."),
-	       type_str);
+	       type_str.c_str ());
       }
     else
       error (_("Trying to read string with inappropriate type."));
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index 8b15b6f..12dda84 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -60,15 +60,14 @@ print_name_maybe_canonical (const char *name,
 			    const struct type_print_options *flags,
 			    struct ui_file *stream)
 {
-  char *s = NULL;
+  std::string s;
 
   if (!flags->raw)
     s = cp_canonicalize_string_full (name,
 				     find_typedef_for_canonicalize,
 				     (void *) flags);
 
-  fputs_filtered (s ? s : name, stream);
-  xfree (s);
+  fputs_filtered (!s.empty () ? s.c_str () : name, stream);
 }
 
 
diff --git a/gdb/c-varobj.c b/gdb/c-varobj.c
index b2b239f..16d5077 100644
--- a/gdb/c-varobj.c
+++ b/gdb/c-varobj.c
@@ -37,8 +37,8 @@ static void cplus_class_num_children (struct type *type, int children[3]);
 int
 varobj_is_anonymous_child (const struct varobj *child)
 {
-  return (strcmp (child->name, ANONYMOUS_STRUCT_NAME) == 0
-	  || strcmp (child->name, ANONYMOUS_UNION_NAME) == 0);
+  return (child->name == ANONYMOUS_STRUCT_NAME
+	  || child->name == ANONYMOUS_UNION_NAME);
 }
 
 /* Given the value and the type of a variable object,
@@ -231,10 +231,10 @@ c_number_of_children (const struct varobj *var)
   return children;
 }
 
-static char *
+static std::string
 c_name_of_variable (const struct varobj *parent)
 {
-  return xstrdup (parent->name);
+  return parent->name;
 }
 
 /* Return the value of element TYPE_INDEX of a structure
@@ -279,40 +279,39 @@ value_struct_element_index (struct value *value, int type_index)
 
    If any of CNAME, CVALUE, or CTYPE is not null, but the corresponding
    information cannot be determined, set *CNAME, *CVALUE, or *CTYPE
-   to NULL.  */
+   to empty.  */
 
 static void 
 c_describe_child (const struct varobj *parent, int index,
-		  char **cname, struct value **cvalue, struct type **ctype,
-		  char **cfull_expression)
+		  std::string *cname, struct value **cvalue,
+		  struct type **ctype, std::string *cfull_expression)
 {
   struct value *value = parent->value;
   struct type *type = varobj_get_value_type (parent);
-  char *parent_expression = NULL;
+  std::string parent_expression;
   int was_ptr;
 
   if (cname)
-    *cname = NULL;
+    *cname = std::string ();
   if (cvalue)
     *cvalue = NULL;
   if (ctype)
     *ctype = NULL;
   if (cfull_expression)
     {
-      *cfull_expression = NULL;
+      *cfull_expression = std::string ();
       parent_expression
 	= varobj_get_path_expr (varobj_get_path_expr_parent (parent));
     }
   adjust_value_for_child_access (&value, &type, &was_ptr, 0);
-      
+
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_ARRAY:
       if (cname)
-	*cname
-	  = xstrdup (int_string (index 
-				 + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
-				 10, 1, 0, 0));
+	*cname = int_string (index
+			     + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
+			     10, 1, 0, 0);
 
       if (cvalue && value)
 	{
@@ -333,10 +332,10 @@ c_describe_child (const struct varobj *parent, int index,
 
       if (cfull_expression)
 	*cfull_expression = 
-	  xstrprintf ("(%s)[%s]", parent_expression, 
-		      int_string (index
-				  + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
-				  10, 1, 0, 0));
+	  string_printf ("(%s)[%s]", parent_expression.c_str (),
+			 int_string (index
+				     + TYPE_LOW_BOUND (TYPE_INDEX_TYPE (type)),
+				     10, 1, 0, 0));
 
 
       break;
@@ -355,25 +354,26 @@ c_describe_child (const struct varobj *parent, int index,
 	      {
 		if (TYPE_CODE (TYPE_FIELD_TYPE (type, index))
 		    == TYPE_CODE_STRUCT)
-		  *cname = xstrdup (ANONYMOUS_STRUCT_NAME);
+		  *cname = ANONYMOUS_STRUCT_NAME;
 		else
-		  *cname = xstrdup (ANONYMOUS_UNION_NAME);
+		  *cname = ANONYMOUS_UNION_NAME;
 	      }
 
 	    if (cfull_expression)
-	      *cfull_expression = xstrdup ("");
+	      *cfull_expression = "";
 	  }
 	else
 	  {
 	    if (cname)
-	      *cname = xstrdup (field_name);
+	      *cname = field_name;
 
 	    if (cfull_expression)
 	      {
 		const char *join = was_ptr ? "->" : ".";
 
-		*cfull_expression = xstrprintf ("(%s)%s%s", parent_expression,
-						join, field_name);
+		*cfull_expression = string_printf ("(%s)%s%s",
+						   parent_expression.c_str (),
+						   join, field_name);
 	      }
 	  }
 
@@ -390,7 +390,7 @@ c_describe_child (const struct varobj *parent, int index,
 
     case TYPE_CODE_PTR:
       if (cname)
-	*cname = xstrprintf ("*%s", parent->name);
+	*cname = string_printf ("*%s", parent->name.c_str ());
 
       if (cvalue && value)
 	{
@@ -413,33 +413,32 @@ c_describe_child (const struct varobj *parent, int index,
 	*ctype = TYPE_TARGET_TYPE (type);
 
       if (cfull_expression)
-	*cfull_expression = xstrprintf ("*(%s)", parent_expression);
-      
+	*cfull_expression = string_printf ("*(%s)", parent_expression.c_str ());
       break;
 
     default:
       /* This should not happen.  */
       if (cname)
-	*cname = xstrdup ("???");
+	*cname = "???";
       if (cfull_expression)
-	*cfull_expression = xstrdup ("???");
+	*cfull_expression = "???";
       /* Don't set value and type, we don't know then.  */
     }
 }
 
-static char *
+static std::string
 c_name_of_child (const struct varobj *parent, int index)
 {
-  char *name;
+  std::string name;
 
   c_describe_child (parent, index, &name, NULL, NULL, NULL);
   return name;
 }
 
-static char *
+static std::string
 c_path_expr_of_child (const struct varobj *child)
 {
-  char *path_expr;
+  std::string path_expr;
 
   c_describe_child (child->parent, child->index, NULL, NULL, NULL, 
 		    &path_expr);
@@ -479,7 +478,7 @@ get_type (const struct varobj *var)
   return type;
 }
 
-static char *
+static std::string
 c_value_of_variable (const struct varobj *var,
 		     enum varobj_display_formats format)
 {
@@ -496,16 +495,11 @@ c_value_of_variable (const struct varobj *var,
     {
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_UNION:
-      return xstrdup ("{...}");
+      return "{...}";
       /* break; */
 
     case TYPE_CODE_ARRAY:
-      {
-	char *number;
-
-	number = xstrprintf ("[%d]", var->num_children);
-	return (number);
-      }
+      return string_printf ("[%d]", var->num_children);
       /* break; */
 
     default:
@@ -515,7 +509,7 @@ c_value_of_variable (const struct varobj *var,
 	    /* This can happen if we attempt to get the value of a struct
 	       member when the parent is an invalid pointer.  This is an
 	       error condition, so we should tell the caller.  */
-	    return NULL;
+	    return std::string ();
 	  }
 	else
 	  {
@@ -523,7 +517,7 @@ c_value_of_variable (const struct varobj *var,
 	      /* Frozen variable and no value yet.  We don't
 		 implicitly fetch the value.  MI response will
 		 use empty string for the value, which is OK.  */
-	      return NULL;
+	      return std::string ();
 
 	    gdb_assert (varobj_value_is_changeable_p (var));
 	    gdb_assert (!value_lazy (var->value));
@@ -531,7 +525,7 @@ c_value_of_variable (const struct varobj *var,
 	    /* If the specified format is the current one,
 	       we can reuse print_value.  */
 	    if (format == var->format)
-	      return xstrdup (var->print_value);
+	      return var->print_value;
 	    else
 	      return varobj_value_get_print_value (var->value, format, var);
 	  }
@@ -629,9 +623,9 @@ cplus_number_of_children (const struct varobj *var)
       adjust_value_for_child_access (&value, &type, NULL, lookup_actual_type);
 
       cplus_class_num_children (type, kids);
-      if (strcmp (var->name, "public") == 0)
+      if (var->name == "public")
 	children = kids[v_public];
-      else if (strcmp (var->name, "private") == 0)
+      else if (var->name == "private")
 	children = kids[v_private];
       else
 	children = kids[v_protected];
@@ -677,7 +671,7 @@ cplus_class_num_children (struct type *type, int children[3])
     }
 }
 
-static char *
+static std::string
 cplus_name_of_variable (const struct varobj *parent)
 {
   return c_name_of_variable (parent);
@@ -704,25 +698,25 @@ match_accessibility (struct type *type, int index, enum accessibility acc)
 
 static void
 cplus_describe_child (const struct varobj *parent, int index,
-		      char **cname, struct value **cvalue, struct type **ctype,
-		      char **cfull_expression)
+		      std::string *cname, struct value **cvalue, struct type **ctype,
+		      std::string *cfull_expression)
 {
   struct value *value;
   struct type *type;
   int was_ptr;
   int lookup_actual_type = 0;
-  char *parent_expression = NULL;
+  const char *parent_expression = NULL;
   const struct varobj *var;
   struct value_print_options opts;
 
   if (cname)
-    *cname = NULL;
+    *cname = std::string ();
   if (cvalue)
     *cvalue = NULL;
   if (ctype)
     *ctype = NULL;
   if (cfull_expression)
-    *cfull_expression = NULL;
+    *cfull_expression = std::string ();
 
   get_user_print_options (&opts);
 
@@ -758,9 +752,9 @@ cplus_describe_child (const struct varobj *parent, int index,
 	  const char *field_name;
 
 	  vptr_fieldno = get_vptr_fieldno (type, &basetype);
-	  if (strcmp (parent->name, "private") == 0)
+	  if (parent->name == "private")
 	    acc = private_field;
-	  else if (strcmp (parent->name, "protected") == 0)
+	  else if (parent->name == "protected")
 	    acc = protected_field;
 
 	  while (index >= 0)
@@ -783,24 +777,24 @@ cplus_describe_child (const struct varobj *parent, int index,
 		{
 		  if (TYPE_CODE (TYPE_FIELD_TYPE (type, type_index))
 		      == TYPE_CODE_STRUCT)
-		    *cname = xstrdup (ANONYMOUS_STRUCT_NAME);
+		    *cname = ANONYMOUS_STRUCT_NAME;
 		  else if (TYPE_CODE (TYPE_FIELD_TYPE (type, type_index))
 			   == TYPE_CODE_UNION)
-		    *cname = xstrdup (ANONYMOUS_UNION_NAME);
+		    *cname = ANONYMOUS_UNION_NAME;
 		}
 
 	      if (cfull_expression)
-		*cfull_expression = xstrdup ("");
+		*cfull_expression = std::string ();
 	    }
 	  else
 	    {
 	      if (cname)
-		*cname = xstrdup (TYPE_FIELD_NAME (type, type_index));
+		*cname = TYPE_FIELD_NAME (type, type_index);
 
 	      if (cfull_expression)
 		*cfull_expression
-		  = xstrprintf ("((%s)%s%s)", parent_expression, join,
-				field_name);
+		  = string_printf ("((%s)%s%s)", parent_expression, join,
+				   field_name);
 	    }
 
 	  if (cvalue && value)
@@ -813,7 +807,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 	{
 	  /* This is a baseclass.  */
 	  if (cname)
-	    *cname = xstrdup (TYPE_FIELD_NAME (type, index));
+	    *cname = TYPE_FIELD_NAME (type, index);
 
 	  if (cvalue && value)
 	    *cvalue = value_cast (TYPE_FIELD_TYPE (type, index), value);
@@ -840,11 +834,11 @@ cplus_describe_child (const struct varobj *parent, int index,
 		 as a constructor, if it exists.  Therefore, we must
 		 indicate that the name is a class name by using the
 		 'class' keyword.  See PR mi/11912  */
-	      *cfull_expression = xstrprintf ("(%s(class %s%s) %s)", 
-					      ptr, 
-					      TYPE_FIELD_NAME (type, index),
-					      ptr,
-					      parent_expression);
+	      *cfull_expression = string_printf ("(%s(class %s%s) %s)",
+						 ptr,
+						 TYPE_FIELD_NAME (type, index),
+						 ptr,
+						 parent_expression);
 	    }
 	}
       else
@@ -892,7 +886,7 @@ cplus_describe_child (const struct varobj *parent, int index,
 
 	  gdb_assert (access);
 	  if (cname)
-	    *cname = xstrdup (access);
+	    *cname = access;
 
 	  /* Value and type and full expression are null here.  */
 	}
@@ -903,19 +897,19 @@ cplus_describe_child (const struct varobj *parent, int index,
     }  
 }
 
-static char *
+static std::string
 cplus_name_of_child (const struct varobj *parent, int index)
 {
-  char *name = NULL;
+  std::string name;
 
   cplus_describe_child (parent, index, &name, NULL, NULL, NULL);
   return name;
 }
 
-static char *
+static std::string
 cplus_path_expr_of_child (const struct varobj *child)
 {
-  char *path_expr;
+  std::string path_expr;
 
   cplus_describe_child (child->parent, child->index, NULL, NULL, NULL, 
 			&path_expr);
@@ -940,7 +934,7 @@ cplus_type_of_child (const struct varobj *parent, int index)
   return type;
 }
 
-static char *
+static std::string
 cplus_value_of_variable (const struct varobj *var,
 			 enum varobj_display_formats format)
 {
@@ -948,7 +942,7 @@ cplus_value_of_variable (const struct varobj *var,
   /* If we have one of our special types, don't print out
      any value.  */
   if (CPLUS_FAKE_CHILD (var))
-    return xstrdup ("");
+    return std::string ();
 
   return c_value_of_variable (var, format);
 }
diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c
index afc4d4a..90f0d08 100644
--- a/gdb/cp-abi.c
+++ b/gdb/cp-abi.c
@@ -212,7 +212,7 @@ cplus_type_from_type_info (struct value *value)
 
 /* See cp-abi.h.  */
 
-char *
+std::string
 cplus_typename_from_type_info (struct value *value)
 {
   if (current_cp_abi.get_typename_from_type_info == NULL)
diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h
index 4349a4a..3be9f43 100644
--- a/gdb/cp-abi.h
+++ b/gdb/cp-abi.h
@@ -196,10 +196,9 @@ extern struct type *cplus_type_from_type_info (struct value *value);
 
 /* Given a value which holds a pointer to a std::type_info, return the
    name of the type which that type_info represents.  Throw an
-   exception if the type name cannot be found.  The result is
-   xmalloc'd and must be freed by the caller.  */
+   exception if the type name cannot be found.  */
 
-extern char *cplus_typename_from_type_info (struct value *value);
+extern std::string cplus_typename_from_type_info (struct value *value);
 
 /* Determine if we are currently in a C++ thunk.  If so, get the
    address of the routine we are thunking to and continue to there
@@ -245,7 +244,7 @@ struct cp_abi_ops
   struct value *(*get_typeid) (struct value *value);
   struct type *(*get_typeid_type) (struct gdbarch *gdbarch);
   struct type *(*get_type_from_type_info) (struct value *value);
-  char *(*get_typename_from_type_info) (struct value *value);
+  std::string (*get_typename_from_type_info) (struct value *value);
   CORE_ADDR (*skip_trampoline) (struct frame_info *, CORE_ADDR);
   int (*pass_by_reference) (struct type *type);
 };
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index ea6dcb2..d409b0b 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -288,14 +288,12 @@ inspect_type (struct demangle_parse_info *info,
 
 		 Canonicalize the name again, and store it in the
 		 current node (RET_COMP).  */
-	      char *canon = cp_canonicalize_string_no_typedefs (name);
+	      std::string canon = cp_canonicalize_string_no_typedefs (name);
 
-	      if (canon != NULL)
+	      if (!canon.empty ())
 		{
-		  /* Copy the canonicalization into the obstack and
-		     free CANON.  */
-		  name = copy_string_to_obstack (&info->obstack, canon, &len);
-		  xfree (canon);
+		  /* Copy the canonicalization into the obstack.  */
+		  name = copy_string_to_obstack (&info->obstack, canon.c_str (), &len);
 		}
 
 	      ret_comp->u.s_name.s = name;
@@ -529,22 +527,21 @@ replace_typedefs (struct demangle_parse_info *info,
     }
 }
 
-/* Parse STRING and convert it to canonical form, resolving any typedefs.
-   If parsing fails, or if STRING is already canonical, return NULL.
-   Otherwise return the canonical form.  The return value is allocated via
-   xmalloc.  If FINDER is not NULL, then type components are passed to
-   FINDER to be looked up.  DATA is passed verbatim to FINDER.  */
+/* Parse STRING and convert it to canonical form, resolving any
+   typedefs.  If parsing fails, or if STRING is already canonical,
+   return the empty string.  Otherwise return the canonical form.  If
+   FINDER is not NULL, then type components are passed to FINDER to be
+   looked up.  DATA is passed verbatim to FINDER.  */
 
-char *
+std::string
 cp_canonicalize_string_full (const char *string,
 			     canonicalization_ftype *finder,
 			     void *data)
 {
-  char *ret;
+  std::string ret;
   unsigned int estimated_len;
   struct demangle_parse_info *info;
 
-  ret = NULL;
   estimated_len = strlen (string) * 2;
   info = cp_demangled_name_to_comp (string, NULL);
   if (info != NULL)
@@ -554,18 +551,15 @@ cp_canonicalize_string_full (const char *string,
 
       /* Convert the tree back into a string.  */
       ret = cp_comp_to_string (info->tree, estimated_len);
-      gdb_assert (ret != NULL);
+      gdb_assert (!ret.empty ());
 
       /* Free the parse information.  */
       cp_demangled_name_parse_free (info);
 
       /* Finally, compare the original string with the computed
 	 name, returning NULL if they are the same.  */
-      if (strcmp (string, ret) == 0)
-	{
-	  xfree (ret);
-	  return NULL;
-	}
+      if (ret == string)
+	return std::string ();
     }
 
   return ret;
@@ -574,46 +568,42 @@ cp_canonicalize_string_full (const char *string,
 /* Like cp_canonicalize_string_full, but always passes NULL for
    FINDER.  */
 
-char *
+std::string
 cp_canonicalize_string_no_typedefs (const char *string)
 {
   return cp_canonicalize_string_full (string, NULL, NULL);
 }
 
 /* Parse STRING and convert it to canonical form.  If parsing fails,
-   or if STRING is already canonical, return NULL.  Otherwise return
-   the canonical form.  The return value is allocated via xmalloc.  */
+   or if STRING is already canonical, return the empty string.
+   Otherwise return the canonical form.  */
 
-char *
+std::string
 cp_canonicalize_string (const char *string)
 {
   struct demangle_parse_info *info;
   unsigned int estimated_len;
-  char *ret;
 
   if (cp_already_canonical (string))
-    return NULL;
+    return std::string ();
 
   info = cp_demangled_name_to_comp (string, NULL);
   if (info == NULL)
-    return NULL;
+    return std::string ();
 
   estimated_len = strlen (string) * 2;
-  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 == NULL)
+  if (ret.empty ())
     {
       warning (_("internal error: string \"%s\" failed to be canonicalized"),
 	       string);
-      return NULL;
+      return std::string ();
     }
 
-  if (strcmp (string, ret) == 0)
-    {
-      xfree (ret);
-      return NULL;
-    }
+  if (ret == string)
+    return std::string ();
 
   return ret;
 }
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 23ffd71..ca7a7d4 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -63,15 +63,15 @@ struct demangle_parse_info
 
 /* Functions from cp-support.c.  */
 
-extern char *cp_canonicalize_string (const char *string);
+extern std::string cp_canonicalize_string (const char *string);
 
-extern char *cp_canonicalize_string_no_typedefs (const char *string);
+extern std::string cp_canonicalize_string_no_typedefs (const char *string);
 
 typedef const char *(canonicalization_ftype) (struct type *, void *);
 
-extern char *cp_canonicalize_string_full (const char *string,
-					  canonicalization_ftype *finder,
-					  void *data);
+extern std::string cp_canonicalize_string_full (const char *string,
+						canonicalization_ftype *finder,
+						void *data);
 
 extern char *cp_class_name_from_physname (const char *physname);
 
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 2230de8..cfc4ed0 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -1664,20 +1664,16 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
 	  sym_name = NULL;	/* pacify "gcc -Werror" */
  	  if (psymtab_language == language_cplus)
  	    {
-	      char *new_name, *name = (char *) xmalloc (p - namestring + 1);
- 	      memcpy (name, namestring, p - namestring);
-
- 	      name[p - namestring] = '\0';
- 	      new_name = cp_canonicalize_string (name);
- 	      if (new_name != NULL)
- 		{
- 		  sym_len = strlen (new_name);
+	      std::string name (namestring, p - namestring);
+	      std::string new_name = cp_canonicalize_string (name.c_str ());
+	      if (!new_name.empty ())
+		{
+		  sym_len = new_name.length ();
 		  sym_name = (char *) obstack_copy0 (&objfile->objfile_obstack,
-						     new_name, sym_len);
- 		  xfree (new_name);
- 		}
-              xfree (name);
- 	    }
+						     new_name.c_str (),
+						     sym_len);
+		}
+	    }
 
  	  if (sym_len == 0)
  	    {
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 6cc79ea..1ad6b00 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -19524,14 +19524,14 @@ dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
 {
   if (name && cu->language == language_cplus)
     {
-      char *canon_name = cp_canonicalize_string (name);
+      std::string canon_name = cp_canonicalize_string (name);
 
-      if (canon_name != NULL)
+      if (!canon_name.empty ())
 	{
-	  if (strcmp (canon_name, name) != 0)
-	    name = (const char *) obstack_copy0 (obstack, canon_name,
-						 strlen (canon_name));
-	  xfree (canon_name);
+	  if (canon_name != name)
+	    name = (const char *) obstack_copy0 (obstack,
+						 canon_name.c_str (),
+						 canon_name.length ());
 	}
     }
 
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index ad890ca..5921aac 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1572,7 +1572,6 @@ struct type *
 lookup_struct_elt_type (struct type *type, const char *name, int noerr)
 {
   int i;
-  char *type_name;
 
   for (;;)
     {
@@ -1586,9 +1585,9 @@ lookup_struct_elt_type (struct type *type, const char *name, int noerr)
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT 
       && TYPE_CODE (type) != TYPE_CODE_UNION)
     {
-      type_name = type_to_string (type);
-      make_cleanup (xfree, type_name);
-      error (_("Type %s is not a structure or union type."), type_name);
+      std::string type_name = type_to_string (type);
+      error (_("Type %s is not a structure or union type."),
+	     type_name.c_str ());
     }
 
 #if 0
@@ -1640,9 +1639,8 @@ lookup_struct_elt_type (struct type *type, const char *name, int noerr)
       return NULL;
     }
 
-  type_name = type_to_string (type);
-  make_cleanup (xfree, type_name);
-  error (_("Type %s has no component named %s."), type_name, name);
+  std::string type_name = type_to_string (type);
+  error (_("Type %s has no component named %s."), type_name.c_str (), name);
 }
 
 /* Store in *MAX the largest number representable by unsigned integer type
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index eda9a11..9be9cd9 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -1081,7 +1081,7 @@ gnuv3_get_typeid (struct value *value)
   struct gdbarch *gdbarch;
   struct cleanup *cleanup;
   struct value *result;
-  char *type_name, *canonical;
+  std::string type_name, canonical;
 
   /* We have to handle values a bit trickily here, to allow this code
      to work properly with non_lvalue values that are really just
@@ -1101,20 +1101,16 @@ gnuv3_get_typeid (struct value *value)
   gdbarch = get_type_arch (type);
 
   type_name = type_to_string (type);
-  if (type_name == NULL)
+  if (type_name.empty ())
     error (_("cannot find typeinfo for unnamed type"));
-  cleanup = make_cleanup (xfree, type_name);
 
   /* We need to canonicalize the type name here, because we do lookups
      using the demangled name, and so we must match the format it
      uses.  E.g., GDB tends to use "const char *" as a type name, but
      the demangler uses "char const *".  */
-  canonical = cp_canonicalize_string (type_name);
-  if (canonical != NULL)
-    {
-      make_cleanup (xfree, canonical);
-      type_name = canonical;
-    }
+  canonical = cp_canonicalize_string (type_name.c_str ());
+  if (!canonical.empty ())
+    type_name = canonical;
 
   typeinfo_type = gnuv3_get_typeid_type (gdbarch);
 
@@ -1129,33 +1125,30 @@ gnuv3_get_typeid (struct value *value)
 
       vtable = gnuv3_get_vtable (gdbarch, type, address);
       if (vtable == NULL)
-	error (_("cannot find typeinfo for object of type '%s'"), type_name);
+	error (_("cannot find typeinfo for object of type '%s'"),
+	       type_name.c_str ());
       typeinfo_value = value_field (vtable, vtable_field_type_info);
       result = value_ind (value_cast (make_pointer_type (typeinfo_type, NULL),
 				      typeinfo_value));
     }
   else
     {
-      char *sym_name;
-      struct bound_minimal_symbol minsym;
-
-      sym_name = concat ("typeinfo for ", type_name, (char *) NULL);
-      make_cleanup (xfree, sym_name);
-      minsym = lookup_minimal_symbol (sym_name, NULL, NULL);
+      std::string sym_name = std::string ("typeinfo for ") + type_name;
+      bound_minimal_symbol minsym
+	= lookup_minimal_symbol (sym_name.c_str (), NULL, NULL);
 
       if (minsym.minsym == NULL)
-	error (_("could not find typeinfo symbol for '%s'"), type_name);
+	error (_("could not find typeinfo symbol for '%s'"), type_name.c_str ());
 
       result = value_at_lazy (typeinfo_type, BMSYMBOL_VALUE_ADDRESS (minsym));
     }
 
-  do_cleanups (cleanup);
   return result;
 }
 
 /* Implement the 'get_typename_from_type_info' method.  */
 
-static char *
+static std::string
 gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
 {
   struct gdbarch *gdbarch = get_type_arch (value_type (type_info_ptr));
@@ -1183,8 +1176,8 @@ gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
   /* Strip off @plt and version suffixes.  */
   atsign = strchr (class_name, '@');
   if (atsign != NULL)
-    return savestring (class_name, atsign - class_name);
-  return xstrdup (class_name);
+    return std::string (class_name, atsign - class_name);
+  return class_name;
 }
 
 /* Implement the 'get_type_from_type_info' method.  */
@@ -1192,26 +1185,14 @@ gnuv3_get_typename_from_type_info (struct value *type_info_ptr)
 static struct type *
 gnuv3_get_type_from_type_info (struct value *type_info_ptr)
 {
-  char *type_name;
-  struct cleanup *cleanup;
-  struct value *type_val;
-  struct type *result;
-
-  type_name = gnuv3_get_typename_from_type_info (type_info_ptr);
-  cleanup = make_cleanup (xfree, type_name);
-
   /* We have to parse the type name, since in general there is not a
      symbol for a type.  This is somewhat bogus since there may be a
      mis-parse.  Another approach might be to re-use the demangler's
      internal form to reconstruct the type somehow.  */
-
-  expression_up expr = parse_expression (type_name);
-
-  type_val = evaluate_type (expr.get ());
-  result = value_type (type_val);
-
-  do_cleanups (cleanup);
-  return result;
+  std::string type_name = gnuv3_get_typename_from_type_info (type_info_ptr);
+  expression_up expr (parse_expression (type_name.c_str ()));
+  struct value *type_val = evaluate_type (expr.get ());
+  return value_type (type_val);
 }
 
 /* Determine if we are currently in a C++ thunk.  If so, get the address
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 8e34b7e..c603c01 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -1688,16 +1688,11 @@ print_return_value_1 (struct ui_out *uiout, struct return_value_info *rv)
     }
   else
     {
-      struct cleanup *oldchain;
-      char *type_name;
-
-      type_name = type_to_string (rv->type);
-      oldchain = make_cleanup (xfree, type_name);
+      std::string type_name = type_to_string (rv->type);
       ui_out_text (uiout, "Value returned has type: ");
-      ui_out_field_string (uiout, "return-type", type_name);
+      ui_out_field_string (uiout, "return-type", type_name.c_str ());
       ui_out_text (uiout, ".");
       ui_out_text (uiout, " Cannot determine contents\n");
-      do_cleanups (oldchain);
     }
 }
 
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 8ceb4ac..1604267 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -3268,27 +3268,28 @@ find_linespec_symbols (struct linespec_state *state,
 		       VEC (symbolp) **symbols,
 		       VEC (bound_minimal_symbol_d) **minsyms)
 {
-  struct cleanup *cleanup;
-  char *canon;
+  demangle_result_storage demangle_storage;
+  std::string ada_lookup_storage;
   const char *lookup_name;
 
-  cleanup = demangle_for_lookup (name, state->language->la_language,
-				 &lookup_name);
   if (state->language->la_language == language_ada)
     {
       /* In Ada, the symbol lookups are performed using the encoded
          name rather than the demangled name.  */
-      lookup_name = ada_name_for_lookup (name);
-      make_cleanup (xfree, (void *) lookup_name);
+      ada_lookup_storage = ada_name_for_lookup (name);
+      lookup_name = ada_lookup_storage.c_str ();
     }
-
-  canon = cp_canonicalize_string_no_typedefs (lookup_name);
-  if (canon != NULL)
+  else
     {
-      lookup_name = canon;
-      make_cleanup (xfree, canon);
+      lookup_name = demangle_for_lookup (name,
+					 state->language->la_language,
+					 demangle_storage);
     }
 
+  std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
+  if (!canon.empty ())
+    lookup_name = canon.c_str ();
+
   /* It's important to not call expand_symtabs_matching unnecessarily
      as it can really slow things down (by unnecessarily expanding
      potentially 1000s of symtabs, which when debugging some apps can
@@ -3307,7 +3308,7 @@ find_linespec_symbols (struct linespec_state *state,
   if (VEC_empty (symbolp, *symbols)
       && VEC_empty (bound_minimal_symbol_d, *minsyms))
     {
-      char *klass, *method;
+      std::string klass, method;
       const char *last, *p, *scope_op;
       VEC (symbolp) *classes;
 
@@ -3327,35 +3328,29 @@ find_linespec_symbols (struct linespec_state *state,
 	 we already attempted to lookup the entire name as a symbol
 	 and failed.  */
       if (last == NULL)
-	{
-	  do_cleanups (cleanup);
-	  return;
-	}
+	return;
 
       /* LOOKUP_NAME points to the class name.
 	 LAST points to the method name.  */
-      klass = XNEWVEC (char, last - lookup_name + 1);
-      make_cleanup (xfree, klass);
-      strncpy (klass, lookup_name, last - lookup_name);
-      klass[last - lookup_name] = '\0';
+      klass = std::string (lookup_name, last - lookup_name);
 
       /* Skip past the scope operator.  */
       last += strlen (scope_op);
-      method = XNEWVEC (char, strlen (last) + 1);
-      make_cleanup (xfree, method);
-      strcpy (method, last);
+      method = last;
 
       /* Find a list of classes named KLASS.  */
-      classes = lookup_prefix_sym (state, file_symtabs, klass);
-      make_cleanup (VEC_cleanup (symbolp), &classes);
+      classes = lookup_prefix_sym (state, file_symtabs, klass.c_str ());
+      struct cleanup *old_chain
+	= make_cleanup (VEC_cleanup (symbolp), &classes);
 
       if (!VEC_empty (symbolp, classes))
 	{
 	  /* Now locate a list of suitable methods named METHOD.  */
 	  TRY
 	    {
-	      find_method (state, file_symtabs, klass, method, classes,
-			   symbols, minsyms);
+	      find_method (state, file_symtabs,
+			   klass.c_str (), method.c_str (),
+			   classes, symbols, minsyms);
 	    }
 
 	  /* If successful, we're done.  If NOT_FOUND_ERROR
@@ -3367,9 +3362,9 @@ find_linespec_symbols (struct linespec_state *state,
 	    }
 	  END_CATCH
 	}
-    }
 
-  do_cleanups (cleanup);
+      do_cleanups (old_chain);
+    }
 }
 
 /* Return all labels named NAME in FUNCTION_SYMBOLS.  Return the
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 16d51f9..147e026 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -49,34 +49,28 @@ print_varobj (struct varobj *var, enum print_values print_values,
 	      int print_expression)
 {
   struct ui_out *uiout = current_uiout;
-  char *type;
   int thread_id;
   char *display_hint;
 
   ui_out_field_string (uiout, "name", varobj_get_objname (var));
   if (print_expression)
     {
-      char *exp = varobj_get_expression (var);
+      std::string exp = varobj_get_expression (var);
 
-      ui_out_field_string (uiout, "exp", exp);
-      xfree (exp);
+      ui_out_field_string (uiout, "exp", exp.c_str ());
     }
   ui_out_field_int (uiout, "numchild", varobj_get_num_children (var));
   
   if (mi_print_value_p (var, print_values))
     {
-      char *val = varobj_get_value (var);
+      std::string val = varobj_get_value (var);
 
-      ui_out_field_string (uiout, "value", val);
-      xfree (val);
+      ui_out_field_string (uiout, "value", val.c_str ());
     }
 
-  type = varobj_get_type (var);
-  if (type != NULL)
-    {
-      ui_out_field_string (uiout, "type", type);
-      xfree (type);
-    }
+  std::string type = varobj_get_type (var);
+  if (!type.empty ())
+    ui_out_field_string (uiout, "type", type.c_str ());
 
   thread_id = varobj_get_thread_id (var);
   if (thread_id > 0)
@@ -246,7 +240,6 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
 {
   enum varobj_display_formats format;
   struct varobj *var;
-  char *val;
   struct ui_out *uiout = current_uiout;
 
   if (argc != 2)
@@ -264,9 +257,8 @@ mi_cmd_var_set_format (char *command, char **argv, int argc)
   ui_out_field_string (uiout, "format", varobj_format_string[(int) format]);
  
   /* Report the value in the new format.  */
-  val = varobj_get_value (var);
-  ui_out_field_string (uiout, "value", val);
-  xfree (val);
+  std::string val = varobj_get_value (var);
+  ui_out_field_string (uiout, "value", val.c_str ());
 }
 
 void
@@ -454,18 +446,15 @@ mi_cmd_var_info_type (char *command, char **argv, int argc)
 {
   struct ui_out *uiout = current_uiout;
   struct varobj *var;
-  char *type_name;
 
   if (argc != 1)
     error (_("-var-info-type: Usage: NAME."));
 
   /* Get varobj handle, if a valid var obj name was specified.  */
   var = varobj_get_handle (argv[0]);
-  type_name = varobj_get_type (var);
-
-  ui_out_field_string (uiout, "type", type_name);
 
-  xfree (type_name);
+  std::string type_name = varobj_get_type (var);
+  ui_out_field_string (uiout, "type", type_name.c_str ());
 }
 
 void
@@ -473,7 +462,6 @@ mi_cmd_var_info_path_expression (char *command, char **argv, int argc)
 {
   struct ui_out *uiout = current_uiout;
   struct varobj *var;
-  char *path_expr;
 
   if (argc != 1)
     error (_("Usage: NAME."));
@@ -481,7 +469,7 @@ mi_cmd_var_info_path_expression (char *command, char **argv, int argc)
   /* Get varobj handle, if a valid var obj name was specified.  */
   var = varobj_get_handle (argv[0]);
   
-  path_expr = varobj_get_path_expr (var);
+  const char *path_expr = varobj_get_path_expr (var);
 
   ui_out_field_string (uiout, "path_expr", path_expr);
 }
@@ -492,7 +480,6 @@ mi_cmd_var_info_expression (char *command, char **argv, int argc)
   struct ui_out *uiout = current_uiout;
   const struct language_defn *lang;
   struct varobj *var;
-  char *exp;
 
   if (argc != 1)
     error (_("-var-info-expression: Usage: NAME."));
@@ -504,9 +491,8 @@ mi_cmd_var_info_expression (char *command, char **argv, int argc)
 
   ui_out_field_string (uiout, "lang", lang->la_natural_name);
 
-  exp = varobj_get_expression (var);
-  ui_out_field_string (uiout, "exp", exp);
-  xfree (exp);
+  std::string exp = varobj_get_expression (var);
+  ui_out_field_string (uiout, "exp", exp.c_str ());
 }
 
 void
@@ -588,17 +574,15 @@ mi_cmd_var_evaluate_expression (char *command, char **argv, int argc)
    
   if (formatFound)
     {
-      char *val = varobj_get_formatted_value (var, format);
+      std::string val = varobj_get_formatted_value (var, format);
 
-      ui_out_field_string (uiout, "value", val);
-      xfree (val);
+      ui_out_field_string (uiout, "value", val.c_str ());
     }
   else
     {
-      char *val = varobj_get_value (var);
+      std::string val = varobj_get_value (var);
 
-      ui_out_field_string (uiout, "value", val);
-      xfree (val);
+      ui_out_field_string (uiout, "value", val.c_str ());
     }
 }
 
@@ -607,7 +591,6 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
 {
   struct ui_out *uiout = current_uiout;
   struct varobj *var;
-  char *expression, *val;
 
   if (argc != 2)
     error (_("-var-assign: Usage: NAME EXPRESSION."));
@@ -618,7 +601,7 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
   if (!varobj_editable_p (var))
     error (_("-var-assign: Variable object is not editable"));
 
-  expression = xstrdup (argv[1]);
+  const char *expression = argv[1];
 
   /* MI command '-var-assign' may write memory, so suppress memory
      changed notification if it does.  */
@@ -629,9 +612,8 @@ mi_cmd_var_assign (char *command, char **argv, int argc)
     error (_("-var-assign: Could not assign "
 	     "expression to variable object"));
 
-  val = varobj_get_value (var);
-  ui_out_field_string (uiout, "value", val);
-  xfree (val);
+  std::string val = varobj_get_value (var);
+  ui_out_field_string (uiout, "value", val.c_str ());
 }
 
 /* Type used for parameters passing to mi_cmd_var_update_iter.  */
@@ -752,10 +734,9 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
 	case VAROBJ_IN_SCOPE:
 	  if (mi_print_value_p (r->varobj, print_values))
 	    {
-	      char *val = varobj_get_value (r->varobj);
+	      std::string val = varobj_get_value (r->varobj);
 
-	      ui_out_field_string (uiout, "value", val);
-	      xfree (val);
+	      ui_out_field_string (uiout, "value", val.c_str ());
 	    }
 	  ui_out_field_string (uiout, "in_scope", "true");
 	  break;
@@ -777,10 +758,9 @@ varobj_update_one (struct varobj *var, enum print_values print_values,
 
       if (r->type_changed)
 	{
-	  char *type_name = varobj_get_type (r->varobj);
+	  std::string type_name = varobj_get_type (r->varobj);
 
-	  ui_out_field_string (uiout, "new_type", type_name);
-	  xfree (type_name);
+	  ui_out_field_string (uiout, "new_type", type_name.c_str ());
 	}
 
       if (r->type_changed || r->children_changed)
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index d804c95..4814394 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -158,22 +158,20 @@ lookup_minimal_symbol (const char *name, const char *sfile,
   unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
   unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
-  int needtofreename = 0;
-  const char *modified_name;
+  const char *modified_name = name;
 
   if (sfile != NULL)
     sfile = lbasename (sfile);
 
   /* For C++, canonicalize the input name.  */
-  modified_name = name;
+  std::string modified_name_storage;
   if (current_language->la_language == language_cplus)
     {
-      char *cname = cp_canonicalize_string (name);
-
-      if (cname)
+      std::string cname = cp_canonicalize_string (name);
+      if (!cname.empty ())
 	{
-	  modified_name = cname;
-	  needtofreename = 1;
+	  std::swap (modified_name_storage, cname);
+	  modified_name = modified_name_storage.c_str ();
 	}
     }
 
@@ -272,9 +270,6 @@ lookup_minimal_symbol (const char *name, const char *sfile,
 	}
     }
 
-  if (needtofreename)
-    xfree ((void *) modified_name);
-
   /* External symbols are best.  */
   if (found_symbol.minsym != NULL)
     {
diff --git a/gdb/python/py-varobj.c b/gdb/python/py-varobj.c
index 7e74454..a6b1968 100644
--- a/gdb/python/py-varobj.c
+++ b/gdb/python/py-varobj.c
@@ -113,11 +113,11 @@ py_varobj_iter_next (struct varobj_iter *self)
       error (_("Invalid item from the child list"));
     }
 
-  vitem = XNEW (struct varobj_item);
+  vitem = new varobj_item ();
   vitem->value = convert_value_from_python (py_v);
   if (vitem->value == NULL)
     gdbpy_print_stack ();
-  vitem->name = xstrdup (name);
+  vitem->name = name;
 
   self->next_raw_index++;
   do_cleanups (back_to);
diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y
index dffccd0..5f44089 100644
--- a/gdb/rust-exp.y
+++ b/gdb/rust-exp.y
@@ -2055,13 +2055,11 @@ convert_ast_to_type (struct parser_state *state,
 	obstack_1grow (&work_obstack, '(');
 	for (i = 0; VEC_iterate (type_ptr, args, i, type); ++i)
 	  {
-	    char *type_name = type_to_string (type);
+	    std::string type_name = type_to_string (type);
 
 	    if (i > 0)
 	      obstack_1grow (&work_obstack, ',');
-	    obstack_grow_str (&work_obstack, type_name);
-
-	    xfree (type_name);
+	    obstack_grow_str (&work_obstack, type_name.c_str ());
 	  }
 
 	obstack_grow_str0 (&work_obstack, ")");
@@ -2109,13 +2107,12 @@ convert_name (struct parser_state *state, const struct rust_op *operation)
   obstack_1grow (&work_obstack, '<');
   for (i = 0; VEC_iterate (type_ptr, types, i, type); ++i)
     {
-      char *type_name = type_to_string (type);
+      std::string type_name = type_to_string (type);
 
       if (i > 0)
 	obstack_1grow (&work_obstack, ',');
 
-      obstack_grow_str (&work_obstack, type_name);
-      xfree (type_name);
+      obstack_grow_str (&work_obstack, type_name.c_str ());
     }
   obstack_grow_str0 (&work_obstack, ">");
 
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index e8ebadd..d72db14 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -649,7 +649,6 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
   int deftype;
   int synonym = 0;
   int i;
-  char *new_name = NULL;
 
   /* We would like to eliminate nameless symbols, but keep their types.
      E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer
@@ -733,6 +732,8 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
   else
     {
     normal:
+      std::string new_name;
+
       if (SYMBOL_LANGUAGE (sym) == language_cplus)
 	{
 	  char *name = (char *) alloca (p - string + 1);
@@ -741,10 +742,11 @@ define_symbol (CORE_ADDR valu, char *string, int desc, int type,
 	  name[p - string] = '\0';
 	  new_name = cp_canonicalize_string (name);
 	}
-      if (new_name != NULL)
+      if (!new_name.empty ())
 	{
-	  SYMBOL_SET_NAMES (sym, new_name, strlen (new_name), 1, objfile);
-	  xfree (new_name);
+	  SYMBOL_SET_NAMES (sym,
+			    new_name.c_str (), new_name.length (),
+			    1, objfile);
 	}
       else
 	SYMBOL_SET_NAMES (sym, string, p - string, 1, objfile);
@@ -1642,17 +1644,18 @@ again:
 	  type_name = NULL;
 	  if (current_subfile->language == language_cplus)
 	    {
-	      char *new_name, *name = (char *) alloca (p - *pp + 1);
+	      char *name = (char *) alloca (p - *pp + 1);
 
 	      memcpy (name, *pp, p - *pp);
 	      name[p - *pp] = '\0';
-	      new_name = cp_canonicalize_string (name);
-	      if (new_name != NULL)
+
+	      std::string new_name = cp_canonicalize_string (name);
+	      if (!new_name.empty ())
 		{
 		  type_name
 		    = (char *) obstack_copy0 (&objfile->objfile_obstack,
-					      new_name, strlen (new_name));
-		  xfree (new_name);
+					      new_name.c_str (),
+					      new_name.length ());
 		}
 	    }
 	  if (type_name == NULL)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 4e03cb7..430bc8d 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -1770,10 +1770,10 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
 }
 
 /* Compute the demangled form of NAME as used by the various symbol
-   lookup functions.  The result is stored in *RESULT_NAME.  Returns a
-   cleanup which can be used to clean up the result.
+   lookup functions.  The result can either be the input NAME
+   directly, or a pointer to a buffer owned by the STORAGE object.
 
-   For Ada, this function just sets *RESULT_NAME to NAME, unmodified.
+   For Ada, this function just returns NAME, unmodified.
    Normally, Ada symbol lookups are performed using the encoded name
    rather than the demangled name, and so it might seem to make sense
    for this function to return an encoded version of NAME.
@@ -1787,59 +1787,38 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
    characters to become lowercase, and thus cause the symbol lookup
    to fail.  */
 
-struct cleanup *
+const char *
 demangle_for_lookup (const char *name, enum language lang,
-		     const char **result_name)
+		     demangle_result_storage &storage)
 {
-  char *demangled_name = NULL;
-  const char *modified_name = NULL;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
-
-  modified_name = name;
-
   /* If we are using C++, D, or Go, demangle the name before doing a
      lookup, so we can always binary search.  */
   if (lang == language_cplus)
     {
-      demangled_name = gdb_demangle (name, DMGL_ANSI | DMGL_PARAMS);
-      if (demangled_name)
-	{
-	  modified_name = demangled_name;
-	  make_cleanup (xfree, demangled_name);
-	}
-      else
-	{
-	  /* If we were given a non-mangled name, canonicalize it
-	     according to the language (so far only for C++).  */
-	  demangled_name = cp_canonicalize_string (name);
-	  if (demangled_name)
-	    {
-	      modified_name = demangled_name;
-	      make_cleanup (xfree, demangled_name);
-	    }
-	}
+      char *demangled_name = gdb_demangle (name, DMGL_ANSI | DMGL_PARAMS);
+      if (demangled_name != NULL)
+	return storage.set_malloc_ptr (demangled_name);
+
+      /* If we were given a non-mangled name, canonicalize it
+	 according to the language (so far only for C++).  */
+      std::string canon = cp_canonicalize_string (name);
+      if (!canon.empty ())
+	return storage.swap_string (canon);
     }
   else if (lang == language_d)
     {
-      demangled_name = d_demangle (name, 0);
-      if (demangled_name)
-	{
-	  modified_name = demangled_name;
-	  make_cleanup (xfree, demangled_name);
-	}
+      char *demangled_name = d_demangle (name, 0);
+      if (demangled_name != NULL)
+	return storage.set_malloc_ptr (demangled_name);
     }
   else if (lang == language_go)
     {
-      demangled_name = go_demangle (name, 0);
-      if (demangled_name)
-	{
-	  modified_name = demangled_name;
-	  make_cleanup (xfree, demangled_name);
-	}
+      char *demangled_name = go_demangle (name, 0);
+      if (demangled_name != NULL)
+	return storage.set_malloc_ptr (demangled_name);
     }
 
-  *result_name = modified_name;
-  return cleanup;
+  return name;
 }
 
 /* See symtab.h.
@@ -1859,15 +1838,11 @@ lookup_symbol_in_language (const char *name, const struct block *block,
 			   const domain_enum domain, enum language lang,
 			   struct field_of_this_result *is_a_field_of_this)
 {
-  const char *modified_name;
-  struct block_symbol returnval;
-  struct cleanup *cleanup = demangle_for_lookup (name, lang, &modified_name);
+  demangle_result_storage storage;
+  const char *modified_name = demangle_for_lookup (name, lang, storage);
 
-  returnval = lookup_symbol_aux (modified_name, block, domain, lang,
-				 is_a_field_of_this);
-  do_cleanups (cleanup);
-
-  return returnval;
+  return lookup_symbol_aux (modified_name, block, domain, lang,
+			    is_a_field_of_this);
 }
 
 /* See symtab.h.  */
@@ -2278,11 +2253,11 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
 					    domain_enum domain)
 {
   enum language lang = current_language->la_language;
-  const char *modified_name;
-  struct cleanup *cleanup = demangle_for_lookup (linkage_name, lang,
-						 &modified_name);
   struct objfile *main_objfile, *cur_objfile;
 
+  demangle_result_storage storage;
+  const char *modified_name = demangle_for_lookup (linkage_name, lang, storage);
+
   if (objfile->separate_debug_objfile_backlink)
     main_objfile = objfile->separate_debug_objfile_backlink;
   else
@@ -2300,13 +2275,9 @@ lookup_symbol_in_objfile_from_linkage_name (struct objfile *objfile,
 	result = lookup_symbol_in_objfile_symtabs (cur_objfile, STATIC_BLOCK,
 						   modified_name, domain);
       if (result.symbol != NULL)
-	{
-	  do_cleanups (cleanup);
-	  return result;
-	}
+	return result;
     }
 
-  do_cleanups (cleanup);
   return (struct block_symbol) {NULL, NULL};
 }
 
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 9b1dbb4..a6bf655 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1637,8 +1637,43 @@ void iterate_over_symbols (const struct block *block, const char *name,
 			   symbol_found_callback_ftype *callback,
 			   void *data);
 
-struct cleanup *demangle_for_lookup (const char *name, enum language lang,
-				     const char **result_name);
+/* Storage type used by demangle_for_lookup.  demangle_for_lookup
+   either returns a const char * pointer that points to either of the
+   fields of this type, or a pointer to the input NAME.  This is done
+   this way because the underlying functions that demangle_for_lookup
+   calls either return a std::string (e.g., cp_canonicalize_string) or
+   a malloc'ed buffer (libiberty's demangled), and we want to avoid
+   unnecessary reallocation/string copying.  */
+class demangle_result_storage
+{
+public:
+
+  /* Swap the std::string storage with STR, and return a pointer to
+     the beginning of the new string.  */
+  const char *swap_string (std::string &str)
+  {
+    std::swap (m_string, str);
+    return m_string.c_str ();
+  }
+
+  /* Set the malloc storage to now point at PTR.  Any previous malloc
+     storage is released.  */
+  const char *set_malloc_ptr (char *ptr)
+  {
+    m_malloc.reset (ptr);
+    return ptr;
+  }
+
+private:
+
+  /* The storage.  */
+  std::string m_string;
+  gdb::unique_xmalloc_ptr<char> m_malloc;
+};
+
+const char *
+  demangle_for_lookup (const char *name, enum language lang,
+		       demangle_result_storage &storage);
 
 struct symbol *allocate_symbol (struct objfile *);
 
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 6851a70..c1b46be 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -368,10 +368,10 @@ type_print (struct type *type, const char *varstring, struct ui_file *stream,
 /* Print TYPE to a string, returning it.  The caller is responsible for
    freeing the string.  */
 
-char *
+std::string
 type_to_string (struct type *type)
 {
-  char *s = NULL;
+  std::string s;
   struct ui_file *stb;
   struct cleanup *old_chain;
 
@@ -381,11 +381,10 @@ type_to_string (struct type *type)
   TRY
     {
       type_print (type, "", stb, -1);
-      s = ui_file_xstrdup (stb, NULL);
+      s = ui_file_as_string (stb);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
-      s = NULL;
     }
   END_CATCH
 
diff --git a/gdb/value.h b/gdb/value.h
index 3299e87..440bc2d 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -992,7 +992,7 @@ extern void modify_field (struct type *type, gdb_byte *addr,
 extern void type_print (struct type *type, const char *varstring,
 			struct ui_file *stream, int show);
 
-extern char *type_to_string (struct type *type);
+extern std::string type_to_string (struct type *type);
 
 extern gdb_byte *baseclass_addr (struct type *type, int index,
 				 gdb_byte *valaddr,
diff --git a/gdb/varobj-iter.h b/gdb/varobj-iter.h
index bdbf661..1e7889b 100644
--- a/gdb/varobj-iter.h
+++ b/gdb/varobj-iter.h
@@ -19,7 +19,7 @@
 typedef struct varobj_item
 {
   /* Name of this item.  */
-  char *name;
+  std::string name;
 
   /* Value of this item.  */
   struct value *value;
@@ -67,6 +67,6 @@ struct varobj_iter_ops
       if ((ITER) != NULL)		       \
 	{				       \
 	  (ITER)->ops->dtor (ITER);	       \
-	  xfree (ITER);		       \
+	  delete (ITER);		       \
 	}				       \
     } while (0)
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 81e897f..afd82d2 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -156,7 +156,7 @@ static int install_variable (struct varobj *);
 
 static void uninstall_variable (struct varobj *);
 
-static struct varobj *create_child (struct varobj *, int, char *);
+static struct varobj *create_child (struct varobj *, int, std::string &);
 
 static struct varobj *
 create_child_with_value (struct varobj *parent, int index,
@@ -184,16 +184,16 @@ static int install_new_value (struct varobj *var, struct value *value,
 
 static int number_of_children (const struct varobj *);
 
-static char *name_of_variable (const struct varobj *);
+static std::string name_of_variable (const struct varobj *);
 
-static char *name_of_child (struct varobj *, int);
+static std::string name_of_child (struct varobj *, int);
 
 static struct value *value_of_root (struct varobj **var_handle, int *);
 
 static struct value *value_of_child (const struct varobj *parent, int index);
 
-static char *my_value_of_variable (struct varobj *var,
-				   enum varobj_display_formats format);
+static std::string my_value_of_variable (struct varobj *var,
+					 enum varobj_display_formats format);
 
 static int is_root_p (const struct varobj *var);
 
@@ -270,8 +270,8 @@ find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
 /* Creates a varobj (not its children).  */
 
 struct varobj *
-varobj_create (char *objname,
-	       char *expression, CORE_ADDR frame, enum varobj_type type)
+varobj_create (const char *objname,
+	       const char *expression, CORE_ADDR frame, enum varobj_type type)
 {
   struct varobj *var;
   struct cleanup *old_chain;
@@ -351,9 +351,9 @@ varobj_create (char *objname,
 
       var->format = variable_default_display (var);
       var->root->valid_block = innermost_block;
-      var->name = xstrdup (expression);
+      var->name = expression;
       /* For a root var, the name and the expr are the same.  */
-      var->path_expr = xstrdup (expression);
+      var->path_expr = expression;
 
       /* When the frame is different from the current frame, 
          we must select the appropriate frame before parsing
@@ -418,7 +418,7 @@ varobj_create (char *objname,
 
   if ((var != NULL) && (objname != NULL))
     {
-      var->obj_name = xstrdup (objname);
+      var->obj_name = objname;
 
       /* If a varobj name is duplicated, the install will fail so
          we must cleanup.  */
@@ -452,7 +452,7 @@ varobj_gen_name (void)
    error if OBJNAME cannot be found.  */
 
 struct varobj *
-varobj_get_handle (char *objname)
+varobj_get_handle (const char *objname)
 {
   struct vlist *cv;
   const char *chp;
@@ -465,7 +465,7 @@ varobj_get_handle (char *objname)
     }
 
   cv = *(varobj_table + index);
-  while ((cv != NULL) && (strcmp (cv->var->obj_name, objname) != 0))
+  while (cv != NULL && cv->var->obj_name != objname)
     cv = cv->next;
 
   if (cv == NULL)
@@ -476,16 +476,16 @@ varobj_get_handle (char *objname)
 
 /* Given the handle, return the name of the object.  */
 
-char *
+const char *
 varobj_get_objname (const struct varobj *var)
 {
-  return var->obj_name;
+  return var->obj_name.c_str ();
 }
 
-/* Given the handle, return the expression represented by the object.  The
-   result must be freed by the caller.  */
+/* Given the handle, return the expression represented by the
+   object.  */
 
-char *
+std::string
 varobj_get_expression (const struct varobj *var)
 {
   return name_of_variable (var);
@@ -544,7 +544,6 @@ varobj_set_display_format (struct varobj *var,
   if (varobj_value_is_changeable_p (var) 
       && var->value && !value_lazy (var->value))
     {
-      xfree (var->print_value);
       var->print_value = varobj_value_get_print_value (var->value,
 						       var->format, var);
     }
@@ -867,7 +866,6 @@ varobj_get_num_children (struct varobj *var)
 VEC (varobj_p)*
 varobj_list_children (struct varobj *var, int *from, int *to)
 {
-  char *name;
   int i, children_changed;
 
   var->dynamic->children_requested = 1;
@@ -904,7 +902,7 @@ varobj_list_children (struct varobj *var, int *from, int *to)
 	  /* Either it's the first call to varobj_list_children for
 	     this variable object, and the child was never created,
 	     or it was explicitly deleted by the client.  */
-	  name = name_of_child (var, i);
+	  std::string name = name_of_child (var, i);
 	  existing = create_child (var, i, name);
 	  VEC_replace (varobj_p, var->children, i, existing);
 	}
@@ -929,14 +927,14 @@ varobj_add_child (struct varobj *var, struct varobj_item *item)
    prints on the console.  The caller is responsible for freeing the string.
    */
 
-char *
+std::string
 varobj_get_type (struct varobj *var)
 {
   /* For the "fake" variables, do not return a type.  (Its type is
      NULL, too.)
      Do not return a type for invalid variables as well.  */
   if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
-    return NULL;
+    return std::string ();
 
   return type_to_string (var->type);
 }
@@ -984,10 +982,11 @@ varobj_get_path_expr_parent (const struct varobj *var)
 
 /* Return a pointer to the full rooted expression of varobj VAR.
    If it has not been computed yet, compute it.  */
-char *
+
+const char *
 varobj_get_path_expr (const struct varobj *var)
 {
-  if (var->path_expr == NULL)
+  if (var->path_expr.empty ())
     {
       /* For root varobjs, we initialize path_expr
 	 when creating varobj, so here it should be
@@ -998,7 +997,7 @@ varobj_get_path_expr (const struct varobj *var)
       mutable_var->path_expr = (*var->root->lang_ops->path_expr_of_child) (var);
     }
 
-  return var->path_expr;
+  return var->path_expr.c_str ();
 }
 
 const struct language_defn *
@@ -1027,14 +1026,14 @@ varobj_is_dynamic_p (const struct varobj *var)
   return var->dynamic->pretty_printer != NULL;
 }
 
-char *
+std::string
 varobj_get_formatted_value (struct varobj *var,
 			    enum varobj_display_formats format)
 {
   return my_value_of_variable (var, format);
 }
 
-char *
+std::string
 varobj_get_value (struct varobj *var)
 {
   return my_value_of_variable (var, var->format);
@@ -1045,7 +1044,7 @@ varobj_get_value (struct varobj *var)
 /* Note: Invokes functions that can call error().  */
 
 int
-varobj_set_value (struct varobj *var, char *expression)
+varobj_set_value (struct varobj *var, const char *expression)
 {
   struct value *val = NULL; /* Initialize to keep gcc happy.  */
   /* The argument "expression" contains the variable's new value.
@@ -1245,18 +1244,12 @@ update_type_if_necessary (struct varobj *var, struct value *new_value)
       get_user_print_options (&opts);
       if (opts.objectprint)
 	{
-	  struct type *new_type;
-	  char *curr_type_str, *new_type_str;
-	  int type_name_changed;
+	  struct type *new_type = value_actual_type (new_value, 0, 0);
+	  std::string new_type_str = type_to_string (new_type);
+	  std::string curr_type_str = varobj_get_type (var);
 
-	  new_type = value_actual_type (new_value, 0, 0);
-	  new_type_str = type_to_string (new_type);
-	  curr_type_str = varobj_get_type (var);
-	  type_name_changed = strcmp (curr_type_str, new_type_str) != 0;
-	  xfree (curr_type_str);
-	  xfree (new_type_str);
-
-	  if (type_name_changed)
+	  /* Did the type name change?  */
+	  if (curr_type_str != new_type_str)
 	    {
 	      var->type = new_type;
 
@@ -1292,7 +1285,6 @@ install_new_value (struct varobj *var, struct value *value, int initial)
   int need_to_fetch;
   int changed = 0;
   int intentionally_not_fetched = 0;
-  char *print_value = NULL;
 
   /* We need to know the varobj's type to decide if the value should
      be fetched or not.  C++ fake children (public/protected/private)
@@ -1374,6 +1366,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      values.  Don't get string rendering if the value is
      lazy -- if it is, the code above has decided that the value
      should not be fetched.  */
+  std::string print_value;
   if (value != NULL && !value_lazy (value)
       && var->dynamic->pretty_printer == NULL)
     print_value = varobj_value_get_print_value (value, var->format, var);
@@ -1417,8 +1410,8 @@ install_new_value (struct varobj *var, struct value *value, int initial)
 	      gdb_assert (!value_lazy (var->value));
 	      gdb_assert (!value_lazy (value));
 
-	      gdb_assert (var->print_value != NULL && print_value != NULL);
-	      if (strcmp (var->print_value, print_value) != 0)
+	      gdb_assert (!var->print_value.empty () && !print_value.empty ());
+	      if (var->print_value != print_value)
 		changed = 1;
 	    }
 	}
@@ -1449,17 +1442,14 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      to see if the variable changed.  */
   if (var->dynamic->pretty_printer != NULL)
     {
-      xfree (print_value);
       print_value = varobj_value_get_print_value (var->value, var->format,
 						  var);
-      if ((var->print_value == NULL && print_value != NULL)
-	  || (var->print_value != NULL && print_value == NULL)
-	  || (var->print_value != NULL && print_value != NULL
-	      && strcmp (var->print_value, print_value) != 0))
-	changed = 1;
+      if ((var->print_value.empty () && !print_value.empty ())
+	  || (!var->print_value.empty () && print_value.empty ())
+	  || (!var->print_value.empty () && !print_value.empty ()
+	      && var->print_value != print_value))
+	  changed = 1;
     }
-  if (var->print_value)
-    xfree (var->print_value);
   var->print_value = print_value;
 
   gdb_assert (!var->value || value_type (var->value));
@@ -1854,9 +1844,9 @@ delete_variable_1 (int *delcountp, struct varobj *var, int only_children_p,
     return;
 
   /* Otherwise, add it to the list of deleted ones and proceed to do so.  */
-  /* If the name is null, this is a temporary variable, that has not
+  /* If the name is empty, this is a temporary variable, that has not
      yet been installed, don't report it, it belongs to the caller...  */
-  if (var->obj_name != NULL)
+  if (!var->obj_name.empty ())
     {
       *delcountp = *delcountp + 1;
     }
@@ -1871,7 +1861,7 @@ delete_variable_1 (int *delcountp, struct varobj *var, int only_children_p,
       VEC_replace (varobj_p, var->parent->children, var->index, NULL);
     }
 
-  if (var->obj_name != NULL)
+  if (!var->obj_name.empty ())
     uninstall_variable (var);
 
   /* Free memory associated with this variable.  */
@@ -1888,13 +1878,13 @@ install_variable (struct varobj *var)
   unsigned int index = 0;
   unsigned int i = 1;
 
-  for (chp = var->obj_name; *chp; chp++)
+  for (chp = var->obj_name.c_str (); *chp; chp++)
     {
       index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
     }
 
   cv = *(varobj_table + index);
-  while ((cv != NULL) && (strcmp (cv->var->obj_name, var->obj_name) != 0))
+  while (cv != NULL && cv->var->obj_name != var->obj_name)
     cv = cv->next;
 
   if (cv != NULL)
@@ -1933,27 +1923,27 @@ uninstall_variable (struct varobj *var)
   unsigned int i = 1;
 
   /* Remove varobj from hash table.  */
-  for (chp = var->obj_name; *chp; chp++)
+  for (chp = var->obj_name.c_str (); *chp; chp++)
     {
       index = (index + (i++ * (unsigned int) *chp)) % VAROBJ_TABLE_SIZE;
     }
 
   cv = *(varobj_table + index);
   prev = NULL;
-  while ((cv != NULL) && (strcmp (cv->var->obj_name, var->obj_name) != 0))
+  while (cv != NULL && cv->var->obj_name != var->obj_name)
     {
       prev = cv;
       cv = cv->next;
     }
 
   if (varobjdebug)
-    fprintf_unfiltered (gdb_stdlog, "Deleting %s\n", var->obj_name);
+    fprintf_unfiltered (gdb_stdlog, "Deleting %s\n", var->obj_name.c_str ());
 
   if (cv == NULL)
     {
       warning
 	("Assertion failed: Could not find variable object \"%s\" to delete",
-	 var->obj_name);
+	 var->obj_name.c_str ());
       return;
     }
 
@@ -1983,7 +1973,7 @@ uninstall_variable (struct varobj *var)
 	    {
 	      warning (_("Assertion failed: Could not find "
 		         "varobj \"%s\" in root list"),
-		       var->obj_name);
+		       var->obj_name.c_str ());
 	      return;
 	    }
 	  if (prer == NULL)
@@ -2000,11 +1990,11 @@ uninstall_variable (struct varobj *var)
    The created VAROBJ takes ownership of the allocated NAME.  */
 
 static struct varobj *
-create_child (struct varobj *parent, int index, char *name)
+create_child (struct varobj *parent, int index, std::string &name)
 {
   struct varobj_item item;
 
-  item.name = name;
+  std::swap (item.name, name);
   item.value = value_of_child (parent, index);
 
   return create_child_with_value (parent, index, &item);
@@ -2015,21 +2005,22 @@ create_child_with_value (struct varobj *parent, int index,
 			 struct varobj_item *item)
 {
   struct varobj *child;
-  char *childs_name;
 
   child = new_variable ();
 
   /* NAME is allocated by caller.  */
-  child->name = item->name;
+  std::swap (child->name, item->name);
   child->index = index;
   child->parent = parent;
   child->root = parent->root;
 
   if (varobj_is_anonymous_child (child))
-    childs_name = xstrprintf ("%s.%d_anonymous", parent->obj_name, index);
+    child->obj_name = string_printf ("%s.%d_anonymous",
+				     parent->obj_name.c_str (), index);
   else
-    childs_name = xstrprintf ("%s.%s", parent->obj_name, item->name);
-  child->obj_name = childs_name;
+    child->obj_name = string_printf ("%s.%s",
+				     parent->obj_name.c_str (),
+				     child->name.c_str ());
 
   install_variable (child);
 
@@ -2059,10 +2050,7 @@ new_variable (void)
 {
   struct varobj *var;
 
-  var = XNEW (struct varobj);
-  var->name = NULL;
-  var->path_expr = NULL;
-  var->obj_name = NULL;
+  var = new varobj ();
   var->index = -1;
   var->type = NULL;
   var->value = NULL;
@@ -2072,7 +2060,6 @@ new_variable (void)
   var->format = FORMAT_NATURAL;
   var->root = NULL;
   var->updated = 0;
-  var->print_value = NULL;
   var->frozen = 0;
   var->not_fetched = 0;
   var->dynamic = XNEW (struct varobj_dynamic);
@@ -2127,12 +2114,8 @@ free_variable (struct varobj *var)
   if (is_root_p (var))
     delete var->root;
 
-  xfree (var->name);
-  xfree (var->obj_name);
-  xfree (var->print_value);
-  xfree (var->path_expr);
   xfree (var->dynamic);
-  xfree (var);
+  delete var;
 }
 
 static void
@@ -2203,17 +2186,17 @@ number_of_children (const struct varobj *var)
   return (*var->root->lang_ops->number_of_children) (var);
 }
 
-/* What is the expression for the root varobj VAR? Returns a malloc'd
-   string.  */
-static char *
+/* What is the expression for the root varobj VAR? */
+
+static std::string
 name_of_variable (const struct varobj *var)
 {
   return (*var->root->lang_ops->name_of_variable) (var);
 }
 
-/* What is the name of the INDEX'th child of VAR? Returns a malloc'd
-   string.  */
-static char *
+/* What is the name of the INDEX'th child of VAR?  */
+
+static std::string
 name_of_child (struct varobj *var, int index)
 {
   return (*var->root->lang_ops->name_of_child) (var, index);
@@ -2331,17 +2314,16 @@ value_of_root (struct varobj **var_handle, int *type_changed)
   if (var->root->floating)
     {
       struct varobj *tmp_var;
-      char *old_type, *new_type;
 
-      tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0,
+      tmp_var = varobj_create (NULL, var->name.c_str (), (CORE_ADDR) 0,
 			       USE_SELECTED_FRAME);
       if (tmp_var == NULL)
 	{
 	  return NULL;
 	}
-      old_type = varobj_get_type (var);
-      new_type = varobj_get_type (tmp_var);
-      if (strcmp (old_type, new_type) == 0)
+      std::string old_type = varobj_get_type (var);
+      std::string new_type = varobj_get_type (tmp_var);
+      if (old_type == new_type)
 	{
 	  /* The expression presently stored inside var->root->exp
 	     remembers the locations of local variables relatively to
@@ -2356,7 +2338,7 @@ value_of_root (struct varobj **var_handle, int *type_changed)
 	}
       else
 	{
-	  tmp_var->obj_name = xstrdup (var->obj_name);
+	  tmp_var->obj_name = var->obj_name;
 	  tmp_var->from = var->from;
 	  tmp_var->to = var->to;
 	  varobj_delete (var, 0);
@@ -2366,8 +2348,6 @@ value_of_root (struct varobj **var_handle, int *type_changed)
 	  var = *var_handle;
 	  *type_changed = 1;
 	}
-      xfree (old_type);
-      xfree (new_type);
     }
   else
     {
@@ -2410,7 +2390,7 @@ value_of_child (const struct varobj *parent, int index)
 }
 
 /* GDB already has a command called "value_of_variable".  Sigh.  */
-static char *
+static std::string
 my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
 {
   if (var->root->is_valid)
@@ -2420,7 +2400,7 @@ my_value_of_variable (struct varobj *var, enum varobj_display_formats format)
       return (*var->root->lang_ops->value_of_variable) (var, format);
     }
   else
-    return NULL;
+    return std::string ();
 }
 
 void
@@ -2432,14 +2412,13 @@ varobj_formatted_print_options (struct value_print_options *opts,
   opts->raw = 1;
 }
 
-char *
+std::string
 varobj_value_get_print_value (struct value *value,
 			      enum varobj_display_formats format,
 			      const struct varobj *var)
 {
   struct ui_file *stb;
   struct cleanup *old_chain;
-  char *thevalue = NULL;
   struct value_print_options opts;
   struct type *type = NULL;
   long len = 0;
@@ -2449,11 +2428,13 @@ varobj_value_get_print_value (struct value *value,
   int string_print = 0;
 
   if (value == NULL)
-    return NULL;
+    return std::string ();
 
   stb = mem_fileopen ();
   old_chain = make_cleanup_ui_file_delete (stb);
 
+  std::string thevalue;
+
 #if HAVE_PYTHON
   if (gdb_python_initialized)
     {
@@ -2518,8 +2499,8 @@ varobj_value_get_print_value (struct value *value,
 			      xfree (hint);
 			    }
 
-			  len = strlen (s);
-			  thevalue = (char *) xmemdup (s, len + 1, len + 1);
+			  thevalue = std::string (s);
+			  len = thevalue.size ();
 			  gdbarch = get_type_arch (value_type (value));
 			  type = builtin_type (gdbarch)->builtin_char;
 			  xfree (s);
@@ -2529,8 +2510,6 @@ varobj_value_get_print_value (struct value *value,
 			      do_cleanups (old_chain);
 			      return thevalue;
 			    }
-
-			  make_cleanup (xfree, thevalue);
 			}
 		      else
 			gdbpy_print_stack ();
@@ -2549,8 +2528,9 @@ varobj_value_get_print_value (struct value *value,
   varobj_formatted_print_options (&opts, format);
 
   /* If the THEVALUE has contents, it is a regular string.  */
-  if (thevalue)
-    LA_PRINT_STRING (stb, type, (gdb_byte *) thevalue, len, encoding, 0, &opts);
+  if (!thevalue.empty ())
+    LA_PRINT_STRING (stb, type, (gdb_byte *) thevalue.c_str (),
+		     len, encoding, 0, &opts);
   else if (string_print)
     /* Otherwise, if string_print is set, and it is not a regular
        string, it is a lazy string.  */
@@ -2559,7 +2539,7 @@ varobj_value_get_print_value (struct value *value,
     /* All other cases.  */
     common_val_print (value, stb, 0, &opts, current_language);
 
-  thevalue = ui_file_xstrdup (stb, NULL);
+  thevalue = ui_file_as_string (stb);
 
   do_cleanups (old_chain);
   return thevalue;
@@ -2672,11 +2652,11 @@ varobj_invalidate_iter (struct varobj *var, void *unused)
 
       /* Try to create a varobj with same expression.  If we succeed
 	 replace the old varobj, otherwise invalidate it.  */
-      tmp_var = varobj_create (NULL, var->name, (CORE_ADDR) 0,
+      tmp_var = varobj_create (NULL, var->name.c_str (), (CORE_ADDR) 0,
 			       USE_CURRENT_FRAME);
       if (tmp_var != NULL) 
 	{ 
-	  tmp_var->obj_name = xstrdup (var->obj_name);
+	  tmp_var->obj_name = var->obj_name;
 	  varobj_delete (var, 0);
 	  install_variable (tmp_var);
 	}
diff --git a/gdb/varobj.h b/gdb/varobj.h
index 6b9a71f..7f4aad2 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -86,22 +86,22 @@ struct varobj_dynamic;
 
 /* Every variable in the system has a structure of this type defined
    for it.  This structure holds all information necessary to manipulate
-   a particular object variable.  Members which must be freed are noted.  */
+   a particular object variable.  */
 struct varobj
 {
-  /* Alloc'd name of the variable for this object.  If this variable is a
+  /* Name of the variable for this object.  If this variable is a
      child, then this name will be the child's source name.
      (bar, not foo.bar).  */
   /* NOTE: This is the "expression".  */
-  char *name;
+  std::string name;
 
-  /* Alloc'd expression for this child.  Can be used to create a
-     root variable corresponding to this child.  */
-  char *path_expr;
+  /* Expression for this child.  Can be used to create a root variable
+     corresponding to this child.  */
+  std::string path_expr;
 
-  /* The alloc'd name for this variable's object.  This is here for
+  /* The name for this variable's object.  This is here for
      convenience when constructing this object's children.  */
-  char *obj_name;
+  std::string obj_name;
 
   /* Index of this variable in its parent or -1.  */
   int index;
@@ -137,7 +137,7 @@ struct varobj
   int updated;
 
   /* Last print value.  */
-  char *print_value;
+  std::string print_value;
 
   /* Is this variable frozen.  Frozen variables are never implicitly
      updated by -var-update * 
@@ -170,18 +170,15 @@ struct lang_varobj_ops
   /* The number of children of PARENT.  */
   int (*number_of_children) (const struct varobj *parent);
 
-  /* The name (expression) of a root varobj.  The returned value must be freed
-     by the caller.  */
-  char *(*name_of_variable) (const struct varobj *parent);
+  /* The name (expression) of a root varobj.  */
+  std::string (*name_of_variable) (const struct varobj *parent);
 
-  /* The name of the INDEX'th child of PARENT.  The returned value must be
-     freed by the caller.  */
-  char *(*name_of_child) (const struct varobj *parent, int index);
+  /* The name of the INDEX'th child of PARENT.  */
+  std::string (*name_of_child) (const struct varobj *parent, int index);
 
   /* Returns the rooted expression of CHILD, which is a variable
-     obtain that has some parent.  The returned value must be freed by the
-     caller.  */
-  char *(*path_expr_of_child) (const struct varobj *child);
+     obtain that has some parent.  */
+  std::string (*path_expr_of_child) (const struct varobj *child);
 
   /* The ``struct value *'' of the INDEX'th child of PARENT.  */
   struct value *(*value_of_child) (const struct varobj *parent, int index);
@@ -189,10 +186,9 @@ struct lang_varobj_ops
   /* The type of the INDEX'th child of PARENT.  */
   struct type *(*type_of_child) (const struct varobj *parent, int index);
 
-  /* The current value of VAR.  The returned value must be freed by the
-     caller.  */
-  char *(*value_of_variable) (const struct varobj *var,
-			      enum varobj_display_formats format);
+  /* The current value of VAR.  */
+  std::string (*value_of_variable) (const struct varobj *var,
+				    enum varobj_display_formats format);
 
   /* Return non-zero if changes in value of VAR must be detected and
      reported by -var-update.  Return zero if -var-update should never
@@ -233,17 +229,17 @@ extern const struct lang_varobj_ops ada_varobj_ops;
 #define default_varobj_ops c_varobj_ops
 /* API functions */
 
-extern struct varobj *varobj_create (char *objname,
-				     char *expression, CORE_ADDR frame,
+extern struct varobj *varobj_create (const char *objname,
+				     const char *expression, CORE_ADDR frame,
 				     enum varobj_type type);
 
 extern char *varobj_gen_name (void);
 
-extern struct varobj *varobj_get_handle (char *name);
+extern struct varobj *varobj_get_handle (const char *name);
 
-extern char *varobj_get_objname (const struct varobj *var);
+extern const char *varobj_get_objname (const struct varobj *var);
 
-extern char *varobj_get_expression (const struct varobj *var);
+extern std::string varobj_get_expression (const struct varobj *var);
 
 /* Delete a varobj and all its children if only_children == 0, otherwise delete
    only the children.  Return the number of deleted variables.  */
@@ -283,23 +279,24 @@ extern int varobj_get_num_children (struct varobj *var);
 extern VEC (varobj_p)* varobj_list_children (struct varobj *var,
 					     int *from, int *to);
 
-extern char *varobj_get_type (struct varobj *var);
+extern std::string varobj_get_type (struct varobj *var);
 
 extern struct type *varobj_get_gdb_type (const struct varobj *var);
 
-extern char *varobj_get_path_expr (const struct varobj *var);
+extern const char *varobj_get_path_[...]

[diff truncated at 100000 bytes]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]