This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: maybe prototyped



In light of the recent discussion about stabs lossage with regards to
prototyped functions, here's something that actually allows the debug
readers to convey the depth of their convictions to the argument
promotion code.

Is this a wise idea?  Who knows?  It does get rid of a FIXME, though.

2001-11-27  Jim Blandy  <jimb@redhat.com>

	Allow debug readers to indicate that a function type may or may
	not be prototyped.
	* gdbtypes.h (TYPE_FLAG_MAYBE_PROTOTYPED): New flag.
	(TYPE_FLAG_INCOMPLETE, TYPE_FLAG_CODE_SPACE,
	TYPE_FLAG_DATA_SPACE): Renumber.
	* stabsread.c (define_symbol): Mark all function types as `maybe
	prototyped', except those that have prototype info, which we
	continue to mark as `prototyped'.
	* valops.c (value_arg_coerce): Change third argument to indicate
	whether the function is definitely prototyped, definitely not
	prototyped, or perhaps prototyped.  Only consult
	COERCE_FLOAT_TO_DOUBLE when they are perhaps prototyped.
	(hand_function_call): Call value_arg_coerce appropriately.

Index: gdb/gdbtypes.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbtypes.h,v
retrieving revision 1.18
diff -c -r1.18 gdbtypes.h
*** gdb/gdbtypes.h	2001/11/15 01:55:59	1.18
--- gdb/gdbtypes.h	2001/11/28 04:45:39
***************
*** 190,201 ****
  #define TYPE_FLAG_VOLATILE (1 << 6)
  
  
! /* This is a function type which appears to have a prototype.  We need this
!    for function calls in order to tell us if it's necessary to coerce the args,
!    or to just do the standard conversions.  This is used with a short field. */
! 
  #define TYPE_FLAG_PROTOTYPED (1 << 7)
  
  /* This flag is used to indicate that processing for this type
     is incomplete.
  
--- 190,212 ----
  #define TYPE_FLAG_VOLATILE (1 << 6)
  
  
! /* This is a function type which definitely has a prototype.  It
!    expects callers to pass its arguments as the types given in the
!    argument list; we don't do the standard K&R-style promotions.  */
  #define TYPE_FLAG_PROTOTYPED (1 << 7)
  
+ 
+ /* This function might be prototyped, or it might not.  Some debug
+    formats don't reliably give us any information about whether a
+    function is prototyped or not.  For example, when GCC emits stabs,
+    all function types, prototyped or not, are emitted in unprototyped
+    form.  Since you can't pass arguments to a function properly
+    without knowing whether it's declared in prototype or K&R style,
+    this is a pain.  The gdbarch macro COERCE_FLOAT_TO_DOUBLE indicates
+    what assumption we should make on a per-target basis.  */
+ #define TYPE_FLAG_MAYBE_PROTOTYPED (1 << 8)
+ 
+ 
  /* This flag is used to indicate that processing for this type
     is incomplete.
  
***************
*** 204,210 ****
     info; the incomplete type has to be marked so that the class and
     the method can be assigned correct types.) */
  
! #define TYPE_FLAG_INCOMPLETE (1 << 8)
  
  /* Instruction-space delimited type.  This is for Harvard architectures
     which have separate instruction and data address spaces (and perhaps
--- 215,221 ----
     info; the incomplete type has to be marked so that the class and
     the method can be assigned correct types.) */
  
! #define TYPE_FLAG_INCOMPLETE (1 << 9)
  
  /* Instruction-space delimited type.  This is for Harvard architectures
     which have separate instruction and data address spaces (and perhaps
***************
*** 225,232 ****
     If neither flag is set, the default space for functions / methods
     is instruction space, and for data objects is data memory.  */
  
! #define TYPE_FLAG_CODE_SPACE (1 << 9)
! #define TYPE_FLAG_DATA_SPACE (1 << 10)
  
  
  struct type
--- 236,243 ----
     If neither flag is set, the default space for functions / methods
     is instruction space, and for data objects is data memory.  */
  
! #define TYPE_FLAG_CODE_SPACE (1 << 10)
! #define TYPE_FLAG_DATA_SPACE (1 << 11)
  
  
  struct type
Index: gdb/stabsread.c
===================================================================
RCS file: /cvs/src/src/gdb/stabsread.c,v
retrieving revision 1.16
diff -c -r1.16 stabsread.c
*** gdb/stabsread.c	2001/09/24 17:16:53	1.16
--- gdb/stabsread.c	2001/11/28 04:45:53
***************
*** 1587,1592 ****
--- 1587,1598 ----
        /* All functions in C++ have prototypes.  */
        if (SYMBOL_LANGUAGE (sym) == language_cplus)
  	TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_PROTOTYPED;
+       else
+         /* Many compilers, including GCC, emit prototyped function
+            types without prototype info, making it impossible to
+            distinguish K&R-style from prototyped function types.  The
+            rest of GDB needs to know this.  */
+         TYPE_FLAGS (SYMBOL_TYPE (sym)) |= TYPE_FLAG_MAYBE_PROTOTYPED;
  
        /* fall into process_prototype_types */
  
***************
*** 1631,1636 ****
--- 1637,1643 ----
  	      TYPE_FIELD_TYPE (ftype, nparams++) = ptype;
  	    }
  	  TYPE_NFIELDS (ftype) = nparams;
+ 	  TYPE_FLAGS (ftype) &= ~TYPE_FLAG_MAYBE_PROTOTYPED;
  	  TYPE_FLAGS (ftype) |= TYPE_FLAG_PROTOTYPED;
  	}
        break;
Index: gdb/valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.41
diff -c -r1.41 valops.c
*** gdb/valops.c	2001/11/13 16:44:13	1.41
--- gdb/valops.c	2001/11/28 04:45:57
***************
*** 1138,1147 ****
     for arguments to be passed to C functions.
  
     If PARAM_TYPE is non-NULL, it is the expected parameter type.
-    IS_PROTOTYPED is non-zero if the function declaration is prototyped.  */
  
  static value_ptr
! value_arg_coerce (value_ptr arg, struct type *param_type, int is_prototyped)
  {
    register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
    register struct type *type
--- 1138,1157 ----
     for arguments to be passed to C functions.
  
     If PARAM_TYPE is non-NULL, it is the expected parameter type.
  
+    PROTOTYPEDNESS takes on one of three values:
+    - zero, meaning that the function is K&R style, and its arguments
+      need to be promoted accordingly,
+    - TYPE_FLAG_PROTOTYPED, meaning that the function is prototyped,
+      and its arguments should be coerced to the formal parameter types, or
+    - TYPE_FLAG_MAYBE_PROTOTYPED, meaning that we don't have accurate
+      information on whether the function is prototyped or not.
+      Floating-point types are promoted if COERCE_FLOAT_TO_DOUBLE says
+      they should be.  See default_coerce_float_to_double and
+      standard_coerce_float_to_double, defined above.  */
  static value_ptr
! value_arg_coerce (value_ptr arg, struct type *param_type, 
!                   int prototypedness)
  {
    register struct type *arg_type = check_typedef (VALUE_TYPE (arg));
    register struct type *type
***************
*** 1162,1168 ****
      case TYPE_CODE_BOOL:
      case TYPE_CODE_ENUM:
        /* If we don't have a prototype, coerce to integer type if necessary.  */
!       if (!is_prototyped)
  	{
  	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
  	    type = builtin_type_int;
--- 1172,1178 ----
      case TYPE_CODE_BOOL:
      case TYPE_CODE_ENUM:
        /* If we don't have a prototype, coerce to integer type if necessary.  */
!       if (prototypedness == 0)
  	{
  	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int))
  	    type = builtin_type_int;
***************
*** 1174,1184 ****
  	type = builtin_type_int;
        break;
      case TYPE_CODE_FLT:
!       /* FIXME: We should always convert floats to doubles in the
!          non-prototyped case.  As many debugging formats include
!          no information about prototyping, we have to live with
!          COERCE_FLOAT_TO_DOUBLE for now.  */
!       if (!is_prototyped && COERCE_FLOAT_TO_DOUBLE (param_type, arg_type))
  	{
  	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
  	    type = builtin_type_double;
--- 1184,1192 ----
  	type = builtin_type_int;
        break;
      case TYPE_CODE_FLT:
!       if (prototypedness == 0
!           || (prototypedness == TYPE_FLAG_MAYBE_PROTOTYPED
!               && COERCE_FLOAT_TO_DOUBLE (param_type, arg_type)))
  	{
  	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double))
  	    type = builtin_type_double;
***************
*** 1437,1446 ****
  
        else
  	{
! 	  int is_prototyped = TYPE_FLAGS (ftype) & TYPE_FLAG_PROTOTYPED;
  	  param_type = TYPE_FIELD_TYPE (ftype, i);
  
! 	  args[i] = value_arg_coerce (args[i], param_type, is_prototyped);
  	}
  
        /*elz: this code is to handle the case in which the function to be called
--- 1445,1456 ----
  
        else
  	{
! 	  int prototypedness
!             = (TYPE_FLAGS (ftype)
!                & (TYPE_FLAG_PROTOTYPED | TYPE_FLAG_MAYBE_PROTOTYPED));
  	  param_type = TYPE_FIELD_TYPE (ftype, i);
  
! 	  args[i] = value_arg_coerce (args[i], param_type, prototypedness);
  	}
  
        /*elz: this code is to handle the case in which the function to be called


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]