Enhance dwarfread.c::resolve_dynamic_type to resolve dynamic ranges
authorJoel Brobecker <brobecker@adacore.com>
Sat, 19 Apr 2014 16:40:53 +0000 (09:40 -0700)
committerJoel Brobecker <brobecker@adacore.com>
Mon, 28 Apr 2014 19:41:48 +0000 (15:41 -0400)
This change breaks down the resolve_dynamic_bounds function which
works only on arrays and its index range types into two functions,
one that resolves range types, and one that resolves arrays (using
the new routine to resolve the array's index range type). The
is_dynamic_type and resolve_dynamic_type function are then re-organized
to handle range types as well.

One small change worth mentioning is the fact that, now that range
types are resolved on their own (rather than in the limited context
of array index types), the resolved range types are created from
a copy of the dynamic range type, rather than from scratch (first
parameter of create_range_type). This allows us to preserve as many
original properties in the resolved type as possible (Eg. the type's
name).

This is preparation work that will help better support dynamic range
types for languages that allow the declaration of such types (Eg. Ada).

gdb/ChangeLog:

        * dwarf2read.c (is_dynamic_type): Return true for dynamic
        range types.  Adjust the array handling implementation to
        take advantage of this change.
        (resolve_dynamic_range): New function, mostly extracted from
        resolve_dynamic_bounds.
        (resolve_dynamic_array): New function, mostly extracted from
        resolve_dynamic_bounds.
        (resolve_dynamic_bounds): Delete.
        (resolve_dynamic_type): Reimplement.  Add handling of
        TYPE_CODE_RANGE types.

gdb/ChangeLog
gdb/gdbtypes.c

index f3f02e744d2198e7b2e0b4c7bc3a4bafc267a591..e1dda4c3a717ab112fef1a7c99a8bf6547b01b98 100644 (file)
@@ -1,3 +1,16 @@
+2014-04-28  Joel Brobecker  <brobecker@adacore.com>
+
+       * dwarf2read.c (is_dynamic_type): Return true for dynamic
+       range types.  Adjust the array handling implementation to
+       take advantage of this change.
+       (resolve_dynamic_range): New function, mostly extracted from
+       resolve_dynamic_bounds.
+       (resolve_dynamic_array): New function, mostly extracted from
+       resolve_dynamic_bounds.
+       (resolve_dynamic_bounds): Delete.
+       (resolve_dynamic_type): Reimplement.  Add handling of
+       TYPE_CODE_RANGE types.
+
 2014-04-28  Joel Brobecker  <brobecker@adacore.com>
 
        * ada-varobj.c (ada_varobj_describe_simple_array_child): Remove
index 8b528b81062e132623008c7555dbe08777d8d82b..1a0742054835456b9edb6a55009b60c063d066b1 100644 (file)
@@ -1623,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));
@@ -1641,47 +1645,18 @@ 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 addr)
 {
   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);
+  gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
 
-      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));
-
-  prop = &TYPE_RANGE_DATA (range_type)->low;
+  prop = &TYPE_RANGE_DATA (dyn_range_type)->low;
   if (dwarf2_evaluate_property (prop, addr, &value))
     {
       low_bound.kind = PROP_CONST;
@@ -1693,13 +1668,13 @@ resolve_dynamic_bounds (struct type *type, CORE_ADDR addr)
       low_bound.data.const_val = 0;
     }
 
-  prop = &TYPE_RANGE_DATA (range_type)->high;
+  prop = &TYPE_RANGE_DATA (dyn_range_type)->high;
   if (dwarf2_evaluate_property (prop, addr, &value))
     {
       high_bound.kind = PROP_CONST;
       high_bound.data.const_val = value;
 
-      if (TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count)
+      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;
     }
@@ -1709,17 +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 addr)
+{
+  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, addr);
+
   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), addr);
   else
     elt_type = TYPE_TARGET_TYPE (type);
 
-  range_type = create_range_type (NULL,
-                                 TYPE_TARGET_TYPE (range_type),
-                                 &low_bound, &high_bound);
-  TYPE_RANGE_DATA (range_type)->flag_bound_evaluated = 1;
   return create_array_type (copy_type (type),
                            elt_type,
                            range_type);
@@ -1731,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, addr);
+       break;
+
+      case TYPE_CODE_RANGE:
+       resolved_type = resolve_dynamic_range (type, addr);
+       break;
+    }
 
   return resolved_type;
 }