From d1f4065e6499c42088b36a058b1de4035d051392 Mon Sep 17 00:00:00 2001 From: Per Bothner Date: Thu, 30 Nov 1995 01:07:28 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 23 ++++++++ gdb/ch-lang.c | 44 ++++++++------- gdb/ch-typeprint.c | 40 ++++++++------ gdb/gdbtypes.c | 134 +++++++++++++++++++++++++-------------------- gdb/gdbtypes.h | 26 ++++++--- 5 files changed, 161 insertions(+), 106 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f15444a570..b064c1c3c5 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,28 @@ Wed Nov 29 13:35:18 1995 Per Bothner + * 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). diff --git a/gdb/ch-lang.c b/gdb/ch-lang.c index 1e681f50b1..a76ae46427 100644 --- a/gdb/ch-lang.c +++ b/gdb/ch-lang.c @@ -304,11 +304,13 @@ type_lower_upper (op, type, result_type) 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; @@ -319,29 +321,19 @@ type_lower_upper (op, type, result_type) /* ... 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: @@ -367,6 +359,7 @@ value_chill_length (val) LONGEST tmp; struct type *type = VALUE_TYPE (val); struct type *ttype; + CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: @@ -404,17 +397,28 @@ evaluate_subexp_chill (expect_type, exp, pos, noside) 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)); diff --git a/gdb/ch-typeprint.c b/gdb/ch-typeprint.c index ca0a1f6271..c85ac90f13 100644 --- a/gdb/ch-typeprint.c +++ b/gdb/ch-typeprint.c @@ -99,10 +99,14 @@ chill_type_print_base (type, stream, show, level) 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) { @@ -111,7 +115,7 @@ chill_type_print_base (type, stream, show, level) 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: @@ -124,16 +128,21 @@ chill_type_print_base (type, stream, show, level) 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: @@ -158,7 +167,7 @@ chill_type_print_base (type, stream, show, level) 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*/ "); @@ -178,7 +187,7 @@ chill_type_print_base (type, stream, show, level) 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 @@ -188,7 +197,7 @@ chill_type_print_base (type, stream, show, level) 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; @@ -197,7 +206,7 @@ chill_type_print_base (type, stream, show, level) 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 @@ -269,9 +278,6 @@ chill_type_print_base (type, stream, show, level) 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)) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index f60232362c..36bf5a24f2 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -323,7 +323,7 @@ create_range_type (result_type, index_type, low_bound, high_bound) 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)); @@ -345,6 +345,7 @@ get_discrete_bounds (type, lowp, highp) struct type *type; LONGEST *lowp, *highp; { + CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_RANGE: @@ -352,8 +353,16 @@ get_discrete_bounds (type, lowp, highp) *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; @@ -371,49 +380,13 @@ get_discrete_bounds (type, lowp, highp) /* ... 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. @@ -429,18 +402,17 @@ create_array_type (result_type, element_type, 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; @@ -481,7 +453,7 @@ create_set_type (result_type, domain_type) 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)); @@ -494,9 +466,8 @@ create_set_type (result_type, 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; @@ -773,9 +744,14 @@ lookup_struct_elt_type (type, name, noerr) { 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) @@ -787,8 +763,6 @@ lookup_struct_elt_type (type, name, noerr) 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 @@ -851,7 +825,7 @@ void fill_in_vptr_fieldno (type) struct type *type; { - check_stub_type (type); + CHECK_TYPEDEF (type); if (TYPE_VPTR_FIELDNO (type) < 0) { @@ -890,10 +864,43 @@ fill_in_vptr_fieldno (type) 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); @@ -905,7 +912,7 @@ check_stub_type (type) if (name == NULL) { complain (&stub_noname_complaint); - return; + return type; } sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, (struct symtab **) NULL); @@ -920,9 +927,9 @@ check_stub_type (type) 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 @@ -935,15 +942,18 @@ check_stub_type (type) ((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. @@ -1175,6 +1185,7 @@ can_dereference (t) 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 @@ -1473,6 +1484,9 @@ recursive_dump_type (type, spaces) 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; diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 29d86014d7..59313d799f 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -120,7 +120,9 @@ enum type_code 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 @@ -145,9 +147,10 @@ enum type_code #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) @@ -486,10 +489,16 @@ allocate_cplus_struct_type PARAMS ((struct type *)); #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 @@ -497,9 +506,6 @@ allocate_cplus_struct_type PARAMS ((struct type *)); #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 */ @@ -734,8 +740,10 @@ lookup_unsigned_typename PARAMS ((char *)); 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));