Use unique_xmalloc_ptr in Python code
[deliverable/binutils-gdb.git] / gdb / varobj.c
index a10560f9fa98a22f7917dd3531bcc3d0e5f847fe..03edf0eb9692ab524926ae01289aa51e06b63993 100644 (file)
@@ -1,6 +1,6 @@
 /* Implementation of the GDB variable objects API.
 
-   Copyright (C) 1999-2015 Free Software Foundation, Inc.
+   Copyright (C) 1999-2016 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -50,7 +50,7 @@ show_varobjdebug (struct ui_file *file, int from_tty,
 
 /* String representations of gdb's format codes.  */
 char *varobj_format_string[] =
-  { "natural", "binary", "decimal", "hexadecimal", "octal" };
+  { "natural", "binary", "decimal", "hexadecimal", "octal", "zero-hexadecimal" };
 
 /* True if we want to allow Python-based pretty-printing.  */
 static int pretty_printing = 0;
@@ -64,12 +64,12 @@ varobj_enable_pretty_printing (void)
 /* Data structures */
 
 /* Every root variable has one of these structures saved in its
-   varobj.  Members which must be free'd are noted.  */
+   varobj.  */
 struct varobj_root
 {
 
-  /* Alloc'd expression for this parent.  */
-  struct expression *exp;
+  /* The expression for this parent.  */
+  expression_up exp;
 
   /* Block for which this expression is valid.  */
   const struct block *valid_block;
@@ -78,7 +78,7 @@ struct varobj_root
      not NULL.  */
   struct frame_id frame;
 
-  /* The thread ID that this varobj_root belong to.  This field
+  /* The global thread ID that this varobj_root belongs to.  This field
      is only valid if valid_block is not NULL.
      When not 0, indicates which thread 'frame' belongs to.
      When 0, indicates that the thread list was empty when the varobj_root
@@ -136,12 +136,6 @@ struct varobj_dynamic
   varobj_item *saved_item;
 };
 
-struct cpstack
-{
-  char *name;
-  struct cpstack *next;
-};
-
 /* A list of varobjs */
 
 struct vlist
@@ -154,16 +148,15 @@ struct vlist
 
 /* Helper functions for the above subcommands.  */
 
-static int delete_variable (struct cpstack **, struct varobj *, int);
+static int delete_variable (struct varobj *, int);
 
-static void delete_variable_1 (struct cpstack **, int *,
-                              struct varobj *, int, int);
+static void delete_variable_1 (int *, struct varobj *, int, int);
 
 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,
@@ -181,10 +174,6 @@ static struct cleanup *make_cleanup_free_variable (struct varobj *var);
 
 static enum varobj_display_formats variable_default_display (struct varobj *);
 
-static void cppush (struct cpstack **pstack, char *name);
-
-static char *cppop (struct cpstack **pstack);
-
 static int update_type_if_necessary (struct varobj *var,
                                     struct value *new_value);
 
@@ -193,20 +182,20 @@ static int install_new_value (struct varobj *var, struct value *value,
 
 /* Language-specific routines.  */
 
-static int number_of_children (struct varobj *);
+static int number_of_children (const struct varobj *);
 
-static char *name_of_variable (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 (struct varobj *parent, int index);
+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 (struct varobj *var);
+static int is_root_p (const struct varobj *var);
 
 static struct varobj *varobj_add_child (struct varobj *var,
                                        struct varobj_item *item);
@@ -214,13 +203,13 @@ static struct varobj *varobj_add_child (struct varobj *var,
 /* Private data */
 
 /* Mappings of varobj_display_formats enums to gdb's format codes.  */
-static int format_code[] = { 0, 't', 'd', 'x', 'o' };
+static int format_code[] = { 0, 't', 'd', 'x', 'o', 'z' };
 
 /* Header of the list of root variable objects.  */
 static struct varobj_root *rootlist;
 
 /* Prime number indicating the number of buckets in the hash table.  */
-/* A prime large enough to avoid too many colisions.  */
+/* A prime large enough to avoid too many collisions.  */
 #define VAROBJ_TABLE_SIZE 227
 
 /* Pointer to the varobj hash table (built at run time).  */
@@ -230,7 +219,7 @@ static struct vlist **varobj_table;
 
 /* API Implementation */
 static int
-is_root_p (struct varobj *var)
+is_root_p (const struct varobj *var)
 {
   return (var->root->rootvar == var);
 }
@@ -239,15 +228,13 @@ is_root_p (struct varobj *var)
 /* Helper function to install a Python environment suitable for
    use during operations on VAR.  */
 struct cleanup *
-varobj_ensure_python_env (struct varobj *var)
+varobj_ensure_python_env (const struct varobj *var)
 {
   return ensure_python_env (var->root->exp->gdbarch,
                            var->root->exp->language_defn);
 }
 #endif
 
-/* Creates a varobj (not its children).  */
-
 /* Return the full FRAME which corresponds to the given CORE_ADDR
    or NULL if no FRAME on the chain corresponds to CORE_ADDR.  */
 
@@ -280,9 +267,11 @@ find_frame_addr_in_frame_chain (CORE_ADDR frame_addr)
   return NULL;
 }
 
+/* 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;
@@ -298,7 +287,6 @@ varobj_create (char *objname,
       const struct block *block;
       const char *p;
       struct value *value = NULL;
-      volatile struct gdb_exception except;
       CORE_ADDR pc;
 
       /* Parse and evaluate the expression, filling in as much of the
@@ -338,16 +326,17 @@ varobj_create (char *objname,
       innermost_block = NULL;
       /* Wrap the call to parse expression, so we can 
          return a sensible error.  */
-      TRY_CATCH (except, RETURN_MASK_ERROR)
+      TRY
        {
          var->root->exp = parse_exp_1 (&p, pc, block, 0);
        }
 
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ERROR)
        {
          do_cleanups (old_chain);
          return NULL;
        }
+      END_CATCH
 
       /* Don't allow variables to be created for types.  */
       if (var->root->exp->elts[0].opcode == OP_TYPE
@@ -362,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
@@ -380,7 +369,7 @@ varobj_create (char *objname,
            error (_("Failed to find the specified frame"));
 
          var->root->frame = get_frame_id (fi);
-         var->root->thread_id = pid_to_thread_id (inferior_ptid);
+         var->root->thread_id = ptid_to_global_thread_id (inferior_ptid);
          old_id = get_frame_id (get_selected_frame (NULL));
          select_frame (fi);     
        }
@@ -388,27 +377,28 @@ varobj_create (char *objname,
       /* We definitely need to catch errors here.
          If evaluate_expression succeeds we got the value we wanted.
          But if it fails, we still go on with a call to evaluate_type().  */
-      TRY_CATCH (except, RETURN_MASK_ERROR)
+      TRY
        {
-         value = evaluate_expression (var->root->exp);
+         value = evaluate_expression (var->root->exp.get ());
        }
-
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ERROR)
        {
          /* Error getting the value.  Try to at least get the
             right type.  */
-         struct value *type_only_value = evaluate_type (var->root->exp);
+         struct value *type_only_value = evaluate_type (var->root->exp.get ());
 
          var->type = value_type (type_only_value);
        }
-       else
-         {
-           int real_type_found = 0;
+      END_CATCH
 
-           var->type = value_actual_type (value, 0, &real_type_found);
-           if (real_type_found)
-             value = value_cast (var->type, value);
-         }
+      if (value != NULL)
+       {
+         int real_type_found = 0;
+
+         var->type = value_actual_type (value, 0, &real_type_found);
+         if (real_type_found)
+           value = value_cast (var->type, value);
+       }
 
       /* Set language info */
       var->root->lang_ops = var->root->exp->language_defn->la_varobj_ops;
@@ -428,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.  */
@@ -462,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;
@@ -475,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)
@@ -486,64 +476,27 @@ varobj_get_handle (char *objname)
 
 /* Given the handle, return the name of the object.  */
 
-char *
-varobj_get_objname (struct varobj *var)
+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.  */
+/* Given the handle, return the expression represented by the
+   object.  */
 
-char *
-varobj_get_expression (struct varobj *var)
+std::string
+varobj_get_expression (const struct varobj *var)
 {
   return name_of_variable (var);
 }
 
-/* Deletes a varobj and all its children if only_children == 0,
-   otherwise deletes only the children; returns a malloc'ed list of
-   all the (malloc'ed) names of the variables that have been deleted
-   (NULL terminated).  */
+/* See varobj.h.  */
 
 int
-varobj_delete (struct varobj *var, char ***dellist, int only_children)
+varobj_delete (struct varobj *var, int only_children)
 {
-  int delcount;
-  int mycount;
-  struct cpstack *result = NULL;
-  char **cp;
-
-  /* Initialize a stack for temporary results.  */
-  cppush (&result, NULL);
-
-  if (only_children)
-    /* Delete only the variable children.  */
-    delcount = delete_variable (&result, var, 1 /* only the children */ );
-  else
-    /* Delete the variable and all its children.  */
-    delcount = delete_variable (&result, var, 0 /* parent+children */ );
-
-  /* We may have been asked to return a list of what has been deleted.  */
-  if (dellist != NULL)
-    {
-      *dellist = xmalloc ((delcount + 1) * sizeof (char *));
-
-      cp = *dellist;
-      mycount = delcount;
-      *cp = cppop (&result);
-      while ((*cp != NULL) && (mycount > 0))
-       {
-         mycount--;
-         cp++;
-         *cp = cppop (&result);
-       }
-
-      if (mycount || (*cp != NULL))
-       warning (_("varobj_delete: assertion failed - mycount(=%d) <> 0"),
-                mycount);
-    }
-
-  return delcount;
+  return delete_variable (var, only_children);
 }
 
 #if HAVE_PYTHON
@@ -580,6 +533,7 @@ varobj_set_display_format (struct varobj *var,
     case FORMAT_DECIMAL:
     case FORMAT_HEXADECIMAL:
     case FORMAT_OCTAL:
+    case FORMAT_ZHEXADECIMAL:
       var->format = format;
       break;
 
@@ -590,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);
     }
@@ -599,15 +552,15 @@ varobj_set_display_format (struct varobj *var,
 }
 
 enum varobj_display_formats
-varobj_get_display_format (struct varobj *var)
+varobj_get_display_format (const struct varobj *var)
 {
   return var->format;
 }
 
-char *
-varobj_get_display_hint (struct varobj *var)
+gdb::unique_xmalloc_ptr<char>
+varobj_get_display_hint (const struct varobj *var)
 {
-  char *result = NULL;
+  gdb::unique_xmalloc_ptr<char> result;
 
 #if HAVE_PYTHON
   struct cleanup *back_to;
@@ -629,7 +582,7 @@ varobj_get_display_hint (struct varobj *var)
 /* Return true if the varobj has items after TO, false otherwise.  */
 
 int
-varobj_has_more (struct varobj *var, int to)
+varobj_has_more (const struct varobj *var, int to)
 {
   if (VEC_length (varobj_p, var->children) > to)
     return 1;
@@ -642,7 +595,7 @@ varobj_has_more (struct varobj *var, int to)
    inside that thread, returns GDB id of the thread -- which
    is always positive.  Otherwise, returns -1.  */
 int
-varobj_get_thread_id (struct varobj *var)
+varobj_get_thread_id (const struct varobj *var)
 {
   if (var->root->valid_block && var->root->thread_id > 0)
     return var->root->thread_id;
@@ -664,7 +617,7 @@ varobj_set_frozen (struct varobj *var, int frozen)
 }
 
 int
-varobj_get_frozen (struct varobj *var)
+varobj_get_frozen (const struct varobj *var)
 {
   return var->frozen;
 }
@@ -700,7 +653,7 @@ static void
 install_dynamic_child (struct varobj *var,
                       VEC (varobj_p) **changed,
                       VEC (varobj_p) **type_changed,
-                      VEC (varobj_p) **new,
+                      VEC (varobj_p) **newobj,
                       VEC (varobj_p) **unchanged,
                       int *cchanged,
                       int index,
@@ -711,9 +664,9 @@ install_dynamic_child (struct varobj *var,
       /* There's no child yet.  */
       struct varobj *child = varobj_add_child (var, item);
 
-      if (new)
+      if (newobj)
        {
-         VEC_safe_push (varobj_p, *new, child);
+         VEC_safe_push (varobj_p, *newobj, child);
          *cchanged = 1;
        }
     }
@@ -740,7 +693,7 @@ install_dynamic_child (struct varobj *var,
 #if HAVE_PYTHON
 
 static int
-dynamic_varobj_has_child_method (struct varobj *var)
+dynamic_varobj_has_child_method (const struct varobj *var)
 {
   struct cleanup *back_to;
   PyObject *printer = var->dynamic->pretty_printer;
@@ -788,7 +741,7 @@ static int
 update_dynamic_varobj_children (struct varobj *var,
                                VEC (varobj_p) **changed,
                                VEC (varobj_p) **type_changed,
-                               VEC (varobj_p) **new,
+                               VEC (varobj_p) **newobj,
                                VEC (varobj_p) **unchanged,
                                int *cchanged,
                                int update_children,
@@ -849,7 +802,7 @@ update_dynamic_varobj_children (struct varobj *var,
 
          install_dynamic_child (var, can_mention ? changed : NULL,
                                 can_mention ? type_changed : NULL,
-                                can_mention ? new : NULL,
+                                can_mention ? newobj : NULL,
                                 can_mention ? unchanged : NULL,
                                 can_mention ? cchanged : NULL, i,
                                 item);
@@ -872,7 +825,7 @@ update_dynamic_varobj_children (struct varobj *var,
 
       *cchanged = 1;
       for (j = i; j < VEC_length (varobj_p, var->children); ++j)
-       varobj_delete (VEC_index (varobj_p, var->children, j), NULL, 0);
+       varobj_delete (VEC_index (varobj_p, var->children, j), 0);
       VEC_truncate (varobj_p, var->children, i);
     }
 
@@ -913,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;
@@ -950,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);
        }
@@ -972,16 +924,17 @@ varobj_add_child (struct varobj *var, struct varobj_item *item)
 }
 
 /* Obtain the type of an object Variable as a string similar to the one gdb
-   prints on the console.  */
+   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);
 }
@@ -989,7 +942,7 @@ varobj_get_type (struct varobj *var)
 /* Obtain the type of an object variable.  */
 
 struct type *
-varobj_get_gdb_type (struct varobj *var)
+varobj_get_gdb_type (const struct varobj *var)
 {
   return var->type;
 }
@@ -998,7 +951,7 @@ varobj_get_gdb_type (struct varobj *var)
    a valid path expression?  */
 
 static int
-is_path_expr_parent (struct varobj *var)
+is_path_expr_parent (const struct varobj *var)
 {
   gdb_assert (var->root->lang_ops->is_path_expr_parent != NULL);
   return var->root->lang_ops->is_path_expr_parent (var);
@@ -1009,17 +962,17 @@ is_path_expr_parent (struct varobj *var)
    parent.  */
 
 int
-varobj_default_is_path_expr_parent (struct varobj *var)
+varobj_default_is_path_expr_parent (const struct varobj *var)
 {
   return 1;
 }
 
 /* Return the path expression parent for VAR.  */
 
-struct varobj *
-varobj_get_path_expr_parent (struct varobj *var)
+const struct varobj *
+varobj_get_path_expr_parent (const struct varobj *var)
 {
-  struct varobj *parent = var;
+  const struct varobj *parent = var;
 
   while (!is_root_p (parent) && !is_path_expr_parent (parent))
     parent = parent->parent;
@@ -1029,29 +982,32 @@ varobj_get_path_expr_parent (struct varobj *var)
 
 /* Return a pointer to the full rooted expression of varobj VAR.
    If it has not been computed yet, compute it.  */
-char *
-varobj_get_path_expr (struct varobj *var)
+
+const char *
+varobj_get_path_expr (const struct varobj *var)
 {
-  if (var->path_expr != NULL)
-    return var->path_expr;
-  else 
+  if (var->path_expr.empty ())
     {
       /* For root varobjs, we initialize path_expr
         when creating varobj, so here it should be
         child varobj.  */
+      struct varobj *mutable_var = (struct varobj *) var;
       gdb_assert (!is_root_p (var));
-      return (*var->root->lang_ops->path_expr_of_child) (var);
+
+      mutable_var->path_expr = (*var->root->lang_ops->path_expr_of_child) (var);
     }
+
+  return var->path_expr.c_str ();
 }
 
 const struct language_defn *
-varobj_get_language (struct varobj *var)
+varobj_get_language (const struct varobj *var)
 {
   return var->root->exp->language_defn;
 }
 
 int
-varobj_get_attributes (struct varobj *var)
+varobj_get_attributes (const struct varobj *var)
 {
   int attributes = 0;
 
@@ -1065,19 +1021,19 @@ varobj_get_attributes (struct varobj *var)
 /* Return true if VAR is a dynamic varobj.  */
 
 int
-varobj_is_dynamic_p (struct varobj *var)
+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);
@@ -1088,33 +1044,31 @@ 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.
      We need to first construct a legal expression for this -- ugh!  */
   /* Does this cover all the bases?  */
-  struct expression *exp;
   struct value *value = NULL; /* Initialize to keep gcc happy.  */
   int saved_input_radix = input_radix;
   const char *s = expression;
-  volatile struct gdb_exception except;
 
   gdb_assert (varobj_editable_p (var));
 
   input_radix = 10;            /* ALWAYS reset to decimal temporarily.  */
-  exp = parse_exp_1 (&s, 0, 0, 0);
-  TRY_CATCH (except, RETURN_MASK_ERROR)
+  expression_up exp = parse_exp_1 (&s, 0, 0, 0);
+  TRY
     {
-      value = evaluate_expression (exp);
+      value = evaluate_expression (exp.get ());
     }
 
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ERROR)
     {
       /* We cannot proceed without a valid expression.  */
-      xfree (exp);
       return 0;
     }
+  END_CATCH
 
   /* All types that are editable must also be changeable.  */
   gdb_assert (varobj_value_is_changeable_p (var));
@@ -1133,13 +1087,16 @@ varobj_set_value (struct varobj *var, char *expression)
 
   /* The new value may be lazy.  value_assign, or
      rather value_contents, will take care of this.  */
-  TRY_CATCH (except, RETURN_MASK_ERROR)
+  TRY
     {
       val = value_assign (var->value, value);
     }
 
-  if (except.reason < 0)
-    return 0;
+  CATCH (except, RETURN_MASK_ERROR)
+    {
+      return 0;
+    }
+  END_CATCH
 
   /* If the value has changed, record it, so that next -var-update can
      report this change.  If a variable had a value of '1', we've set it
@@ -1287,18 +1244,17 @@ 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;
+         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);
-         if (strcmp (curr_type_str, new_type_str) != 0)
+         /* Did the type name change?  */
+         if (curr_type_str != new_type_str)
            {
              var->type = new_type;
 
              /* This information may be not valid for a new type.  */
-             varobj_delete (var, NULL, 1);
+             varobj_delete (var, 1);
              VEC_free (varobj_p, var->children);
              var->num_children = -1;
              return 1;
@@ -1329,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)
@@ -1369,7 +1324,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
      will be lazy, which means we've lost that old value.  */
   if (need_to_fetch && value && value_lazy (value))
     {
-      struct varobj *parent = var->parent;
+      const struct varobj *parent = var->parent;
       int frozen = var->frozen;
 
       for (; !frozen && parent; parent = parent->parent)
@@ -1385,20 +1340,20 @@ install_new_value (struct varobj *var, struct value *value, int initial)
        }
       else
        {
-         volatile struct gdb_exception except;
 
-         TRY_CATCH (except, RETURN_MASK_ERROR)
+         TRY
            {
              value_fetch_lazy (value);
            }
 
-         if (except.reason < 0)
+         CATCH (except, RETURN_MASK_ERROR)
            {
              /* Set the value to NULL, so that for the next -var-update,
                 we don't try to compare the new value with this value,
                 that we couldn't even read.  */
              value = NULL;
            }
+         END_CATCH
        }
     }
 
@@ -1411,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);
@@ -1454,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;
            }
        }
@@ -1486,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));
@@ -1509,7 +1462,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
    selected sub-range of VAR.  If no range was selected using
    -var-set-update-range, then both will be -1.  */
 void
-varobj_get_child_range (struct varobj *var, int *from, int *to)
+varobj_get_child_range (const struct varobj *var, int *from, int *to)
 {
   *from = var->from;
   *to = var->to;
@@ -1554,7 +1507,7 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
   Py_XDECREF (constructor);
 
   /* If there are any children now, wipe them.  */
-  varobj_delete (var, NULL, 1 /* children only */);
+  varobj_delete (var, 1 /* children only */);
   var->num_children = -1;
 
   do_cleanups (back_to);
@@ -1571,7 +1524,7 @@ varobj_set_visualizer (struct varobj *var, const char *visualizer)
    NEW_VALUE may be NULL, if the varobj is now out of scope.  */
 
 static int
-varobj_value_has_mutated (struct varobj *var, struct value *new_value,
+varobj_value_has_mutated (const struct varobj *var, struct value *new_value,
                          struct type *new_type)
 {
   /* If we haven't previously computed the number of children in var,
@@ -1612,11 +1565,11 @@ varobj_value_has_mutated (struct varobj *var, struct value *new_value,
    to point to the new varobj.  */
 
 VEC(varobj_update_result) *
-varobj_update (struct varobj **varp, int explicit)
+varobj_update (struct varobj **varp, int is_explicit)
 {
   int type_changed = 0;
   int i;
-  struct value *new;
+  struct value *newobj;
   VEC (varobj_update_result) *stack = NULL;
   VEC (varobj_update_result) *result = NULL;
 
@@ -1625,7 +1578,7 @@ varobj_update (struct varobj **varp, int explicit)
      changing type.  One use case for frozen varobjs is
      retaining previously evaluated expressions, and we don't
      want them to be reevaluated at all.  */
-  if (!explicit && (*varp)->frozen)
+  if (!is_explicit && (*varp)->frozen)
     return result;
 
   if (!(*varp)->root->is_valid)
@@ -1650,15 +1603,15 @@ varobj_update (struct varobj **varp, int explicit)
         the frame in which a local existed.  We are letting the 
         value_of_root variable dispose of the varobj if the type
         has changed.  */
-      new = value_of_root (varp, &type_changed);
-      if (update_type_if_necessary(*varp, new))
+      newobj = value_of_root (varp, &type_changed);
+      if (update_type_if_necessary(*varp, newobj))
          type_changed = 1;
       r.varobj = *varp;
       r.type_changed = type_changed;
-      if (install_new_value ((*varp), new, type_changed))
+      if (install_new_value ((*varp), newobj, type_changed))
        r.changed = 1;
       
-      if (new == NULL)
+      if (newobj == NULL)
        r.status = VAROBJ_NOT_IN_SCOPE;
       r.value_installed = 1;
 
@@ -1693,19 +1646,19 @@ varobj_update (struct varobj **varp, int explicit)
        {
          struct type *new_type;
 
-         new = value_of_child (v->parent, v->index);
-         if (update_type_if_necessary(v, new))
+         newobj = value_of_child (v->parent, v->index);
+         if (update_type_if_necessary(v, newobj))
            r.type_changed = 1;
-         if (new)
-           new_type = value_type (new);
+         if (newobj)
+           new_type = value_type (newobj);
          else
            new_type = v->root->lang_ops->type_of_child (v->parent, v->index);
 
-         if (varobj_value_has_mutated (v, new, new_type))
+         if (varobj_value_has_mutated (v, newobj, new_type))
            {
              /* The children are no longer valid; delete them now.
                 Report the fact that its type changed as well.  */
-             varobj_delete (v, NULL, 1 /* only_children */);
+             varobj_delete (v, 1 /* only_children */);
              v->num_children = -1;
              v->to = -1;
              v->from = -1;
@@ -1713,7 +1666,7 @@ varobj_update (struct varobj **varp, int explicit)
              r.type_changed = 1;
            }
 
-         if (install_new_value (v, new, r.type_changed))
+         if (install_new_value (v, newobj, r.type_changed))
            {
              r.changed = 1;
              v->updated = 0;
@@ -1725,7 +1678,7 @@ varobj_update (struct varobj **varp, int explicit)
       if (varobj_is_dynamic_p (v))
        {
          VEC (varobj_p) *changed = 0, *type_changed = 0, *unchanged = 0;
-         VEC (varobj_p) *new = 0;
+         VEC (varobj_p) *newobj = 0;
          int i, children_changed = 0;
 
          if (v->frozen)
@@ -1757,14 +1710,14 @@ varobj_update (struct varobj **varp, int explicit)
 
          /* If update_dynamic_varobj_children returns 0, then we have
             a non-conforming pretty-printer, so we skip it.  */
-         if (update_dynamic_varobj_children (v, &changed, &type_changed, &new,
+         if (update_dynamic_varobj_children (v, &changed, &type_changed, &newobj,
                                              &unchanged, &children_changed, 1,
                                              v->from, v->to))
            {
-             if (children_changed || new)
+             if (children_changed || newobj)
                {
                  r.children_changed = 1;
-                 r.new = new;
+                 r.newobj = newobj;
                }
              /* Push in reverse order so that the first child is
                 popped from the work stack first, and so will be
@@ -1853,13 +1806,12 @@ varobj_update (struct varobj **varp, int explicit)
  */
 
 static int
-delete_variable (struct cpstack **resultp, struct varobj *var,
-                int only_children_p)
+delete_variable (struct varobj *var, int only_children_p)
 {
   int delcount = 0;
 
-  delete_variable_1 (resultp, &delcount, var,
-                    only_children_p, 1 /* remove_from_parent_p */ );
+  delete_variable_1 (&delcount, var, only_children_p,
+                    1 /* remove_from_parent_p */ );
 
   return delcount;
 }
@@ -1869,8 +1821,7 @@ delete_variable (struct cpstack **resultp, struct varobj *var,
    and the parent is not removed we dump core.  It must be always
    initially called with remove_from_parent_p set.  */
 static void
-delete_variable_1 (struct cpstack **resultp, int *delcountp,
-                  struct varobj *var, int only_children_p,
+delete_variable_1 (int *delcountp, struct varobj *var, int only_children_p,
                   int remove_from_parent_p)
 {
   int i;
@@ -1884,7 +1835,7 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp,
        continue;
       if (!remove_from_parent_p)
        child->parent = NULL;
-      delete_variable_1 (resultp, delcountp, child, 0, only_children_p);
+      delete_variable_1 (delcountp, child, 0, only_children_p);
     }
   VEC_free (varobj_p, var->children);
 
@@ -1893,11 +1844,10 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp,
     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 ())
     {
-      cppush (resultp, xstrdup (var->obj_name));
       *delcountp = *delcountp + 1;
     }
 
@@ -1911,7 +1861,7 @@ delete_variable_1 (struct cpstack **resultp, int *delcountp,
       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.  */
@@ -1928,20 +1878,20 @@ 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)
     error (_("Duplicate variable object name"));
 
   /* Add varobj to hash table.  */
-  newvl = xmalloc (sizeof (struct vlist));
+  newvl = XNEW (struct vlist);
   newvl->next = *(varobj_table + index);
   newvl->var = var;
   *(varobj_table + index) = newvl;
@@ -1973,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;
     }
 
@@ -2023,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)
@@ -2035,13 +1985,16 @@ uninstall_variable (struct varobj *var)
 
 }
 
-/* Create and install a child of the parent of the given name.  */
+/* Create and install a child of the parent of the given name.
+
+   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);
@@ -2052,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);
 
@@ -2096,24 +2050,19 @@ new_variable (void)
 {
   struct varobj *var;
 
-  var = (struct varobj *) xmalloc (sizeof (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;
   var->num_children = -1;
   var->parent = NULL;
   var->children = NULL;
-  var->format = 0;
+  var->format = FORMAT_NATURAL;
   var->root = NULL;
   var->updated = 0;
-  var->print_value = NULL;
   var->frozen = 0;
   var->not_fetched = 0;
-  var->dynamic
-    = (struct varobj_dynamic *) xmalloc (sizeof (struct varobj_dynamic));
+  var->dynamic = XNEW (struct varobj_dynamic);
   var->dynamic->children_requested = 0;
   var->from = -1;
   var->to = -1;
@@ -2131,7 +2080,7 @@ new_root_variable (void)
 {
   struct varobj *var = new_variable ();
 
-  var->root = (struct varobj_root *) xmalloc (sizeof (struct varobj_root));
+  var->root = new varobj_root ();
   var->root->lang_ops = NULL;
   var->root->exp = NULL;
   var->root->valid_block = NULL;
@@ -2162,25 +2111,17 @@ free_variable (struct varobj *var)
   varobj_clear_saved_item (var->dynamic);
   value_free (var->value);
 
-  /* Free the expression if this is a root variable.  */
   if (is_root_p (var))
-    {
-      xfree (var->root->exp);
-      xfree (var->root);
-    }
+    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
 do_free_variable_cleanup (void *var)
 {
-  free_variable (var);
+  free_variable ((struct varobj *) var);
 }
 
 static struct cleanup *
@@ -2201,7 +2142,7 @@ make_cleanup_free_variable (struct varobj *var)
 
    For example, top-level references are always stripped.  */
 struct type *
-varobj_get_value_type (struct varobj *var)
+varobj_get_value_type (const struct varobj *var)
 {
   struct type *type;
 
@@ -2228,36 +2169,6 @@ variable_default_display (struct varobj *var)
   return FORMAT_NATURAL;
 }
 
-/* FIXME: The following should be generic for any pointer.  */
-static void
-cppush (struct cpstack **pstack, char *name)
-{
-  struct cpstack *s;
-
-  s = (struct cpstack *) xmalloc (sizeof (struct cpstack));
-  s->name = name;
-  s->next = *pstack;
-  *pstack = s;
-}
-
-/* FIXME: The following should be generic for any pointer.  */
-static char *
-cppop (struct cpstack **pstack)
-{
-  struct cpstack *s;
-  char *v;
-
-  if ((*pstack)->name == NULL && (*pstack)->next == NULL)
-    return NULL;
-
-  s = *pstack;
-  v = s->name;
-  *pstack = (*pstack)->next;
-  xfree (s);
-
-  return v;
-}
-\f
 /*
  * Language-dependencies
  */
@@ -2270,22 +2181,22 @@ cppop (struct cpstack **pstack)
    is the number of children that the user will see in the variable
    display.  */
 static int
-number_of_children (struct varobj *var)
+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 *
-name_of_variable (struct varobj *var)
+/* 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);
@@ -2295,7 +2206,7 @@ name_of_child (struct varobj *var, int index)
    to it and return 1.  Otherwise, return 0.  */
 
 static int
-check_scope (struct varobj *var)
+check_scope (const struct varobj *var)
 {
   struct frame_info *fi;
   int scope;
@@ -2346,8 +2257,9 @@ value_of_root_1 (struct varobj **var_handle)
     }
   else
     {
-      ptid_t ptid = thread_id_to_pid (var->root->thread_id);
-      if (in_thread_list (ptid))
+      ptid_t ptid = global_thread_id_to_ptid (var->root->thread_id);
+
+      if (!ptid_equal (minus_one_ptid, ptid))
        {
          switch_to_thread (ptid);
          within_scope = check_scope (var);
@@ -2356,14 +2268,17 @@ value_of_root_1 (struct varobj **var_handle)
 
   if (within_scope)
     {
-      volatile struct gdb_exception except;
 
       /* We need to catch errors here, because if evaluate
          expression fails we want to just return NULL.  */
-      TRY_CATCH (except, RETURN_MASK_ERROR)
+      TRY
        {
-         new_val = evaluate_expression (var->root->exp);
+         new_val = evaluate_expression (var->root->exp.get ());
        }
+      CATCH (except, RETURN_MASK_ERROR)
+       {
+       }
+      END_CATCH
     }
 
   do_cleanups (back_to);
@@ -2399,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
@@ -2417,28 +2331,23 @@ value_of_root (struct varobj **var_handle, int *type_changed)
             button, for example).  Naturally, those locations are not
             correct in other frames, so update the expression.  */
 
-         struct expression *tmp_exp = var->root->exp;
-
-         var->root->exp = tmp_var->root->exp;
-         tmp_var->root->exp = tmp_exp;
+         std::swap (var->root->exp, tmp_var->root->exp);
 
-         varobj_delete (tmp_var, NULL, 0);
+         varobj_delete (tmp_var, 0);
          *type_changed = 0;
        }
       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, NULL, 0);
+         varobj_delete (var, 0);
 
          install_variable (tmp_var);
          *var_handle = tmp_var;
          var = *var_handle;
          *type_changed = 1;
        }
-      xfree (old_type);
-      xfree (new_type);
     }
   else
     {
@@ -2459,7 +2368,7 @@ value_of_root (struct varobj **var_handle, int *type_changed)
        /* The type has mutated, so the children are no longer valid.
           Just delete them, and tell our caller that the type has
           changed.  */
-       varobj_delete (var, NULL, 1 /* only_children */);
+       varobj_delete (var, 1 /* only_children */);
        var->num_children = -1;
        var->to = -1;
        var->from = -1;
@@ -2471,7 +2380,7 @@ value_of_root (struct varobj **var_handle, int *type_changed)
 
 /* What is the ``struct value *'' for the INDEX'th child of PARENT?  */
 static struct value *
-value_of_child (struct varobj *parent, int index)
+value_of_child (const struct varobj *parent, int index)
 {
   struct value *value;
 
@@ -2481,7 +2390,7 @@ value_of_child (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)
@@ -2491,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
@@ -2503,30 +2412,29 @@ 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,
-                             struct varobj *var)
+                             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;
   char *encoding = NULL;
-  struct gdbarch *gdbarch = NULL;
   /* Initialize it just to avoid a GCC false warning.  */
   CORE_ADDR str_addr = 0;
   int string_print = 0;
 
   if (value == NULL)
-    return NULL;
+    return std::string ();
 
   stb = mem_fileopen ();
   old_chain = make_cleanup_ui_file_delete (stb);
 
-  gdbarch = get_type_arch (value_type (value));
+  std::string thevalue;
+
 #if HAVE_PYTHON
   if (gdb_python_initialized)
     {
@@ -2576,32 +2484,31 @@ varobj_value_get_print_value (struct value *value,
                         string_print.  Otherwise just return the extracted
                         string as a value.  */
 
-                     char *s = python_string_to_target_string (output);
+                     gdb::unique_xmalloc_ptr<char> s
+                       = python_string_to_target_string (output);
 
                      if (s)
                        {
-                         char *hint;
+                         struct gdbarch *gdbarch;
 
-                         hint = gdbpy_get_display_hint (value_formatter);
+                         gdb::unique_xmalloc_ptr<char> hint
+                           = gdbpy_get_display_hint (value_formatter);
                          if (hint)
                            {
-                             if (!strcmp (hint, "string"))
+                             if (!strcmp (hint.get (), "string"))
                                string_print = 1;
-                             xfree (hint);
                            }
 
-                         len = strlen (s);
-                         thevalue = xmemdup (s, len + 1, len + 1);
+                         thevalue = std::string (s.get ());
+                         len = thevalue.size ();
+                         gdbarch = get_type_arch (value_type (value));
                          type = builtin_type (gdbarch)->builtin_char;
-                         xfree (s);
 
                          if (!string_print)
                            {
                              do_cleanups (old_chain);
                              return thevalue;
                            }
-
-                         make_cleanup (xfree, thevalue);
                        }
                      else
                        gdbpy_print_stack ();
@@ -2620,8 +2527,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.  */
@@ -2630,14 +2538,14 @@ 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;
 }
 
 int
-varobj_editable_p (struct varobj *var)
+varobj_editable_p (const struct varobj *var)
 {
   struct type *type;
 
@@ -2665,7 +2573,7 @@ varobj_editable_p (struct varobj *var)
 /* Call VAR's value_is_changeable_p language-specific callback.  */
 
 int
-varobj_value_is_changeable_p (struct varobj *var)
+varobj_value_is_changeable_p (const struct varobj *var)
 {
   return var->root->lang_ops->value_is_changeable_p (var);
 }
@@ -2674,7 +2582,7 @@ varobj_value_is_changeable_p (struct varobj *var)
    selected frame, and not bound to thread/frame.  Such variable objects
    are created using '@' as frame specifier to -var-create.  */
 int
-varobj_floating_p (struct varobj *var)
+varobj_floating_p (const struct varobj *var)
 {
   return var->root->floating;
 }
@@ -2683,7 +2591,7 @@ varobj_floating_p (struct varobj *var)
    languages.  */
 
 int
-varobj_default_value_is_changeable_p (struct varobj *var)
+varobj_default_value_is_changeable_p (const struct varobj *var)
 {
   int r;
   struct type *type;
@@ -2743,12 +2651,12 @@ 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);
-         varobj_delete (var, NULL, 0);
+         tmp_var->obj_name = var->obj_name;
+         varobj_delete (var, 0);
          install_variable (tmp_var);
        }
       else
@@ -2772,10 +2680,7 @@ extern void _initialize_varobj (void);
 void
 _initialize_varobj (void)
 {
-  int sizeof_table = sizeof (struct vlist *) * VAROBJ_TABLE_SIZE;
-
-  varobj_table = xmalloc (sizeof_table);
-  memset (varobj_table, 0, sizeof_table);
+  varobj_table = XCNEWVEC (struct vlist *, VAROBJ_TABLE_SIZE);
 
   add_setshow_zuinteger_cmd ("varobj", class_maintenance,
                             &varobjdebug,
This page took 0.047208 seconds and 4 git commands to generate.