* valops.c (value_cast): Cehck for cast to array type *before*
we coerce array to pointer (in case arg2 is already array). * valops.c (call_function_by_hand): Set using_gcc to 2 if using gcc2. Needed for REG_STRUCT_HAS_ADDR to work on sparc. Also check REG_STRUCT_HAS_ADDR for union, array and string types. * valops.c (call_function_by_hand): Re-arrange code for pushing paramaters on the stack so we can do better STACK_ALIGN. * valops.c (call_function_by_hand): Call error if the number of arguments is fewer than parameter types in function type.
This commit is contained in:
parent
732ff6aff3
commit
f7a69ed795
|
@ -1,3 +1,18 @@
|
||||||
|
Fri Mar 3 17:42:48 1995 Per Bothner <bothner@kalessin.cygnus.com>
|
||||||
|
|
||||||
|
* valops.c (value_cast): Cehck for cast to array type *before*
|
||||||
|
we coerce array to pointer (in case arg2 is already array).
|
||||||
|
|
||||||
|
* valops.c (call_function_by_hand): Set using_gcc to 2 if using
|
||||||
|
gcc2. Needed for REG_STRUCT_HAS_ADDR to work on sparc.
|
||||||
|
Also check REG_STRUCT_HAS_ADDR for union, array and string types.
|
||||||
|
|
||||||
|
* valops.c (call_function_by_hand): Re-arrange code for pushing
|
||||||
|
paramaters on the stack so we can do better STACK_ALIGN.
|
||||||
|
|
||||||
|
* valops.c (call_function_by_hand): Call error if the number
|
||||||
|
of arguments is fewer than parameter types in function type.
|
||||||
|
|
||||||
Fri Mar 3 17:13:05 1995 Doug Evans <dje@canuck.cygnus.com>
|
Fri Mar 3 17:13:05 1995 Doug Evans <dje@canuck.cygnus.com>
|
||||||
|
|
||||||
* sparc-tdep.c (sparc_extract_struct_value_address): Move
|
* sparc-tdep.c (sparc_extract_struct_value_address): Move
|
||||||
|
|
152
gdb/valops.c
152
gdb/valops.c
|
@ -117,29 +117,14 @@ value_cast (type, arg2)
|
||||||
struct type *type;
|
struct type *type;
|
||||||
register value_ptr arg2;
|
register value_ptr arg2;
|
||||||
{
|
{
|
||||||
register enum type_code code1;
|
register enum type_code code1 = TYPE_CODE (type);
|
||||||
register enum type_code code2;
|
register enum type_code code2;
|
||||||
register int scalar;
|
register int scalar;
|
||||||
|
|
||||||
if (VALUE_TYPE (arg2) == type)
|
if (VALUE_TYPE (arg2) == type)
|
||||||
return arg2;
|
return arg2;
|
||||||
|
|
||||||
/* Coerce arrays but not enums. Enums will work as-is
|
COERCE_REF(arg2);
|
||||||
and coercing them would cause an infinite recursion. */
|
|
||||||
if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_ENUM)
|
|
||||||
COERCE_ARRAY (arg2);
|
|
||||||
|
|
||||||
COERCE_VARYING_ARRAY (arg2);
|
|
||||||
|
|
||||||
code1 = TYPE_CODE (type);
|
|
||||||
code2 = TYPE_CODE (VALUE_TYPE (arg2));
|
|
||||||
|
|
||||||
if (code1 == TYPE_CODE_COMPLEX)
|
|
||||||
return cast_into_complex (type, arg2);
|
|
||||||
if (code1 == TYPE_CODE_BOOL)
|
|
||||||
code1 = TYPE_CODE_INT;
|
|
||||||
if (code2 == TYPE_CODE_BOOL)
|
|
||||||
code2 = TYPE_CODE_INT;
|
|
||||||
|
|
||||||
/* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
|
/* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
|
||||||
is treated like a cast to (TYPE [N])OBJECT,
|
is treated like a cast to (TYPE [N])OBJECT,
|
||||||
|
@ -163,6 +148,25 @@ value_cast (type, arg2)
|
||||||
return arg2;
|
return arg2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (current_language->c_style_arrays
|
||||||
|
&& (VALUE_REPEATED (arg2)
|
||||||
|
|| TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_ARRAY))
|
||||||
|
arg2 = value_coerce_array (arg2); \
|
||||||
|
|
||||||
|
if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FUNC) \
|
||||||
|
arg2 = value_coerce_function (arg2);
|
||||||
|
|
||||||
|
COERCE_VARYING_ARRAY (arg2);
|
||||||
|
|
||||||
|
code2 = TYPE_CODE (VALUE_TYPE (arg2));
|
||||||
|
|
||||||
|
if (code1 == TYPE_CODE_COMPLEX)
|
||||||
|
return cast_into_complex (type, arg2);
|
||||||
|
if (code1 == TYPE_CODE_BOOL)
|
||||||
|
code1 = TYPE_CODE_INT;
|
||||||
|
if (code2 == TYPE_CODE_BOOL)
|
||||||
|
code2 = TYPE_CODE_INT;
|
||||||
|
|
||||||
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|
||||||
|| code2 == TYPE_CODE_ENUM || code2 == TYPE_CODE_RANGE);
|
|| code2 == TYPE_CODE_ENUM || code2 == TYPE_CODE_RANGE);
|
||||||
|
|
||||||
|
@ -999,7 +1003,7 @@ call_function_by_hand (function, nargs, args)
|
||||||
{
|
{
|
||||||
struct block *b = block_for_pc (funaddr);
|
struct block *b = block_for_pc (funaddr);
|
||||||
/* If compiled without -g, assume GCC. */
|
/* If compiled without -g, assume GCC. */
|
||||||
using_gcc = b == NULL || BLOCK_GCC_COMPILED (b);
|
using_gcc = b == NULL ? 0 : BLOCK_GCC_COMPILED (b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Are we returning a value using a structure return or a normal
|
/* Are we returning a value using a structure return or a normal
|
||||||
|
@ -1065,6 +1069,9 @@ call_function_by_hand (function, nargs, args)
|
||||||
sp = old_sp; /* It really is used, for some ifdef's... */
|
sp = old_sp; /* It really is used, for some ifdef's... */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (nargs < TYPE_NFIELDS (ftype))
|
||||||
|
error ("too few arguments in function call");
|
||||||
|
|
||||||
for (i = nargs - 1; i >= 0; i--)
|
for (i = nargs - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
struct type *param_type;
|
struct type *param_type;
|
||||||
|
@ -1075,17 +1082,71 @@ call_function_by_hand (function, nargs, args)
|
||||||
args[i] = value_arg_coerce (args[i], param_type);
|
args[i] = value_arg_coerce (args[i], param_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined (REG_STRUCT_HAS_ADDR)
|
||||||
|
{
|
||||||
|
/* This is a machine like the sparc, where we may need to pass a pointer
|
||||||
|
to the structure, not the structure itself. */
|
||||||
|
for (i = nargs - 1; i >= 0; i--)
|
||||||
|
if ((TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT
|
||||||
|
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_UNION
|
||||||
|
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_ARRAY
|
||||||
|
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRING)
|
||||||
|
&& REG_STRUCT_HAS_ADDR (using_gcc, VALUE_TYPE (args[i])))
|
||||||
|
{
|
||||||
|
CORE_ADDR addr;
|
||||||
|
int len = TYPE_LENGTH (VALUE_TYPE (args[i]));
|
||||||
|
#ifdef STACK_ALIGN
|
||||||
|
int aligned_len = STACK_ALIGN (len);
|
||||||
|
#else
|
||||||
|
int aligned_len = len;
|
||||||
|
#endif
|
||||||
|
#if !(1 INNER_THAN 2)
|
||||||
|
/* The stack grows up, so the address of the thing we push
|
||||||
|
is the stack pointer before we push it. */
|
||||||
|
addr = sp;
|
||||||
|
#else
|
||||||
|
sp -= aligned_len;
|
||||||
|
#endif
|
||||||
|
/* Push the structure. */
|
||||||
|
write_memory (sp, VALUE_CONTENTS (args[i]), len);
|
||||||
|
#if 1 INNER_THAN 2
|
||||||
|
/* The stack grows down, so the address of the thing we push
|
||||||
|
is the stack pointer after we push it. */
|
||||||
|
addr = sp;
|
||||||
|
#else
|
||||||
|
sp += aligned_len;
|
||||||
|
#endif
|
||||||
|
/* The value we're going to pass is the address of the thing
|
||||||
|
we just pushed. */
|
||||||
|
args[i] = value_from_longest (lookup_pointer_type (value_type),
|
||||||
|
(LONGEST) addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* REG_STRUCT_HAS_ADDR. */
|
||||||
|
|
||||||
|
/* Reserve space for the return structure to be written on the
|
||||||
|
stack, if necessary */
|
||||||
|
|
||||||
|
if (struct_return)
|
||||||
|
{
|
||||||
|
int len = TYPE_LENGTH (value_type);
|
||||||
|
#ifdef STACK_ALIGN
|
||||||
|
len = STACK_ALIGN (len);
|
||||||
|
#endif
|
||||||
|
#if 1 INNER_THAN 2
|
||||||
|
sp -= len;
|
||||||
|
struct_addr = sp;
|
||||||
|
#else
|
||||||
|
struct_addr = sp;
|
||||||
|
sp += len;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef STACK_ALIGN
|
#ifdef STACK_ALIGN
|
||||||
/* If stack grows down, we must leave a hole at the top. */
|
/* If stack grows down, we must leave a hole at the top. */
|
||||||
{
|
{
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
/* Reserve space for the return structure to be written on the
|
|
||||||
stack, if necessary */
|
|
||||||
|
|
||||||
if (struct_return)
|
|
||||||
len += TYPE_LENGTH (value_type);
|
|
||||||
|
|
||||||
for (i = nargs - 1; i >= 0; i--)
|
for (i = nargs - 1; i >= 0; i--)
|
||||||
len += TYPE_LENGTH (VALUE_TYPE (args[i]));
|
len += TYPE_LENGTH (VALUE_TYPE (args[i]));
|
||||||
#ifdef CALL_DUMMY_STACK_ADJUST
|
#ifdef CALL_DUMMY_STACK_ADJUST
|
||||||
|
@ -1099,49 +1160,6 @@ call_function_by_hand (function, nargs, args)
|
||||||
}
|
}
|
||||||
#endif /* STACK_ALIGN */
|
#endif /* STACK_ALIGN */
|
||||||
|
|
||||||
/* Reserve space for the return structure to be written on the
|
|
||||||
stack, if necessary */
|
|
||||||
|
|
||||||
if (struct_return)
|
|
||||||
{
|
|
||||||
#if 1 INNER_THAN 2
|
|
||||||
sp -= TYPE_LENGTH (value_type);
|
|
||||||
struct_addr = sp;
|
|
||||||
#else
|
|
||||||
struct_addr = sp;
|
|
||||||
sp += TYPE_LENGTH (value_type);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined (REG_STRUCT_HAS_ADDR)
|
|
||||||
{
|
|
||||||
/* This is a machine like the sparc, where we may need to pass a pointer
|
|
||||||
to the structure, not the structure itself. */
|
|
||||||
for (i = nargs - 1; i >= 0; i--)
|
|
||||||
if (TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT
|
|
||||||
&& REG_STRUCT_HAS_ADDR (using_gcc, VALUE_TYPE (args[i])))
|
|
||||||
{
|
|
||||||
CORE_ADDR addr;
|
|
||||||
#if !(1 INNER_THAN 2)
|
|
||||||
/* The stack grows up, so the address of the thing we push
|
|
||||||
is the stack pointer before we push it. */
|
|
||||||
addr = sp;
|
|
||||||
#endif
|
|
||||||
/* Push the structure. */
|
|
||||||
sp = value_push (sp, args[i]);
|
|
||||||
#if 1 INNER_THAN 2
|
|
||||||
/* The stack grows down, so the address of the thing we push
|
|
||||||
is the stack pointer after we push it. */
|
|
||||||
addr = sp;
|
|
||||||
#endif
|
|
||||||
/* The value we're going to pass is the address of the thing
|
|
||||||
we just pushed. */
|
|
||||||
args[i] = value_from_longest (lookup_pointer_type (value_type),
|
|
||||||
(LONGEST) addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* REG_STRUCT_HAS_ADDR. */
|
|
||||||
|
|
||||||
#ifdef PUSH_ARGUMENTS
|
#ifdef PUSH_ARGUMENTS
|
||||||
PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr);
|
PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr);
|
||||||
#else /* !PUSH_ARGUMENTS */
|
#else /* !PUSH_ARGUMENTS */
|
||||||
|
|
Loading…
Reference in New Issue