* elflink.h (elf_bfd_final_link): Check if dynobj is not NULL
[binutils-gdb.git] / gdb / valops.c
index 22c6948b0e526197e035f4025a66b86cfc79e5e2..4e14b095e173d0c637aeece6efa185c7c806e2eb 100644 (file)
@@ -1092,16 +1092,34 @@ default_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
 }
 
 
-/* A default function for COERCE_FLOAT_TO_DOUBLE: do the coercion only
-   when we don't have any type for the argument at hand.  This occurs
-   when we have no debug info, or when passing varargs.
-
-   This is an annoying default: the rule the compiler follows is to do
-   the standard promotions whenever there is no prototype in scope,
-   and almost all targets want this behavior.  But there are some old
-   architectures which want this odd behavior.  If you want to go
-   through them all and fix them, please do.  Modern gdbarch-style
-   targets may find it convenient to use standard_coerce_float_to_double.  */
+/* Functions to use for the COERCE_FLOAT_TO_DOUBLE gdbarch method.
+
+   How you should pass arguments to a function depends on whether it
+   was defined in K&R style or prototype style.  If you define a
+   function using the K&R syntax that takes a `float' argument, then
+   callers must pass that argument as a `double'.  If you define the
+   function using the prototype syntax, then you must pass the
+   argument as a `float', with no promotion.
+
+   Unfortunately, on certain older platforms, the debug info doesn't
+   indicate reliably how each function was defined.  A function type's
+   TYPE_FLAG_PROTOTYPED flag may be clear, even if the function was
+   defined in prototype style.  When calling a function whose
+   TYPE_FLAG_PROTOTYPED flag is clear, GDB consults the
+   COERCE_FLOAT_TO_DOUBLE gdbarch method to decide what to do.
+
+   For modern targets, it is proper to assume that, if the prototype
+   flag is clear, that can be trusted: `float' arguments should be
+   promoted to `double'.  You should register the function
+   `standard_coerce_float_to_double' to get this behavior.
+
+   For some older targets, if the prototype flag is clear, that
+   doesn't tell us anything.  So we guess that, if we don't have a
+   type for the formal parameter (i.e., the first argument to
+   COERCE_FLOAT_TO_DOUBLE is null), then we should promote it;
+   otherwise, we should leave it alone.  The function
+   `default_coerce_float_to_double' provides this behavior; it is the
+   default value, for compatibility with older configurations.  */
 int
 default_coerce_float_to_double (struct type *formal, struct type *actual)
 {
@@ -1109,10 +1127,6 @@ default_coerce_float_to_double (struct type *formal, struct type *actual)
 }
 
 
-/* Always coerce floats to doubles when there is no prototype in scope.
-   If your architecture follows the standard type promotion rules for
-   calling unprototyped functions, your gdbarch init function can pass
-   this function to set_gdbarch_coerce_float_to_double to use its logic.  */
 int
 standard_coerce_float_to_double (struct type *formal, struct type *actual)
 {
@@ -1306,6 +1320,7 @@ hand_function_call (value_ptr function, int nargs, value_ptr *args)
   CORE_ADDR real_pc;
   struct type *param_type = NULL;
   struct type *ftype = check_typedef (SYMBOL_TYPE (function));
+  int n_method_args = 0;
 
   dummy = alloca (SIZEOF_CALL_DUMMY_WORDS);
   sizeof_dummy1 = REGISTER_SIZE * SIZEOF_CALL_DUMMY_WORDS / sizeof (ULONGEST);
@@ -1410,11 +1425,31 @@ hand_function_call (value_ptr function, int nargs, value_ptr *args)
   sp = old_sp;                 /* It really is used, for some ifdef's... */
 #endif
 
-  if (nargs < TYPE_NFIELDS (ftype))
+  if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+    {
+      i = 0;
+      while (TYPE_CODE (TYPE_ARG_TYPES (ftype)[i]) != TYPE_CODE_VOID)
+       i++;
+      n_method_args = i;
+      if (nargs < i)
+       error ("too few arguments in method call");
+    }
+  else if (nargs < TYPE_NFIELDS (ftype))
     error ("too few arguments in function call");
 
   for (i = nargs - 1; i >= 0; i--)
     {
+      /* Assume that methods are always prototyped, unless they are off the
+        end (which we should only be allowing if there is a ``...'').  
+         FIXME.  */
+      if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+       {
+         if (i < n_method_args)
+           args[i] = value_arg_coerce (args[i], TYPE_ARG_TYPES (ftype)[i], 1);
+         else
+           args[i] = value_arg_coerce (args[i], NULL, 0);
+       }
+
       /* If we're off the end of the known arguments, do the standard
          promotions.  FIXME: if we had a prototype, this should only
          be allowed if ... were present.  */
@@ -1423,10 +1458,8 @@ hand_function_call (value_ptr function, int nargs, value_ptr *args)
 
       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);
+         args[i] = value_arg_coerce (args[i], param_type, TYPE_PROTOTYPED (ftype));
        }
 
       /*elz: this code is to handle the case in which the function to be called
@@ -1570,18 +1603,18 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
 
   sp = PUSH_ARGUMENTS (nargs, args, sp, struct_return, struct_addr);
 
-#ifdef PUSH_RETURN_ADDRESS     /* for targets that use no CALL_DUMMY */
-  /* There are a number of targets now which actually don't write any
-     CALL_DUMMY instructions into the target, but instead just save the
-     machine state, push the arguments, and jump directly to the callee
-     function.  Since this doesn't actually involve executing a JSR/BSR
-     instruction, the return address must be set up by hand, either by
-     pushing onto the stack or copying into a return-address register
-     as appropriate.  Formerly this has been done in PUSH_ARGUMENTS,
-     but that's overloading its functionality a bit, so I'm making it
-     explicit to do it here.  */
-  sp = PUSH_RETURN_ADDRESS (real_pc, sp);
-#endif /* PUSH_RETURN_ADDRESS */
+  if (PUSH_RETURN_ADDRESS_P ())
+    /* for targets that use no CALL_DUMMY */
+    /* There are a number of targets now which actually don't write
+       any CALL_DUMMY instructions into the target, but instead just
+       save the machine state, push the arguments, and jump directly
+       to the callee function.  Since this doesn't actually involve
+       executing a JSR/BSR instruction, the return address must be set
+       up by hand, either by pushing onto the stack or copying into a
+       return-address register as appropriate.  Formerly this has been
+       done in PUSH_ARGUMENTS, but that's overloading its
+       functionality a bit, so I'm making it explicit to do it here.  */
+    sp = PUSH_RETURN_ADDRESS (real_pc, sp);
 
   if (STACK_ALIGN_P () && !INNER_THAN (1, 2))
     {