Thu Nov 20 04:11:27 1997 Geoffrey Noer <noer@cygnus.com>
[deliverable/binutils-gdb.git] / gdb / gdbtypes.c
index f5a8c3fb74f383df2da2d4ef3ab38bb208d90435..2f4e411fb3022e70ebb068c8ab118071aa533b7f 100644 (file)
@@ -1,5 +1,5 @@
 /* Support routines for manipulating internal types for GDB.
 /* Support routines for manipulating internal types for GDB.
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
 This file is part of GDB.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
 This file is part of GDB.
@@ -16,10 +16,10 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 
 #include "defs.h"
-#include <string.h>
+#include "gdb_string.h"
 #include "bfd.h"
 #include "symtab.h"
 #include "symfile.h"
 #include "bfd.h"
 #include "symtab.h"
 #include "symfile.h"
@@ -54,6 +54,18 @@ struct type *builtin_type_complex;
 struct type *builtin_type_double_complex;
 struct type *builtin_type_string;
 
 struct type *builtin_type_double_complex;
 struct type *builtin_type_string;
 
+struct extra { char str[128]; int len; }; /* maximum extention is 128! FIXME */
+
+static void add_name PARAMS ((struct extra *, char *));
+static void add_mangled_type PARAMS ((struct extra *, struct type *));
+#if 0
+static void cfront_mangle_name PARAMS ((struct type *, int, int));
+#endif
+static void print_bit_vector PARAMS ((B_TYPE *, int));
+static void print_arg_types PARAMS ((struct type **, int));
+static void dump_fn_fieldlists PARAMS ((struct type *, int));
+static void print_cplus_stuff PARAMS ((struct type *, int));
+
 /* Alloc a new type structure and fill it with some defaults.  If
    OBJFILE is non-NULL, then allocate the space for the type structure
    in that objfile's type_obstack. */
 /* Alloc a new type structure and fill it with some defaults.  If
    OBJFILE is non-NULL, then allocate the space for the type structure
    in that objfile's type_obstack. */
@@ -74,6 +86,7 @@ alloc_type (objfile)
     {
       type  = (struct type *) obstack_alloc (&objfile -> type_obstack,
                                             sizeof (struct type));
     {
       type  = (struct type *) obstack_alloc (&objfile -> type_obstack,
                                             sizeof (struct type));
+      OBJSTAT (objfile, n_types++);
     }
   memset ((char *) type, 0, sizeof (struct type));
 
     }
   memset ((char *) type, 0, sizeof (struct type));
 
@@ -323,7 +336,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
   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));
   TYPE_NFIELDS (result_type) = 2;
   TYPE_FIELDS (result_type) = (struct field *)
     TYPE_ALLOC (result_type, 2 * sizeof (struct field));
@@ -336,51 +349,68 @@ create_range_type (result_type, index_type, low_bound, high_bound)
   return (result_type);
 }
 
   return (result_type);
 }
 
-/* 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. */
+/* Set *LOWP and *HIGHP to the lower and upper bounds of discrete type TYPE.
+   Return 1 of type is a range type, 0 if it is discrete (and bounds
+   will fit in LONGEST), or -1 otherwise. */
 
 
-struct type *
-force_to_range_type (type)
+int
+get_discrete_bounds (type, lowp, highp)
      struct type *type;
      struct type *type;
+     LONGEST *lowp, *highp;
 {
 {
+  CHECK_TYPEDEF (type);
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_RANGE:
   switch (TYPE_CODE (type))
     {
     case TYPE_CODE_RANGE:
-      return type;
-
+      *lowp = TYPE_LOW_BOUND (type);
+      *highp = TYPE_HIGH_BOUND (type);
+      return 1;
     case TYPE_CODE_ENUM:
     case TYPE_CODE_ENUM:
-      {
-       int low_bound = TYPE_FIELD_BITPOS (type, 0);
-       int high_bound = TYPE_FIELD_BITPOS (type, TYPE_NFIELDS (type) - 1);
-       struct type *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;
-      }
+      if (TYPE_NFIELDS (type) > 0)
+       {
+         /* The enums may not be sorted by value, so search all
+            entries */
+         int i;
+
+         *lowp = *highp = TYPE_FIELD_BITPOS (type, 0);
+         for (i = 0; i < TYPE_NFIELDS (type); i++)
+           {
+             if (TYPE_FIELD_BITPOS (type, i) < *lowp)
+               *lowp = TYPE_FIELD_BITPOS (type, i);
+             if (TYPE_FIELD_BITPOS (type, i) > *highp)
+               *highp = TYPE_FIELD_BITPOS (type, i);
+           }
+       }
+      else
+       {
+         *lowp = 0;
+         *highp = -1;
+       }
+      return 0;
     case TYPE_CODE_BOOL:
     case TYPE_CODE_BOOL:
-      {
-       struct type *range_type = create_range_type (NULL, type, 0, 1);
-       TYPE_NAME (range_type) = TYPE_NAME (range_type);
-       TYPE_DUMMY_RANGE (range_type) = 1;
-       return range_type;
-      }
+      *lowp = 0;
+      *highp = 1;
+      return 0;
+    case TYPE_CODE_INT:
+      if (TYPE_LENGTH (type) > sizeof (LONGEST))  /* Too big */
+       return -1;
+      if (!TYPE_UNSIGNED (type))
+       {
+         *lowp = - (1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1));
+         *highp = -*lowp - 1;
+         return 0;
+       }
+      /* ... fall through for unsigned ints ... */
     case TYPE_CODE_CHAR:
     case TYPE_CODE_CHAR:
-      {
-       struct type *range_type = create_range_type (NULL, type, 0, 255);
-       TYPE_NAME (range_type) = TYPE_NAME (range_type);
-       TYPE_DUMMY_RANGE (range_type) = 1;
-       return range_type;
-      }
+      *lowp = 0;
+      /* This round-about calculation is to avoid shifting by
+        TYPE_LENGTH (type) * TARGET_CHAR_BIT, which will not work
+        if TYPE_LENGTH (type) == sizeof (LONGEST). */
+      *highp = 1 << (TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1);
+      *highp = (*highp - 1) | *highp;
+      return 0;
     default:
     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);
-      }
+      return -1;
     }
 }
 
     }
 }
 
@@ -399,18 +429,17 @@ create_array_type (result_type, element_type, range_type)
      struct type *element_type;
      struct 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;
   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;
   TYPE_LENGTH (result_type) =
     TYPE_LENGTH (element_type) * (high_bound - low_bound + 1);
   TYPE_NFIELDS (result_type) = 1;
@@ -420,6 +449,10 @@ create_array_type (result_type, element_type, range_type)
   TYPE_FIELD_TYPE (result_type, 0) = range_type;
   TYPE_VPTR_FIELDNO (result_type) = -1;
 
   TYPE_FIELD_TYPE (result_type, 0) = range_type;
   TYPE_VPTR_FIELDNO (result_type) = -1;
 
+  /* TYPE_FLAG_TARGET_STUB will take care of zero length arrays */
+  if (TYPE_LENGTH (result_type) == 0)
+    TYPE_FLAGS (result_type) |= TYPE_FLAG_TARGET_STUB;
+
   return (result_type);
 }
 
   return (result_type);
 }
 
@@ -451,7 +484,7 @@ create_set_type (result_type, domain_type)
      struct type *result_type;
      struct 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));
   if (result_type == NULL)
     {
       result_type = alloc_type (TYPE_OBJFILE (domain_type));
@@ -464,13 +497,11 @@ create_set_type (result_type, domain_type)
 
   if (! (TYPE_FLAGS (domain_type) & TYPE_FLAG_STUB))
     {
 
   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 = high_bound - low_bound + 1;
       TYPE_LENGTH (result_type)
-       = ((bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT)
-         * TARGET_CHAR_BIT;
+       = (bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
     }
   TYPE_FIELD_TYPE (result_type, 0) = domain_type;
   return (result_type);
     }
   TYPE_FIELD_TYPE (result_type, 0) = domain_type;
   return (result_type);
@@ -744,9 +775,14 @@ lookup_struct_elt_type (type, name, noerr)
 {
   int i;
 
 {
   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);
       type = TYPE_TARGET_TYPE (type);
+    }
 
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
       TYPE_CODE (type) != TYPE_CODE_UNION)
 
   if (TYPE_CODE (type) != TYPE_CODE_STRUCT &&
       TYPE_CODE (type) != TYPE_CODE_UNION)
@@ -758,8 +794,6 @@ lookup_struct_elt_type (type, name, noerr)
       error (" is not a structure or union type.");
     }
 
       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
 #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
@@ -822,7 +856,7 @@ void
 fill_in_vptr_fieldno (type)
      struct type *type;
 {
 fill_in_vptr_fieldno (type)
      struct type *type;
 {
-  check_stub_type (type);
+  CHECK_TYPEDEF (type);
 
   if (TYPE_VPTR_FIELDNO (type) < 0)
     {
 
   if (TYPE_VPTR_FIELDNO (type) < 0)
     {
@@ -845,6 +879,35 @@ fill_in_vptr_fieldno (type)
     }
 }
 
     }
 }
 
+/* Find the method and field indices for the destructor in class type T.
+   Return 1 if the destructor was found, otherwise, return 0.  */
+
+int
+get_destructor_fn_field (t, method_indexp, field_indexp)
+     struct type *t;
+     int *method_indexp;
+     int *field_indexp;
+{
+  int i;
+
+  for (i = 0; i < TYPE_NFN_FIELDS (t); i++)
+    {
+      int j;
+      struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
+
+      for (j = 0; j < TYPE_FN_FIELDLIST_LENGTH (t, i); j++)
+       {
+         if (DESTRUCTOR_PREFIX_P (TYPE_FN_FIELD_PHYSNAME (f, j)))
+           {
+             *method_indexp = i;
+             *field_indexp = j;
+             return 1;
+           }
+       }
+    }
+  return 0;
+}
+
 /* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
 
    If this is a stubbed struct (i.e. declared as struct foo *), see if
 /* Added by Bryan Boreham, Kewill, Sun Sep 17 18:07:17 1989.
 
    If this is a stubbed struct (i.e. declared as struct foo *), see if
@@ -861,11 +924,44 @@ fill_in_vptr_fieldno (type)
 struct complaint stub_noname_complaint =
   {"stub type has NULL name", 0, 0};
 
 struct complaint stub_noname_complaint =
   {"stub type has NULL name", 0, 0};
 
-void 
-check_stub_type (type)
-     struct type *type;
+struct type *
+check_typedef (type)
+     register struct type *type;
 {
 {
-  if (TYPE_FLAGS(type) & TYPE_FLAG_STUB)
+  struct type *orig_type = type;
+  while (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
+    {
+      if (!TYPE_TARGET_TYPE (type))
+       {
+         char* name;
+         struct symbol *sym;
+
+         /* It is dangerous to call lookup_symbol if we are currently
+            reading a symtab.  Infinite recursion is one danger. */
+         if (currently_reading_symtab)
+           return type;
+
+         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).  */
+         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) && ! currently_reading_symtab)
     {
       char* name = type_name_no_tag (type);
       /* FIXME: shouldn't we separately check the TYPE_NAME and the
     {
       char* name = type_name_no_tag (type);
       /* FIXME: shouldn't we separately check the TYPE_NAME and the
@@ -876,7 +972,7 @@ check_stub_type (type)
       if (name == NULL)
        {
          complain (&stub_noname_complaint);
       if (name == NULL)
        {
          complain (&stub_noname_complaint);
-         return;
+         return type;
        }
       sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, 
                           (struct symtab **) NULL);
        }
       sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, 
                           (struct symtab **) NULL);
@@ -891,9 +987,9 @@ check_stub_type (type)
   if (TYPE_FLAGS (type) & TYPE_FLAG_TARGET_STUB)
     {
       struct type *range_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
        { }
       else if (TYPE_CODE (type) == TYPE_CODE_ARRAY
               && TYPE_NFIELDS (type) == 1
@@ -906,16 +1002,215 @@ check_stub_type (type)
            ((TYPE_FIELD_BITPOS (range_type, 1)
              - TYPE_FIELD_BITPOS (range_type, 0)
              + 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_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;
        }
     }
          TYPE_FLAGS (type) &= ~TYPE_FLAG_TARGET_STUB;
        }
     }
+  /* Cache TYPE_LENGTH for future use. */
+  TYPE_LENGTH (orig_type) = TYPE_LENGTH (type);
+  return type;
+}
+
+/* New code added to support parsing of Cfront stabs strings */
+#include <ctype.h>
+#define INIT_EXTRA { pextras->len=0; pextras->str[0]='\0'; }
+#define ADD_EXTRA(c) { pextras->str[pextras->len++]=c; }
+
+static void 
+add_name(pextras,n) 
+  struct extra * pextras;
+  char * n; 
+{
+  int nlen;
+
+  if ((nlen = (n ? strlen(n) : 0))==0) 
+    return;
+  sprintf(pextras->str+pextras->len,"%d%s",nlen,n);
+  pextras->len=strlen(pextras->str);
+}
+
+static void 
+add_mangled_type(pextras,t) 
+  struct extra * pextras;
+  struct type * t;
+{
+  enum type_code tcode;
+  int tlen, tflags;
+  char * tname;
+
+  tcode = TYPE_CODE(t);
+  tlen = TYPE_LENGTH(t);
+  tflags = TYPE_FLAGS(t);
+  tname = TYPE_NAME(t);
+  /* args of "..." seem to get mangled as "e" */
+
+  switch (tcode) 
+    {
+      case TYPE_CODE_INT: 
+        if (tflags==1)
+          ADD_EXTRA('U');
+        switch (tlen) 
+          {
+            case 1:
+              ADD_EXTRA('c');
+              break;
+            case 2:
+              ADD_EXTRA('s');
+              break;
+            case 4: 
+              {
+              char* pname;
+              if ((pname=strrchr(tname,'l'),pname) && !strcmp(pname,"long"))
+                ADD_EXTRA('l')
+              else
+                ADD_EXTRA('i')
+              }
+              break;
+            default: 
+              {
+          
+                static struct complaint msg = {"Bad int type code length x%x\n",0,0};
+          
+                complain (&msg, tlen);
+          
+              }
+          }
+        break;
+      case TYPE_CODE_FLT: 
+          switch (tlen) 
+            {
+              case 4:
+                ADD_EXTRA('f');
+                break;
+              case 8:
+                ADD_EXTRA('d');
+                break;
+              case 16:
+                ADD_EXTRA('r');
+                break;
+              default: 
+               {
+                  static struct complaint msg = {"Bad float type code length x%x\n",0,0};
+                 complain (&msg, tlen);
+               }
+             }
+            break;
+      case TYPE_CODE_REF:
+        ADD_EXTRA('R');
+        /* followed by what it's a ref to */
+        break;
+      case TYPE_CODE_PTR:
+        ADD_EXTRA('P');
+        /* followed by what it's a ptr to */
+        break;
+      case TYPE_CODE_TYPEDEF: 
+        {
+          static struct complaint msg = {"Typedefs in overloaded functions not yet supported\n",0,0};
+          complain (&msg);
+        }
+      /* followed by type bytes & name */
+      break;
+    case TYPE_CODE_FUNC:
+      ADD_EXTRA('F');
+      /* followed by func's arg '_' & ret types */
+      break;
+    case TYPE_CODE_VOID:
+      ADD_EXTRA('v');
+      break;
+    case TYPE_CODE_METHOD:
+      ADD_EXTRA('M');
+      /* followed by name of class and func's arg '_' & ret types */
+      add_name(pextras,tname);
+      ADD_EXTRA('F');  /* then mangle function */
+      break;
+    case TYPE_CODE_STRUCT: /* C struct */
+    case TYPE_CODE_UNION:  /* C union */
+    case TYPE_CODE_ENUM:   /* Enumeration type */
+      /* followed by name of type */
+      add_name(pextras,tname);
+      break;
+
+    /* errors possible types/not supported */
+    case TYPE_CODE_CHAR:              
+    case TYPE_CODE_ARRAY:  /* Array type */
+    case TYPE_CODE_MEMBER: /* Member type */
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_COMPLEX:            /* Complex float */
+    case TYPE_CODE_UNDEF:
+    case TYPE_CODE_SET:                /* Pascal sets */
+    case TYPE_CODE_RANGE:  
+    case TYPE_CODE_STRING:
+    case TYPE_CODE_BITSTRING:
+    case TYPE_CODE_ERROR:
+    default: 
+      {
+        static struct complaint msg = {"Unknown type code x%x\n",0,0};
+        complain (&msg, tcode);
+      }
+    }
+  if (t->target_type)
+    add_mangled_type(pextras,t->target_type);
+}
+
+#if 0
+void
+cfront_mangle_name(type, i, j)
+     struct type *type;
+     int i;
+     int j;
+{
+   struct fn_field *f;
+   char *mangled_name = gdb_mangle_name (type, i, j);
+
+   f = TYPE_FN_FIELDLIST1 (type, i);   /* moved from below */
+
+   /* kludge to support cfront methods - gdb expects to find "F" for 
+      ARM_mangled names, so when we mangle, we have to add it here */
+   if (ARM_DEMANGLING) 
+     {
+       int k;
+       char * arm_mangled_name;
+       struct fn_field *method = &f[j];
+       char *field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+        char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
+        char *newname = type_name_no_tag (type);
+
+        struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
+       int nargs = TYPE_NFIELDS(ftype);        /* number of args */
+       struct extra extras, * pextras = &extras;       
+       INIT_EXTRA
+
+       if (TYPE_FN_FIELD_STATIC_P (f, j))      /* j for sublist within this list */
+         ADD_EXTRA('S')
+       ADD_EXTRA('F')
+       /* add args here! */
+       if (nargs <= 1)                         /* no args besides this */
+               ADD_EXTRA('v')
+       else {
+         for (k=1; k<nargs; k++) 
+           {
+             struct type * t;
+             t = TYPE_FIELD_TYPE(ftype,k);
+             add_mangled_type(pextras,t);
+           }
+       }
+       ADD_EXTRA('\0')
+       printf("add_mangled_type: %s\n",extras.str); /* FIXME */
+       arm_mangled_name = malloc(strlen(mangled_name)+extras.len);
+        sprintf(arm_mangled_name,"%s%s",mangled_name,extras.str);
+       free(mangled_name);
+       mangled_name = arm_mangled_name;
+     }
 }
 }
+#endif /* 0 */
+
+#undef ADD_EXTRA
+/* End of new code added to support parsing of Cfront stabs strings */
 
 /* Ugly hack to convert method stubs into method types.
 
 
 /* Ugly hack to convert method stubs into method types.
 
@@ -942,14 +1237,16 @@ check_stub_method (type, i, j)
   struct type **argtypes;
   struct type *mtype;
 
   struct type **argtypes;
   struct type *mtype;
 
-  if (demangled_name == NULL)
-    {
-      error ("Internal: Cannot demangle mangled name `%s'.", mangled_name);
-    }
+  /* Make sure we got back a function string that we can use.  */
+  if (demangled_name)
+    p = strchr (demangled_name, '(');
+
+  if (demangled_name == NULL || p == NULL)
+    error ("Internal: Cannot demangle mangled name `%s'.", mangled_name);
 
   /* Now, read in the parameters that define this type.  */
 
   /* Now, read in the parameters that define this type.  */
-  argtypetext = strchr (demangled_name, '(') + 1;
-  p = argtypetext;
+  p += 1;
+  argtypetext = p;
   while (*p)
     {
       if (*p == '(')
   while (*p)
     {
       if (*p == '(')
@@ -1019,7 +1316,8 @@ check_stub_method (type, i, j)
 
   free (demangled_name);
 
 
   free (demangled_name);
 
-  f = TYPE_FN_FIELDLIST1 (type, i);
+  f = TYPE_FN_FIELDLIST1 (type, i);    
+
   TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
 
   /* Now update the old "stub" type into a real type.  */
   TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
 
   /* Now update the old "stub" type into a real type.  */
@@ -1127,6 +1425,7 @@ lookup_fundamental_type (objfile, typeid)
       objfile -> fundamental_types = (struct type **)
        obstack_alloc (&objfile -> type_obstack, nbytes);
       memset ((char *) objfile -> fundamental_types, 0, nbytes);
       objfile -> fundamental_types = (struct type **)
        obstack_alloc (&objfile -> type_obstack, nbytes);
       memset ((char *) objfile -> fundamental_types, 0, nbytes);
+      OBJSTAT (objfile, n_types += FT_NUM_MEMBERS);
     }
 
   /* Look for this particular type in the fundamental type vector.  If one is
     }
 
   /* Look for this particular type in the fundamental type vector.  If one is
@@ -1146,6 +1445,7 @@ can_dereference (t)
      struct type *t;
 {
   /* FIXME: Should we return true for references as well as pointers?  */
      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
   return
     (t != NULL
      && TYPE_CODE (t) == TYPE_CODE_PTR
@@ -1335,6 +1635,8 @@ print_cplus_stuff (type, spaces)
     }
 }
 
     }
 }
 
+static struct obstack dont_print_type_obstack;
+
 void
 recursive_dump_type (type, spaces)
      struct type *type;
 void
 recursive_dump_type (type, spaces)
      struct type *type;
@@ -1342,6 +1644,32 @@ recursive_dump_type (type, spaces)
 {
   int idx;
 
 {
   int idx;
 
+  if (spaces == 0)
+    obstack_begin (&dont_print_type_obstack, 0);
+
+  if (TYPE_NFIELDS (type) > 0
+      || (TYPE_CPLUS_SPECIFIC (type) && TYPE_NFN_FIELDS (type) > 0))
+    {
+      struct type **first_dont_print
+       = (struct type **)obstack_base (&dont_print_type_obstack);
+
+      int i = (struct type **)obstack_next_free (&dont_print_type_obstack)
+       - first_dont_print;
+
+      while (--i >= 0)
+       {
+         if (type == first_dont_print[i])
+           {
+             printfi_filtered (spaces, "type node ");
+             gdb_print_address (type, gdb_stdout);
+             printf_filtered (" <same as already seen type>\n");
+             return;
+           }
+       }
+
+      obstack_ptr_grow (&dont_print_type_obstack, type);
+    }
+
   printfi_filtered (spaces, "type node ");
   gdb_print_address (type, gdb_stdout);
   printf_filtered ("\n");
   printfi_filtered (spaces, "type node ");
   gdb_print_address (type, gdb_stdout);
   printf_filtered ("\n");
@@ -1416,6 +1744,9 @@ recursive_dump_type (type, spaces)
       case TYPE_CODE_BOOL:
        printf_filtered ("(TYPE_CODE_BOOL)");
        break;
       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;
       default:
        printf_filtered ("(UNKNOWN TYPE CODE)");
        break;
@@ -1508,6 +1839,8 @@ recursive_dump_type (type, spaces)
        break;
 
     }
        break;
 
     }
+  if (spaces == 0)
+    obstack_free (&dont_print_type_obstack, NULL);
 }
 
 #endif /* MAINTENANCE_CMDS */
 }
 
 #endif /* MAINTENANCE_CMDS */
This page took 0.030562 seconds and 4 git commands to generate.