(check_typedef): New prototype.
(CHECK_TYPEDEF): New macro.
(TYPE_DUMMY_RANGE): Removed.
* gdbtypes.c (get_discrete_bounds): Fix paren error; make more robust.
(create_array_type): Don't force_to_range_type; users of the
array are responsible for handling non-range index types.
(create_set_type): Likewise.
(force_to_range_type): Removed.
(check_typedef): New function handles stub types and typedefs.
(check_stub_type): Just call check_typedef. (To be removed.)
(recursive_dump_type): Handle TYPE_CODE_TYPEDEF.
* ch-lang.c (type_lower_upper): Use get_discrete_bounds.
(evaluate_subexp_chill): Handle string repetition.
Re-arrange to handle EVAL_AVOID_SIDE_EFFECTS better.
* ch-typeprint.c (chill_type_print_base): Handle TYPE_CODE_TYPEDEF.
Pass show=0 in recursive calls various places.
(case TYPE_CODE_ARRAY): Don't require index type to have
TYPE_CODE_RANGE.
(case TYPE_CODE_RANGE): Don't need to support TYPE_DUMMY_RANGE.
* gdbtypes.c, ch-lang.c, ch-typeprint.c (numerous places):
Add check_typedef/CHECK_TYPEDEF as needed.
Wed Nov 29 13:35:18 1995 Per Bothner <bothner@kalessin.cygnus.com>
+ * gdbtypes.h (enum type_code): Added TYPE_CODE_TYPEDEF.
+ (check_typedef): New prototype.
+ (CHECK_TYPEDEF): New macro.
+ (TYPE_DUMMY_RANGE): Removed.
+ * gdbtypes.c (get_discrete_bounds): Fix paren error; make more robust.
+ (create_array_type): Don't force_to_range_type; users of the
+ array are responsible for handling non-range index types.
+ (create_set_type): Likewise.
+ (force_to_range_type): Removed.
+ (check_typedef): New function handles stub types and typedefs.
+ (check_stub_type): Just call check_typedef. (To be removed.)
+ (recursive_dump_type): Handle TYPE_CODE_TYPEDEF.
+ * ch-lang.c (type_lower_upper): Use get_discrete_bounds.
+ (evaluate_subexp_chill): Handle string repetition.
+ Re-arrange to handle EVAL_AVOID_SIDE_EFFECTS better.
+ * ch-typeprint.c (chill_type_print_base): Handle TYPE_CODE_TYPEDEF.
+ Pass show=0 in recursive calls various places.
+ (case TYPE_CODE_ARRAY): Don't require index type to have
+ TYPE_CODE_RANGE.
+ (case TYPE_CODE_RANGE): Don't need to support TYPE_DUMMY_RANGE.
+ * gdbtypes.c, ch-lang.c, ch-typeprint.c (numerous places):
+ Add check_typedef/CHECK_TYPEDEF as needed.
+
* top.c (command_line_input): Only strip out an initial #-comment.
Looking for internal comments is language-specific (breaks Scheme).
struct type *type;
struct type **result_type;
{
- LONGEST tmp;
- *result_type = builtin_type_int;
+ LONGEST low, high;
+ *result_type = type;
+ CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_STRUCT:
+ *result_type = builtin_type_int;
if (chill_varying_type (type))
return type_lower_upper (op, TYPE_FIELD_TYPE (type, 1), result_type);
break;
/* ... fall through ... */
case TYPE_CODE_RANGE:
- if (TYPE_DUMMY_RANGE (type) > 0)
- return type_lower_upper (op, TYPE_TARGET_TYPE (type), result_type);
*result_type = TYPE_TARGET_TYPE (type);
return op == UNOP_LOWER ? TYPE_LOW_BOUND (type) : TYPE_HIGH_BOUND (type);
case TYPE_CODE_ENUM:
- *result_type = type;
- if (TYPE_NFIELDS (type) > 0)
- return TYPE_FIELD_BITPOS (type,
- op == UNOP_LOWER ? 0
- : TYPE_NFIELDS (type) - 1);
-
case TYPE_CODE_BOOL:
- *result_type = type;
- return op == UNOP_LOWER ? 0 : 1;
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
- *result_type = type;
- tmp = (LONGEST) 1 << (TARGET_CHAR_BIT * TYPE_LENGTH (type));
- if (TYPE_UNSIGNED (type))
- return op == UNOP_LOWER ? 0 : tmp - (LONGEST) 1;
- tmp = tmp >> 1;
- return op == UNOP_LOWER ? -tmp : (tmp - 1);
+ if (get_discrete_bounds (type, &low, &high) >= 0)
+ {
+ *result_type = type;
+ return op == UNOP_LOWER ? low : high;
+ }
+ break;
case TYPE_CODE_UNDEF:
case TYPE_CODE_PTR:
case TYPE_CODE_UNION:
LONGEST tmp;
struct type *type = VALUE_TYPE (val);
struct type *ttype;
+ CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
switch (op)
{
case MULTI_SUBSCRIPT:
- if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
+ if (noside == EVAL_SKIP)
break;
(*pos) += 3;
nargs = longest_to_int (exp->elts[pc + 1].longconst);
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
+ type = check_typedef (VALUE_TYPE (arg1));
- switch (TYPE_CODE (VALUE_TYPE (arg1)))
+ if (nargs == 1 && TYPE_CODE (type) == TYPE_CODE_INT)
+ {
+ /* Looks like string repetition. */
+ value_ptr string = evaluate_subexp_with_coercion (exp, pos, noside);
+ return value_concat (arg1, string);
+ }
+
+ switch (TYPE_CODE (type))
{
case TYPE_CODE_PTR:
case TYPE_CODE_FUNC:
/* It's a function call. */
+ if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ break;
+
/* Allocate arg vector, including space for the function to be
called in argvec[0] and a terminating NULL */
argvec = (value_ptr *) alloca (sizeof (value_ptr) * (nargs + 2));
return;
}
- check_stub_type (type);
+ if (TYPE_CODE (type) != TYPE_CODE_TYPEDEF)
+ CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
+ case TYPE_CODE_TYPEDEF:
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
+ break;
case TYPE_CODE_PTR:
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_VOID)
{
break;
}
fprintf_filtered (stream, "REF ");
- chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
break;
case TYPE_CODE_BOOL:
break;
case TYPE_CODE_ARRAY:
- range_type = TYPE_FIELD_TYPE (type, 0);
- index_type = TYPE_TARGET_TYPE (range_type);
- low_bound = TYPE_FIELD_BITPOS (range_type, 0);
- high_bound = TYPE_FIELD_BITPOS (range_type, 1);
fputs_filtered ("ARRAY (", stream);
- print_type_scalar (index_type, low_bound, stream);
- fputs_filtered (":", stream);
- print_type_scalar (index_type, high_bound, stream);
+ range_type = TYPE_FIELD_TYPE (type, 0);
+ if (TYPE_CODE (range_type) != TYPE_CODE_RANGE)
+ chill_print_type (range_type, "", stream, 0, level);
+ else
+ {
+ index_type = TYPE_TARGET_TYPE (range_type);
+ low_bound = TYPE_FIELD_BITPOS (range_type, 0);
+ high_bound = TYPE_FIELD_BITPOS (range_type, 1);
+ print_type_scalar (index_type, low_bound, stream);
+ fputs_filtered (":", stream);
+ print_type_scalar (index_type, high_bound, stream);
+ }
fputs_filtered (") ", stream);
- chill_print_type (TYPE_TARGET_TYPE (type), "", stream, show, level);
+ chill_print_type (TYPE_TARGET_TYPE (type), "", stream, 0, level);
break;
case TYPE_CODE_BITSTRING:
case TYPE_CODE_MEMBER:
fprintf_filtered (stream, "MEMBER ");
- chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
break;
case TYPE_CODE_REF:
fprintf_filtered (stream, "/*LOC*/ ");
if (TYPE_CODE (param_type) == TYPE_CODE_REF)
{
chill_type_print_base (TYPE_TARGET_TYPE (param_type),
- stream, show, level);
+ stream, 0, level);
fputs_filtered (" LOC", stream);
}
else
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
{
fputs_filtered (" RETURNS (", stream);
- chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
+ chill_type_print_base (TYPE_TARGET_TYPE (type), stream, 0, level);
fputs_filtered (")", stream);
}
break;
if (chill_varying_type (type))
{
chill_type_print_base (TYPE_FIELD_TYPE (type, 1),
- stream, show, level);
+ stream, 0, level);
fputs_filtered (" VARYING", stream);
}
else
break;
case TYPE_CODE_RANGE:
- if (TYPE_DUMMY_RANGE (type) > 0)
- chill_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
- else
{
struct type *target = TYPE_TARGET_TYPE (type);
if (target && TYPE_NAME (target))
if (TYPE_FLAGS (index_type) & TYPE_FLAG_STUB)
TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
else
- TYPE_LENGTH (result_type) = TYPE_LENGTH (index_type);
+ TYPE_LENGTH (result_type) = TYPE_LENGTH (check_typedef (index_type));
TYPE_NFIELDS (result_type) = 2;
TYPE_FIELDS (result_type) = (struct field *)
TYPE_ALLOC (result_type, 2 * sizeof (struct field));
struct type *type;
LONGEST *lowp, *highp;
{
+ CHECK_TYPEDEF (type);
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
*highp = TYPE_HIGH_BOUND (type);
return 1;
case TYPE_CODE_ENUM:
- *lowp = TYPE_FIELD_BITPOS (type, 0);
- *highp = TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1);
+ if (TYPE_NFIELDS (type) > 0)
+ {
+ *lowp = TYPE_FIELD_BITPOS (type, 0);
+ *highp = TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1);
+ }
+ else
+ {
+ *lowp = 0;
+ *highp = -1;
+ }
return 0;
case TYPE_CODE_BOOL:
*lowp = 0;
/* ... fall through for unsigned ints ... */
case TYPE_CODE_CHAR:
*lowp = 0;
- *highp = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT) - 1;
+ *highp = (1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT)) - 1;
return 0;
default:
return -1;
}
}
-/* A lot of code assumes that the "index type" of an array/string/
- set/bitstring is specifically a range type, though in some languages
- it can be any discrete type. */
-
-struct type *
-force_to_range_type (type)
- struct type *type;
-{
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_RANGE:
- return type;
-
- case TYPE_CODE_ENUM:
- case TYPE_CODE_BOOL:
- case TYPE_CODE_CHAR:
- {
- LONGEST low_bound, high_bound;
- struct type *range_type;
- get_discrete_bounds (type, &low_bound, &high_bound);
- range_type = create_range_type (NULL, type, low_bound, high_bound);
- TYPE_NAME (range_type) = TYPE_NAME (range_type);
- TYPE_DUMMY_RANGE (range_type) = 1;
- return range_type;
- }
- default:
- {
- static struct complaint msg =
- { "array index type must be a discrete type", 0, 0};
- complain (&msg);
-
- return create_range_type (NULL, builtin_type_int, 0, 0);
- }
- }
-}
-
/* Create an array type using either a blank type supplied in RESULT_TYPE,
or creating a new type, inheriting the objfile from RANGE_TYPE.
struct type *element_type;
struct type *range_type;
{
- int low_bound;
- int high_bound;
+ LONGEST low_bound, high_bound;
- range_type = force_to_range_type (range_type);
if (result_type == NULL)
{
result_type = alloc_type (TYPE_OBJFILE (range_type));
}
TYPE_CODE (result_type) = TYPE_CODE_ARRAY;
TYPE_TARGET_TYPE (result_type) = element_type;
- low_bound = TYPE_LOW_BOUND (range_type);
- high_bound = TYPE_HIGH_BOUND (range_type);
+ if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0)
+ low_bound = high_bound = 0;
+ CHECK_TYPEDEF (element_type);
TYPE_LENGTH (result_type) =
TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
TYPE_NFIELDS (result_type) = 1;
struct type *result_type;
struct type *domain_type;
{
- int low_bound, high_bound, bit_length;
+ LONGEST low_bound, high_bound, bit_length;
if (result_type == NULL)
{
result_type = alloc_type (TYPE_OBJFILE (domain_type));
if (! (TYPE_FLAGS (domain_type) & TYPE_FLAG_STUB))
{
- domain_type = force_to_range_type (domain_type);
- low_bound = TYPE_LOW_BOUND (domain_type);
- high_bound = TYPE_HIGH_BOUND (domain_type);
+ if (get_discrete_bounds (domain_type, &low_bound, &high_bound) < 0)
+ low_bound = high_bound = 0;
bit_length = high_bound - low_bound + 1;
TYPE_LENGTH (result_type)
= (bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
{
int i;
- while (TYPE_CODE (type) == TYPE_CODE_PTR ||
- TYPE_CODE (type) == TYPE_CODE_REF)
+ for (;;)
+ {
+ CHECK_TYPEDEF (type);
+ if (TYPE_CODE (type) != TYPE_CODE_PTR
+ && TYPE_CODE (type) != TYPE_CODE_REF)
+ break;
type = TYPE_TARGET_TYPE (type);
+ }
if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
TYPE_CODE (type) != TYPE_CODE_UNION)
error (" is not a structure or union type.");
}
- check_stub_type (type);
-
#if 0
/* FIXME: This change put in by Michael seems incorrect for the case where
the structure tag name is the same as the member name. I.E. when doing
fill_in_vptr_fieldno (type)
struct type *type;
{
- check_stub_type (type);
+ CHECK_TYPEDEF (type);
if (TYPE_VPTR_FIELDNO (type) < 0)
{
struct complaint stub_noname_complaint =
{"stub type has NULL name", 0, 0};
-void
+void
check_stub_type (type)
struct type *type;
{
+ check_typedef (type);
+}
+
+struct type *
+check_typedef (type)
+ register struct type *type;
+{
+ struct type *orig_type = type;
+ while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+ {
+ if (!TYPE_TARGET_TYPE (type))
+ {
+ char* name = type_name_no_tag (type);
+ /* FIXME: shouldn't we separately check the TYPE_NAME and the
+ TYPE_TAG_NAME, and look in STRUCT_NAMESPACE and/or VAR_NAMESPACE
+ as appropriate? (this code was written before TYPE_NAME and
+ TYPE_TAG_NAME were separate). */
+ struct symbol *sym;
+ if (name == NULL)
+ {
+ complain (&stub_noname_complaint);
+ return type;
+ }
+ sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
+ (struct symtab **) NULL);
+ if (sym)
+ TYPE_TARGET_TYPE (type) = SYMBOL_TYPE (sym);
+ else
+ TYPE_TARGET_TYPE (type) = alloc_type (NULL); /* TYPE_CODE_UNDEF */
+ }
+ type = TYPE_TARGET_TYPE (type);
+ }
+
if (TYPE_FLAGS(type) & TYPE_FLAG_STUB)
{
char* name = type_name_no_tag (type);
if (name == NULL)
{
complain (&stub_noname_complaint);
- return;
+ return type;
}
sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0,
(struct symtab **) NULL);
if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
{
struct type *range_type;
+ struct type *target_type = check_typedef (TYPE_TARGET_TYPE (type));
- check_stub_type (TYPE_TARGET_TYPE (type));
- if (TYPE_FLAGS (TYPE_TARGET_TYPE (type)) & TYPE_FLAG_STUB)
+ if (TYPE_FLAGS (target_type) & TYPE_FLAG_STUB)
{ }
else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
&& TYPE_NFIELDS (type) == 1
((TYPE_FIELD_BITPOS (range_type, 1)
- TYPE_FIELD_BITPOS (range_type, 0)
+ 1)
- * TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
+ * TYPE_LENGTH (target_type));
TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
}
else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
{
- TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+ TYPE_LENGTH (type) = TYPE_LENGTH (target_type);
TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
}
}
+ /* Cache TYPE_LENGTH for future use. */
+ TYPE_LENGTH (orig_type) = TYPE_LENGTH (type);
+ return type;
}
/* Ugly hack to convert method stubs into method types.
struct type *t;
{
/* FIXME: Should we return true for references as well as pointers? */
+ CHECK_TYPEDEF (t);
return
(t != NULL
&& TYPE_CODE (t) == TYPE_CODE_PTR
case TYPE_CODE_BOOL:
printf_filtered ("(TYPE_CODE_BOOL)");
break;
+ case TYPE_CODE_TYPEDEF:
+ printf_filtered ("(TYPE_CODE_TYPEDEF)");
+ break;
default:
printf_filtered ("(UNKNOWN TYPE CODE)");
break;
TYPE_CODE_BOOL,
/* Fortran */
- TYPE_CODE_COMPLEX /* Complex float */
+ TYPE_CODE_COMPLEX, /* Complex float */
+
+ TYPE_CODE_TYPEDEF
};
/* For now allow source to use TYPE_CODE_CLASS for C++ classes, as an
#define TYPE_FLAG_STUB (1 << 2)
/* The target type of this type is a stub type, and this type needs to
- be updated if it gets un-stubbed in check_stub_type. Currently only
- used for arrays and ranges, in which TYPE_LENGTH of the array/range
- gets set based on the TYPE_LENGTH of the target type. */
+ be updated if it gets un-stubbed in check_typedef.
+ Used for arrays and ranges, in which TYPE_LENGTH of the array/range
+ gets set based on the TYPE_LENGTH of the target type.
+ Also, set for TYPE_CODE_TYPEDEF. */
#define TYPE_FLAG_TARGET_STUB (1 << 3)
#define TYPE_TARGET_TYPE(thistype) (thistype)->target_type
#define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
+/* Note that if thistype is a TYPEDEF type, you have to call check_typedef.
+ But check_typedef does set the TYPE_LENGTH of the TYPEDEF type,
+ so you only have to call check_typedef once. Since allocate_value
+ calls check_typedef, TYPE_LENGTH (VALUE_TYPE (X)) is safe. */
#define TYPE_LENGTH(thistype) (thistype)->length
#define TYPE_OBJFILE(thistype) (thistype)->objfile
#define TYPE_FLAGS(thistype) (thistype)->flags
#define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED)
+/* Note that TYPE_CODE can be TYPE_CODE_TYPEDEF, so if you wan the real
+ type, you need to do TYPE_CODE (check_type (this_type)). */
#define TYPE_CODE(thistype) (thistype)->code
#define TYPE_NFIELDS(thistype) (thistype)->nfields
#define TYPE_FIELDS(thistype) (thistype)->fields
#define TYPE_INDEX_TYPE(type) TYPE_FIELD_TYPE (type, 0)
#define TYPE_LOW_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 0)
#define TYPE_HIGH_BOUND(range_type) TYPE_FIELD_BITPOS (range_type, 1)
-/* If TYPE_DUMMY_RANGE is true for a range type, it was allocated
- by force_to_range_type. */
-#define TYPE_DUMMY_RANGE(type) ((type)->vptr_fieldno)
/* Moto-specific stuff for FORTRAN arrays */
extern struct type *
lookup_signed_typename PARAMS ((char *));
-extern void
-check_stub_type PARAMS ((struct type *));
+extern struct type *
+check_typedef PARAMS ((struct type *));
+
+#define CHECK_TYPEDEF(TYPE) (TYPE) = check_typedef (TYPE)
extern void
check_stub_method PARAMS ((struct type *, int, int));