[gnu.gdb.bug] Diffs to gdb 3.1 and to g++ for use of gdb with C++.

randy@WHEATIES.AI.MIT.EDU (Randy Smith) (03/15/89)

    Following are diffs to several files in gdb 3.1 and one file in
  gcc (dbxout.c) to get gdb to work properly with g++.  Please send
  bug reports to bug-gdb@prep.ai.mit.edu.  When making bug reports
  on these diffs, please refer to "version 2 of the gdb 3.1 g++ diffs"
  (version 1 being the diffs that Micheal Tiemann sent out recently).  

    I'm sending these out because I expect there to be a non-trivial
  amount of time before gdb 3.2.

						-- Randy

Return-Path: <mdt@yahi>
Date: Tue, 14 Mar 89 08:58:55 PST
From: mdt@yahi.stanford.edu (Michael Tiemann)
To: randy@wheaties.ai.mit.edu
Subject: GDB diffs
Reply-To: tiemann@lurch.stanford.edu

These diffs need new stuff in dbxout.c to work.

yahi% ls -lt *~
-rw-rw-rw-  1 mdt          8160 Feb  2 08:43 Makefile~
-rw-rw-rw-  1 mdt         25165 Jan 31 09:55 values.c~
-rw-rw-rw-  1 mdt        126178 Jan 30 08:59 dbxread.c~
-rw-rw-rw-  1 mdt         17586 Jan 23 12:42 symseg.h~
-rw-rw-rw-  1 mdt         32311 Jan 19 15:09 valops.c~
-rw-rw-rw-  1 mdt         53573 Jan 17 11:29 symtab.c~
-rw-rw-rw-  1 mdt         14228 Jan 17 11:29 symtab.h~
-rw-rw-rw-  1 mdt         26368 Jan 11 10:51 valprint.c~
-rw-rw-rw-  1 mdt         25932 Jan  2 21:00 eval.c~
yahi% diff -c2 dbxread.c~ dbxread.c
*** dbxread.c~	Mon Jan 30 08:59:56 1989
--- dbxread.c	Tue Mar 14 00:25:16 1989
***************
*** 144,148 ****
  
  /* C++ */
! static struct type **read_args();
  
  /* Macro to determine which symbols to ignore when reading the first symbol
--- 144,148 ----
  
  /* C++ */
! static struct type **read_args ();
  
  /* Macro to determine which symbols to ignore when reading the first symbol
***************
*** 3629,3632 ****
--- 3629,3650 ----
        break;
  
+     case '#':
+       {
+ 	struct type *domain = read_type (pp);
+ 	char c;
+ 	struct type *return_type;
+ 	struct type **args;
+ 
+ 	if (*(*pp)++ != ',')
+ 	  error ("invalid member type data format, at symtab pos %d.",
+ 		 symnum);
+ 
+ 	return_type = read_type (pp);
+ 	args = read_args (pp, ';');
+ 	type = dbx_alloc_type (typenums);
+ 	smash_to_method_type (type, domain, return_type, args);
+       }
+       break;
+ 
      case '&':
        type1 = read_type (pp);
***************
*** 3786,3789 ****
--- 3804,3812 ----
    int read_possible_virtual_info = 0;
  
+   if (TYPE_CODE (type) == TYPE_CODE_UNDEF)
+     {
+       TYPE_MAIN_VARIANT (type) = type;
+     }
+ 
    TYPE_CODE (type) = TYPE_CODE_STRUCT;
  
***************
*** 3918,3921 ****
--- 3941,3945 ----
        if (**pp == ':')
   	{
+ 	  /* This makes TYPE_FIELD_STATIC true.  */
   	  list->field.bitpos = (long)-1;
   	  p = ++(*pp);
***************
*** 3926,3930 ****
   	  continue;
   	}
!        else if (**pp != ',')
  	 error ("Invalid symbol data: bad structure-type format at symtab pos %d.",
  	       symnum);
--- 3950,3966 ----
   	  continue;
   	}
!       else if (**pp == '~')
! 	{
! 	  /* This is a local enum declaration.  This makes TYPE_FIELD_CONST true.  */
! 	  list->field.bitpos = (long)-2;
! 	  *pp += 1;
! 	  if (**pp != 'i')
! 	    error ("invalid local constant declaration at symtab pos %d.", symnum);
! 	  *pp += 1;
! 	  list->field.bitsize = read_number (pp, ';');
! 	  nfields++;
! 	  continue;
! 	}
!       else if (**pp != ',')
  	 error ("Invalid symbol data: bad structure-type format at symtab pos %d.",
  	       symnum);
***************
*** 4010,4014 ****
  
  	      new_sublist->fn_field.type = read_type (pp);
! 	      new_sublist->fn_field.args = read_args (pp, ':');
  	      p = *pp;
  	      while (*p != ';') p++;
--- 4046,4053 ----
  
  	      new_sublist->fn_field.type = read_type (pp);
! 	      if (**pp != ':')
! 		error ("invalid symtab info for method at symbol number %d.", symnum);
! 	      *pp += 1;
! 	      new_sublist->fn_field.args = TYPE_ARG_TYPES (new_sublist->fn_field.type);
  	      p = *pp;
  	      while (*p != ';') p++;
yahi% diff -c2 eval.c~ eval.c
*** eval.c~	Mon Jan  2 21:00:35 1989
--- eval.c	Sun Mar 12 23:33:59 1989
***************
*** 377,383 ****
  	goto nosideret;
        /* Now, convert these values to an address.  */
        arg3 = value_from_long (builtin_type_long,
  			      value_as_long (arg1) + value_as_long (arg2));
!       VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)));
        return value_ind (arg3);
  
--- 377,387 ----
  	goto nosideret;
        /* Now, convert these values to an address.  */
+       if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
+ 	  || (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_MEMBER
+ 	      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_METHOD))
+ 	error ("non-pointer-to-member value used in pointer-to-member construct");
        arg3 = value_from_long (builtin_type_long,
  			      value_as_long (arg1) + value_as_long (arg2));
!       VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))));
        return value_ind (arg3);
  
***************
*** 388,394 ****
  	goto nosideret;
        /* Now, convert these values to an address.  */
        arg3 = value_from_long (builtin_type_long,
  			      value_as_long (arg1) + value_as_long (arg2));
!       VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)));
        return value_ind (arg3);
  
--- 392,402 ----
  	goto nosideret;
        /* Now, convert these values to an address.  */
+       if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_PTR
+ 	  || (TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_MEMBER
+ 	      && TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) != TYPE_CODE_METHOD))
+ 	error ("non-pointer-to-member value used in pointer-to-member construct");
        arg3 = value_from_long (builtin_type_long,
  			      value_as_long (arg1) + value_as_long (arg2));
!       VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))));
        return value_ind (arg3);
  
yahi% diff -c2 symseg.h~ symseg.h
*** symseg.h~	Mon Jan 23 12:42:18 1989
--- symseg.h	Mon Mar 13 07:32:29 1989
***************
*** 122,125 ****
--- 122,126 ----
    /* C++ */
    TYPE_CODE_MEMBER,		/* Member type */
+   TYPE_CODE_METHOD,		/* Method type */
    TYPE_CODE_REF,		/* C++ Reference types */
  };
***************
*** 147,151 ****
    /* For a pointer type, describes the type of object pointed to.
       For an array type, describes the type of the elements.
!      For a function type, describes the type of the value.
       For a range type, describes the type of the full range.
       Unused otherwise.  */
--- 148,152 ----
    /* For a pointer type, describes the type of object pointed to.
       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.
       Unused otherwise.  */
***************
*** 158,161 ****
--- 159,164 ----
    /* C++: also need a reference type.  */
    struct type *reference_type;
+   struct type **arg_types;
+ 
    /* Type that is a function returning this type.
       Zero if no such function type is known here.
***************
*** 226,230 ****
       which consists of an overloaded name, followed by the types of
       arguments that the method expects, and then the name after it
!      has been renamed to make it distinct. */
    struct fn_fieldlist
      {
--- 229,233 ----
       which consists of an overloaded name, followed by the types of
       arguments that the method expects, and then the name after it
!      has been renamed to make it distinct.  */
    struct fn_fieldlist
      {
***************
*** 240,244 ****
  	  char *name;
  #endif
! 	  /* The type of the argument */
  	  struct type *type;
  	  /* The argument list */
--- 243,247 ----
  	  char *name;
  #endif
! 	  /* The return value of the method */
  	  struct type *type;
  	  /* The argument list */
yahi% diff -c2 symtab.c~ symtab.c
*** symtab.c~	Tue Jan 17 11:29:19 1989
--- symtab.c	Mon Mar 13 00:12:27 1989
***************
*** 362,365 ****
--- 362,432 ----
  }
  
+ struct type *
+ lookup_method_type (type, domain, args)
+      struct type *type, *domain, **args;
+ {
+   register struct type *mtype = TYPE_MAIN_VARIANT (type);
+   struct type *main_type;
+ 
+   main_type = mtype;
+   while (mtype)
+     {
+       if (TYPE_DOMAIN_TYPE (mtype) == domain)
+ 	{
+ 	  struct type **t1 = args;
+ 	  struct type **t2 = TYPE_ARG_TYPES (mtype);
+ 	  if (t2)
+ 	    {
+ 	      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;
+ 	    }
+ 	}
+       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;
+   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;
+ }
+ 
  /* Given a type TYPE, return a type which has offset OFFSET,
     via_virtual VIA_VIRTUAL, and via_public VIA_PUBLIC.
***************
*** 491,494 ****
--- 558,579 ----
  
    TYPE_MAIN_VARIANT (type) = lookup_member_type (domain, to_type);
+ }
+ 
+ /* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.  */
+ 
+ void
+ smash_to_method_type (type, domain, to_type, args)
+      struct type *type, *domain, *to_type, **args;
+ {
+   bzero (type, sizeof (struct type));
+   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_CODE (type) = TYPE_CODE_METHOD;
+ 
+   TYPE_MAIN_VARIANT (type) = lookup_method_type (domain, to_type, args);
  }
  
yahi% diff -c2 symtab.h~ symtab.h
*** symtab.h~	Tue Jan 17 11:29:06 1989
--- symtab.h	Tue Mar 14 00:08:59 1989
***************
*** 232,235 ****
--- 232,236 ----
  #define TYPE_NFN_FIELDS_TOTAL(thistype) (thistype)->nfn_fields_total
  #define TYPE_BASECLASSES(thistype) (thistype)->baseclasses
+ #define TYPE_ARG_TYPES(thistype) (thistype)->arg_types
  #define TYPE_BASECLASS(thistype,index) (thistype)->baseclasses[index]
  #define TYPE_N_BASECLASSES(thistype) (thistype)->n_baseclasses
***************
*** 257,260 ****
--- 258,262 ----
  #define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1)
  #define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize)
+ #define TYPE_FIELD_CONST(thistype, n) ((thistype)->fields[n].bitpos == -2)
  
  #define TYPE_FN_FIELDLISTS(thistype) (thistype)->fn_fieldlists
yahi% diff -c2 valops.c~ valops.c
*** valops.c~	Thu Jan 19 15:09:14 1989
--- valops.c	Tue Mar 14 00:25:46 1989
***************
*** 525,536 ****
      /* If it's a member function, just look at the function
         part of it.  */
-     if (code == TYPE_CODE_MEMBER)
-       {
- 	ftype = TYPE_TARGET_TYPE (ftype);
- 	code = TYPE_CODE (ftype);
-       }
- 
      /* Determine address to call.  */
!     if (code == TYPE_CODE_FUNC)
        {
  	funaddr = VALUE_ADDRESS (function);
--- 525,530 ----
      /* If it's a member function, just look at the function
         part of it.  */
      /* Determine address to call.  */
!     if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
        {
  	funaddr = VALUE_ADDRESS (function);
***************
*** 540,545 ****
        {
  	funaddr = value_as_long (function);
! 	if (TYPE_CODE (TYPE_TARGET_TYPE (ftype))
! 	    == TYPE_CODE_FUNC)
  	  value_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype));
  	else
--- 534,539 ----
        {
  	funaddr = value_as_long (function);
! 	if (TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_FUNC
! 	    || TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_METHOD)
  	  value_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype));
  	else
***************
*** 803,808 ****
  
  	  if (i >= 0)
! 	    return TYPE_FIELD_STATIC (t, i)
! 	      ? value_static_field (t, name, i) : value_field (arg1, i);
  
  	  if (TYPE_N_BASECLASSES (t) == 0)
--- 797,807 ----
  
  	  if (i >= 0)
! 	    {
! 	      if (TYPE_FIELD_STATIC (t, i))
! 		return value_static_field (t, name, i);
! 	      if (TYPE_FIELD_CONST (t, i))
! 		return value_from_long (TYPE_FIELD_TYPE (t, i), TYPE_FIELD_BITSIZE (t, i));
! 	      return value_field (arg1, i);
! 	    }
  
  	  if (TYPE_N_BASECLASSES (t) == 0)
***************
*** 912,917 ****
  
  	  if (i >= 0)
! 	    return TYPE_FIELD_STATIC (t, i)
! 	      ? value_static_field (t, name, i) : value_field (arg1, i);
  
  	  if (TYPE_N_BASECLASSES (t) == 0)
--- 911,921 ----
  
  	  if (i >= 0)
! 	    {
! 	      if (TYPE_FIELD_STATIC (t, i))
! 		return value_static_field (t, name, i);
! 	      if (TYPE_FIELD_CONST (t, i))
! 		return value_from_long (TYPE_FIELD_TYPE (t, i), TYPE_FIELD_BITSIZE (t, i));
! 	      return value_field (arg1, i);
! 	    }
  
  	  if (TYPE_N_BASECLASSES (t) == 0)
***************
*** 1061,1069 ****
  	      if (TYPE_FIELD_PACKED (t, i))
  		error ("pointers to bitfield members not allowed");
  
  	      v = value_from_long (builtin_type_int,
  				   (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
! 	      VALUE_TYPE (v) = lookup_pointer_type (
! 		      lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass));
  	      return v;
  	    }
--- 1065,1084 ----
  	      if (TYPE_FIELD_PACKED (t, i))
  		error ("pointers to bitfield members not allowed");
+ 	      if (TYPE_FIELD_STATIC (t, i))
+ 		{
+ 		  struct symbol *sym = lookup_symbol (TYPE_FIELD_STATIC_PHYSNAME (t, i),
+ 						      0, VAR_NAMESPACE, 0);
+ 		  if (! sym)
+ 		    error ("Internal error: could not find physical static variable named %s",
+ 			   TYPE_FIELD_BITSIZE (t, i));
+ 		  return value_from_long (lookup_pointer_type (TYPE_FIELD_TYPE (t, i)),
+ 					  (CORE_ADDR) SYMBOL_BLOCK_VALUE (sym));
+ 		}
+ 	      if (TYPE_FIELD_CONST (t, i))
+ 		error ("cannot get address of local enum declaration");
  
  	      v = value_from_long (builtin_type_int,
  				   (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
! 	      VALUE_TYPE (v) = lookup_pointer_type (lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass));
  	      return v;
  	    }
yahi% diff -c2 valprint.c~ valprint.c
*** valprint.c~	Wed Jan 11 10:51:31 1989
--- valprint.c	Tue Mar 14 08:14:03 1989
***************
*** 186,190 ****
  	  break;
  	}
!       if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
  	{
  	  struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
--- 186,190 ----
  	  break;
  	}
!       if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
  	{
  	  struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
***************
*** 195,297 ****
  
  	  val = unpack_long (builtin_type_int, valaddr);
! 	  if (TYPE_CODE (target) == TYPE_CODE_FUNC)
  	    {
! 	      if (val < 128)
  		{
! 		  len = TYPE_NFN_FIELDS (domain);
! 		  for (i = 0; i < len; i++)
! 		    {
! 		      f = TYPE_FN_FIELDLIST1 (domain, i);
! 		      len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
  
! 		      for (j = 0; j < len2; j++)
! 			{
! 			  QUIT;
! 			  if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
! 			    {
! 			      kind = "virtual";
! 			      goto common;
! 			    }
! 			}
! 		    }
! 		}
! 	      else
! 		{
! 		  struct symbol *sym = find_pc_function ((CORE_ADDR) val);
! 		  if (sym == 0)
! 		    error ("invalid pointer to member function");
! 		  len = TYPE_NFN_FIELDS (domain);
! 		  for (i = 0; i < len; i++)
  		    {
! 		      f = TYPE_FN_FIELDLIST1 (domain, i);
! 		      len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
! 
! 		      for (j = 0; j < len2; j++)
  			{
! 			  QUIT;
! 			  if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
! 			    goto common;
  			}
  		    }
  		}
- 	    common:
- 	      if (i < len)
- 		{
- 		  fputc ('&', stream);
- 		  type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
- 		  fprintf (stream, kind);
- 		  if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
- 		      && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
- 		    type_print_method_args
- 		      (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
- 		       TYPE_FN_FIELDLIST_NAME (domain, i), stream);
- 		  else
- 		    type_print_method_args
- 		      (TYPE_FN_FIELD_ARGS (f, j), "",
- 		       TYPE_FN_FIELDLIST_NAME (domain, i), stream);
- 		  break;
- 		}
  	    }
  	  else
  	    {
! 	      /* VAL is a byte offset into the structure type DOMAIN.
! 		 Find the name of the field for that offset and
! 		 print it.  */
! 	      int extra = 0;
! 	      int bits = 0;
! 	      len = TYPE_NFIELDS (domain);
! 	      val <<= 3;	/* @@ Make VAL into bit offset */
  	      for (i = 0; i < len; i++)
  		{
! 		  int bitpos = TYPE_FIELD_BITPOS (domain, i);
! 		  QUIT;
! 		  if (val == bitpos)
! 		    break;
! 		  if (val < bitpos && i > 0)
  		    {
! 		      int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
! 		      /* Somehow pointing into a field.  */
! 		      i -= 1;
! 		      extra = (val - TYPE_FIELD_BITPOS (domain, i));
! 		      if (extra & 0x3)
! 			bits = 1;
! 		      else
! 			extra >>= 3;
! 		      break;
  		    }
  		}
- 	      if (i < len)
- 		{
- 		  fputc ('&', stream);
- 		  type_print_base (domain, stream, 0, 0);
- 		  fprintf (stream, "::");
- 		  fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
- 		  if (extra)
- 		    fprintf (stream, " + %d bytes", extra);
- 		  if (bits)
- 		    fprintf (stream, " (offset in bits)");
- 		  break;
- 		}
  	    }
  	  fputc ('(', stream);
  	  type_print (type, "", stream, -1);
--- 195,253 ----
  
  	  val = unpack_long (builtin_type_int, valaddr);
! 	  if (val < 128)
  	    {
! 	      len = TYPE_NFN_FIELDS (domain);
! 	      for (i = 0; i < len; i++)
  		{
! 		  f = TYPE_FN_FIELDLIST1 (domain, i);
! 		  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
  
! 		  for (j = 0; j < len2; j++)
  		    {
! 		      QUIT;
! 		      if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
  			{
! 			  kind = "virtual";
! 			  goto common;
  			}
  		    }
  		}
  	    }
  	  else
  	    {
! 	      struct symbol *sym = find_pc_function ((CORE_ADDR) val);
! 	      if (sym == 0)
! 		error ("invalid pointer to member function");
! 	      len = TYPE_NFN_FIELDS (domain);
  	      for (i = 0; i < len; i++)
  		{
! 		  f = TYPE_FN_FIELDLIST1 (domain, i);
! 		  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
! 
! 		  for (j = 0; j < len2; j++)
  		    {
! 		      QUIT;
! 		      if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
! 			goto common;
  		    }
  		}
  	    }
+ 	common:
+ 	  if (i < len)
+ 	    {
+ 	      fputc ('&', stream);
+ 	      type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
+ 	      fprintf (stream, kind);
+ 	      if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
+ 		  && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
+ 		type_print_method_args
+ 		  (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
+ 		   TYPE_FN_FIELDLIST_NAME (domain, i), stream);
+ 	      else
+ 		type_print_method_args
+ 		  (TYPE_FN_FIELD_ARGS (f, j), "",
+ 		   TYPE_FN_FIELDLIST_NAME (domain, i), stream);
+ 	      break;
+ 	    }
  	  fputc ('(', stream);
  	  type_print (type, "", stream, -1);
***************
*** 298,301 ****
--- 254,304 ----
  	  fprintf (stream, ") %d", val >> 3);
  	}
+       else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
+ 	{
+ 	  struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
+ 	  struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type));
+ 	  char *kind = "";
+ 
+ 	  /* VAL is a byte offset into the structure type DOMAIN.
+ 	     Find the name of the field for that offset and
+ 	     print it.  */
+ 	  int extra = 0;
+ 	  int bits = 0;
+ 	  len = TYPE_NFIELDS (domain);
+ 	  /* @@ Make VAL into bit offset */
+ 	  val = unpack_long (builtin_type_int, valaddr) << 3;
+ 	  for (i = 0; i < len; i++)
+ 	    {
+ 	      int bitpos = TYPE_FIELD_BITPOS (domain, i);
+ 	      QUIT;
+ 	      if (val == bitpos)
+ 		break;
+ 	      if (val < bitpos && i > 0)
+ 		{
+ 		  int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
+ 		  /* Somehow pointing into a field.  */
+ 		  i -= 1;
+ 		  extra = (val - TYPE_FIELD_BITPOS (domain, i));
+ 		  if (extra & 0x3)
+ 		    bits = 1;
+ 		  else
+ 		    extra >>= 3;
+ 		  break;
+ 		}
+ 	    }
+ 	  if (i < len)
+ 	    {
+ 	      fputc ('&', stream);
+ 	      type_print_base (domain, stream, 0, 0);
+ 	      fprintf (stream, "::");
+ 	      fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
+ 	      if (extra)
+ 		fprintf (stream, " + %d bytes", extra);
+ 	      if (bits)
+ 		fprintf (stream, " (offset in bits)");
+ 	      break;
+ 	    }
+ 	  fprintf (stream, "%d", val >> 3);
+ 	}
        else
  	{
***************
*** 385,426 ****
      case TYPE_CODE_STRUCT:
      case TYPE_CODE_UNION:
!       fprintf (stream, "{");
!       len = TYPE_NFIELDS (type);
!       n_baseclasses = TYPE_N_BASECLASSES (type);
!       for (i = 1; i <= n_baseclasses; i++)
! 	{
! 	  fprintf (stream, "\n<%s> = ", TYPE_NAME (TYPE_BASECLASS (type, i)));
! 	  val_print (TYPE_FIELD_TYPE (type, 0),
! 		     valaddr + TYPE_FIELD_BITPOS (type, i-1) / 8,
! 		     0, stream, 0, 0);
! 	}
!       if (i > 1) fprintf (stream, "\nmembers of %s: ", TYPE_NAME (type));
!       for (i -= 1; i < len; i++)
! 	{
! 	  if (i > n_baseclasses) fprintf (stream, ", ");
! 	  fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i));
! 	  /* check if static field */
! 	  if (TYPE_FIELD_STATIC (type, i))
! 	    {
! 	      value v;
  
! 	      v = value_static_field (type, TYPE_FIELD_NAME (type, i), i);
! 	      val_print (TYPE_FIELD_TYPE (type, i),
! 			 VALUE_CONTENTS (v), 0, stream, format, deref_ref);
! 	    }
! 	  else if (TYPE_FIELD_PACKED (type, i))
! 	    {
! 	      val = unpack_field_as_long (type, valaddr, i);
! 	      val_print (TYPE_FIELD_TYPE (type, i), &val, 0,
! 			 stream, format, deref_ref);
! 	    }
! 	  else
! 	    {
! 	      val_print (TYPE_FIELD_TYPE (type, i), 
! 			 valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
! 			 0, stream, format, deref_ref);
! 	    }
! 	}
!       fprintf (stream, "}");
        break;
  
--- 388,437 ----
      case TYPE_CODE_STRUCT:
      case TYPE_CODE_UNION:
!       {
! 	int members_printed = 0;
  
! 	fprintf (stream, "{");
! 	len = TYPE_NFIELDS (type);
! 	n_baseclasses = TYPE_N_BASECLASSES (type);
! 	for (i = 1; i <= n_baseclasses; i++)
! 	  {
! 	    fprintf (stream, "\n<%s> = ", TYPE_NAME (TYPE_BASECLASS (type, i)));
! 	    val_print (TYPE_FIELD_TYPE (type, 0),
! 		       valaddr + TYPE_FIELD_BITPOS (type, i-1) / 8,
! 		       0, stream, 0, 0);
! 	  }
! 	if (i > 1) fprintf (stream, "\nmembers of %s: ", TYPE_NAME (type));
! 	for (i -= 1; i < len; i++)
! 	  {
! 	    if (TYPE_FIELD_CONST (type, i))
! 	      /* No need to print this out.  */
! 	      continue;
! 	    if (members_printed) fprintf (stream, ", ");
! 	    members_printed = 1;
! 	    fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i));
! 	    /* check if static field */
! 	    if (TYPE_FIELD_STATIC (type, i))
! 	      {
! 		value v;
! 
! 		v = value_static_field (type, TYPE_FIELD_NAME (type, i), i);
! 		val_print (TYPE_FIELD_TYPE (type, i),
! 			   VALUE_CONTENTS (v), 0, stream, format, deref_ref);
! 	      }
! 	    else if (TYPE_FIELD_PACKED (type, i))
! 	      {
! 		val = unpack_field_as_long (type, valaddr, i);
! 		val_print (TYPE_FIELD_TYPE (type, i), &val, 0,
! 			   stream, format, deref_ref);
! 	      }
! 	    else
! 	      {
! 		val_print (TYPE_FIELD_TYPE (type, i), 
! 			   valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
! 			   0, stream, format, deref_ref);
! 	      }
! 	  }
! 	fprintf (stream, "}");
!       }
        break;
  
***************
*** 573,576 ****
--- 584,588 ----
         &&
         (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
+ 	|| code == TYPE_CODE_METHOD
  	|| code == TYPE_CODE_ARRAY
  	|| code == TYPE_CODE_MEMBER
***************
*** 694,697 ****
--- 706,711 ----
  
      case TYPE_CODE_MEMBER:
+       if (passed_a_ptr)
+ 	fputc ('(', stream);
        type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
  				 passed_a_ptr);
***************
*** 702,705 ****
--- 716,730 ----
        break;
  
+     case TYPE_CODE_METHOD:
+       if (passed_a_ptr)
+ 	fputc ('(', stream);
+       type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
+ 				 passed_a_ptr);
+       fputc (' ', stream);
+       type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0,
+ 		       passed_a_ptr);
+       fprintf (stream, "::");
+       break;
+ 
      case TYPE_CODE_REF:
        type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
***************
*** 758,761 ****
--- 783,810 ----
        break;
  
+     case TYPE_CODE_METHOD:
+       if (passed_a_ptr)
+ 	fputc (')', stream);
+       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
+       if (passed_a_ptr)
+ 	{
+ 	  int i;
+ 	  struct type **args = TYPE_ARG_TYPES (type);
+ 
+ 	  fputc ('(', stream);
+ 	  if (args[1] == 0)
+ 	    fprintf (stream, "...");
+ 	  else for (i = 1; args[i] != 0 && args[i]->code != TYPE_CODE_VOID; i++)
+ 	    {
+ 	      type_print_1 (args[i], "", stream, -1, 0);
+ 	      if (args[i+1] == 0)
+ 		fprintf (stream, "...");
+ 	      else if (args[i+1]->code != TYPE_CODE_VOID)
+ 		fputc (',', stream);
+ 	    }
+ 	  fputc (')', stream);
+ 	}
+       break;
+ 
      case TYPE_CODE_PTR:
      case TYPE_CODE_REF:
***************
*** 819,822 ****
--- 868,872 ----
      case TYPE_CODE_REF:
      case TYPE_CODE_FUNC:
+     case TYPE_CODE_METHOD:
        type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
        break;
***************
*** 887,891 ****
  		  if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
  		    fprintf (stream, "virtual ");
! 		  type_print (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j))), "", stream, 0);
  		  if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
  		      && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
--- 937,941 ----
  		  if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
  		    fprintf (stream, "virtual ");
! 		  type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), "", stream, 0);
  		  if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
  		      && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
yahi% diff -c2 values.c~ values.c
*** values.c~	Tue Jan 31 09:55:59 1989
--- values.c	Sat Mar 11 18:14:26 1989
***************
*** 659,669 ****
        = fill_in_vptr_fieldno (type);
  
!   /* Pretend that this array is just an array of pointers to integers.
!      This will have to change for multiple inheritance.  */
!   vtbl = value_copy (value_field (arg1, TYPE_VPTR_FIELDNO (type)));
!   VALUE_TYPE (vtbl) = lookup_pointer_type (builtin_type_int);
  
    /* Index into the virtual function table.  */
!   vfn = value_subscript (vtbl, vi);
  
    /* Reinstantiate the function pointer with the correct type.  */
--- 659,669 ----
        = fill_in_vptr_fieldno (type);
  
!   /* The virtual function table is now an array of structures
!      which have the form { int16 offset, delta; void* pfn; }.  */
!   vtbl = value_ind (value_field (arg1, TYPE_VPTR_FIELDNO (type)));
  
    /* Index into the virtual function table.  */
!   vfn = value_struct_elt (value_subscript (vtbl, vi), 0, "pfn",
! 			  "internal error in virtual function lookup");
  
    /* Reinstantiate the function pointer with the correct type.  */
yahi% 

Michael

==================
Return-Path: <mdt@yahi>
Date: Tue, 14 Mar 89 09:17:44 PST
From: mdt@yahi.stanford.edu (Michael Tiemann)
To: randy@wheaties.ai.mit.edu
Subject: dbxout.c diffs
Reply-To: tiemann@lurch.stanford.edu

Here are the dbxout.c diffs.  Please post these diffs and the GDB
diffs to both bug-gdb and bug-g++, thanks.  I will do a build and fix up the
installation process a little.

Michael

yahi% diff -c2 dbxout.c~ dbxout.c
*** dbxout.c~	Mon Feb 27 17:43:02 1989
--- dbxout.c	Tue Mar 14 09:15:54 1989
***************
*** 431,435 ****
  	   of each field.  */
  	/* Omit here the nameless fields that are used to skip bits.  */
! 	if (DECL_NAME (tem) != 0)
  	  {
  	    /* Continue the line if necessary,
--- 431,436 ----
  	   of each field.  */
  	/* Omit here the nameless fields that are used to skip bits.  */
! 	if (DECL_NAME (tem) != 0
! 	    && (use_gdb_dbx_extensions || TREE_CODE (tem) != CONST_DECL))
  	  {
  	    /* Continue the line if necessary,
***************
*** 468,472 ****
  	    else if (TREE_CODE (tem) == CONST_DECL)
  	      {
! 		/* How do we do this?  */
  	      }
  	    else
--- 469,474 ----
  	    else if (TREE_CODE (tem) == CONST_DECL)
  	      {
! 		/* Only get here if using GDB's extensions to DBX format.  */
! 		fprintf (asmfile, "~i%d;", TREE_INT_CST_LOW (DECL_INITIAL (tem)));
  	      }
  	    else
***************
*** 523,527 ****
  		  t = tem; /* Get to the FUNCTION_DECL */
  		  dbxout_type (TREE_TYPE (t), 0); /* METHOD_TYPE */
- 		  dbxout_args (TYPE_ARG_TYPES (TREE_TYPE (t)));
  		  fprintf (asmfile, ":%s;%c%c",
  			   IDENTIFIER_POINTER (DECL_NAME (t)),
--- 525,528 ----
***************
*** 575,579 ****
  		  t = tem; /* Get to the FUNCTION_DECL */
  		  dbxout_type (TREE_TYPE (t), 0); /* METHOD_TYPE */
- 		  dbxout_args (TYPE_ARG_TYPES (TREE_TYPE (t)));
  		  fprintf (asmfile, ":%s;%c%c",
  			   IDENTIFIER_POINTER (DECL_NAME (t)),
--- 576,579 ----
***************
*** 626,630 ****
  
      case ENUMERAL_TYPE:
!       if ((TYPE_NAME (type) != 0 && !full)
  	  || TYPE_SIZE (type) == 0)
  	{
--- 626,635 ----
  
      case ENUMERAL_TYPE:
!       if ((TYPE_NAME (type) != 0
! 	   && !full
! 	   && ((TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
! 		&& ! ANON_AGGRNAME_P (DECL_NAME (TYPE_NAME (type))))
! 	       || (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
! 		   && ! ANON_AGGRNAME_P (TYPE_NAME (type)))))
  	  || TYPE_SIZE (type) == 0)
  	{
***************
*** 689,693 ****
        if (use_gdb_dbx_extensions)
  	{
! 	  putc ('@', asmfile);
  	  CHARS (1);
  	  dbxout_type (TYPE_METHOD_BASETYPE (type), 0);
--- 694,698 ----
        if (use_gdb_dbx_extensions)
  	{
! 	  putc ('#', asmfile);
  	  CHARS (1);
  	  dbxout_type (TYPE_METHOD_BASETYPE (type), 0);
***************
*** 695,698 ****
--- 700,706 ----
  	  CHARS (1);
  	  dbxout_type (TREE_TYPE (type), 0);
+ 	  dbxout_args (TYPE_ARG_TYPES (type));
+ 	  putc (';', asmfile);
+ 	  CHARS (1);
  	}
        else
***************
*** 786,791 ****
  	break;
        FORCE_TEXT;
        fprintf (asmfile, ".stabs \"%s:%c",
! 	       IDENTIFIER_POINTER (DECL_ORIGINAL_NAME (decl)),
  	       TREE_PUBLIC (decl) ? 'F' : 'f');
  
--- 794,801 ----
  	break;
        FORCE_TEXT;
+       /* For GDB 3.1, it may be better to use DECL_NAME (instead of DECL_ORIGINAL_NAME
+ 	 in this case.  */
        fprintf (asmfile, ".stabs \"%s:%c",
! 	       IDENTIFIER_POINTER (DECL_NAME (decl)),
  	       TREE_PUBLIC (decl) ? 'F' : 'f');
  
***************
*** 844,847 ****
--- 854,879 ----
  	break;
  
+       /* If the variable is really a constant, inform dbx of such.  */
+       if (TREE_STATIC (decl) && TREE_READONLY (decl)
+ 	  && DECL_INITIAL (decl) != 0)
+ 	{
+ #if 0
+ 	  /* The sun4 assembler does not grok this.  */
+ 	  name = IDENTIFIER_POINTER (DECL_NAME (decl));
+ 	  if (TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE
+ 	      || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
+ 	    {
+ 	      int ival = TREE_INT_CST_LOW (DECL_INITIAL (decl));
+ 	      fprintf (asmfile, ".stabs \"%s\":c=i%d\n", name, ival);
+ 	      return;
+ 	    }
+ 	  else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE)
+ 	    {
+ 	      /* don't know how to do this yet.  */
+ 	    }
+ #endif
+ 	  break;
+ 	}
+ 
        /* Don't mention a variable at all
  	 if it was completely optimized into nothingness.  */
***************
*** 1262,1266 ****
  	  FORCE_TEXT;
  	  fprintf (asmfile, ".stabs \"%s:T",
! 		   IDENTIFIER_POINTER (TREE_PURPOSE (link)));
  	  dbxout_type (type, 1);
  	  dbxout_finish_symbol ();
--- 1294,1298 ----
  	  FORCE_TEXT;
  	  fprintf (asmfile, ".stabs \"%s:T",
! 		   ANON_AGGRNAME_P (TREE_PURPOSE (link)) ? "" : IDENTIFIER_POINTER (TREE_PURPOSE (link)));
  	  dbxout_type (type, 1);
  	  dbxout_finish_symbol ();
yahi%