Use a wrapper for PyErr_Fetch
[deliverable/binutils-gdb.git] / gdb / python / py-value.c
index f9b10b7bc7d02aeb6323b9cf1b415695ed18a11c..9cc56e6cd1d1494a83b91cdcb9831cf14d8d271f 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to values.
 
 /* Python interface to values.
 
-   Copyright (C) 2008-2017 Free Software Foundation, Inc.
+   Copyright (C) 2008-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
@@ -21,7 +21,7 @@
 #include "charset.h"
 #include "value.h"
 #include "language.h"
 #include "charset.h"
 #include "value.h"
 #include "language.h"
-#include "dfp.h"
+#include "target-float.h"
 #include "valprint.h"
 #include "infcall.h"
 #include "expression.h"
 #include "valprint.h"
 #include "infcall.h"
 #include "expression.h"
@@ -29,6 +29,7 @@
 #include "python.h"
 
 #include "python-internal.h"
 #include "python.h"
 
 #include "python-internal.h"
+#include "py-ref.h"
 
 /* Even though Python scalar types directly map to host types, we use
    target types here to remain consistent with the values system in
 
 /* Even though Python scalar types directly map to host types, we use
    target types here to remain consistent with the values system in
@@ -87,7 +88,7 @@ valpy_dealloc (PyObject *obj)
   if (self->next)
     self->next->prev = self->prev;
 
   if (self->next)
     self->next->prev = self->prev;
 
-  value_free (self->value);
+  value_decref (self->value);
 
   if (self->address)
     /* Use braces to appease gcc warning.  *sigh*  */
 
   if (self->address)
     /* Use braces to appease gcc warning.  *sigh*  */
@@ -146,8 +147,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
       return NULL;
     }
 
       return NULL;
     }
 
-  value_obj->value = value;
-  release_value_or_incref (value);
+  value_obj->value = release_value (value).release ();
   value_obj->address = NULL;
   value_obj->type = NULL;
   value_obj->dynamic_type = NULL;
   value_obj->address = NULL;
   value_obj->type = NULL;
   value_obj->dynamic_type = NULL;
@@ -177,11 +177,10 @@ valpy_dereference (PyObject *self, PyObject *args)
   TRY
     {
       struct value *res_val;
   TRY
     {
       struct value *res_val;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
 
       res_val = value_ind (((value_object *) self)->value);
       result = value_to_value_object (res_val);
 
       res_val = value_ind (((value_object *) self)->value);
       result = value_to_value_object (res_val);
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -208,7 +207,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
   TRY
     {
       struct value *self_val, *res_val;
   TRY
     {
       struct value *self_val, *res_val;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
 
       self_val = ((value_object *) self)->value;
       switch (TYPE_CODE (check_typedef (value_type (self_val))))
 
       self_val = ((value_object *) self)->value;
       switch (TYPE_CODE (check_typedef (value_type (self_val))))
@@ -217,6 +216,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
           res_val = value_ind (self_val);
           break;
         case TYPE_CODE_REF:
+        case TYPE_CODE_RVALUE_REF:
           res_val = coerce_ref (self_val);
           break;
         default:
           res_val = coerce_ref (self_val);
           break;
         default:
@@ -225,7 +225,6 @@ valpy_referenced_value (PyObject *self, PyObject *args)
         }
 
       result = value_to_value_object (res_val);
         }
 
       result = value_to_value_object (res_val);
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -239,19 +238,17 @@ valpy_referenced_value (PyObject *self, PyObject *args)
 /* Return a value which is a reference to the value.  */
 
 static PyObject *
 /* Return a value which is a reference to the value.  */
 
 static PyObject *
-valpy_reference_value (PyObject *self, PyObject *args)
+valpy_reference_value (PyObject *self, PyObject *args, enum type_code refcode)
 {
   PyObject *result = NULL;
 
   TRY
     {
       struct value *self_val;
 {
   PyObject *result = NULL;
 
   TRY
     {
       struct value *self_val;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
 
       self_val = ((value_object *) self)->value;
 
       self_val = ((value_object *) self)->value;
-      result = value_to_value_object (value_ref (self_val));
-
-      do_cleanups (cleanup);
+      result = value_to_value_object (value_ref (self_val, refcode));
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -262,6 +259,18 @@ valpy_reference_value (PyObject *self, PyObject *args)
   return result;
 }
 
   return result;
 }
 
+static PyObject *
+valpy_lvalue_reference_value (PyObject *self, PyObject *args)
+{
+  return valpy_reference_value (self, args, TYPE_CODE_REF);
+}
+
+static PyObject *
+valpy_rvalue_reference_value (PyObject *self, PyObject *args)
+{
+  return valpy_reference_value (self, args, TYPE_CODE_RVALUE_REF);
+}
+
 /* Return a "const" qualified version of the value.  */
 
 static PyObject *
 /* Return a "const" qualified version of the value.  */
 
 static PyObject *
@@ -272,13 +281,11 @@ valpy_const_value (PyObject *self, PyObject *args)
   TRY
     {
       struct value *self_val, *res_val;
   TRY
     {
       struct value *self_val, *res_val;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
 
       self_val = ((value_object *) self)->value;
       res_val = make_cv_value (1, 0, self_val);
       result = value_to_value_object (res_val);
 
       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)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -300,12 +307,10 @@ valpy_get_address (PyObject *self, void *closure)
       TRY
        {
          struct value *res_val;
       TRY
        {
          struct value *res_val;
-         struct cleanup *cleanup
-           = make_cleanup_value_free_to_mark (value_mark ());
+         scoped_value_mark free_values;
 
          res_val = value_addr (val_obj->value);
          val_obj->address = value_to_value_object (res_val);
 
          res_val = value_addr (val_obj->value);
          val_obj->address = value_to_value_object (res_val);
-         do_cleanups (cleanup);
        }
       CATCH (except, RETURN_MASK_ALL)
        {
        }
       CATCH (except, RETURN_MASK_ALL)
        {
@@ -353,13 +358,12 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
   TRY
     {
       struct value *val = obj->value;
   TRY
     {
       struct value *val = obj->value;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
 
       type = value_type (val);
       type = check_typedef (type);
 
 
       type = value_type (val);
       type = check_typedef (type);
 
-      if (((TYPE_CODE (type) == TYPE_CODE_PTR)
-          || (TYPE_CODE (type) == TYPE_CODE_REF))
+      if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
          && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
        {
          struct value *target;
          && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))
        {
          struct value *target;
@@ -376,7 +380,7 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
              if (was_pointer)
                type = lookup_pointer_type (type);
              else
              if (was_pointer)
                type = lookup_pointer_type (type);
              else
-               type = lookup_reference_type (type);
+               type = lookup_lvalue_reference_type (type);
            }
        }
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
            }
        }
       else if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
@@ -386,8 +390,6 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
          /* Re-use object's static type.  */
          type = NULL;
        }
          /* Re-use object's static type.  */
          type = NULL;
        }
-
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -409,34 +411,92 @@ valpy_get_dynamic_type (PyObject *self, void *closure)
    A lazy string is a pointer to a string with an optional encoding and
    length.  If ENCODING is not given, encoding is set to None.  If an
    ENCODING is provided the encoding parameter is set to ENCODING, but
    A lazy string is a pointer to a string with an optional encoding and
    length.  If ENCODING is not given, encoding is set to None.  If an
    ENCODING is provided the encoding parameter is set to ENCODING, but
-   the string is not encoded.  If LENGTH is provided then the length
-   parameter is set to LENGTH, otherwise length will be set to -1 (first
-   null of appropriate with).  */
+   the string is not encoded.
+   If LENGTH is provided then the length parameter is set to LENGTH.
+   Otherwise if the value is an array of known length then the array's length
+   is used.  Otherwise the length will be set to -1 (meaning first null of
+   appropriate with).
+
+   Note: In order to not break any existing uses this allows creating
+   lazy strings from anything.  PR 20769.  E.g.,
+   gdb.parse_and_eval("my_int_variable").lazy_string().
+   "It's easier to relax restrictions than it is to impose them after the
+   fact."  So we should be flagging any unintended uses as errors, but it's
+   perhaps too late for that.  */
+
 static PyObject *
 valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
 {
   gdb_py_longest length = -1;
   struct value *value = ((value_object *) self)->value;
   const char *user_encoding = NULL;
 static PyObject *
 valpy_lazy_string (PyObject *self, PyObject *args, PyObject *kw)
 {
   gdb_py_longest length = -1;
   struct value *value = ((value_object *) self)->value;
   const char *user_encoding = NULL;
-  static char *keywords[] = { "encoding", "length", NULL };
+  static const char *keywords[] = { "encoding", "length", NULL };
   PyObject *str_obj = NULL;
 
   PyObject *str_obj = NULL;
 
-  if (!PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG, keywords,
-                                   &user_encoding, &length))
+  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|s" GDB_PY_LL_ARG,
+                                       keywords, &user_encoding, &length))
     return NULL;
 
     return NULL;
 
+  if (length < -1)
+    {
+      PyErr_SetString (PyExc_ValueError, _("Invalid length."));
+      return NULL;
+    }
+
   TRY
     {
   TRY
     {
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
+      struct type *type, *realtype;
+      CORE_ADDR addr;
 
 
-      if (TYPE_CODE (value_type (value)) == TYPE_CODE_PTR)
-       value = value_ind (value);
+      type = value_type (value);
+      realtype = check_typedef (type);
 
 
-      str_obj = gdbpy_create_lazy_string_object (value_address (value), length,
-                                                user_encoding,
-                                                value_type (value));
+      switch (TYPE_CODE (realtype))
+       {
+       case TYPE_CODE_ARRAY:
+         {
+           LONGEST array_length = -1;
+           LONGEST low_bound, high_bound;
+
+           /* PR 20786: There's no way to specify an array of length zero.
+              Record a length of [0,-1] which is how Ada does it.  Anything
+              we do is broken, but this one possible solution.  */
+           if (get_array_bounds (realtype, &low_bound, &high_bound))
+             array_length = high_bound - low_bound + 1;
+           if (length == -1)
+             length = array_length;
+           else if (array_length == -1)
+             {
+               type = lookup_array_range_type (TYPE_TARGET_TYPE (realtype),
+                                               0, length - 1);
+             }
+           else if (length != array_length)
+             {
+               /* We need to create a new array type with the
+                  specified length.  */
+               if (length > array_length)
+                 error (_("Length is larger than array size."));
+               type = lookup_array_range_type (TYPE_TARGET_TYPE (realtype),
+                                               low_bound,
+                                               low_bound + length - 1);
+             }
+           addr = value_address (value);
+           break;
+         }
+       case TYPE_CODE_PTR:
+         /* If a length is specified we defer creating an array of the
+            specified width until we need to.  */
+         addr = value_as_address (value);
+         break;
+       default:
+         /* Should flag an error here.  PR 20769.  */
+         addr = value_address (value);
+         break;
+       }
 
 
-      do_cleanups (cleanup);
+      str_obj = gdbpy_create_lazy_string_object (addr, length, user_encoding,
+                                                type);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -457,18 +517,17 @@ static PyObject *
 valpy_string (PyObject *self, PyObject *args, PyObject *kw)
 {
   int length = -1;
 valpy_string (PyObject *self, PyObject *args, PyObject *kw)
 {
   int length = -1;
-  gdb_byte *buffer;
+  gdb::unique_xmalloc_ptr<gdb_byte> buffer;
   struct value *value = ((value_object *) self)->value;
   struct value *value = ((value_object *) self)->value;
-  PyObject *unicode;
   const char *encoding = NULL;
   const char *errors = NULL;
   const char *user_encoding = NULL;
   const char *la_encoding = NULL;
   struct type *char_type;
   const char *encoding = NULL;
   const char *errors = NULL;
   const char *user_encoding = NULL;
   const char *la_encoding = NULL;
   struct type *char_type;
-  static char *keywords[] = { "encoding", "errors", "length", NULL };
+  static const char *keywords[] = { "encoding", "errors", "length", NULL };
 
 
-  if (!PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords,
-                                   &user_encoding, &errors, &length))
+  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|ssi", keywords,
+                                       &user_encoding, &errors, &length))
     return NULL;
 
   TRY
     return NULL;
 
   TRY
@@ -482,12 +541,9 @@ valpy_string (PyObject *self, PyObject *args, PyObject *kw)
   END_CATCH
 
   encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
   END_CATCH
 
   encoding = (user_encoding && *user_encoding) ? user_encoding : la_encoding;
-  unicode = PyUnicode_Decode ((const char *) buffer,
-                             length * TYPE_LENGTH (char_type),
-                             encoding, errors);
-  xfree (buffer);
-
-  return unicode;
+  return PyUnicode_Decode ((const char *) buffer.get (),
+                          length * TYPE_LENGTH (char_type),
+                          encoding, errors);
 }
 
 /* A helper function that implements the various cast operators.  */
 }
 
 /* A helper function that implements the various cast operators.  */
@@ -513,7 +569,7 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
     {
       struct value *val = ((value_object *) self)->value;
       struct value *res_val;
     {
       struct value *val = ((value_object *) self)->value;
       struct value *res_val;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
 
       if (op == UNOP_DYNAMIC_CAST)
        res_val = value_dynamic_cast (type, val);
 
       if (op == UNOP_DYNAMIC_CAST)
        res_val = value_dynamic_cast (type, val);
@@ -526,7 +582,6 @@ valpy_do_cast (PyObject *self, PyObject *args, enum exp_opcode op)
        }
 
       result = value_to_value_object (res_val);
        }
 
       result = value_to_value_object (res_val);
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -578,14 +633,13 @@ value_has_field (struct value *v, PyObject *field)
 {
   struct type *parent_type, *val_type;
   enum type_code type_code;
 {
   struct type *parent_type, *val_type;
   enum type_code type_code;
-  PyObject *type_object = PyObject_GetAttrString (field, "parent_type");
+  gdbpy_ref<> type_object (PyObject_GetAttrString (field, "parent_type"));
   int has_field = 0;
 
   if (type_object == NULL)
     return -1;
 
   int has_field = 0;
 
   if (type_object == NULL)
     return -1;
 
-  parent_type = type_object_to_type (type_object);
-  Py_DECREF (type_object);
+  parent_type = type_object_to_type (type_object.get ());
   if (parent_type == NULL)
     {
       PyErr_SetString (PyExc_TypeError,
   if (parent_type == NULL)
     {
       PyErr_SetString (PyExc_TypeError,
@@ -598,8 +652,7 @@ value_has_field (struct value *v, PyObject *field)
     {
       val_type = value_type (v);
       val_type = check_typedef (val_type);
     {
       val_type = value_type (v);
       val_type = check_typedef (val_type);
-      if (TYPE_CODE (val_type) == TYPE_CODE_REF
-         || TYPE_CODE (val_type) == TYPE_CODE_PTR)
+      if (TYPE_IS_REFERENCE (val_type) || TYPE_CODE (val_type) == TYPE_CODE_PTR)
       val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
 
       type_code = TYPE_CODE (val_type);
       val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
 
       type_code = TYPE_CODE (val_type);
@@ -625,16 +678,12 @@ value_has_field (struct value *v, PyObject *field)
 static int
 get_field_flag (PyObject *field, const char *flag_name)
 {
 static int
 get_field_flag (PyObject *field, const char *flag_name)
 {
-  int flag_value;
-  PyObject *flag_object = PyObject_GetAttrString (field, flag_name);
+  gdbpy_ref<> flag_object (PyObject_GetAttrString (field, flag_name));
 
   if (flag_object == NULL)
     return -1;
 
 
   if (flag_object == NULL)
     return -1;
 
-  flag_value = PyObject_IsTrue (flag_object);
-  Py_DECREF (flag_object);
-
-  return flag_value;
+  return PyObject_IsTrue (flag_object.get ());
 }
 
 /* Return the "type" attribute of a gdb.Field object.
 }
 
 /* Return the "type" attribute of a gdb.Field object.
@@ -643,13 +692,12 @@ get_field_flag (PyObject *field, const char *flag_name)
 static struct type *
 get_field_type (PyObject *field)
 {
 static struct type *
 get_field_type (PyObject *field)
 {
-  PyObject *ftype_obj = PyObject_GetAttrString (field, "type");
+  gdbpy_ref<> ftype_obj (PyObject_GetAttrString (field, "type"));
   struct type *ftype;
 
   if (ftype_obj == NULL)
     return NULL;
   struct type *ftype;
 
   if (ftype_obj == NULL)
     return NULL;
-  ftype = type_object_to_type (ftype_obj);
-  Py_DECREF (ftype_obj);
+  ftype = type_object_to_type (ftype_obj.get ());
   if (ftype == NULL)
     PyErr_SetString (PyExc_TypeError,
                     _("'type' attribute of gdb.Field object is not a "
   if (ftype == NULL)
     PyErr_SetString (PyExc_TypeError,
                     _("'type' attribute of gdb.Field object is not a "
@@ -705,25 +753,19 @@ valpy_getitem (PyObject *self, PyObject *key)
        }
       else
        {
        }
       else
        {
-         PyObject *name_obj = PyObject_GetAttrString (key, "name");
+         gdbpy_ref<> name_obj (PyObject_GetAttrString (key, "name"));
 
          if (name_obj == NULL)
            return NULL;
 
          if (name_obj != Py_None)
            {
 
          if (name_obj == NULL)
            return NULL;
 
          if (name_obj != Py_None)
            {
-             field = python_string_to_host_string (name_obj);
-             Py_DECREF (name_obj);
+             field = python_string_to_host_string (name_obj.get ());
              if (field == NULL)
                return NULL;
            }
          else
            {
              if (field == NULL)
                return NULL;
            }
          else
            {
-             PyObject *bitpos_obj;
-             int valid;
-
-             Py_DECREF (name_obj);
-
              if (!PyObject_HasAttrString (key, "bitpos"))
                {
                  PyErr_SetString (PyExc_AttributeError,
              if (!PyObject_HasAttrString (key, "bitpos"))
                {
                  PyErr_SetString (PyExc_AttributeError,
@@ -732,12 +774,10 @@ valpy_getitem (PyObject *self, PyObject *key)
 
                  return NULL;
                }
 
                  return NULL;
                }
-             bitpos_obj = PyObject_GetAttrString (key, "bitpos");
+             gdbpy_ref<> bitpos_obj (PyObject_GetAttrString (key, "bitpos"));
              if (bitpos_obj == NULL)
                return NULL;
              if (bitpos_obj == NULL)
                return NULL;
-             valid = gdb_py_int_as_long (bitpos_obj, &bitpos);
-             Py_DECREF (bitpos_obj);
-             if (!valid)
+             if (!gdb_py_int_as_long (bitpos_obj.get (), &bitpos))
                return NULL;
 
              field_type = get_field_type (key);
                return NULL;
 
              field_type = get_field_type (key);
@@ -750,8 +790,8 @@ valpy_getitem (PyObject *self, PyObject *key)
   TRY
     {
       struct value *tmp = self_value->value;
   TRY
     {
       struct value *tmp = self_value->value;
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
       struct value *res_val = NULL;
       struct value *res_val = NULL;
+      scoped_value_mark free_values;
 
       if (field)
        res_val = value_struct_elt (&tmp, NULL, field.get (), NULL,
 
       if (field)
        res_val = value_struct_elt (&tmp, NULL, field.get (), NULL,
@@ -767,7 +807,11 @@ valpy_getitem (PyObject *self, PyObject *key)
          if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
            res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
          else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
          if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
            res_val = value_cast (lookup_pointer_type (base_class_type), tmp);
          else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
-           res_val = value_cast (lookup_reference_type (base_class_type), tmp);
+           res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
+                                 tmp);
+         else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
+           res_val = value_cast (lookup_rvalue_reference_type (base_class_type),
+                                 tmp);
          else
            res_val = value_cast (base_class_type, tmp);
        }
          else
            res_val = value_cast (base_class_type, tmp);
        }
@@ -796,7 +840,6 @@ valpy_getitem (PyObject *self, PyObject *key)
 
       if (res_val)
        result = value_to_value_object (res_val);
 
       if (res_val)
        result = value_to_value_object (res_val);
-      do_cleanups (cleanup);
     }
   CATCH (ex, RETURN_MASK_ALL)
     {
     }
   CATCH (ex, RETURN_MASK_ALL)
     {
@@ -826,7 +869,6 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
   struct value *function = ((value_object *) self)->value;
   struct value **vargs = NULL;
   struct type *ftype = NULL;
   struct value *function = ((value_object *) self)->value;
   struct value **vargs = NULL;
   struct type *ftype = NULL;
-  struct value *mark = value_mark ();
   PyObject *result = NULL;
 
   TRY
   PyObject *result = NULL;
 
   TRY
@@ -874,12 +916,12 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
 
   TRY
     {
 
   TRY
     {
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (mark);
-      struct value *return_value;
+      scoped_value_mark free_values;
 
 
-      return_value = call_function_by_hand (function, args_count, vargs);
+      value *return_value
+       = call_function_by_hand (function, NULL,
+                                gdb::make_array_view (vargs, args_count));
       result = value_to_value_object (return_value);
       result = value_to_value_object (return_value);
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -895,23 +937,17 @@ valpy_call (PyObject *self, PyObject *args, PyObject *keywords)
 static PyObject *
 valpy_str (PyObject *self)
 {
 static PyObject *
 valpy_str (PyObject *self)
 {
-  std::string s;
-  PyObject *result;
   struct value_print_options opts;
 
   get_user_print_options (&opts);
   opts.deref_ref = 0;
 
   struct value_print_options opts;
 
   get_user_print_options (&opts);
   opts.deref_ref = 0;
 
+  string_file stb;
+
   TRY
     {
   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,
+      common_val_print (((value_object *) self)->value, &stb, 0,
                        &opts, python_language);
                        &opts, python_language);
-      s = ui_file_as_string (stb);
-
-      do_cleanups (old_chain);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -919,9 +955,7 @@ valpy_str (PyObject *self)
     }
   END_CATCH
 
     }
   END_CATCH
 
-  result = PyUnicode_Decode (s.c_str (), s.length (), host_charset (), NULL);
-
-  return result;
+  return PyUnicode_Decode (stb.c_str (), stb.size (), host_charset (), NULL);
 }
 
 /* Implements gdb.Value.is_optimized_out.  */
 }
 
 /* Implements gdb.Value.is_optimized_out.  */
@@ -1015,7 +1049,7 @@ enum valpy_opcode
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
 
 /* If TYPE is a reference, return the target; otherwise return TYPE.  */
 #define STRIP_REFERENCE(TYPE) \
-  ((TYPE_CODE (TYPE) == TYPE_CODE_REF) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
+  (TYPE_IS_REFERENCE (TYPE) ? (TYPE_TARGET_TYPE (TYPE)) : (TYPE))
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
 
 /* Helper for valpy_binop.  Returns a value object which is the result
    of applying the operation specified by OPCODE to the given
@@ -1027,11 +1061,12 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
   PyObject *result = NULL;
 
   struct value *arg1, *arg2;
   PyObject *result = 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;
 
   struct value *res_val = NULL;
   enum exp_opcode op = OP_NULL;
   int handled = 0;
 
+  scoped_value_mark free_values;
+
   /* 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
   /* 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
@@ -1039,17 +1074,11 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
      python as well.  */
   arg1 = convert_value_from_python (self);
   if (arg1 == NULL)
      python as well.  */
   arg1 = convert_value_from_python (self);
   if (arg1 == NULL)
-    {
-      do_cleanups (cleanup);
-      return NULL;
-    }
+    return NULL;
 
   arg2 = convert_value_from_python (other);
   if (arg2 == NULL)
 
   arg2 = convert_value_from_python (other);
   if (arg2 == NULL)
-    {
-      do_cleanups (cleanup);
-      return NULL;
-    }
+    return NULL;
 
   switch (opcode)
     {
 
   switch (opcode)
     {
@@ -1143,7 +1172,6 @@ valpy_binop_throw (enum valpy_opcode opcode, PyObject *self, PyObject *other)
   if (res_val)
     result = value_to_value_object (res_val);
 
   if (res_val)
     result = value_to_value_object (res_val);
 
-  do_cleanups (cleanup);
   return result;
 }
 
   return result;
 }
 
@@ -1222,12 +1250,11 @@ valpy_negative (PyObject *self)
   TRY
     {
       /* Perhaps overkill, but consistency has some virtue.  */
   TRY
     {
       /* Perhaps overkill, but consistency has some virtue.  */
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
       struct value *val;
 
       val = value_neg (((value_object *) self)->value);
       result = value_to_value_object (val);
       struct value *val;
 
       val = value_neg (((value_object *) self)->value);
       result = value_to_value_object (val);
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1252,12 +1279,10 @@ valpy_absolute (PyObject *self)
 
   TRY
     {
 
   TRY
     {
-      struct cleanup *cleanup = make_cleanup_value_free_to_mark (value_mark ());
+      scoped_value_mark free_values;
 
       if (value_less (value, value_zero (value_type (value), not_lval)))
        isabs = 0;
 
       if (value_less (value, value_zero (value_type (value), not_lval)))
        isabs = 0;
-
-      do_cleanups (cleanup);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1286,12 +1311,9 @@ valpy_nonzero (PyObject *self)
 
       if (is_integral_type (type) || TYPE_CODE (type) == TYPE_CODE_PTR)
        nonzero = !!value_as_long (self_value->value);
 
       if (is_integral_type (type) || TYPE_CODE (type) == TYPE_CODE_PTR)
        nonzero = !!value_as_long (self_value->value);
-      else if (TYPE_CODE (type) == TYPE_CODE_FLT)
-       nonzero = value_as_double (self_value->value) != 0;
-      else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT)
-       nonzero = !decimal_is_zero (value_contents (self_value->value),
-                                TYPE_LENGTH (type),
-                                gdbarch_byte_order (get_type_arch (type)));
+      else if (is_floating_value (self_value->value))
+       nonzero = !target_float_is_zero (value_contents (self_value->value),
+                                        type);
       else
        /* All other values are True.  */
        nonzero = 1;
       else
        /* All other values are True.  */
        nonzero = 1;
@@ -1375,15 +1397,13 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
   int result;
   struct value *value_other;
   struct value *value_self;
   int result;
   struct value *value_other;
   struct value *value_self;
-  struct value *mark = value_mark ();
-  struct cleanup *cleanup;
+
+  scoped_value_mark free_values;
 
   value_other = convert_value_from_python (other);
   if (value_other == NULL)
     return -1;
 
 
   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)
   value_self = ((value_object *) self)->value;
 
   switch (op)
@@ -1416,7 +1436,6 @@ valpy_richcompare_throw (PyObject *self, PyObject *other, int op)
       break;
     }
 
       break;
     }
 
-  do_cleanups (cleanup);
   return result;
 }
 
   return result;
 }
 
@@ -1478,7 +1497,14 @@ valpy_int (PyObject *self)
 
   TRY
     {
 
   TRY
     {
-      if (!is_integral_type (type))
+      if (is_floating_value (value))
+       {
+         type = builtin_type_pylong;
+         value = value_cast (type, value);
+       }
+
+      if (!is_integral_type (type)
+         && TYPE_CODE (type) != TYPE_CODE_PTR)
        error (_("Cannot convert value to int."));
 
       l = value_as_long (value);
        error (_("Cannot convert value to int."));
 
       l = value_as_long (value);
@@ -1489,7 +1515,10 @@ valpy_int (PyObject *self)
     }
   END_CATCH
 
     }
   END_CATCH
 
-  return gdb_py_object_from_longest (l);
+  if (TYPE_UNSIGNED (type))
+    return gdb_py_object_from_ulongest (l).release ();
+  else
+    return gdb_py_object_from_longest (l).release ();
 }
 #endif
 
 }
 #endif
 
@@ -1503,6 +1532,12 @@ valpy_long (PyObject *self)
 
   TRY
     {
 
   TRY
     {
+      if (is_floating_value (value))
+       {
+         type = builtin_type_pylong;
+         value = value_cast (type, value);
+       }
+
       type = check_typedef (type);
 
       if (!is_integral_type (type)
       type = check_typedef (type);
 
       if (!is_integral_type (type)
@@ -1535,10 +1570,17 @@ valpy_float (PyObject *self)
     {
       type = check_typedef (type);
 
     {
       type = check_typedef (type);
 
-      if (TYPE_CODE (type) != TYPE_CODE_FLT)
+      if (TYPE_CODE (type) == TYPE_CODE_FLT && is_floating_value (value))
+       d = target_float_to_host_double (value_contents (value), type);
+      else if (TYPE_CODE (type) == TYPE_CODE_INT)
+       {
+         /* Note that valpy_long accepts TYPE_CODE_PTR and some
+            others here here -- but casting a pointer or bool to a
+            float seems wrong.  */
+         d = value_as_long (value);
+       }
+      else
        error (_("Cannot convert value to float."));
        error (_("Cannot convert value to float."));
-
-      d = value_as_double (value);
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
@@ -1559,8 +1601,7 @@ value_to_value_object (struct value *val)
   val_obj = PyObject_New (value_object, &value_object_type);
   if (val_obj != NULL)
     {
   val_obj = PyObject_New (value_object, &value_object_type);
   if (val_obj != NULL)
     {
-      val_obj->value = val;
-      release_value_or_incref (val);
+      val_obj->value = release_value (val).release ();
       val_obj->address = NULL;
       val_obj->type = NULL;
       val_obj->dynamic_type = NULL;
       val_obj->address = NULL;
       val_obj->type = NULL;
       val_obj->dynamic_type = NULL;
@@ -1620,13 +1661,11 @@ convert_value_from_python (PyObject *obj)
                 ULONGEST instead.  */
              if (PyErr_ExceptionMatches (PyExc_OverflowError))
                {
                 ULONGEST instead.  */
              if (PyErr_ExceptionMatches (PyExc_OverflowError))
                {
-                 PyObject *etype, *evalue, *etraceback, *zero;
-
-                 PyErr_Fetch (&etype, &evalue, &etraceback);
-                 zero = PyInt_FromLong (0);
+                 gdbpy_err_fetch fetched_error;
+                 gdbpy_ref<> zero (PyInt_FromLong (0));
 
                  /* Check whether obj is positive.  */
 
                  /* Check whether obj is positive.  */
-                 if (PyObject_RichCompareBool (obj, zero, Py_GT) > 0)
+                 if (PyObject_RichCompareBool (obj, zero.get (), Py_GT) > 0)
                    {
                      ULONGEST ul;
 
                    {
                      ULONGEST ul;
 
@@ -1635,10 +1674,10 @@ convert_value_from_python (PyObject *obj)
                        value = value_from_ulongest (builtin_type_upylong, ul);
                    }
                  else
                        value = value_from_ulongest (builtin_type_upylong, ul);
                    }
                  else
-                   /* There's nothing we can do.  */
-                   PyErr_Restore (etype, evalue, etraceback);
-
-                 Py_DECREF (zero);
+                   {
+                     /* There's nothing we can do.  */
+                     fetched_error.restore ();
+                   }
                }
            }
          else
                }
            }
          else
@@ -1658,7 +1697,11 @@ convert_value_from_python (PyObject *obj)
          double d = PyFloat_AsDouble (obj);
 
          if (! PyErr_Occurred ())
          double d = PyFloat_AsDouble (obj);
 
          if (! PyErr_Occurred ())
-           value = value_from_double (builtin_type_pyfloat, d);
+           {
+             value = allocate_value (builtin_type_pyfloat);
+             target_float_from_host_double (value_contents_raw (value),
+                                            value_type (value), d);
+           }
        }
       else if (gdbpy_is_string (obj))
        {
        }
       else if (gdbpy_is_string (obj))
        {
@@ -1689,9 +1732,7 @@ convert_value_from_python (PyObject *obj)
     }
   CATCH (except, RETURN_MASK_ALL)
     {
     }
   CATCH (except, RETURN_MASK_ALL)
     {
-      PyErr_Format (except.reason == RETURN_QUIT
-                   ? PyExc_KeyboardInterrupt : PyExc_RuntimeError,
-                   "%s", except.message);
+      gdbpy_convert_exception (except);
       return NULL;
     }
   END_CATCH
       return NULL;
     }
   END_CATCH
@@ -1722,6 +1763,83 @@ gdbpy_history (PyObject *self, PyObject *args)
   return value_to_value_object (res_val);
 }
 
   return value_to_value_object (res_val);
 }
 
+/* Return the value of a convenience variable.  */
+PyObject *
+gdbpy_convenience_variable (PyObject *self, PyObject *args)
+{
+  const char *varname;
+  struct value *res_val = NULL;
+
+  if (!PyArg_ParseTuple (args, "s", &varname))
+    return NULL;
+
+  TRY
+    {
+      struct internalvar *var = lookup_only_internalvar (varname);
+
+      if (var != NULL)
+       {
+         res_val = value_of_internalvar (python_gdbarch, var);
+         if (TYPE_CODE (value_type (res_val)) == TYPE_CODE_VOID)
+           res_val = NULL;
+       }
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  if (res_val == NULL)
+    Py_RETURN_NONE;
+
+  return value_to_value_object (res_val);
+}
+
+/* Set the value of a convenience variable.  */
+PyObject *
+gdbpy_set_convenience_variable (PyObject *self, PyObject *args)
+{
+  const char *varname;
+  PyObject *value_obj;
+  struct value *value = NULL;
+
+  if (!PyArg_ParseTuple (args, "sO", &varname, &value_obj))
+    return NULL;
+
+  /* None means to clear the variable.  */
+  if (value_obj != Py_None)
+    {
+      value = convert_value_from_python (value_obj);
+      if (value == NULL)
+       return NULL;
+    }
+
+  TRY
+    {
+      if (value == NULL)
+       {
+         struct internalvar *var = lookup_only_internalvar (varname);
+
+         if (var != NULL)
+           clear_internalvar (var);
+       }
+      else
+       {
+         struct internalvar *var = lookup_internalvar (varname);
+
+         set_internalvar (var, value);
+       }
+    }
+  CATCH (except, RETURN_MASK_ALL)
+    {
+      GDB_PY_HANDLE_EXCEPTION (except);
+    }
+  END_CATCH
+
+  Py_RETURN_NONE;
+}
+
 /* Returns 1 in OBJ is a gdb.Value object, 0 otherwise.  */
 
 int
 /* Returns 1 in OBJ is a gdb.Value object, 0 otherwise.  */
 
 int
@@ -1742,7 +1860,7 @@ gdbpy_initialize_values (void)
 
 \f
 
 
 \f
 
-static PyGetSetDef value_object_getset[] = {
+static gdb_PyGetSetDef value_object_getset[] = {
   { "address", valpy_get_address, NULL, "The address of the value.",
     NULL },
   { "is_optimized_out", valpy_get_is_optimized_out, NULL,
   { "address", valpy_get_address, NULL, "The address of the value.",
     NULL },
   { "is_optimized_out", valpy_get_is_optimized_out, NULL,
@@ -1773,8 +1891,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." },
   { "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,
+  { "reference_value", valpy_lvalue_reference_value, METH_NOARGS,
     "Return a value of type TYPE_CODE_REF referencing this value." },
     "Return a value of type TYPE_CODE_REF referencing this value." },
+  { "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
+    "Return a value of type TYPE_CODE_RVALUE_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,
   { "const_value", valpy_const_value, METH_NOARGS,
     "Return a 'const' qualied version of the same value." },
   { "lazy_string", (PyCFunction) valpy_lazy_string,
This page took 0.035403 seconds and 4 git commands to generate.