Rephrase error message in infcall.c:call_function_by_hand
[deliverable/binutils-gdb.git] / gdb / gdbtypes.c
index 94ae1792f774f89bcc2203416a5da5a2fa11f573..2bdb4ebe72df0b75941dd438b3488f1d4e334d9e 100644 (file)
@@ -1105,6 +1105,32 @@ type_name_no_tag (const struct type *type)
   return TYPE_NAME (type);
 }
 
+/* A wrapper of type_name_no_tag which calls error if the type is anonymous.
+   Since GCC PR debug/47510 DWARF provides associated information to detect the
+   anonymous class linkage name from its typedef.
+
+   Parameter TYPE should not yet have CHECK_TYPEDEF applied, this function will
+   apply it itself.  */
+
+const char *
+type_name_no_tag_or_error (struct type *type)
+{
+  struct type *saved_type = type;
+  const char *name;
+  struct objfile *objfile;
+
+  CHECK_TYPEDEF (type);
+
+  name = type_name_no_tag (type);
+  if (name != NULL)
+    return name;
+
+  name = type_name_no_tag (saved_type);
+  objfile = TYPE_OBJFILE (saved_type);
+  error (_("Invalid anonymous type %s [in module %s], GCC PR debug/47510 bug?"),
+        name ? name : "<anonymous>", objfile ? objfile->name : "<arch>");
+}
+
 /* Lookup a typedef or primitive type named NAME, visible in lexical
    block BLOCK.  If NOERR is nonzero, return zero if NAME is not
    suitably defined.  */
@@ -1902,6 +1928,8 @@ init_type (enum type_code code, int length, int flags,
     TYPE_STUB_SUPPORTED (type) = 1;
   if (flags & TYPE_FLAG_FIXED_INSTANCE)
     TYPE_FIXED_INSTANCE (type) = 1;
+  if (flags & TYPE_FLAG_GNU_IFUNC)
+    TYPE_GNU_IFUNC (type) = 1;
 
   if (name)
     TYPE_NAME (type) = obsavestring (name, strlen (name),
@@ -1955,6 +1983,68 @@ is_integral_type (struct type *t)
         || (TYPE_CODE (t) == TYPE_CODE_BOOL)));
 }
 
+/* Return true if TYPE is scalar.  */
+
+static int
+is_scalar_type (struct type *type)
+{
+  CHECK_TYPEDEF (type);
+
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_ARRAY:
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+    case TYPE_CODE_SET:
+    case TYPE_CODE_STRING:
+    case TYPE_CODE_BITSTRING:
+      return 0;
+    default:
+      return 1;
+    }
+}
+
+/* Return true if T is scalar, or a composite type which in practice has
+   the memory layout of a scalar type.  E.g., an array or struct with only
+   one scalar element inside it, or a union with only scalar elements.  */
+
+int
+is_scalar_type_recursive (struct type *t)
+{
+  CHECK_TYPEDEF (t);
+
+  if (is_scalar_type (t))
+    return 1;
+  /* Are we dealing with an array or string of known dimensions?  */
+  else if ((TYPE_CODE (t) == TYPE_CODE_ARRAY
+           || TYPE_CODE (t) == TYPE_CODE_STRING) && TYPE_NFIELDS (t) == 1
+          && TYPE_CODE (TYPE_INDEX_TYPE (t)) == TYPE_CODE_RANGE)
+    {
+      LONGEST low_bound, high_bound;
+      struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (t));
+
+      get_discrete_bounds (TYPE_INDEX_TYPE (t), &low_bound, &high_bound);
+
+      return high_bound == low_bound && is_scalar_type_recursive (elt_type);
+    }
+  /* Are we dealing with a struct with one element?  */
+  else if (TYPE_CODE (t) == TYPE_CODE_STRUCT && TYPE_NFIELDS (t) == 1)
+    return is_scalar_type_recursive (TYPE_FIELD_TYPE (t, 0));
+  else if (TYPE_CODE (t) == TYPE_CODE_UNION)
+    {
+      int i, n = TYPE_NFIELDS (t);
+
+      /* If all elements of the union are scalar, then the union is scalar.  */
+      for (i = 0; i < n; i++)
+       if (!is_scalar_type_recursive (TYPE_FIELD_TYPE (t, i)))
+         return 0;
+
+      return 1;
+    }
+
+  return 0;
+}
+
 /* A helper function which returns true if types A and B represent the
    "same" class type.  This is true if the types have the same main
    type, or the same name.  */
@@ -2039,7 +2129,8 @@ is_public_ancestor (struct type *base, struct type *dclass)
 static int
 is_unique_ancestor_worker (struct type *base, struct type *dclass,
                           int *offset,
-                          const bfd_byte *contents, CORE_ADDR address)
+                          const gdb_byte *valaddr, int embedded_offset,
+                          CORE_ADDR address, struct value *val)
 {
   int i, count = 0;
 
@@ -2048,11 +2139,13 @@ is_unique_ancestor_worker (struct type *base, struct type *dclass,
 
   for (i = 0; i < TYPE_N_BASECLASSES (dclass) && count < 2; ++i)
     {
-      struct type *iter = check_typedef (TYPE_BASECLASS (dclass, i));
-      int this_offset = baseclass_offset (dclass, i, contents, address);
+      struct type *iter;
+      int this_offset;
+
+      iter = check_typedef (TYPE_BASECLASS (dclass, i));
 
-      if (this_offset == -1)
-       error (_("virtual baseclass botch"));
+      this_offset = baseclass_offset (dclass, i, valaddr, embedded_offset,
+                                     address, val);
 
       if (class_types_same_p (base, iter))
        {
@@ -2074,8 +2167,9 @@ is_unique_ancestor_worker (struct type *base, struct type *dclass,
        }
       else
        count += is_unique_ancestor_worker (base, iter, offset,
-                                           contents + this_offset,
-                                           address + this_offset);
+                                           valaddr,
+                                           embedded_offset + this_offset,
+                                           address, val);
     }
 
   return count;
@@ -2090,8 +2184,9 @@ is_unique_ancestor (struct type *base, struct value *val)
   int offset = -1;
 
   return is_unique_ancestor_worker (base, value_type (val), &offset,
-                                   value_contents (val),
-                                   value_address (val)) == 1;
+                                   value_contents_for_printing (val),
+                                   value_embedded_offset (val),
+                                   value_address (val), val) == 1;
 }
 
 \f
@@ -3705,6 +3800,8 @@ gdbtypes_post_init (struct gdbarch *gdbarch)
     = lookup_pointer_type (builtin_type->builtin_void);
   builtin_type->builtin_func_ptr
     = lookup_pointer_type (lookup_function_type (builtin_type->builtin_void));
+  builtin_type->builtin_func_func
+    = lookup_function_type (builtin_type->builtin_func_ptr);
 
   /* This type represents a GDB internal function.  */
   builtin_type->internal_fn
@@ -3818,6 +3915,18 @@ objfile_type (struct objfile *objfile)
                 "<text variable, no debug info>", objfile);
   TYPE_TARGET_TYPE (objfile_type->nodebug_text_symbol)
     = objfile_type->builtin_int;
+  objfile_type->nodebug_text_gnu_ifunc_symbol
+    = init_type (TYPE_CODE_FUNC, 1, TYPE_FLAG_GNU_IFUNC,
+                "<text gnu-indirect-function variable, no debug info>",
+                objfile);
+  TYPE_TARGET_TYPE (objfile_type->nodebug_text_gnu_ifunc_symbol)
+    = objfile_type->nodebug_text_symbol;
+  objfile_type->nodebug_got_plt_symbol
+    = init_type (TYPE_CODE_PTR, gdbarch_addr_bit (gdbarch) / 8, 0,
+                "<text from jump slot in .got.plt, no debug info>",
+                objfile);
+  TYPE_TARGET_TYPE (objfile_type->nodebug_got_plt_symbol)
+    = objfile_type->nodebug_text_symbol;
   objfile_type->nodebug_data_symbol
     = init_type (TYPE_CODE_INT,
                 gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT, 0,
This page took 0.026988 seconds and 4 git commands to generate.