Add a TRY_CATCH to get_prev_frame_always to better manage errors during unwind.
[deliverable/binutils-gdb.git] / gdb / gdbtypes.c
index 9456059fae5da6a41762f4a652fb1cbf36f07e67..d58193e82f45fb3db8ab069ee89423e7e1c976b8 100644 (file)
@@ -40,6 +40,7 @@
 #include "cp-support.h"
 #include "bcache.h"
 #include "dwarf2loc.h"
+#include "gdbcore.h"
 
 /* Initialize BADNESS constants.  */
 
@@ -1622,13 +1623,17 @@ is_dynamic_type (struct type *type)
 
   switch (TYPE_CODE (type))
     {
+    case TYPE_CODE_RANGE:
+      return !has_static_range (TYPE_RANGE_DATA (type));
+      break;
+
     case TYPE_CODE_ARRAY:
       {
-       const struct type *range_type;
-
        gdb_assert (TYPE_NFIELDS (type) == 1);
-       range_type = TYPE_INDEX_TYPE (type);
-       if (!has_static_range (TYPE_RANGE_DATA (range_type)))
+
+       /* The array is dynamic if either the bounds are dynamic,
+          or the elements it contains have a dynamic contents.  */
+       if (is_dynamic_type (TYPE_INDEX_TYPE (type)))
          return 1;
        else
          return is_dynamic_type (TYPE_TARGET_TYPE (type));
@@ -1640,38 +1645,19 @@ is_dynamic_type (struct type *type)
     }
 }
 
-/* Resolves dynamic bound values of an array type TYPE to static ones.
-   ADDRESS might be needed to resolve the subrange bounds, it is the location
-   of the associated array.  */
-
 static struct type *
-resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
+resolve_dynamic_range (struct type *dyn_range_type)
 {
   CORE_ADDR value;
-  struct type *elt_type;
-  struct type *range_type;
-  struct type *ary_dim;
+  struct type *static_range_type;
   const struct dynamic_prop *prop;
   const struct dwarf2_locexpr_baton *baton;
   struct dynamic_prop low_bound, high_bound;
 
-  if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
-    {
-      struct type *copy = copy_type (type);
-
-      TYPE_TARGET_TYPE (copy)
-       = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
-
-      return copy;
-    }
+  gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
 
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
-
-  elt_type = type;
-  range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
-
-  prop = &TYPE_RANGE_DATA (range_type)->low;
-  if (dwarf2_evaluate_property (prop, addr, &value))
+  prop = &TYPE_RANGE_DATA (dyn_range_type)->low;
+  if (dwarf2_evaluate_property (prop, &value))
     {
       low_bound.kind = PROP_CONST;
       low_bound.data.const_val = value;
@@ -1682,11 +1668,15 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
       low_bound.data.const_val = 0;
     }
 
-  prop = &TYPE_RANGE_DATA (range_type)->high;
-  if (dwarf2_evaluate_property (prop, addr, &value))
+  prop = &TYPE_RANGE_DATA (dyn_range_type)->high;
+  if (dwarf2_evaluate_property (prop, &value))
     {
       high_bound.kind = PROP_CONST;
       high_bound.data.const_val = value;
+
+      if (TYPE_RANGE_DATA (dyn_range_type)->flag_upper_bound_is_count)
+       high_bound.data.const_val
+         = low_bound.data.const_val + high_bound.data.const_val - 1;
     }
   else
     {
@@ -1694,16 +1684,38 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
       high_bound.data.const_val = 0;
     }
 
+  static_range_type = create_range_type (copy_type (dyn_range_type),
+                                        TYPE_TARGET_TYPE (dyn_range_type),
+                                        &low_bound, &high_bound);
+  TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1;
+  return static_range_type;
+}
+
+/* Resolves dynamic bound values of an array type TYPE to static ones.
+   ADDRESS might be needed to resolve the subrange bounds, it is the location
+   of the associated array.  */
+
+static struct type *
+resolve_dynamic_array (struct type *type)
+{
+  CORE_ADDR value;
+  struct type *elt_type;
+  struct type *range_type;
+  struct type *ary_dim;
+
+  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
+
+  elt_type = type;
+  range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
+  range_type = resolve_dynamic_range (range_type);
+
   ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
 
   if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
-    elt_type = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), addr);
+    elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type));
   else
     elt_type = TYPE_TARGET_TYPE (type);
 
-  range_type = create_range_type (NULL,
-                                 TYPE_TARGET_TYPE (range_type),
-                                 &low_bound, &high_bound);
   return create_array_type (copy_type (type),
                            elt_type,
                            range_type);
@@ -1715,12 +1727,37 @@ struct type *
 resolve_dynamic_type (struct type *type, CORE_ADDR addr)
 {
   struct type *real_type = check_typedef (type);
-  struct type *resolved_type;
+  struct type *resolved_type = type;
 
   if (!is_dynamic_type (real_type))
     return type;
 
-  resolved_type = resolve_dynamic_bounds (type, addr);
+  switch (TYPE_CODE (type))
+    {
+      case TYPE_CODE_TYPEDEF:
+       resolved_type = copy_type (type);
+       TYPE_TARGET_TYPE (resolved_type)
+         = resolve_dynamic_type (TYPE_TARGET_TYPE (type), addr);
+       break;
+
+      case TYPE_CODE_REF:
+       {
+         CORE_ADDR target_addr = read_memory_typed_address (addr, type);
+
+         resolved_type = copy_type (type);
+         TYPE_TARGET_TYPE (resolved_type)
+           = resolve_dynamic_type (TYPE_TARGET_TYPE (type), target_addr);
+         break;
+       }
+
+      case TYPE_CODE_ARRAY:
+       resolved_type = resolve_dynamic_array (type);
+       break;
+
+      case TYPE_CODE_RANGE:
+       resolved_type = resolve_dynamic_range (type);
+       break;
+    }
 
   return resolved_type;
 }
@@ -2545,7 +2582,7 @@ rank_function (struct type **parms, int nparms,
 
   bv = xmalloc (sizeof (struct badness_vector));
   bv->length = nargs + 1;      /* add 1 for the length-match rank.  */
-  bv->rank = xmalloc ((nargs + 1) * sizeof (int));
+  bv->rank = XNEWVEC (struct rank, nargs + 1);
 
   /* First compare the lengths of the supplied lists.
      If there is a mismatch, set it to a high value.  */
@@ -3070,6 +3107,8 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
        case TYPE_CODE_CHAR:
        case TYPE_CODE_RANGE:
        case TYPE_CODE_BOOL:
+         if (TYPE_DECLARED_CLASS (arg))
+           return INCOMPATIBLE_TYPE_BADNESS;
          return INTEGER_PROMOTION_BADNESS;
        case TYPE_CODE_FLT:
          return INT_FLOAT_CONVERSION_BADNESS;
@@ -3087,6 +3126,8 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
        case TYPE_CODE_RANGE:
        case TYPE_CODE_BOOL:
        case TYPE_CODE_ENUM:
+         if (TYPE_DECLARED_CLASS (parm) || TYPE_DECLARED_CLASS (arg))
+           return INCOMPATIBLE_TYPE_BADNESS;
          return INTEGER_CONVERSION_BADNESS;
        case TYPE_CODE_FLT:
          return INT_FLOAT_CONVERSION_BADNESS;
@@ -3100,6 +3141,8 @@ rank_one_type (struct type *parm, struct type *arg, struct value *value)
        case TYPE_CODE_RANGE:
        case TYPE_CODE_BOOL:
        case TYPE_CODE_ENUM:
+         if (TYPE_DECLARED_CLASS (arg))
+           return INCOMPATIBLE_TYPE_BADNESS;
          return INTEGER_CONVERSION_BADNESS;
        case TYPE_CODE_FLT:
          return INT_FLOAT_CONVERSION_BADNESS;
This page took 0.025874 seconds and 4 git commands to generate.