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. */
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),
|| (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. */
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;
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))
{
}
else
count += is_unique_ancestor_worker (base, iter, offset,
- contents + this_offset,
- address + this_offset);
+ valaddr,
+ embedded_offset + this_offset,
+ address, val);
}
return count;
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
= 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
"<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,