#include "demangle.h"
#include "complaints.h"
#include "gdbcmd.h"
+#include "wrapper.h"
/* These variables point to the objects
representing the predefined C data types. */
struct type *builtin_type_int64;
struct type *builtin_type_uint64;
struct type *builtin_type_bool;
+struct type *builtin_type_v4sf;
+struct type *builtin_type_v4si;
+struct type *builtin_type_v8qi;
+struct type *builtin_type_v4hi;
+struct type *builtin_type_v2si;
+struct type *builtin_type_ptr;
+struct type *builtin_type_CORE_ADDR;
+struct type *builtin_type_bfd_vma;
int opaque_type_resolution = 1;
-
+int overload_debug = 0;
struct extra
{
return (result_type);
}
+
+/* Construct and return a type of the form:
+ struct NAME { ELT_TYPE ELT_NAME[N]; }
+ We use these types for SIMD registers. For example, the type of
+ the SSE registers on the late x86-family processors is:
+ struct __builtin_v4sf { float f[4]; }
+ built by the function call:
+ init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4)
+ The type returned is a permanent type, allocated using malloc; it
+ doesn't live in any objfile's obstack. */
+static struct type *
+init_simd_type (char *name,
+ struct type *elt_type,
+ char *elt_name,
+ int n)
+{
+ struct type *t;
+ struct field *f;
+
+ /* Build the field structure. */
+ f = xmalloc (sizeof (*f));
+ memset (f, 0, sizeof (*f));
+ f->loc.bitpos = 0;
+ f->type = create_array_type (0, elt_type,
+ create_range_type (0, builtin_type_int,
+ 0, n-1));
+ f->name = elt_name;
+
+ /* Build a struct type with that field. */
+ t = init_type (TYPE_CODE_STRUCT, n * TYPE_LENGTH (elt_type), 0, 0, 0);
+ t->nfields = 1;
+ t->fields = f;
+ t->tag_name = name;
+
+ return t;
+}
+
+
/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE.
A MEMBER is a wierd thing -- it amounts to a typed offset into
a struct, e.g. "an int at offset 8". A MEMBER TYPE doesn't
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
- if (t_field_name && STREQ (t_field_name, name))
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
return TYPE_FIELD_TYPE (type, i);
}
#undef ADD_EXTRA
/* End of new code added to support parsing of Cfront stabs strings */
+/* Parse a type expression in the string [P..P+LENGTH). If an error occurs,
+ silently return builtin_type_void. */
+
+struct type *
+safe_parse_type (char *p, int length)
+{
+ struct ui_file *saved_gdb_stderr;
+ struct type *type;
+
+ /* Suppress error messages. */
+ saved_gdb_stderr = gdb_stderr;
+ gdb_stderr = ui_file_new ();
+
+ /* Call parse_and_eval_type() without fear of longjmp()s. */
+ if (!gdb_parse_and_eval_type (p, length, &type))
+ type = builtin_type_void;
+
+ /* Stop suppressing error messages. */
+ ui_file_delete (gdb_stderr);
+ gdb_stderr = saved_gdb_stderr;
+
+ return type;
+}
+
/* Ugly hack to convert method stubs into method types.
He ain't kiddin'. This demangles the name of the method into a string
argtypetext = p;
while (*p)
{
- if (*p == '(')
+ if (*p == '(' || *p == '<')
{
depth += 1;
}
- else if (*p == ')')
+ else if (*p == ')' || *p == '>')
{
depth -= 1;
}
if (strncmp (argtypetext, "...", p - argtypetext) != 0)
{
argtypes[argcount] =
- parse_and_eval_type (argtypetext, p - argtypetext);
+ safe_parse_type (argtypetext, p - argtypetext);
argcount += 1;
}
argtypetext = p + 1;
}
- if (*p == '(')
+ if (*p == '(' || *p == '<')
{
depth += 1;
}
- else if (*p == ')')
+ else if (*p == ')' || *p == '>')
{
depth -= 1;
}
&& TYPE_CODE (TYPE_TARGET_TYPE (t)) != TYPE_CODE_VOID);
}
+int
+is_integral_type (t)
+ struct type *t;
+{
+ CHECK_TYPEDEF (t);
+ return
+ ((t != NULL)
+ && ((TYPE_CODE (t) == TYPE_CODE_INT)
+ || (TYPE_CODE (t) == TYPE_CODE_ENUM)
+ || (TYPE_CODE (t) == TYPE_CODE_CHAR)
+ || (TYPE_CODE (t) == TYPE_CODE_RANGE)
+ || (TYPE_CODE (t) == TYPE_CODE_BOOL)));
+}
+
/* Chill varying string and arrays are represented as follows:
struct { int __var_length; ELEMENT_TYPE[MAX_SIZE] __var_data};
count_virtual_fns (dclass)
struct type *dclass;
{
- int base; /* index for base classes */
int fn, oi; /* function and overloaded instance indices */
-
int vfuncs; /* count to return */
/* recurse on bases that can share virtual table */
/* Now rank all the parameters of the candidate function */
for (i = 1; i <= min_len; i++)
- bv->rank[i] = rank_one_type (parms[i - 1], args[i - 1]);
+ bv->rank[i] = rank_one_type (parms[i-1], args[i-1]);
/* If more arguments than parameters, add dummy entries */
for (i = min_len + 1; i <= nargs; i++)
if (TYPE_CODE (arg) == TYPE_CODE_TYPEDEF)
arg = check_typedef (arg);
+ /*
+ Well, damnit, if the names are exactly the same,
+ i'll say they are exactly the same. This happens when we generate
+ method stubs. The types won't point to the same address, but they
+ really are the same.
+ */
+
+ if (TYPE_NAME (parm) == TYPE_NAME (arg))
+ return 0;
+
/* Check if identical after resolving typedefs */
if (parm == arg)
return 0;
-#if 0
- /* Debugging only */
- printf ("------ Arg is %s [%d], parm is %s [%d]\n",
- TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm));
-#endif
+ /* See through references, since we can almost make non-references
+ references. */
+ if (TYPE_CODE (arg) == TYPE_CODE_REF)
+ return (rank_one_type (TYPE_TARGET_TYPE (arg), parm)
+ + REFERENCE_CONVERSION_BADNESS);
+ if (TYPE_CODE (parm) == TYPE_CODE_REF)
+ return (rank_one_type (arg, TYPE_TARGET_TYPE (parm))
+ + REFERENCE_CONVERSION_BADNESS);
+ if (overload_debug)
+ /* Debugging only. */
+ fprintf_filtered (gdb_stderr,"------ Arg is %s [%d], parm is %s [%d]\n",
+ TYPE_NAME (arg), TYPE_CODE (arg), TYPE_NAME (parm), TYPE_CODE (parm));
/* x -> y means arg of type x being supplied for parameter of type y */
{
if (TYPE_UNSIGNED (arg))
{
- if (!strcmp (TYPE_NAME (parm), TYPE_NAME (arg)))
+ if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg)))
return 0; /* unsigned int -> unsigned int, or unsigned long -> unsigned long */
- else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (TYPE_NAME (parm), "long"))
+ else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
return INTEGER_PROMOTION_BADNESS; /* unsigned int -> unsigned long */
else
return INTEGER_COERCION_BADNESS; /* unsigned long -> unsigned int */
}
else
{
- if (!strcmp (TYPE_NAME (arg), "long") && !strcmp (TYPE_NAME (parm), "int"))
+ if (!strcmp_iw (TYPE_NAME (arg), "long") && !strcmp_iw (TYPE_NAME (parm), "int"))
return INTEGER_COERCION_BADNESS; /* signed long -> unsigned int */
else
return INTEGER_CONVERSION_BADNESS; /* signed int/long -> unsigned int/long */
}
else if (!TYPE_NOSIGN (arg) && !TYPE_UNSIGNED (arg))
{
- if (!strcmp (TYPE_NAME (parm), TYPE_NAME (arg)))
+ if (!strcmp_iw (TYPE_NAME (parm), TYPE_NAME (arg)))
return 0;
- else if (!strcmp (TYPE_NAME (arg), "int") && !strcmp (TYPE_NAME (parm), "long"))
+ else if (!strcmp_iw (TYPE_NAME (arg), "int") && !strcmp_iw (TYPE_NAME (parm), "long"))
return INTEGER_PROMOTION_BADNESS;
else
return INTEGER_COERCION_BADNESS;
struct fn_field *f;
printfi_filtered (spaces, "fn_fieldlists ");
- gdb_print_address (TYPE_FN_FIELDLISTS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELDLISTS (type), gdb_stdout);
printf_filtered ("\n");
for (method_idx = 0; method_idx < TYPE_NFN_FIELDS (type); method_idx++)
{
printfi_filtered (spaces + 2, "[%d] name '%s' (",
method_idx,
TYPE_FN_FIELDLIST_NAME (type, method_idx));
- gdb_print_address (TYPE_FN_FIELDLIST_NAME (type, method_idx),
- gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELDLIST_NAME (type, method_idx),
+ gdb_stdout);
printf_filtered (") length %d\n",
TYPE_FN_FIELDLIST_LENGTH (type, method_idx));
for (overload_idx = 0;
printfi_filtered (spaces + 4, "[%d] physname '%s' (",
overload_idx,
TYPE_FN_FIELD_PHYSNAME (f, overload_idx));
- gdb_print_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
- gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELD_PHYSNAME (f, overload_idx),
+ gdb_stdout);
printf_filtered (")\n");
printfi_filtered (spaces + 8, "type ");
- gdb_print_address (TYPE_FN_FIELD_TYPE (f, overload_idx), gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELD_TYPE (f, overload_idx), gdb_stdout);
printf_filtered ("\n");
recursive_dump_type (TYPE_FN_FIELD_TYPE (f, overload_idx),
spaces + 8 + 2);
printfi_filtered (spaces + 8, "args ");
- gdb_print_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELD_ARGS (f, overload_idx), gdb_stdout);
printf_filtered ("\n");
print_arg_types (TYPE_FN_FIELD_ARGS (f, overload_idx), spaces);
printfi_filtered (spaces + 8, "fcontext ");
- gdb_print_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
- gdb_stdout);
+ gdb_print_host_address (TYPE_FN_FIELD_FCONTEXT (f, overload_idx),
+ gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces + 8, "is_const %d\n",
{
printfi_filtered (spaces, "virtual_field_bits (%d bits at *",
TYPE_N_BASECLASSES (type));
- gdb_print_address (TYPE_FIELD_VIRTUAL_BITS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_VIRTUAL_BITS (type), gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_VIRTUAL_BITS (type),
{
printfi_filtered (spaces, "private_field_bits (%d bits at *",
TYPE_NFIELDS (type));
- gdb_print_address (TYPE_FIELD_PRIVATE_BITS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_PRIVATE_BITS (type), gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_PRIVATE_BITS (type),
TYPE_NFIELDS (type));
{
printfi_filtered (spaces, "protected_field_bits (%d bits at *",
TYPE_NFIELDS (type));
- gdb_print_address (TYPE_FIELD_PROTECTED_BITS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_PROTECTED_BITS (type), gdb_stdout);
printf_filtered (")");
print_bit_vector (TYPE_FIELD_PROTECTED_BITS (type),
TYPE_NFIELDS (type));
if (type == first_dont_print[i])
{
printfi_filtered (spaces, "type node ");
- gdb_print_address (type, gdb_stdout);
+ gdb_print_host_address (type, gdb_stdout);
printf_filtered (" <same as already seen type>\n");
return;
}
}
printfi_filtered (spaces, "type node ");
- gdb_print_address (type, gdb_stdout);
+ gdb_print_host_address (type, gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "name '%s' (",
TYPE_NAME (type) ? TYPE_NAME (type) : "<NULL>");
- gdb_print_address (TYPE_NAME (type), gdb_stdout);
+ gdb_print_host_address (TYPE_NAME (type), gdb_stdout);
printf_filtered (")\n");
if (TYPE_TAG_NAME (type) != NULL)
{
printfi_filtered (spaces, "tagname '%s' (",
TYPE_TAG_NAME (type));
- gdb_print_address (TYPE_TAG_NAME (type), gdb_stdout);
+ gdb_print_host_address (TYPE_TAG_NAME (type), gdb_stdout);
printf_filtered (")\n");
}
printfi_filtered (spaces, "code 0x%x ", TYPE_CODE (type));
puts_filtered ("\n");
printfi_filtered (spaces, "length %d\n", TYPE_LENGTH (type));
printfi_filtered (spaces, "objfile ");
- gdb_print_address (TYPE_OBJFILE (type), gdb_stdout);
+ gdb_print_host_address (TYPE_OBJFILE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "target_type ");
- gdb_print_address (TYPE_TARGET_TYPE (type), gdb_stdout);
+ gdb_print_host_address (TYPE_TARGET_TYPE (type), gdb_stdout);
printf_filtered ("\n");
if (TYPE_TARGET_TYPE (type) != NULL)
{
recursive_dump_type (TYPE_TARGET_TYPE (type), spaces + 2);
}
printfi_filtered (spaces, "pointer_type ");
- gdb_print_address (TYPE_POINTER_TYPE (type), gdb_stdout);
+ gdb_print_host_address (TYPE_POINTER_TYPE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "reference_type ");
- gdb_print_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
+ gdb_print_host_address (TYPE_REFERENCE_TYPE (type), gdb_stdout);
printf_filtered ("\n");
printfi_filtered (spaces, "flags 0x%x", TYPE_FLAGS (type));
if (TYPE_FLAGS (type) & TYPE_FLAG_UNSIGNED)
}
puts_filtered ("\n");
printfi_filtered (spaces, "nfields %d ", TYPE_NFIELDS (type));
- gdb_print_address (TYPE_FIELDS (type), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELDS (type), gdb_stdout);
puts_filtered ("\n");
for (idx = 0; idx < TYPE_NFIELDS (type); idx++)
{
"[%d] bitpos %d bitsize %d type ",
idx, TYPE_FIELD_BITPOS (type, idx),
TYPE_FIELD_BITSIZE (type, idx));
- gdb_print_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_TYPE (type, idx), gdb_stdout);
printf_filtered (" name '%s' (",
TYPE_FIELD_NAME (type, idx) != NULL
? TYPE_FIELD_NAME (type, idx)
: "<NULL>");
- gdb_print_address (TYPE_FIELD_NAME (type, idx), gdb_stdout);
+ gdb_print_host_address (TYPE_FIELD_NAME (type, idx), gdb_stdout);
printf_filtered (")\n");
if (TYPE_FIELD_TYPE (type, idx) != NULL)
{
}
}
printfi_filtered (spaces, "vptr_basetype ");
- gdb_print_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
+ gdb_print_host_address (TYPE_VPTR_BASETYPE (type), gdb_stdout);
puts_filtered ("\n");
if (TYPE_VPTR_BASETYPE (type) != NULL)
{
case TYPE_CODE_METHOD:
case TYPE_CODE_FUNC:
printfi_filtered (spaces, "arg_types ");
- gdb_print_address (TYPE_ARG_TYPES (type), gdb_stdout);
+ gdb_print_host_address (TYPE_ARG_TYPES (type), gdb_stdout);
puts_filtered ("\n");
print_arg_types (TYPE_ARG_TYPES (type), spaces);
break;
case TYPE_CODE_STRUCT:
printfi_filtered (spaces, "cplus_stuff ");
- gdb_print_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
+ gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
puts_filtered ("\n");
print_cplus_stuff (type, spaces);
break;
the value. Pick cplus_struct_type, even though we know it isn't
any particular one. */
printfi_filtered (spaces, "type_specific ");
- gdb_print_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
+ gdb_print_host_address (TYPE_CPLUS_SPECIFIC (type), gdb_stdout);
if (TYPE_CPLUS_SPECIFIC (type) != NULL)
{
printf_filtered (" (unknown data form)");
&showlist);
opaque_type_resolution = 1;
+
+ /* Build SIMD types. */
+ builtin_type_v4sf
+ = init_simd_type ("__builtin_v4sf", builtin_type_float, "f", 4);
+ builtin_type_v4si
+ = init_simd_type ("__builtin_v4si", builtin_type_int32, "f", 4);
+ builtin_type_v8qi
+ = init_simd_type ("__builtin_v8qi", builtin_type_int8, "f", 8);
+ builtin_type_v4hi
+ = init_simd_type ("__builtin_v4hi", builtin_type_int16, "f", 4);
+ builtin_type_v2si
+ = init_simd_type ("__builtin_v2si", builtin_type_int32, "f", 2);
+
+ /* Pointer/Address types. */
+ /* NOTE: At present there is no way of differentiating between at
+ target address and the target C language pointer type type even
+ though the two can be different (cf d10v) */
+ builtin_type_ptr =
+ init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8,
+ TYPE_FLAG_UNSIGNED,
+ "__ptr", (struct objfile *) NULL);
+ builtin_type_CORE_ADDR =
+ init_type (TYPE_CODE_INT, TARGET_PTR_BIT / 8,
+ TYPE_FLAG_UNSIGNED,
+ "__CORE_ADDR", (struct objfile *) NULL);
+ builtin_type_bfd_vma =
+ init_type (TYPE_CODE_INT, TARGET_BFD_VMA_BIT / 8,
+ TYPE_FLAG_UNSIGNED,
+ "__bfd_vma", (struct objfile *) NULL);
}
void
_initialize_gdbtypes ()
{
+ struct cmd_list_element *c;
build_gdbtypes ();
/* FIXME - For the moment, handle types by swapping them in and out.
register_gdbarch_swap (&builtin_type_uint32, sizeof (struct type *), NULL);
register_gdbarch_swap (&builtin_type_int64, sizeof (struct type *), NULL);
register_gdbarch_swap (&builtin_type_uint64, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4sf, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4si, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v8qi, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v4hi, sizeof (struct type *), NULL);
+ register_gdbarch_swap (&builtin_type_v2si, sizeof (struct type *), NULL);
+ REGISTER_GDBARCH_SWAP (builtin_type_ptr);
+ REGISTER_GDBARCH_SWAP (builtin_type_CORE_ADDR);
+ REGISTER_GDBARCH_SWAP (builtin_type_bfd_vma);
register_gdbarch_swap (NULL, 0, build_gdbtypes);
+
+ add_show_from_set (
+ add_set_cmd ("overload", no_class, var_zinteger, (char *) &overload_debug,
+ "Set debugging of C++ overloading.\n\
+ When enabled, ranking of the functions\n\
+ is displayed.", &setdebuglist),
+ &showdebuglist);
}