Use unique_xmalloc_ptr in Python code
[deliverable/binutils-gdb.git] / gdb / python / py-value.c
index a1a7a1dd3c755088b2bcb0c7d29a0caa9fc3d33d..b959f2e10dd17a5042cdee3b63ab3677b56bfc17 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to values.
 
-   Copyright (C) 2008-2014 Free Software Foundation, Inc.
+   Copyright (C) 2008-2016 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -172,10 +172,9 @@ gdbpy_preserve_values (const struct extension_language_defn *extlang,
 static PyObject *
 valpy_dereference (PyObject *self, PyObject *args)
 {
-  volatile struct gdb_exception except;
   PyObject *result = NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct value *res_val;
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
@@ -184,7 +183,11 @@ valpy_dereference (PyObject *self, PyObject *args)
       result = value_to_value_object (res_val);
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return result;
 }
@@ -200,10 +203,9 @@ valpy_dereference (PyObject *self, PyObject *args)
 static PyObject *
 valpy_referenced_value (PyObject *self, PyObject *args)
 {
-  volatile struct gdb_exception except;
   PyObject *result = NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct value *self_val, *res_val;
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
@@ -225,7 +227,64 @@ valpy_referenced_value (PyObject *self, PyObject *args)
       result = value_to_value_object (res_val);
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  return result;
+}
+
+/* Return a value which is a reference to the value.  */
+
+static PyObject *
+valpy_reference_value (PyObject *self, PyObject *args)
+{
+  PyObject *result = NULL;
+
+  TRY
+    {
+      struct value *self_val;
+      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+
+      self_val = ((value_object *) self)->value;
+      result = value_to_value_object (value_ref (self_val));
+
+      do_cleanups (cleanup);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  return result;
+}
+
+/* Return a "const" qualified version of the value.  */
+
+static PyObject *
+valpy_const_value (PyObject *self, PyObject *args)
+{
+  PyObject *result = NULL;
+
+  TRY
+    {
+      struct value *self_val, *res_val;
+      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+
+      self_val = ((value_object *) self)->value;
+      res_val = make_cv_value (1, 0, self_val);
+      result = value_to_value_object (res_val);
+
+      do_cleanups (cleanup);
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return result;
 }
@@ -235,11 +294,10 @@ static PyObject *
 valpy_get_address (PyObject *self, void *closure)
 {
   value_object *val_obj = (value_object *) self;
-  volatile struct gdb_exception except;
 
   if (!val_obj->address)
     {
-      TRY_CATCH (except, RETURN_MASK_ALL)
+      TRY
        {
          struct value *res_val;
          struct cleanup *cleanup
@@ -249,11 +307,12 @@ valpy_get_address (PyObject *self, void *closure)
          val_obj->address = value_to_value_object (res_val);
          do_cleanups (cleanup);
        }
-      if (except.reason < 0)
+      CATCH (except, RETURN_MASK_ALL)
        {
          val_obj->address = Py_None;
          Py_INCREF (Py_None);
        }
+      END_CATCH
     }
 
   Py_XINCREF (val_obj->address);
@@ -283,7 +342,6 @@ static PyObject *
 valpy_get_dynamic_type (PyObject *self, void *closure)
 {
   value_object *obj = (value_object *) self;
-  volatile struct gdb_exception except;
   struct type *type = NULL;
 
   if (obj->dynamic_type != NULL)
@@ -292,13 +350,13 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
       return obj->dynamic_type;
     }
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct value *val = obj->value;
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
       type = value_type (val);
-      CHECK_TYPEDEF (type);
+      type = check_typedef (type);
 
       if (((TYPE_CODE (type) == TYPE_CODE_PTR)
           || (TYPE_CODE (type) == TYPE_CODE_REF))
@@ -331,7 +389,11 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
 
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   if (type == NULL)
     obj->dynamic_type = valpy_get_type (self, NULL);
@@ -358,13 +420,12 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
   const char *user_encoding = NULL;
   static char *keywords[] = { "encoding", "length", NULL };
   PyObject *str_obj = NULL;
-  volatile struct gdb_exception except;
 
   if (!PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, keywords,
                                    &user_encoding, &length))
     return NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
@@ -377,7 +438,11 @@ valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
 
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return str_obj;
 }
@@ -394,7 +459,6 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
   int length = -1;
   gdb_byte *buffer;
   struct value *value = ((value_object *) self)->value;
-  volatile struct gdb_exception except;
   PyObject *unicode;
   const char *encoding = NULL;
   const char *errors = NULL;
@@ -407,11 +471,15 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
                                    &user_encoding, &errors, &length))
     return NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       LA_GET_STRING (value, &buffer, &length, &char_type, &la_encoding);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
   unicode = PyUnicode_Decode ((const char *) buffer,
@@ -429,7 +497,6 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
 {
   PyObject *type_obj, *result = NULL;
   struct type *type;
-  volatile struct gdb_exception except;
 
   if (! PyArg_ParseTuple (args, "O", &type_obj))
     return NULL;
@@ -442,7 +509,7 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
       return NULL;
     }
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct value *val = ((value_object *) self)->value;
       struct value *res_val;
@@ -461,7 +528,11 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
       result = value_to_value_object (res_val);
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return result;
 }
@@ -508,7 +579,6 @@ value_has_field (struct value *v, PyObject *field)
   struct type *parent_type, *val_type;
   enum type_code type_code;
   PyObject *type_object = PyObject_GetAttrString (field, "parent_type");
-  volatile struct gdb_exception except;
   int has_field = 0;
 
   if (type_object == NULL)
@@ -524,7 +594,7 @@ value_has_field (struct value *v, PyObject *field)
       return -1;
     }
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       val_type = value_type (v);
       val_type = check_typedef (val_type);
@@ -539,7 +609,11 @@ value_has_field (struct value *v, PyObject *field)
       else
        has_field = 0;
     }
-  GDB_PY_SET_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_SET_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return has_field;
 }
@@ -591,11 +665,11 @@ get_field_type (PyObject *field)
 static PyObject *
 valpy_getitem (PyObject *self, PyObject *key)
 {
+  struct gdb_exception except = exception_none;
   value_object *self_value = (value_object *) self;
-  char *field = NULL;
+  gdb::unique_xmalloc_ptr<char> field;
   struct type *base_class_type = NULL, *field_type = NULL;
   long bitpos = -1;
-  volatile struct gdb_exception except;
   PyObject *result = NULL;
 
   if (gdbpy_is_string (key))
@@ -673,14 +747,15 @@ valpy_getitem (PyObject *self, PyObject *key)
        }
     }
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct value *tmp = self_value->value;
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
       struct value *res_val = NULL;
 
       if (field)
-       res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
+       res_val = value_struct_elt (&tmp, NULL, field.get (), NULL,
+                                   "struct/class/union");
       else if (bitpos >= 0)
        res_val = value_struct_elt_bitpos (&tmp, bitpos, field_type,
                                           "struct/class/union");
@@ -723,8 +798,12 @@ valpy_getitem (PyObject *self, PyObject *key)
        result = value_to_value_object (res_val);
       do_cleanups (cleanup);
     }
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      except = ex;
+    }
+  END_CATCH
 
-  xfree (field);
   GDB_PY_HANDLE_EXCEPTION (except);
 
   return result;
@@ -744,18 +823,21 @@ static PyObject *
 valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
 {
   Py_ssize_t args_count;
-  volatile struct gdb_exception except;
   struct value *function = ((value_object *) self)->value;
   struct value **vargs = NULL;
   struct type *ftype = NULL;
   struct value *mark = value_mark ();
   PyObject *result = NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       ftype = check_typedef (value_type (function));
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   if (TYPE_CODE (ftype) != TYPE_CODE_FUNC)
     {
@@ -776,7 +858,7 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
     {
       int i;
 
-      vargs = alloca (sizeof (struct value *) * args_count);
+      vargs = XALLOCAVEC (struct value *, args_count);
       for (i = 0; i < args_count; i++)
        {
          PyObject *item = PyTuple_GetItem (args, i);
@@ -790,7 +872,7 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
        }
     }
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark);
       struct value *return_value;
@@ -799,7 +881,11 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
       result = value_to_value_object (return_value);
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return result;
 }
@@ -809,29 +895,31 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
 static PyObject *
 valpy_str (PyObject *self)
 {
-  char *s = NULL;
+  std::string s;
   PyObject *result;
   struct value_print_options opts;
-  volatile struct gdb_exception except;
 
   get_user_print_options (&opts);
   opts.deref_ref = 0;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct ui_file *stb = mem_fileopen ();
       struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
 
       common_val_print (((value_object *) self)->value, stb, 0,
                        &opts, python_language);
-      s = ui_file_xstrdup (stb, NULL);
+      s = ui_file_as_string (stb);
 
       do_cleanups (old_chain);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
-  result = PyUnicode_Decode (s, strlen (s), host_charset (), NULL);
-  xfree (s);
+  result = PyUnicode_Decode (s.c_str (), s.length (), host_charset (), NULL);
 
   return result;
 }
@@ -842,13 +930,16 @@ valpy_get_is_optimized_out (PyObject *self, void *closure)
 {
   struct value *value = ((value_object *) self)->value;
   int opt = 0;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       opt = value_optimized_out (value);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   if (opt)
     Py_RETURN_TRUE;
@@ -862,13 +953,16 @@ valpy_get_is_lazy (PyObject *self, void *closure)
 {
   struct value *value = ((value_object *) self)->value;
   int opt = 0;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       opt = value_lazy (value);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   if (opt)
     Py_RETURN_TRUE;
@@ -881,24 +975,27 @@ static PyObject *
 valpy_fetch_lazy (PyObject *self, PyObject *args)
 {
   struct value *value = ((value_object *) self)->value;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       if (value_lazy (value))
        value_fetch_lazy (value);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   Py_RETURN_NONE;
 }
 
 /* Calculate and return the address of the PyObject as the value of
    the builtin __hash__ call.  */
-static long
+static Py_hash_t
 valpy_hash (PyObject *self)
 {
-  return (long) (intptr_t) self;
+  return (intptr_t) self;
 }
 
 enum valpy_opcode
@@ -920,136 +1017,153 @@ enum valpy_opcode
 #define STRIP_REFERENCE(TYPE) \
   ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
-/* Returns a value object which is the result of applying the operation
-   specified by OPCODE to the given arguments.  Returns NULL on error, with
-   a python exception set.  */
+/* Helper for valpy_binop.  Returns a value object which is the result
+   of applying the operation specified by OPCODE to the given
+   arguments.  Throws a GDB exception on error.  */
+
 static PyObject *
-valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
+valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
 {
-  volatile struct gdb_exception except;
   PyObject *result = NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  struct value *arg1, *arg2;
+  struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+  struct value *res_val = NULL;
+  enum exp_opcode op = OP_NULL;
+  int handled = 0;
+
+  /* If the gdb.Value object is the second operand, then it will be
+     passed to us as the OTHER argument, and SELF will be an entirely
+     different kind of object, altogether.  Because of this, we can't
+     assume self is a gdb.Value object and need to convert it from
+     python as well.  */
+  arg1 = convert_value_from_python (self);
+  if (arg1 == NULL)
     {
-      struct value *arg1, *arg2;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
-      struct value *res_val = NULL;
-      enum exp_opcode op = OP_NULL;
-      int handled = 0;
-
-      /* If the gdb.Value object is the second operand, then it will be passed
-        to us as the OTHER argument, and SELF will be an entirely different
-        kind of object, altogether.  Because of this, we can't assume self is
-        a gdb.Value object and need to convert it from python as well.  */
-      arg1 = convert_value_from_python (self);
-      if (arg1 == NULL)
-       {
-         do_cleanups (cleanup);
-         break;
-       }
+      do_cleanups (cleanup);
+      return NULL;
+    }
 
-      arg2 = convert_value_from_python (other);
-      if (arg2 == NULL)
-       {
-         do_cleanups (cleanup);
-         break;
-       }
+  arg2 = convert_value_from_python (other);
+  if (arg2 == NULL)
+    {
+      do_cleanups (cleanup);
+      return NULL;
+    }
 
-      switch (opcode)
-       {
-       case VALPY_ADD:
+  switch (opcode)
+    {
+    case VALPY_ADD:
+      {
+       struct type *ltype = value_type (arg1);
+       struct type *rtype = value_type (arg2);
+
+       ltype = check_typedef (ltype);
+       ltype = STRIP_REFERENCE (ltype);
+       rtype = check_typedef (rtype);
+       rtype = STRIP_REFERENCE (rtype);
+
+       handled = 1;
+       if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+           && is_integral_type (rtype))
+         res_val = value_ptradd (arg1, value_as_long (arg2));
+       else if (TYPE_CODE (rtype) == TYPE_CODE_PTR
+                && is_integral_type (ltype))
+         res_val = value_ptradd (arg2, value_as_long (arg1));
+       else
          {
-           struct type *ltype = value_type (arg1);
-           struct type *rtype = value_type (arg2);
-
-           CHECK_TYPEDEF (ltype);
-           ltype = STRIP_REFERENCE (ltype);
-           CHECK_TYPEDEF (rtype);
-           rtype = STRIP_REFERENCE (rtype);
-
-           handled = 1;
-           if (TYPE_CODE (ltype) == TYPE_CODE_PTR
-               && is_integral_type (rtype))
-             res_val = value_ptradd (arg1, value_as_long (arg2));
-           else if (TYPE_CODE (rtype) == TYPE_CODE_PTR
-                    && is_integral_type (ltype))
-             res_val = value_ptradd (arg2, value_as_long (arg1));
-           else
-             {
-               handled = 0;
-               op = BINOP_ADD;
-             }
+           handled = 0;
+           op = BINOP_ADD;
          }
-         break;
-       case VALPY_SUB:
+      }
+      break;
+    case VALPY_SUB:
+      {
+       struct type *ltype = value_type (arg1);
+       struct type *rtype = value_type (arg2);
+
+       ltype = check_typedef (ltype);
+       ltype = STRIP_REFERENCE (ltype);
+       rtype = check_typedef (rtype);
+       rtype = STRIP_REFERENCE (rtype);
+
+       handled = 1;
+       if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+           && TYPE_CODE (rtype) == TYPE_CODE_PTR)
+         /* A ptrdiff_t for the target would be preferable here.  */
+         res_val = value_from_longest (builtin_type_pyint,
+                                       value_ptrdiff (arg1, arg2));
+       else if (TYPE_CODE (ltype) == TYPE_CODE_PTR
+                && is_integral_type (rtype))
+         res_val = value_ptradd (arg1, - value_as_long (arg2));
+       else
          {
-           struct type *ltype = value_type (arg1);
-           struct type *rtype = value_type (arg2);
-
-           CHECK_TYPEDEF (ltype);
-           ltype = STRIP_REFERENCE (ltype);
-           CHECK_TYPEDEF (rtype);
-           rtype = STRIP_REFERENCE (rtype);
-
-           handled = 1;
-           if (TYPE_CODE (ltype) == TYPE_CODE_PTR
-               && TYPE_CODE (rtype) == TYPE_CODE_PTR)
-             /* A ptrdiff_t for the target would be preferable here.  */
-             res_val = value_from_longest (builtin_type_pyint,
-                                           value_ptrdiff (arg1, arg2));
-           else if (TYPE_CODE (ltype) == TYPE_CODE_PTR
-                    && is_integral_type (rtype))
-             res_val = value_ptradd (arg1, - value_as_long (arg2));
-           else
-             {
-               handled = 0;
-               op = BINOP_SUB;
-             }
+           handled = 0;
+           op = BINOP_SUB;
          }
-         break;
-       case VALPY_MUL:
-         op = BINOP_MUL;
-         break;
-       case VALPY_DIV:
-         op = BINOP_DIV;
-         break;
-       case VALPY_REM:
-         op = BINOP_REM;
-         break;
-       case VALPY_POW:
-         op = BINOP_EXP;
-         break;
-       case VALPY_LSH:
-         op = BINOP_LSH;
-         break;
-       case VALPY_RSH:
-         op = BINOP_RSH;
-         break;
-       case VALPY_BITAND:
-         op = BINOP_BITWISE_AND;
-         break;
-       case VALPY_BITOR:
-         op = BINOP_BITWISE_IOR;
-         break;
-       case VALPY_BITXOR:
-         op = BINOP_BITWISE_XOR;
-         break;
-       }
+      }
+      break;
+    case VALPY_MUL:
+      op = BINOP_MUL;
+      break;
+    case VALPY_DIV:
+      op = BINOP_DIV;
+      break;
+    case VALPY_REM:
+      op = BINOP_REM;
+      break;
+    case VALPY_POW:
+      op = BINOP_EXP;
+      break;
+    case VALPY_LSH:
+      op = BINOP_LSH;
+      break;
+    case VALPY_RSH:
+      op = BINOP_RSH;
+      break;
+    case VALPY_BITAND:
+      op = BINOP_BITWISE_AND;
+      break;
+    case VALPY_BITOR:
+      op = BINOP_BITWISE_IOR;
+      break;
+    case VALPY_BITXOR:
+      op = BINOP_BITWISE_XOR;
+      break;
+    }
 
-      if (!handled)
-       {
-         if (binop_user_defined_p (op, arg1, arg2))
-           res_val = value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
-         else
-           res_val = value_binop (arg1, arg2, op);
-       }
+  if (!handled)
+    {
+      if (binop_user_defined_p (op, arg1, arg2))
+       res_val = value_x_binop (arg1, arg2, op, OP_NULL, EVAL_NORMAL);
+      else
+       res_val = value_binop (arg1, arg2, op);
+    }
 
-      if (res_val)
-       result = value_to_value_object (res_val);
+  if (res_val)
+    result = value_to_value_object (res_val);
 
-      do_cleanups (cleanup);
+  do_cleanups (cleanup);
+  return result;
+}
+
+/* Returns a value object which is the result of applying the operation
+   specified by OPCODE to the given arguments.  Returns NULL on error, with
+   a python exception set.  */
+static PyObject *
+valpy_binop (enum valpy_opcode opcode, PyObject *self, PyObject *other)
+{
+  PyObject *result = NULL;
+
+  TRY
+    {
+      result = valpy_binop_throw (opcode, self, other);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return result;
 }
@@ -1103,10 +1217,9 @@ valpy_power (PyObject *self, PyObject *other, PyObject *unused)
 static PyObject *
 valpy_negative (PyObject *self)
 {
-  volatile struct gdb_exception except;
   PyObject *result = NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       /* Perhaps overkill, but consistency has some virtue.  */
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
@@ -1116,7 +1229,11 @@ valpy_negative (PyObject *self)
       result = value_to_value_object (val);
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return result;
 }
@@ -1131,10 +1248,9 @@ static PyObject *
 valpy_absolute (PyObject *self)
 {
   struct value *value = ((value_object *) self)->value;
-  volatile struct gdb_exception except;
   int isabs = 1;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
 
@@ -1143,7 +1259,11 @@ valpy_absolute (PyObject *self)
 
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   if (isabs)
     return valpy_positive (self);
@@ -1155,12 +1275,12 @@ valpy_absolute (PyObject *self)
 static int
 valpy_nonzero (PyObject *self)
 {
-  volatile struct gdb_exception except;
+  struct gdb_exception except = exception_none;
   value_object *self_value = (value_object *) self;
   struct type *type;
   int nonzero = 0; /* Appease GCC warning.  */
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       type = check_typedef (value_type (self_value->value));
 
@@ -1176,6 +1296,12 @@ valpy_nonzero (PyObject *self)
        /* All other values are True.  */
        nonzero = 1;
     }
+  CATCH (ex, RETURN_MASK_ALL)
+    {
+      except = ex;
+    }
+  END_CATCH
+
   /* This is not documented in the Python documentation, but if this
      function fails, return -1 as slot_nb_nonzero does (the default
      Python nonzero function).  */
@@ -1189,13 +1315,16 @@ static PyObject *
 valpy_invert (PyObject *self)
 {
   struct value *val = NULL;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       val = value_complement (((value_object *) self)->value);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return value_to_value_object (val);
 }
@@ -1235,13 +1364,69 @@ valpy_xor (PyObject *self, PyObject *other)
   return valpy_binop (VALPY_BITXOR, self, other);
 }
 
+/* Helper for valpy_richcompare.  Implements comparison operations for
+   value objects.  Returns true/false on success.  Returns -1 with a
+   Python exception set if a Python error is detected.  Throws a GDB
+   exception on other errors (memory error, etc.).  */
+
+static int
+valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
+{
+  int result;
+  struct value *value_other;
+  struct value *value_self;
+  struct value *mark = value_mark ();
+  struct cleanup *cleanup;
+
+  value_other = convert_value_from_python (other);
+  if (value_other == NULL)
+    return -1;
+
+  cleanup = make_cleanup_value_free_to_mark (mark);
+
+  value_self = ((value_object *) self)->value;
+
+  switch (op)
+    {
+    case Py_LT:
+      result = value_less (value_self, value_other);
+      break;
+    case Py_LE:
+      result = value_less (value_self, value_other)
+       || value_equal (value_self, value_other);
+      break;
+    case Py_EQ:
+      result = value_equal (value_self, value_other);
+      break;
+    case Py_NE:
+      result = !value_equal (value_self, value_other);
+      break;
+    case Py_GT:
+      result = value_less (value_other, value_self);
+      break;
+    case Py_GE:
+      result = (value_less (value_other, value_self)
+               || value_equal (value_self, value_other));
+      break;
+    default:
+      /* Can't happen.  */
+      PyErr_SetString (PyExc_NotImplementedError,
+                      _("Invalid operation on gdb.Value."));
+      result = -1;
+      break;
+    }
+
+  do_cleanups (cleanup);
+  return result;
+}
+
+
 /* Implements comparison operations for value objects.  Returns NULL on error,
    with a python exception set.  */
 static PyObject *
 valpy_richcompare (PyObject *self, PyObject *other, int op)
 {
   int result = 0;
-  volatile struct gdb_exception except;
 
   if (other == Py_None)
     /* Comparing with None is special.  From what I can tell, in Python
@@ -1262,52 +1447,15 @@ valpy_richcompare (PyObject *self, PyObject *other, int op)
        return NULL;
     }
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
-      struct value *value_other, *mark = value_mark ();
-      struct cleanup *cleanup;
-
-      value_other = convert_value_from_python (other);
-      if (value_other == NULL)
-       {
-         result = -1;
-         break;
-       }
-
-      cleanup = make_cleanup_value_free_to_mark (mark);
-
-      switch (op) {
-        case Py_LT:
-         result = value_less (((value_object *) self)->value, value_other);
-         break;
-       case Py_LE:
-         result = value_less (((value_object *) self)->value, value_other)
-           || value_equal (((value_object *) self)->value, value_other);
-         break;
-       case Py_EQ:
-         result = value_equal (((value_object *) self)->value, value_other);
-         break;
-       case Py_NE:
-         result = !value_equal (((value_object *) self)->value, value_other);
-         break;
-        case Py_GT:
-         result = value_less (value_other, ((value_object *) self)->value);
-         break;
-       case Py_GE:
-         result = value_less (value_other, ((value_object *) self)->value)
-           || value_equal (((value_object *) self)->value, value_other);
-         break;
-       default:
-         /* Can't happen.  */
-         PyErr_SetString (PyExc_NotImplementedError,
-                          _("Invalid operation on gdb.Value."));
-         result = -1;
-         break;
-      }
-
-      do_cleanups (cleanup);
+      result = valpy_richcompare_throw (self, other, op);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   /* In this case, the Python exception has already been set.  */
   if (result < 0)
@@ -1327,16 +1475,19 @@ valpy_int (PyObject *self)
   struct value *value = ((value_object *) self)->value;
   struct type *type = value_type (value);
   LONGEST l = 0;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       if (!is_integral_type (type))
        error (_("Cannot convert value to int."));
 
       l = value_as_long (value);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return gdb_py_object_from_longest (l);
 }
@@ -1349,11 +1500,10 @@ valpy_long (PyObject *self)
   struct value *value = ((value_object *) self)->value;
   struct type *type = value_type (value);
   LONGEST l = 0;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
-      CHECK_TYPEDEF (type);
+      type = check_typedef (type);
 
       if (!is_integral_type (type)
          && TYPE_CODE (type) != TYPE_CODE_PTR)
@@ -1361,9 +1511,16 @@ valpy_long (PyObject *self)
 
       l = value_as_long (value);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
-  return gdb_py_long_from_longest (l);
+  if (TYPE_UNSIGNED (type))
+    return gdb_py_long_from_ulongest (l);
+  else
+    return gdb_py_long_from_longest (l);
 }
 
 /* Implements conversion to float.  */
@@ -1373,18 +1530,21 @@ valpy_float (PyObject *self)
   struct value *value = ((value_object *) self)->value;
   struct type *type = value_type (value);
   double d = 0;
-  volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
-      CHECK_TYPEDEF (type);
+      type = check_typedef (type);
 
       if (TYPE_CODE (type) != TYPE_CODE_FLT)
        error (_("Cannot convert value to float."));
 
       d = value_as_double (value);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return PyFloat_FromDouble (d);
 }
@@ -1431,12 +1591,11 @@ struct value *
 convert_value_from_python (PyObject *obj)
 {
   struct value *value = NULL; /* -Wall */
-  volatile struct gdb_exception except;
   int cmp;
 
   gdb_assert (obj != NULL);
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       if (PyBool_Check (obj))
        {
@@ -1485,6 +1644,7 @@ convert_value_from_python (PyObject *obj)
          else
            value = value_from_longest (builtin_type_pylong, l);
        }
+#if PY_MAJOR_VERSION == 2
       else if (PyInt_Check (obj))
        {
          long l = PyInt_AsLong (obj);
@@ -1492,6 +1652,7 @@ convert_value_from_python (PyObject *obj)
          if (! PyErr_Occurred ())
            value = value_from_longest (builtin_type_pyint, l);
        }
+#endif
       else if (PyFloat_Check (obj))
        {
          double d = PyFloat_AsDouble (obj);
@@ -1501,17 +1662,11 @@ convert_value_from_python (PyObject *obj)
        }
       else if (gdbpy_is_string (obj))
        {
-         char *s;
-
-         s = python_string_to_target_string (obj);
+         gdb::unique_xmalloc_ptr<char> s
+           = python_string_to_target_string (obj);
          if (s != NULL)
-           {
-             struct cleanup *old;
-
-             old = make_cleanup (xfree, s);
-             value = value_cstring (s, strlen (s), builtin_type_pychar);
-             do_cleanups (old);
-           }
+           value = value_cstring (s.get (), strlen (s.get ()),
+                                  builtin_type_pychar);
        }
       else if (PyObject_TypeCheck (obj, &value_object_type))
        value = value_copy (((value_object *) obj)->value);
@@ -1532,13 +1687,14 @@ convert_value_from_python (PyObject *obj)
                      PyString_AsString (PyObject_Str (obj)));
 #endif
     }
-  if (except.reason < 0)
+  CATCH (except, RETURN_MASK_ALL)
     {
       PyErr_Format (except.reason == RETURN_QUIT
                    ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
                    "%s", except.message);
       return NULL;
     }
+  END_CATCH
 
   return value;
 }
@@ -1549,16 +1705,19 @@ gdbpy_history (PyObject *self, PyObject *args)
 {
   int i;
   struct value *res_val = NULL;          /* Initialize to appease gcc warning.  */
-  volatile struct gdb_exception except;
 
   if (!PyArg_ParseTuple (args, "i", &i))
     return NULL;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  TRY
     {
       res_val = access_value_history (i);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
 
   return value_to_value_object (res_val);
 }
@@ -1614,6 +1773,10 @@ reinterpret_cast operator."
   { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
   { "referenced_value", valpy_referenced_value, METH_NOARGS,
     "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
+  { "reference_value", valpy_reference_value, METH_NOARGS,
+    "Return a value of type TYPE_CODE_REF referencing this value." },
+  { "const_value", valpy_const_value, METH_NOARGS,
+    "Return a 'const' qualied version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
     METH_VARARGS | METH_KEYWORDS,
     "lazy_string ([encoding]  [, length]) -> lazy_string\n\
@@ -1662,6 +1825,9 @@ static PyNumberMethods value_object_as_number = {
   NULL,                       /* nb_inplace_add */
   NULL,                       /* nb_inplace_subtract */
   NULL,                       /* nb_inplace_multiply */
+#ifndef IS_PY3K
+  NULL,                       /* nb_inplace_divide */
+#endif
   NULL,                       /* nb_inplace_remainder */
   NULL,                       /* nb_inplace_power */
   NULL,                       /* nb_inplace_lshift */
@@ -1670,7 +1836,13 @@ static PyNumberMethods value_object_as_number = {
   NULL,                       /* nb_inplace_xor */
   NULL,                       /* nb_inplace_or */
   NULL,                       /* nb_floor_divide */
-  valpy_divide                /* nb_true_divide */
+  valpy_divide,               /* nb_true_divide */
+  NULL,                              /* nb_inplace_floor_divide */
+  NULL,                              /* nb_inplace_true_divide */
+#ifndef HAVE_LIBPYTHON2_4
+  /* This was added in Python 2.5.  */
+  valpy_long,                /* nb_index */
+#endif /* HAVE_LIBPYTHON2_4 */
 };
 
 static PyMappingMethods value_object_as_mapping = {
This page took 0.051734 seconds and 4 git commands to generate.