Don't edit bogus sh_link on reading relocatable objects (Oracle fix)
[binutils-gdb.git] / gdb / varobj.c
index 758753f178c8bc887ff61f74c3f90c94d195360b..c448fc82d75b04a144c3757a63415b596cdb0370 100644 (file)
@@ -1,6 +1,6 @@
 /* Implementation of the GDB variable objects API.
 
-   Copyright (C) 1999-2020 Free Software Foundation, Inc.
+   Copyright (C) 1999-2021 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
@@ -31,6 +31,7 @@
 #include "varobj-iter.h"
 #include "parser-defs.h"
 #include "gdbarch.h"
+#include <algorithm>
 
 #if HAVE_PYTHON
 #include "python/python.h"
@@ -100,9 +101,6 @@ struct varobj_root
 
   /* The varobj for this root node.  */
   struct varobj *rootvar = NULL;
-
-  /* Next root variable */
-  struct varobj_root *next = NULL;
 };
 
 /* Dynamic part of varobj.  */
@@ -126,22 +124,14 @@ struct varobj_dynamic
 
   /* The iterator returned by the printer's 'children' method, or NULL
      if not available.  */
-  struct varobj_iter *child_iter = NULL;
+  std::unique_ptr<varobj_iter> child_iter;
 
   /* We request one extra item from the iterator, so that we can
      report to the caller whether there are more items than we have
      already reported.  However, we don't want to install this value
      when we read it, because that will mess up future updates.  So,
      we stash it here instead.  */
-  varobj_item *saved_item = NULL;
-};
-
-/* A list of varobjs */
-
-struct vlist
-{
-  struct varobj *var;
-  struct vlist *next;
+  std::unique_ptr<varobj_item> saved_item;
 };
 
 /* Private function prototypes */
@@ -152,7 +142,7 @@ static int delete_variable (struct varobj *, bool);
 
 static void delete_variable_1 (int *, struct varobj *, bool, bool);
 
-static bool install_variable (struct varobj *);
+static void install_variable (struct varobj *);
 
 static void uninstall_variable (struct varobj *);
 
@@ -197,8 +187,8 @@ static struct varobj *varobj_add_child (struct varobj *var,
 /* Mappings of varobj_display_formats enums to gdb's format codes.  */
 static int format_code[] = { 0, 't', 'd', 'x', 'o', 'z' };
 
-/* Header of the list of root variable objects.  */
-static struct varobj_root *rootlist;
+/* List of root variable objects.  */
+static std::list<struct varobj_root *> rootlist;
 
 /* Pointer to the varobj hash table (built at run time).  */
 static htab_t varobj_table;
@@ -321,9 +311,10 @@ varobj_create (const char *objname,
        }
 
       /* Don't allow variables to be created for types.  */
-      if (var->root->exp->elts[0].opcode == OP_TYPE
-         || var->root->exp->elts[0].opcode == OP_TYPEOF
-         || var->root->exp->elts[0].opcode == OP_DECLTYPE)
+      enum exp_opcode opcode = var->root->exp->first_opcode ();
+      if (opcode == OP_TYPE
+         || opcode == OP_TYPEOF
+         || opcode == OP_DECLTYPE)
        {
          fprintf_unfiltered (gdb_stderr, "Attempt to use a type name"
                              " as an expression.\n");
@@ -400,11 +391,7 @@ varobj_create (const char *objname,
   if ((var != NULL) && (objname != NULL))
     {
       var->obj_name = objname;
-
-      /* If a varobj name is duplicated, the install will fail so
-        we must cleanup.  */
-      if (!install_variable (var.get ()))
-       return NULL;
+      install_variable (var.get ());
     }
 
   return var.release ();
@@ -469,16 +456,11 @@ varobj_delete (struct varobj *var, bool only_children)
 static PyObject *
 instantiate_pretty_printer (PyObject *constructor, struct value *value)
 {
-  PyObject *val_obj = NULL; 
-  PyObject *printer;
-
-  val_obj = value_to_value_object (value);
-  if (! val_obj)
+  gdbpy_ref<> val_obj (value_to_value_object (value));
+  if (val_obj == nullptr)
     return NULL;
 
-  printer = PyObject_CallFunctionObjArgs (constructor, val_obj, NULL);
-  Py_DECREF (val_obj);
-  return printer;
+  return PyObject_CallFunctionObjArgs (constructor, val_obj.get (), NULL);
 }
 
 #endif
@@ -635,14 +617,15 @@ install_dynamic_child (struct varobj *var,
   else
     {
       varobj *existing = var->children[index];
-      bool type_updated = update_type_if_necessary (existing, item->value);
+      bool type_updated = update_type_if_necessary (existing,
+                                                   item->value.get ());
 
       if (type_updated)
        {
          if (type_changed != NULL)
            type_changed->push_back (existing);
        }
-      if (install_new_value (existing, item->value, 0))
+      if (install_new_value (existing, item->value.get (), 0))
        {
          if (!type_updated && changed != NULL)
            changed->push_back (existing);
@@ -670,7 +653,7 @@ dynamic_varobj_has_child_method (const struct varobj *var)
 /* A factory for creating dynamic varobj's iterators.  Returns an
    iterator object suitable for iterating over VAR's children.  */
 
-static struct varobj_iter *
+static std::unique_ptr<varobj_iter>
 varobj_get_iterator (struct varobj *var)
 {
 #if HAVE_PYTHON
@@ -678,21 +661,7 @@ varobj_get_iterator (struct varobj *var)
     return py_varobj_get_iterator (var, var->dynamic->pretty_printer);
 #endif
 
-  gdb_assert_not_reached (_("\
-requested an iterator from a non-dynamic varobj"));
-}
-
-/* Release and clear VAR's saved item, if any.  */
-
-static void
-varobj_clear_saved_item (struct varobj_dynamic *var)
-{
-  if (var->saved_item != NULL)
-    {
-      value_decref (var->saved_item->value);
-      delete var->saved_item;
-      var->saved_item = NULL;
-    }
+  gdb_assert_not_reached ("requested an iterator from a non-dynamic varobj");
 }
 
 static bool
@@ -712,10 +681,8 @@ update_dynamic_varobj_children (struct varobj *var,
 
   if (update_children || var->dynamic->child_iter == NULL)
     {
-      varobj_iter_delete (var->dynamic->child_iter);
       var->dynamic->child_iter = varobj_get_iterator (var);
-
-      varobj_clear_saved_item (var->dynamic);
+      var->dynamic->saved_item.reset (nullptr);
 
       i = 0;
 
@@ -729,28 +696,18 @@ update_dynamic_varobj_children (struct varobj *var,
      are more children.  */
   for (; to < 0 || i < to + 1; ++i)
     {
-      varobj_item *item;
+      std::unique_ptr<varobj_item> item;
 
       /* See if there was a leftover from last time.  */
       if (var->dynamic->saved_item != NULL)
-       {
-         item = var->dynamic->saved_item;
-         var->dynamic->saved_item = NULL;
-       }
+       item = std::move (var->dynamic->saved_item);
       else
-       {
-         item = varobj_iter_next (var->dynamic->child_iter);
-         /* Release vitem->value so its lifetime is not bound to the
-            execution of a command.  */
-         if (item != NULL && item->value != NULL)
-           item->value = release_value (item->value).release ();
-       }
+       item = var->dynamic->child_iter->next ();
 
       if (item == NULL)
        {
          /* Iteration is done.  Remove iterator from VAR.  */
-         varobj_iter_delete (var->dynamic->child_iter);
-         var->dynamic->child_iter = NULL;
+         var->dynamic->child_iter.reset (nullptr);
          break;
        }
       /* We don't want to push the extra child on any report list.  */
@@ -763,13 +720,11 @@ update_dynamic_varobj_children (struct varobj *var,
                                 can_mention ? newobj : NULL,
                                 can_mention ? unchanged : NULL,
                                 can_mention ? cchanged : NULL, i,
-                                item);
-
-         delete item;
+                                item.get ());
        }
       else
        {
-         var->dynamic->saved_item = item;
+         var->dynamic->saved_item = std::move (item);
 
          /* We want to truncate the child list just before this
             element.  */
@@ -1080,8 +1035,7 @@ install_visualizer (struct varobj_dynamic *var, PyObject *constructor,
   Py_XDECREF (var->pretty_printer);
   var->pretty_printer = visualizer;
 
-  varobj_iter_delete (var->child_iter);
-  var->child_iter = NULL;
+  var->child_iter.reset (nullptr);
 }
 
 /* Install the default visualizer for VAR.  */
@@ -1775,7 +1729,7 @@ delete_variable_1 (int *delcountp, struct varobj *var, bool only_children_p,
 }
 
 /* Install the given variable VAR with the object name VAR->OBJ_NAME.  */
-static bool
+static void
 install_variable (struct varobj *var)
 {
   hashval_t hash = htab_hash_string (var->obj_name.c_str ());
@@ -1790,25 +1744,13 @@ install_variable (struct varobj *var)
 
   /* If root, add varobj to root list.  */
   if (is_root_p (var))
-    {
-      /* Add to list of root variables.  */
-      if (rootlist == NULL)
-       var->root->next = NULL;
-      else
-       var->root->next = rootlist;
-      rootlist = var->root;
-    }
-
-  return true;                 /* OK */
+    rootlist.push_front (var->root);
 }
 
 /* Uninstall the object VAR.  */
 static void
 uninstall_variable (struct varobj *var)
 {
-  struct varobj_root *cr;
-  struct varobj_root *prer;
-
   hashval_t hash = htab_hash_string (var->obj_name.c_str ());
   htab_remove_elt_with_hash (varobj_table, var->obj_name.c_str (), hash);
 
@@ -1818,32 +1760,9 @@ uninstall_variable (struct varobj *var)
   /* If root, remove varobj from root list.  */
   if (is_root_p (var))
     {
-      /* Remove from list of root variables.  */
-      if (rootlist == var->root)
-       rootlist = var->root->next;
-      else
-       {
-         prer = NULL;
-         cr = rootlist;
-         while ((cr != NULL) && (cr->rootvar != var))
-           {
-             prer = cr;
-             cr = cr->next;
-           }
-         if (cr == NULL)
-           {
-             warning (_("Assertion failed: Could not find "
-                        "varobj \"%s\" in root list"),
-                      var->obj_name.c_str ());
-             return;
-           }
-         if (prer == NULL)
-           rootlist = NULL;
-         else
-           prer->next = cr->next;
-       }
+      auto iter = std::find (rootlist.begin (), rootlist.end (), var->root);
+      rootlist.erase (iter);
     }
-
 }
 
 /* Create and install a child of the parent of the given name.
@@ -1856,7 +1775,7 @@ create_child (struct varobj *parent, int index, std::string &name)
   struct varobj_item item;
 
   std::swap (item.name, name);
-  item.value = value_of_child (parent, index);
+  item.value = release_value (value_of_child (parent, index));
 
   return create_child_with_value (parent, index, &item);
 }
@@ -1887,12 +1806,12 @@ create_child_with_value (struct varobj *parent, int index,
   if (item->value != NULL)
     /* If the child had no evaluation errors, var->value
        will be non-NULL and contain a valid type.  */
-    child->type = value_actual_type (item->value, 0, NULL);
+    child->type = value_actual_type (item->value.get (), 0, NULL);
   else
     /* Otherwise, we must compute the type.  */
     child->type = (*child->root->lang_ops->type_of_child) (child->parent,
                                                           child->index);
-  install_new_value (child, item->value, 1);
+  install_new_value (child, item->value.get (), 1);
 
   return child;
 }
@@ -1924,13 +1843,12 @@ varobj::~varobj ()
     }
 #endif
 
-  varobj_iter_delete (var->dynamic->child_iter);
-  varobj_clear_saved_item (var->dynamic);
+  /* This must be deleted before the root object, because Python-based
+     destructors need access to some components.  */
+  delete var->dynamic;
 
   if (is_root_p (var))
     delete var->root;
-
-  delete var->dynamic;
 }
 
 /* Return the type of the value that's stored in VAR,
@@ -2290,7 +2208,7 @@ varobj_value_get_print_value (struct value *value,
 
                          thevalue = std::string (s.get ());
                          len = thevalue.size ();
-                         gdbarch = get_type_arch (value_type (value));
+                         gdbarch = value_type (value)->arch ();
                          type = builtin_type (gdbarch)->builtin_char;
 
                          if (!string_print)
@@ -2400,21 +2318,19 @@ varobj_default_value_is_changeable_p (const struct varobj *var)
   return r;
 }
 
-/* Iterate all the existing _root_ VAROBJs and call the FUNC callback for them
-   with an arbitrary caller supplied DATA pointer.  */
+/* Iterate all the existing _root_ VAROBJs and call the FUNC callback
+   for each one.  */
 
 void
-all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
+all_root_varobjs (gdb::function_view<void (struct varobj *var)> func)
 {
-  struct varobj_root *var_root, *var_root_next;
-
   /* Iterate "safely" - handle if the callee deletes its passed VAROBJ.  */
-
-  for (var_root = rootlist; var_root != NULL; var_root = var_root_next)
+  auto iter = rootlist.begin ();
+  auto end = rootlist.end ();
+  while (iter != end)
     {
-      var_root_next = var_root->next;
-
-      (*func) (var_root->rootvar, data);
+      auto self = iter++;
+      func ((*self)->rootvar);
     }
 }
 
@@ -2426,7 +2342,7 @@ all_root_varobjs (void (*func) (struct varobj *var, void *data), void *data)
    varobj must be either re-evaluated, or marked as invalid here.  */
 
 static void
-varobj_invalidate_iter (struct varobj *var, void *unused)
+varobj_invalidate_iter (struct varobj *var)
 {
   /* global and floating var must be re-evaluated.  */
   if (var->root->floating || var->root->valid_block == NULL)
@@ -2457,7 +2373,7 @@ varobj_invalidate_iter (struct varobj *var, void *unused)
 void 
 varobj_invalidate (void)
 {
-  all_root_varobjs (varobj_invalidate_iter, NULL);
+  all_root_varobjs (varobj_invalidate_iter);
 }
 
 /* A hash function for a varobj.  */