* gdbtypes.h (enum type_code): Added TYPE_CODE_TYPEDEF.
authorPer Bothner <per@bothner.com>
Thu, 30 Nov 1995 01:07:28 +0000 (01:07 +0000)
committerPer Bothner <per@bothner.com>
Thu, 30 Nov 1995 01:07:28 +0000 (01:07 +0000)
(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
gdb/ch-lang.c
gdb/ch-typeprint.c
gdb/gdbtypes.c
gdb/gdbtypes.h

index f15444a5701e0d20d8c225c55d1004851408e142..b064c1c3c5047daa8163ca54a89107f3eb2ac90b 100644 (file)
@@ -1,5 +1,28 @@
 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).
        
index 1e681f50b1a03de407696f4d9aac4f898916a9ba..a76ae4642713a3444dbd09416e188e682035e342 100644 (file)
@@ -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));
index ca0a1f6271a57daf40b17b949f250b6523c19935..c85ac90f1300cc0dc901eff9a234dff392f176b5 100644 (file)
@@ -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))
index f60232362cd51598fbac170c430fce3a4c653c58..36bf5a24f2721a5e016d78cf8c1cff1aa0cd5c1d 100644 (file)
@@ -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;
index 29d86014d7e92ca29494ed7718dce06efb4da055..59313d799fd4f5c06f2bb2f5736256d0345782b0 100644 (file)
@@ -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));