Improve G++ debugging support.
authorJohn Gilmore <gnu@cygnus>
Wed, 27 Nov 1991 09:43:59 +0000 (09:43 +0000)
committerJohn Gilmore <gnu@cygnus>
Wed, 27 Nov 1991 09:43:59 +0000 (09:43 +0000)
gdb/ChangeLog
gdb/buildsym.c
gdb/coffread.c
gdb/mipsread.c
gdb/remote-vx.68.c
gdb/symtab.c
gdb/symtab.h
gdb/values.c

index 126f90f481a325d240e91f2f59c7631522df4d8c..43a2678e6274a30d90b6bb2d73d30cfacf93d495 100644 (file)
@@ -1,3 +1,36 @@
+Wed Nov 27 01:23:41 1991  John Gilmore  (gnu at cygnus.com)
+
+       Fix bugs in C++ debugging.
+
+       * symtab.h:  target_type is not used in record types.
+       Eliminate TYPE_MAIN_VARIANT and TYPE_NEXT_VARIANT.  Eliminate
+       lookup_method_type.
+
+       * symtab.c (lookup_member_type):  Don't chain them up, just
+       allocate one in symbol_obstack when we need one.
+       (allocate_stub_method):  Build stub in symbol_obstack.
+       (check_stub_method):  Move here from values.c.  Don't deallocate
+       stub; overwrite it.
+       (lookup_method_type):  Gone now.
+
+       * buildsym.c: Handle g++ v1 stabs a little bit better.
+       Change some C++ parsing error()s to complain()ts.
+       * buildsym.c, findvar.c, printcmd.c, symtab.c:  Make unions and
+       structs have the same representation and work the same as far as
+       C++ is concerned. 
+       * buildsym.c, symtab.c, values.c: Remove all references to
+       TYPE_MAIN_VARIANT and TYPE_NEXT_VARIANT.
+
+       * valops.c:  Improve comments and indentation.  Only call
+       check_stub_method when the stub flag is on.
+       * valprint.c:  Fix or mark minor bugs and unportabilities.
+       
+       * coffread.c (anonymous unions):  Allocate a cplus structure.
+
+       * mipsread.c:  Eliminate "template" types.  Build new, real
+       types whenever we need them.  Allocate cplus structures as needed.
+       Bulletproof the type parsing a bit more.  Mark storage leaks.
+
 Fri Nov 22 16:39:57 1991  John Gilmore  (gnu at cygnus.com)
 
        * inflow.c (terminal_inferior):  Check the results of ioctl's, and
index 83e2608e8eb038945d665f45bfe44c1fe92c306f..5021bfeffc0e25cf57d783abff57aad637e86ce7 100644 (file)
@@ -93,8 +93,17 @@ You seem to have compiled your program with \
 Therefore GDB will not know about your class variables", 0, 0};
 #endif
 
+struct complaint invalid_cpp_abbrev_complaint =
+  {"invalid C++ abbreviation `%s'", 0, 0};
+
+struct complaint invalid_cpp_type_complaint =
+  {"C++ abbreviated type name unknown at symtab pos %d", 0, 0};
+
+struct complaint member_fn_complaint =
+  {"member function type missing, got '%c'", 0, 0};
+
 struct complaint const_vol_complaint =
-  {"const/volatile indicator missing (ok if using g++ v1.x), got '%c'", 0, 0};
+  {"const/volatile indicator missing, got '%c'", 0, 0};
 
 struct complaint error_type_complaint =
   {"debug info mismatch between compiler and debugger", 0, 0};
@@ -1635,7 +1644,7 @@ read_type (pp)
        type = dbx_alloc_type (typenums);
        TYPE_CODE (type) = code;
        TYPE_NAME (type) = type_name;
-       if (code == TYPE_CODE_STRUCT)
+       if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
          {
            TYPE_CPLUS_SPECIFIC (type)
              = (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
@@ -1857,9 +1866,6 @@ read_struct_type (pp, type)
   register struct next_fnfieldlist *mainlist = 0;
   int nfn_fields = 0;
 
-  if (TYPE_MAIN_VARIANT (type) == 0)
-    TYPE_MAIN_VARIANT (type) = type;
-
   TYPE_CODE (type) = TYPE_CODE_STRUCT;
   TYPE_CPLUS_SPECIFIC (type)
     = (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
@@ -1996,20 +2002,22 @@ read_struct_type (pp, type)
                  prefix = vb_name;
                  break;
                default:
-                 error ("invalid abbreviation at symtab pos %d.", symnum);
+                 complain (&invalid_cpp_abbrev_complaint, *pp);
+                 prefix = "INVALID_C++_ABBREV";
+                 break;
                }
              *pp = p + 1;
              context = read_type (pp);
              name = type_name_no_tag (context);
              if (name == 0)
                {
-                 error ("type name unknown at symtab pos %d.", symnum);
+                 complain (&invalid_cpp_type_complaint, symnum);
                  TYPE_NAME (context) = name;
                }
              list->field.name = obconcat (prefix, name, "");
              p = ++(*pp);
              if (p[-1] != ':')
-               error ("invalid abbreviation at symtab pos %d.", symnum);
+               complain (&invalid_cpp_abbrev_complaint, *pp);
              list->field.type = read_type (pp);
              (*pp)++;                  /* Skip the comma.  */
              list->field.bitpos = read_number (pp, ';');
@@ -2020,7 +2028,7 @@ read_struct_type (pp, type)
          else if (*p == '_')
            break;
          else
-           error ("invalid abbreviation at symtab pos %d.", symnum);
+           complain (&invalid_cpp_abbrev_complaint, *pp);
 
          nfields++;
          continue;
@@ -2192,14 +2200,17 @@ read_struct_type (pp, type)
 
          /* read in the name.  */
          while (*p != ':') p++;
-#if 0
          if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == CPLUS_MARKER)
            {
+             /* This is a completely wierd case.  In order to stuff in the
+                names that might contain colons (the usual name delimiter),
+                Mike Tiemann defined a different name format which is
+                signalled if the identifier is "op$".  In that case, the
+                format is "op$::XXXX." where XXXX is the name.  This is
+                used for names like "+" or "=".  YUUUUUUUK!  FIXME!  */
              /* This lets the user type "break operator+".
                 We could just put in "+" as the name, but that wouldn't
                 work for "*".  */
-            /* I don't understand what this is trying to do.
-               It seems completely bogus.  -Per Bothner. */
              static char opname[32] = {'o', 'p', CPLUS_MARKER};
              char *o = opname + 3;
 
@@ -2214,7 +2225,6 @@ read_struct_type (pp, type)
              *pp = p + 1;
            }
          else
-#endif
              main_fn_name = savestring (*pp, p - *pp);
          /* Skip past '::'.  */
          *pp = p + 2;
@@ -2272,10 +2282,13 @@ read_struct_type (pp, type)
                  new_sublist->fn_field.is_volatile = 1;
                  (*pp)++;
                  break;
+               case '*': /* File compiled with g++ version 1 -- no info */
+               case '?':
+               case '.':
+                 break;
                default:
-                 /* This probably just means we're processing a file compiled
-                    with g++ version 1.  */
                  complain(&const_vol_complaint, **pp);
+                 break;
                }
 
              switch (*(*pp)++)
@@ -2320,8 +2333,13 @@ read_struct_type (pp, type)
                  /* static member function.  */
                  new_sublist->fn_field.voffset = VOFFSET_STATIC;
                  break;
+
                default:
-                 /* **pp == '.'.  */
+                 /* error */
+                 complain (&member_fn_complaint, (*pp)[-1]);
+                 /* Fall through into normal member function.  */
+
+               case '.':
                  /* normal member function.  */
                  new_sublist->fn_field.voffset = 0;
                  new_sublist->fn_field.fcontext = 0;
index 6a9b82fbc5cf5215ee218621e36be0a57ac43d50..f3447a5513a0ebed6aa7c0d47682e43bcbc449e0 100644 (file)
@@ -1816,6 +1816,10 @@ decode_base_type (cs, c_type, aux)
            /* anonymous union type */
            type = coff_alloc_type (cs->c_symnum);
            TYPE_NAME (type) = concat ("union ", "<opaque>", NULL);
+           TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
+             obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
+           bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type));
+           TYPE_LENGTH (type) = 0;
            TYPE_LENGTH (type) = 0;
            TYPE_FIELDS (type) = 0;
            TYPE_NFIELDS (type) = 0;
index 07e1a7c74d4c3628148b1b51f787eed9f729e412..1002dee5873975db7b992fc7044261d11591a191 100644 (file)
@@ -1,6 +1,6 @@
 /* Read a symbol table in MIPS' format (Third-Eye).
-   Copyright (C) 1986, 1987, 1989-1991 Free Software Foundation, Inc.
-   Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU
+   Copyright 1986, 1987, 1989, 1990, 1991 Free Software Foundation, Inc.
+   Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU.
 
 This file is part of GDB.
 
@@ -161,15 +161,6 @@ struct type *builtin_type_fixed_dec;
 struct type *builtin_type_float_dec;
 struct type *builtin_type_string;
 
-/* Template types */
-
-static struct type *builtin_type_ptr;
-static struct type *builtin_type_struct;
-static struct type *builtin_type_union;
-static struct type *builtin_type_enum;
-static struct type *builtin_type_range;
-static struct type *builtin_type_set;
-
 /* Forward declarations */
 
 static struct symbol   *new_symbol();
@@ -243,9 +234,6 @@ mipscoff_symfile_read(sf, addr, mainline)
   int symtab_offset;
   int stringtab_offset;
 
-  /* Initialize a variable that we couldn't do at _initialize_ time. */
-  builtin_type_ptr = lookup_pointer_type (builtin_type_void);
-
 /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
    desc = fileno ((FILE *)(abfd->iostream));   /* Raw file descriptor */
 /* End of warning */
@@ -1066,7 +1054,7 @@ static struct type *parse_type(ax, sh, bs)
 
        TIR            *t;
        struct type    *tp = 0, *tp1;
-       char           *fmt = "%s";
+       char           *fmt;
 
        /* Procedures start off by one */
        if (sh->st == stProc || sh->st == stStaticProc)
@@ -1079,38 +1067,43 @@ static struct type *parse_type(ax, sh, bs)
 
        /* Use aux as a type information record, map its basic type */
        t = &ax->ti;
-       if (t->bt > 26 || t->bt == btPicture) {
+       if (t->bt > (sizeof (map_bt)/sizeof (*map_bt))) {
                complain (&basic_type_complaint, t->bt);
                return builtin_type_int;
        }
        if (map_bt[t->bt])
                tp = *map_bt[t->bt];
+               fmt = "%s";
        else {
-               /* Cannot use builtin types, use templates */
-               tp = make_type(TYPE_CODE_VOID, 0, 0, 0);
+               /* Cannot use builtin types -- build our own */
                switch (t->bt) {
                    case btAdr:
-                       *tp = *builtin_type_ptr;
+                       tp = lookup_pointer_type (builtin_type_void);
+                       fmt = "%s";
                        break;
                    case btStruct:
-                       *tp = *builtin_type_struct;
+                       tp = make_struct_type(TYPE_CODE_STRUCT, 0, 0, 0);
                        fmt = "struct %s";
                        break;
                    case btUnion:
-                       *tp = *builtin_type_union;
+                       tp = make_struct_type(TYPE_CODE_UNION, 0, 0, 0);
                        fmt = "union %s";
                        break;
                    case btEnum:
-                       *tp = *builtin_type_enum;
+                       tp = make_type(TYPE_CODE_ENUM, 0, 0, 0);
                        fmt = "enum %s";
                        break;
                    case btRange:
-                       *tp = *builtin_type_range;
+                       tp = make_type(TYPE_CODE_RANGE, 0, 0, 0);
+                       fmt = "%s";
                        break;
                    case btSet:
-                       *tp = *builtin_type_set;
+                       tp = make_type(TYPE_CODE_SET, 0, 0, 0);
                        fmt = "set %s";
                        break;
+                   default:
+                       complain (&basic_type_complaint, t->bt);
+                       return builtin_type_int;
                }
        }
 
@@ -2548,6 +2541,7 @@ make_type(code, length, uns, name)
 {
        register struct type *type;
 
+       /* FIXME, I don't think this ever gets freed.  */
        type = (struct type *) xzalloc(sizeof(struct type));
        TYPE_CODE(type) = code;
        TYPE_LENGTH(type) = length;
@@ -2558,6 +2552,25 @@ make_type(code, length, uns, name)
        return type;
 }
 
+/* Create and initialize a new struct or union type, a la make_type.  */
+
+static
+struct type *
+make_struct_type(code, length, uns, name)
+     enum type_code code;
+     int length, uns;
+     char *name;
+{
+       register struct type *type;
+
+       type = make_type (code, length, uns, name);
+       
+       /* FIXME, I don't think this ever gets freed.  */
+       TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
+         xzalloc (sizeof (struct cplus_struct_type));
+       return type;
+}
+
 /* Allocate a new field named NAME to the type TYPE */
 
 static
@@ -2795,15 +2808,4 @@ _initialize_mipsread ()
                                           0, "fixed_decimal");
        builtin_type_float_dec = make_type(TYPE_CODE_FLT, sizeof(double),
                                           0, "floating_decimal");
-
-       /* Templates types */
-       builtin_type_struct = make_type(TYPE_CODE_STRUCT, 0, 0, 0);
-       builtin_type_union = make_type(TYPE_CODE_UNION, 0, 0, 0);
-       builtin_type_enum = make_type(TYPE_CODE_ENUM, 0, 0, 0);
-       builtin_type_range = make_type(TYPE_CODE_RANGE, 0, 0, 0);
-       builtin_type_set = make_type(TYPE_CODE_SET, 0, 0, 0);
-
-       /* We can't do this now because builtin_type_void may not
-          be set yet.  Do it at symbol reading time.  */
-       /* builtin_type_ptr = lookup_pointer_type (builtin_type_void); */
 }
index 4848ca2d6d0645ef36fbe2d40f60980725401324..3a46d213561c63c9ffa7feae31f9b87974a42185 100644 (file)
@@ -318,7 +318,8 @@ vx_call_function (function, nargs, args)
        to the structure, not the structure itself.  */
     if (REG_STRUCT_HAS_ADDR (using_gcc))
       for (i = nargs - 1; i >= 0; i--)
-       if (TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT)
+       if (   TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT
+           || TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_UNION)
          {
            CORE_ADDR addr;
 #if !(1 INNER_THAN 2)
index 488bc7ece9aae936c8e8964bbe10a33dc956fed8..3c5eea356912ca70a24c1b5a4e67227a682de1bb 100644 (file)
@@ -393,7 +393,7 @@ lookup_template_type (name, type, block)
   strcpy(nam, name);
   strcat(nam, "<");
   strcat(nam, type->name);
-  strcat(nam, " >");           /* extra space still introduced in gcc? */
+  strcat(nam, " >");   /* FIXME, extra space still introduced in gcc? */
 
   sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **)NULL);
 
@@ -416,7 +416,7 @@ lookup_struct_elt_type (type, name, noerr)
 {
   int i;
 
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+  if (   TYPE_CODE (type) != TYPE_CODE_STRUCT
       && TYPE_CODE (type) != TYPE_CODE_UNION)
     {
       target_terminal_ours ();
@@ -524,212 +524,118 @@ struct type *
 lookup_member_type (type, domain)
      struct type *type, *domain;
 {
-  register struct type *mtype = TYPE_MAIN_VARIANT (type);
-  struct type *main_type;
-
-  main_type = mtype;
-  while (mtype)
-    {
-      if (TYPE_DOMAIN_TYPE (mtype) == domain)
-       return mtype;
-      mtype = TYPE_NEXT_VARIANT (mtype);
-    }
-
-  /* This is the first time anyone wanted this member type.  */
-  if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    mtype  = (struct type *) xmalloc (sizeof (struct type));
-  else
-    mtype  = (struct type *) obstack_alloc (symbol_obstack,
-                                           sizeof (struct type));
-
-  bzero (mtype, sizeof (struct type));
-  if (main_type == 0)
-    main_type = mtype;
-  else
-    {
-      TYPE_NEXT_VARIANT (mtype) = TYPE_NEXT_VARIANT (main_type);
-      TYPE_NEXT_VARIANT (main_type) = mtype;
-    }
-  TYPE_MAIN_VARIANT (mtype) = main_type;
-  TYPE_TARGET_TYPE (mtype) = type;
-  TYPE_DOMAIN_TYPE (mtype) = domain;
-  /* New type is permanent if type pointed to is permanent.  */
-  if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
-
-  /* In practice, this is never used.  */
-  TYPE_LENGTH (mtype) = 1;
-  TYPE_CODE (mtype) = TYPE_CODE_MEMBER;
-
-#if 0
-  /* Now splice in the new member pointer type.  */
-  if (main_type)
-    {
-      /* This type was not "smashed".  */
-      TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
-      TYPE_CHAIN (main_type) = mtype;
-    }
-#endif
+  register struct type *mtype;
 
+  mtype  = (struct type *) obstack_alloc (symbol_obstack,
+                                         sizeof (struct type));
+  smash_to_member_type (mtype, domain, type);
   return mtype;
 }
 
-/* Allocate a stub method whose return type is
-   TYPE.  We will fill in arguments later.  This always
-   returns a fresh type.  If we unify this type with
-   an existing type later, the storage allocated
-   here can be freed.  */
+/* Allocate a stub method whose return type is TYPE.  
+   This apparently happens for speed of symbol reading, since parsing
+   out the arguments to the method is cpu-intensive, the way we are doing
+   it.  So, we will fill in arguments later.
+   This always returns a fresh type.   */
+
 struct type *
 allocate_stub_method (type)
      struct type *type;
 {
-  struct type *mtype = (struct type *)xmalloc (sizeof (struct type));
+  struct type *mtype = (struct type *) obstack_alloc (symbol_obstack,
+                                                     sizeof (struct type));
   bzero (mtype, sizeof (struct type));
-  TYPE_MAIN_VARIANT (mtype) = mtype;
   TYPE_TARGET_TYPE (mtype) = type;
+  /*  _DOMAIN_TYPE (mtype) = unknown yet */
+  /*  _ARG_TYPES (mtype) = unknown yet */
   TYPE_FLAGS (mtype) = TYPE_FLAG_STUB;
   TYPE_CODE (mtype) = TYPE_CODE_METHOD;
   TYPE_LENGTH (mtype) = 1;
   return mtype;
 }
 
-/* Lookup a method type belonging to class DOMAIN, returning type TYPE,
-   and taking a list of arguments ARGS.
-   If one is not found, allocate a new one.  */
+/* Ugly hack to convert method stubs into method types.
 
-struct type *
-lookup_method_type (domain, type, args)
-     struct type *domain, *type, **args;
+   He ain't kiddin'.  This demangles the name of the method into a string
+   including argument types, parses out each argument type, generates
+   a string casting a zero to that type, evaluates the string, and stuffs
+   the resulting type into an argtype vector!!!  Then it knows the type
+   of the whole function (including argument types for overloading),
+   which info used to be in the stab's but was removed to hack back
+   the space required for them.  */
+void
+check_stub_method (type, i, j)
+     struct type *type;
+     int i, j;
 {
-  register struct type *mtype = TYPE_MAIN_VARIANT (type);
-  struct type *main_type;
-
-  main_type = mtype;
-  while (mtype)
-    {
-      if (TYPE_DOMAIN_TYPE (mtype) == domain)
+  extern char *gdb_mangle_name (), *strchr ();
+  struct fn_field *f;
+  char *mangled_name = gdb_mangle_name (type, i, j);
+  char *demangled_name = cplus_demangle (mangled_name, 0);
+  char *argtypetext, *p;
+  int depth = 0, argcount = 1;
+  struct type **argtypes;
+  struct type *mtype;
+
+  /* Now, read in the parameters that define this type.  */
+  argtypetext = strchr (demangled_name, '(') + 1;
+  p = argtypetext;
+  while (*p)
+    {
+      if (*p == '(')
+       depth += 1;
+      else if (*p == ')')
+       depth -= 1;
+      else if (*p == ',' && depth == 0)
+       argcount += 1;
+
+      p += 1;
+    }
+  /* We need one more slot for the void [...] or NULL [end of arglist] */
+  argtypes = (struct type **) obstack_alloc (symbol_obstack,
+                               (argcount+1) * sizeof (struct type *));
+  p = argtypetext;
+  argtypes[0] = lookup_pointer_type (type);
+  argcount = 1;
+
+  if (*p != ')')                       /* () means no args, skip while */
+    {
+      depth = 0;
+      while (*p)
        {
-         struct type **t1 = args;
-         struct type **t2 = TYPE_ARG_TYPES (mtype);
-         if (t2)
+         if (depth <= 0 && (*p == ',' || *p == ')'))
            {
-             int i;
-             for (i = 0; t1[i] != 0 && t1[i]->code != TYPE_CODE_VOID; i++)
-               if (t1[i] != t2[i])
-                 break;
-             if (t1[i] == t2[i])
-               return mtype;
+             argtypes[argcount] =
+                 parse_and_eval_type (argtypetext, p - argtypetext);
+             argcount += 1;
+             argtypetext = p + 1;
            }
-       }
-      mtype = TYPE_NEXT_VARIANT (mtype);
-    }
 
-  /* This is the first time anyone wanted this member type.  */
-  if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    mtype  = (struct type *) xmalloc (sizeof (struct type));
-  else
-    mtype  = (struct type *) obstack_alloc (symbol_obstack,
-                                           sizeof (struct type));
+         if (*p == '(')
+           depth += 1;
+         else if (*p == ')')
+           depth -= 1;
 
-  bzero (mtype, sizeof (struct type));
-  if (main_type == 0)
-    main_type = mtype;
-  else
-    {
-      TYPE_NEXT_VARIANT (mtype) = TYPE_NEXT_VARIANT (main_type);
-      TYPE_NEXT_VARIANT (main_type) = mtype;
-    }
-  TYPE_MAIN_VARIANT (mtype) = main_type;
-  TYPE_TARGET_TYPE (mtype) = type;
-  TYPE_DOMAIN_TYPE (mtype) = domain;
-  TYPE_ARG_TYPES (mtype) = args;
-  /* New type is permanent if type pointed to is permanent.  */
-  if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
-
-  /* In practice, this is never used.  */
-  TYPE_LENGTH (mtype) = 1;
-  TYPE_CODE (mtype) = TYPE_CODE_METHOD;
-
-#if 0
-  /* Now splice in the new member pointer type.  */
-  if (main_type)
-    {
-      /* This type was not "smashed".  */
-      TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
-      TYPE_CHAIN (main_type) = mtype;
-    }
-#endif
-
-  return mtype;
-}
-
-#if 0
-/* Given a type TYPE, return a type which has offset OFFSET,
-   via_virtual VIA_VIRTUAL, and via_public VIA_PUBLIC.
-   May need to construct such a type if none exists.  */
-struct type *
-lookup_basetype_type (type, offset, via_virtual, via_public)
-     struct type *type;
-     int offset;
-     int via_virtual, via_public;
-{
-  register struct type *btype = TYPE_MAIN_VARIANT (type);
-  struct type *main_type;
-
-  if (offset != 0)
-    {
-      printf ("Internal error: type offset non-zero in lookup_basetype_type");
-      offset = 0;
-    }
-
-  main_type = btype;
-  while (btype)
-    {
-      if (/* TYPE_OFFSET (btype) == offset
-         && */ TYPE_VIA_PUBLIC (btype) == via_public
-         && TYPE_VIA_VIRTUAL (btype) == via_virtual)
-       return btype;
-      btype = TYPE_NEXT_VARIANT (btype);
+         p += 1;
+       }
     }
 
-  /* This is the first time anyone wanted this member type.  */
-  if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    btype  = (struct type *) xmalloc (sizeof (struct type));
+  if (p[-2] != '.')                    /* ... */
+    argtypes[argcount] = builtin_type_void;    /* Ellist terminator */
   else
-    btype  = (struct type *) obstack_alloc (symbol_obstack,
-                                           sizeof (struct type));
+    argtypes[argcount] = NULL;         /* List terminator */
 
-  if (main_type == 0)
-    {
-      main_type = btype;
-      bzero (btype, sizeof (struct type));
-      TYPE_MAIN_VARIANT (btype) = main_type;
-    }
-  else
-    {
-      bcopy (main_type, btype, sizeof (struct type));
-      TYPE_NEXT_VARIANT (main_type) = btype;
-    }
-/* TYPE_OFFSET (btype) = offset; */
-  if (via_public)
-    TYPE_FLAGS (btype) |= TYPE_FLAG_VIA_PUBLIC;
-  if (via_virtual)
-    TYPE_FLAGS (btype) |= TYPE_FLAG_VIA_VIRTUAL;
-  /* New type is permanent if type pointed to is permanent.  */
-  if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
-    TYPE_FLAGS (btype) |= TYPE_FLAG_PERM;
+  free (demangled_name);
 
-  /* In practice, this is never used.  */
-  TYPE_LENGTH (btype) = 1;
-  TYPE_CODE (btype) = TYPE_CODE_STRUCT;
-  TYPE_CPLUS_SPECIFIC (btype)
-    = (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)));
-  bzero (TYPE_CPLUS_SPECIFIC (btype), sizeof (struct cplus_struct_type));
+  f = TYPE_FN_FIELDLIST1 (type, i);
+  TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
 
-  return btype;
+  /* Now update the old "stub" type into a real type.  */
+  mtype = TYPE_FN_FIELD_TYPE (f, j);
+  TYPE_DOMAIN_TYPE (mtype) = type;
+  TYPE_ARG_TYPES (mtype) = argtypes;
+  TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
 }
-#endif
 
 /* Given a type TYPE, return a type of functions that return that type.
    May need to construct such a type if this is the first use.  */
@@ -813,7 +719,11 @@ create_array_type (element_type, number)
 }
 
 \f
-/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE.  */
+/* 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
+   include the offset (that's the value of the MEMBER itself), but does
+   include the structure type into which it points (for some reason).  */
 
 void
 smash_to_member_type (type, domain, to_type)
@@ -822,15 +732,12 @@ smash_to_member_type (type, domain, to_type)
   bzero (type, sizeof (struct type));
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
-
-  /* In practice, this is never needed.  */
-  TYPE_LENGTH (type) = 1;
+  TYPE_LENGTH (type) = 1;      /* In practice, this is never needed.  */
   TYPE_CODE (type) = TYPE_CODE_MEMBER;
-
-  TYPE_MAIN_VARIANT (type) = lookup_member_type (domain, to_type);
 }
 
-/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.  */
+/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.
+   METHOD just means `function that gets an extra "this" argument'.  */
 
 void
 smash_to_method_type (type, domain, to_type, args)
@@ -840,12 +747,8 @@ smash_to_method_type (type, domain, to_type, args)
   TYPE_TARGET_TYPE (type) = to_type;
   TYPE_DOMAIN_TYPE (type) = domain;
   TYPE_ARG_TYPES (type) = args;
-
-  /* In practice, this is never needed.  */
-  TYPE_LENGTH (type) = 1;
+  TYPE_LENGTH (type) = 1;      /* In practice, this is never needed.  */
   TYPE_CODE (type) = TYPE_CODE_METHOD;
-
-  TYPE_MAIN_VARIANT (type) = lookup_method_type (domain, to_type, args);
 }
 \f
 /* Find which partial symtab on the partial_symtab_list contains
@@ -1988,7 +1891,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
                                     (struct symtab **)NULL);
        
          if (sym_class &&
-             (TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT
+             (   TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT
               || TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_UNION))
            {
              /* Arg token is not digits => try it as a function name
@@ -2772,11 +2675,10 @@ init_type (code, length, uns, name)
   TYPE_NAME (type) = name;
 
   /* C++ fancies.  */
-  if (code == TYPE_CODE_STRUCT)
+  if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
     {
       TYPE_CPLUS_SPECIFIC (type)
        = (struct cplus_struct_type *) xmalloc (sizeof (struct cplus_struct_type));
-      TYPE_MAIN_VARIANT (type) = type;
       TYPE_NFN_FIELDS (type) = 0;
       TYPE_N_BASECLASSES (type) = 0;
     }
index 8675a76011702a808cf287d534d4cc14825e93c7..801bc5f12fb763c8892d83a5acc7ab45dacb56bb 100644 (file)
@@ -131,10 +131,9 @@ struct type
      For an array type, describes the type of the elements.
      For a function or method type, describes the type of the value.
      For a range type, describes the type of the full range.
-     For a record type, it's the "main variant" of the record type,
-     used for computing pointers to members.
      Unused otherwise.  */
   struct type *target_type;
+
   /* Type that is a pointer to this type.
      Zero if no such pointer-to type is known yet.
      The debugger may add the address of such a type
@@ -142,7 +141,6 @@ struct type
   struct type *pointer_type;
   /* C++: also need a reference type.  */
   struct type *reference_type;
-
   /* Type that is a function returning this type.
      Zero if no such function type is known here.
      The debugger may add the address of such a type
@@ -189,7 +187,7 @@ struct type
      the field number of that pointer in the structure.
 
      For types that are pointer to member types, VPTR_BASETYPE
-     ifs the type that this pointer is a member of.
+     is the type that this pointer is a member of.
 
      Unused otherwise.  */
   struct type *vptr_basetype;
@@ -204,23 +202,10 @@ struct type
     } type_specific;
 };
 
-/* C++ language-specific information for TYPE_CODE_STRUCT nodes.  */
+/* C++ language-specific information for TYPE_CODE_STRUCT and TYPE_CODE_UNION
+   nodes.  */
 struct cplus_struct_type
 {
-  /* Handling of pointers to members:
-     TYPE_MAIN_VARIANT is used for pointer and pointer
-     to member types.  Normally it is the value of the address of its
-     containing type.  However, for pointers to members, we must be
-     able to allocate pointer to member types and look them up
-     from some place of reference.
-     NEXT_VARIANT is the next element in the chain.
-
-     A long time ago (Jul 88; GDB 2.5) Tiemann said that
-     MAIN_VARIANT/NEXT_VARIANT may no longer be necessary and that he
-     might eliminate it.  I don't know whether this is still true (or
-     ever was).  */
-  struct type *next_variant;
-
   B_TYPE *virtual_field_bits; /* if base class is virtual */
   B_TYPE *private_field_bits;
   B_TYPE *protected_field_bits;
@@ -676,8 +661,6 @@ int current_source_line;
 #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
 #define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
 #define TYPE_FUNCTION_TYPE(thistype) (thistype)->function_type
-#define TYPE_MAIN_VARIANT(thistype) (thistype)->target_type
-#define TYPE_NEXT_VARIANT(thistype) (TYPE_CPLUS_SPECIFIC (thistype))->next_variant
 #define TYPE_LENGTH(thistype) (thistype)->length
 #define TYPE_FLAGS(thistype) (thistype)->flags
 #define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED)
@@ -812,7 +795,6 @@ extern int contained_in();
 extern struct type *lookup_template_type ();
 extern struct type *lookup_reference_type ();
 extern struct type *lookup_member_type ();
-extern struct type *lookup_method_type ();
 extern void smash_to_method_type ();
 void smash_to_member_type (
 #ifdef __STDC__
index f141bc8cb022a49455d69057bb2014db120b78a2..afc5f3cccbf65972b4265b8f2e66783e5fc98748 100644 (file)
@@ -1147,7 +1147,7 @@ value_static_field (type, fieldname, fieldno)
 }
 
 /* Compute the address of the baseclass which is
-   the INDEXth baseclass of TYPE.  The TYPE base
+   the INDEXth baseclass of class TYPE.  The TYPE base
    of the object is at VALADDR.
 
    If ERRP is non-NULL, set *ERRP to be the errno code of any error,
@@ -1175,9 +1175,6 @@ baseclass_addr (type, index, valaddr, valuep, errp)
       register int n_baseclasses = TYPE_N_BASECLASSES (type);
       char *vbase_name, *type_name = type_name_no_tag (basetype);
 
-      if (TYPE_MAIN_VARIANT (basetype))
-       basetype = TYPE_MAIN_VARIANT (basetype);
-
       vbase_name = (char *)alloca (strlen (type_name) + 8);
       sprintf (vbase_name, "_vb$%s", type_name);
       /* First look for the virtual baseclass pointer
@@ -1238,84 +1235,6 @@ baseclass_addr (type, index, valaddr, valuep, errp)
     *valuep = 0;
   return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8;
 }
-
-/* Ugly hack to convert method stubs into method types.
-
-   He ain't kiddin'.  This demangles the name of the method into a string
-   including argument types, parses out each argument type, generates
-   a string casting a zero to that type, evaluates the string, and stuffs
-   the resulting type into an argtype vector!!!  Then it knows the type
-   of the whole function (including argument types for overloading),
-   which info used to be in the stab's but was removed to hack back
-   the space required for them.  */
-void
-check_stub_method (type, i, j)
-     struct type *type;
-     int i, j;
-{
-  extern char *gdb_mangle_name (), *strchr ();
-  struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
-  char *mangled_name = gdb_mangle_name (type, i, j);
-  char *demangled_name = cplus_demangle (mangled_name, 0);
-  char *argtypetext, *p;
-  int depth = 0, argcount = 1;
-  struct type **argtypes;
-
-  /* Now, read in the parameters that define this type.  */
-  argtypetext = strchr (demangled_name, '(') + 1;
-  p = argtypetext;
-  while (*p)
-    {
-      if (*p == '(')
-       depth += 1;
-      else if (*p == ')')
-       depth -= 1;
-      else if (*p == ',' && depth == 0)
-       argcount += 1;
-
-      p += 1;
-    }
-  /* We need one more slot for the void [...] or NULL [end of arglist] */
-  argtypes = (struct type **)xmalloc ((argcount+1) * sizeof (struct type *));
-  p = argtypetext;
-  argtypes[0] = lookup_pointer_type (type);
-  argcount = 1;
-
-  if (*p != ')')                       /* () means no args, skip while */
-    {
-      depth = 0;
-      while (*p)
-       {
-         if (depth <= 0 && (*p == ',' || *p == ')'))
-           {
-             argtypes[argcount] =
-                 parse_and_eval_type (argtypetext, p - argtypetext);
-             argcount += 1;
-             argtypetext = p + 1;
-           }
-
-         if (*p == '(')
-           depth += 1;
-         else if (*p == ')')
-           depth -= 1;
-
-         p += 1;
-       }
-    }
-
-  if (p[-2] != '.')                    /* ... */
-    argtypes[argcount] = builtin_type_void;    /* Ellist terminator */
-  else
-    argtypes[argcount] = NULL;         /* List terminator */
-
-  free (demangled_name);
-
-  type = lookup_method_type (type, TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), argtypes);
-  /* Free the stub type...it's no longer needed.  */
-  free (TYPE_FN_FIELD_TYPE (f, j));
-  TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
-  TYPE_FN_FIELD_TYPE (f, j) = type;
-}
 \f
 long
 unpack_field_as_long (type, valaddr, fieldno)
@@ -1548,9 +1467,9 @@ set_return_value (val)
   if (code == TYPE_CODE_ERROR)
     error ("Function return type unknown.");
 
-  if (code == TYPE_CODE_STRUCT
-      || code == TYPE_CODE_UNION)
-    error ("Specifying a struct or union return value is not supported.");
+  if (   code == TYPE_CODE_STRUCT
+      || code == TYPE_CODE_UNION)      /* FIXME, implement struct return.  */
+    error ("GDB does not support specifying a struct or union return value.");
 
   /* FIXME, this is bogus.  We don't know what the return conventions
      are, or how values should be promoted.... */