minor cleanups in is_dynamic_type
[platform/upstream/binutils.git] / gdb / gdbtypes.c
index d510ee6..ba35883 100644 (file)
@@ -1623,66 +1623,37 @@ is_dynamic_type (struct type *type)
 
   switch (TYPE_CODE (type))
     {
+    case TYPE_CODE_RANGE:
+      return !has_static_range (TYPE_RANGE_DATA (type));
+
     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));
-       break;
+       return is_dynamic_type (TYPE_TARGET_TYPE (type));
       }
-    default:
-      return 0;
-      break;
     }
-}
 
-/* 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.  */
+  return 0;
+}
 
 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;
-    }
-
-  if (TYPE_CODE (type) == TYPE_CODE_REF)
-    {
-      struct type *copy = copy_type (type);
-      CORE_ADDR target_addr = read_memory_typed_address (addr, type);
-
-      TYPE_TARGET_TYPE (copy)
-       = resolve_dynamic_bounds (TYPE_TARGET_TYPE (type), target_addr);
-      return copy;
-    }
-
-  gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY);
-
-  elt_type = type;
-  range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
+  gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
 
-  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;
@@ -1693,11 +1664,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
     {
@@ -1705,16 +1680,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);
@@ -1726,12 +1723,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;
 }
@@ -2556,7 +2578,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.  */
@@ -3081,6 +3103,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;
@@ -3098,6 +3122,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;
@@ -3111,6 +3137,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;
@@ -4355,6 +4383,10 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
     = arch_type (gdbarch, TYPE_CODE_INTERNAL_FUNCTION, 0,
                 "<internal function>");
 
+  /* This type represents an xmethod.  */
+  builtin_type->xmethod
+    = arch_type (gdbarch, TYPE_CODE_XMETHOD, 0, "<xmethod>");
+
   return builtin_type;
 }