aboutsummaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c134
1 files changed, 76 insertions, 58 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index d2702a8..a476ddc 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -117,29 +117,14 @@ value_cast (type, arg2)
struct type *type;
register value_ptr arg2;
{
- register enum type_code code1;
+ register enum type_code code1 = TYPE_CODE (type);
register enum type_code code2;
register int scalar;
if (VALUE_TYPE (arg2) == type)
return arg2;
- /* Coerce arrays but not enums. Enums will work as-is
- 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;
+ COERCE_REF(arg2);
/* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
is treated like a cast to (TYPE [N])OBJECT,
@@ -163,6 +148,25 @@ value_cast (type, 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
|| 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);
/* 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
@@ -1065,6 +1069,9 @@ call_function_by_hand (function, nargs, args)
sp = old_sp; /* It really is used, for some ifdef's... */
#endif
+ if (nargs < TYPE_NFIELDS (ftype))
+ error ("too few arguments in function call");
+
for (i = nargs - 1; i >= 0; i--)
{
struct type *param_type;
@@ -1075,64 +1082,39 @@ call_function_by_hand (function, nargs, args)
args[i] = value_arg_coerce (args[i], param_type);
}
-#ifdef STACK_ALIGN
- /* If stack grows down, we must leave a hole at the top. */
- {
- 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--)
- len += TYPE_LENGTH (VALUE_TYPE (args[i]));
-#ifdef CALL_DUMMY_STACK_ADJUST
- len += CALL_DUMMY_STACK_ADJUST;
-#endif
-#if 1 INNER_THAN 2
- sp -= STACK_ALIGN (len) - len;
-#else
- sp += STACK_ALIGN (len) - len;
-#endif
- }
-#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
+ 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. */
- sp = value_push (sp, args[i]);
+ 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. */
@@ -1142,6 +1124,42 @@ call_function_by_hand (function, nargs, args)
}
#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
+ /* If stack grows down, we must leave a hole at the top. */
+ {
+ int len = 0;
+
+ for (i = nargs - 1; i >= 0; i--)
+ len += TYPE_LENGTH (VALUE_TYPE (args[i]));
+#ifdef CALL_DUMMY_STACK_ADJUST
+ len += CALL_DUMMY_STACK_ADJUST;
+#endif
+#if 1 INNER_THAN 2
+ sp -= STACK_ALIGN (len) - len;
+#else
+ sp += STACK_ALIGN (len) - len;
+#endif
+ }
+#endif /* STACK_ALIGN */
+
#ifdef PUSH_ARGUMENTS
PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr);
#else /* !PUSH_ARGUMENTS */