* gdbtypes.c (copy_type): New function.
authorJoel Brobecker <brobecker@gnat.com>
Wed, 22 Oct 2008 20:11:56 +0000 (20:11 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Wed, 22 Oct 2008 20:11:56 +0000 (20:11 +0000)
        * gdbtypes.h (copy_type): Add declaration.
        * ada-lang.c (ada_to_fixed_type_1): If there is a parallel XVZ
        variable, then use it.

gdb/ChangeLog
gdb/ada-lang.c
gdb/gdbtypes.c
gdb/gdbtypes.h

index 5892c33c1918999743498fa290587dcdeac387ce..62d8bb907d04fd0619cd08b3edba798d80c811d7 100644 (file)
@@ -1,3 +1,10 @@
+2008-10-22  Joel brobecker  <brobecker@adacore.com>
+
+       * gdbtypes.c (copy_type): New function.
+       * gdbtypes.h (copy_type): Add declaration.
+       * ada-lang.c (ada_to_fixed_type_1): If there is a parallel XVZ
+       variable, then use it.
+
 2008-10-22  Joel Brobecker  <brobecker@adacore.com>
 
        * target.h (struct target_ops): Add new field to_get_ada_task_ptid.
index 60ceacccbb190b8f056fac5f2a0f3fb5d250da90..cce7da9f0a84464db6bee26174e5ebec18e94f9b 100644 (file)
@@ -7357,6 +7357,46 @@ ada_to_fixed_type_1 (struct type *type, const gdb_byte *valaddr,
             if (real_type != NULL)
               return to_fixed_record_type (real_type, valaddr, address, NULL);
           }
+
+        /* Check to see if there is a parallel ___XVZ variable.
+           If there is, then it provides the actual size of our type.  */
+        else if (ada_type_name (fixed_record_type) != NULL)
+          {
+            char *name = ada_type_name (fixed_record_type);
+            char *xvz_name = alloca (strlen (name) + 7 /* "___XVZ\0" */);
+            int xvz_found = 0;
+            LONGEST size;
+
+            sprintf (xvz_name, "%s___XVZ", name);
+            size = get_int_var_value (xvz_name, &xvz_found);
+            if (xvz_found && TYPE_LENGTH (fixed_record_type) != size)
+              {
+                fixed_record_type = copy_type (fixed_record_type);
+                TYPE_LENGTH (fixed_record_type) = size;
+
+                /* The FIXED_RECORD_TYPE may have be a stub.  We have
+                   observed this when the debugging info is STABS, and
+                   apparently it is something that is hard to fix.
+
+                   In practice, we don't need the actual type definition
+                   at all, because the presence of the XVZ variable allows us
+                   to assume that there must be a XVS type as well, which we
+                   should be able to use later, when we need the actual type
+                   definition.
+
+                   In the meantime, pretend that the "fixed" type we are
+                   returning is NOT a stub, because this can cause trouble
+                   when using this type to create new types targeting it.
+                   Indeed, the associated creation routines often check
+                   whether the target type is a stub and will try to replace
+                   it, thus using a type with the wrong size. This, in turn,
+                   might cause the new type to have the wrong size too.
+                   Consider the case of an array, for instance, where the size
+                   of the array is computed from the number of elements in
+                   our array multiplied by the size of its element.  */
+                TYPE_STUB (fixed_record_type) = 0;
+              }
+          }
         return fixed_record_type;
       }
     case TYPE_CODE_ARRAY:
index 2029d5d20aa90ce862ee748bfa0048fee6c4ad33..b5a5de0e5ee126312f5e80cb8fc9af26ef68fee3 100644 (file)
@@ -3040,6 +3040,28 @@ copy_type_recursive (struct objfile *objfile,
   return new_type;
 }
 
+/* Make a copy of the given TYPE, except that the pointer & reference
+   types are not preserved.
+   
+   This function assumes that the given type has an associated objfile.
+   This objfile is used to allocate the new type.  */
+
+struct type *
+copy_type (const struct type *type)
+{
+  struct type *new_type;
+
+  gdb_assert (TYPE_OBJFILE (type) != NULL);
+
+  new_type = alloc_type (TYPE_OBJFILE (type));
+  TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
+  TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
+  memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
+         sizeof (struct main_type));
+
+  return new_type;
+}
+
 static struct type *
 build_flt (int bit, char *name, const struct floatformat **floatformats)
 {
index 0a48db2b5e6e272a287557c6a443c9b211ffcb67..2a41c5b90a6d7493c89dc40f5e2e2aa4318d1f38 100644 (file)
@@ -1261,4 +1261,6 @@ extern struct type *copy_type_recursive (struct objfile *objfile,
                                         struct type *type,
                                         htab_t copied_types);
 
+extern struct type *copy_type (const struct type *type);
+
 #endif /* GDBTYPES_H */