- if (method)
- {
- CORE_ADDR funaddr;
- struct type *val_type;
-
- funaddr = find_function_addr (method, &val_type);
-
- block_for_pc (funaddr);
-
- CHECK_TYPEDEF (val_type);
-
- if ((val_type == NULL)
- || (TYPE_CODE(val_type) == TYPE_CODE_ERROR))
- {
- if (expect_type != NULL)
- val_type = expect_type;
- }
-
- struct_return = using_struct_return (exp->gdbarch, method,
- val_type);
- }
- else if (expect_type != NULL)
- {
- struct_return = using_struct_return (exp->gdbarch, NULL,
- check_typedef (expect_type));
- }
-
- /* Found a function symbol. Now we will substitute its
- value in place of the message dispatcher (obj_msgSend),
- so that we call the method directly instead of thru
- the dispatcher. The main reason for doing this is that
- we can now evaluate the return value and parameter values
- according to their known data types, in case we need to
- do things like promotion, dereferencing, special handling
- of structs and doubles, etc.
-
- We want to use the type signature of 'method', but still
- jump to objc_msgSend() or objc_msgSend_stret() to better
- mimic the behavior of the runtime. */
-
- if (method)
- {
- if (TYPE_CODE (value_type (method)) != TYPE_CODE_FUNC)
- error (_("method address has symbol information "
- "with non-function type; skipping"));
-
- /* Create a function pointer of the appropriate type, and
- replace its value with the value of msg_send or
- msg_send_stret. We must use a pointer here, as
- msg_send and msg_send_stret are of pointer type, and
- the representation may be different on systems that use
- function descriptors. */
- if (struct_return)
- called_method
- = value_from_pointer (lookup_pointer_type (value_type (method)),
- value_as_address (msg_send_stret));
- else
- called_method
- = value_from_pointer (lookup_pointer_type (value_type (method)),
- value_as_address (msg_send));
- }
- else
- {
- if (struct_return)
- called_method = msg_send_stret;
- else
- called_method = msg_send;
- }
-
- if (noside == EVAL_SKIP)
- goto nosideret;
-
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- {
- /* If the return type doesn't look like a function type,
- call an error. This can happen if somebody tries to
- turn a variable into a function call. This is here
- because people often want to call, eg, strcmp, which
- gdb doesn't know is a function. If gdb isn't asked for
- it's opinion (ie. through "whatis"), it won't offer
- it. */
-
- struct type *type = value_type (called_method);
-
- if (type && TYPE_CODE (type) == TYPE_CODE_PTR)
- type = TYPE_TARGET_TYPE (type);
- type = TYPE_TARGET_TYPE (type);
-
- if (type)
- {
- if ((TYPE_CODE (type) == TYPE_CODE_ERROR) && expect_type)
- return allocate_value (expect_type);
- else
- return allocate_value (type);
- }
- else
- error (_("Expression of type other than "
- "\"method returning ...\" used as a method"));
- }
-
- /* Now depending on whether we found a symbol for the method,
- we will either call the runtime dispatcher or the method
- directly. */
-
- argvec[0] = called_method;
- argvec[1] = target;
- argvec[2] = value_from_longest (long_type, selector);
- /* User-supplied arguments. */
- for (tem = 0; tem < nargs; tem++)
- argvec[tem + 3] = evaluate_subexp_with_coercion (exp, pos, noside);
- argvec[tem + 3] = 0;
-
- if (gnu_runtime && (method != NULL))
- {
- /* Function objc_msg_lookup returns a pointer. */
- deprecated_set_value_type (argvec[0],
- lookup_pointer_type (lookup_function_type (value_type (argvec[0]))));
- argvec[0]
- = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
- }
-
- ret = call_function_by_hand (argvec[0], nargs + 2, argvec + 1);
- return ret;
- }
- break;
-
- case OP_FUNCALL:
- (*pos) += 2;
- op = exp->elts[*pos].opcode;
- nargs = longest_to_int (exp->elts[pc + 1].longconst);
- /* Allocate arg vector, including space for the function to be
- called in argvec[0] and a terminating NULL. */
- argvec = (struct value **)
- alloca (sizeof (struct value *) * (nargs + 3));
- if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
- {
- /* First, evaluate the structure into arg2. */
- pc2 = (*pos)++;
-
- if (noside == EVAL_SKIP)
- goto nosideret;
-
- if (op == STRUCTOP_MEMBER)
- {
- arg2 = evaluate_subexp_for_address (exp, pos, noside);
- }
- else
- {
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
- }
-
- /* If the function is a virtual function, then the
- aggregate value (providing the structure) plays
- its part by providing the vtable. Otherwise,
- it is just along for the ride: call the function
- directly. */
-
- arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-
- type = check_typedef (value_type (arg1));
- if (TYPE_CODE (type) == TYPE_CODE_METHODPTR)
- {
- if (noside == EVAL_AVOID_SIDE_EFFECTS)
- arg1 = value_zero (TYPE_TARGET_TYPE (type), not_lval);
- else
- arg1 = cplus_method_ptr_to_value (&arg2, arg1);
-
- /* Now, say which argument to start evaluating from. */
- nargs++;
- tem = 2;
- argvec[1] = arg2;
- }
- else if (TYPE_CODE (type) == TYPE_CODE_MEMBERPTR)
- {
- struct type *type_ptr
- = lookup_pointer_type (TYPE_DOMAIN_TYPE (type));
- struct type *target_type_ptr
- = lookup_pointer_type (TYPE_TARGET_TYPE (type));
-
- /* Now, convert these values to an address. */
- arg2 = value_cast (type_ptr, arg2);
-
- mem_offset = value_as_long (arg1);
-
- arg1 = value_from_pointer (target_type_ptr,
- value_as_long (arg2) + mem_offset);
- arg1 = value_ind (arg1);
- tem = 1;
- }
- else
- error (_("Non-pointer-to-member value used in pointer-to-member "
- "construct"));
- }
- else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
- {
- /* Hair for method invocations. */
- int tem2;
-
- nargs++;
- /* First, evaluate the structure into arg2. */
- pc2 = (*pos)++;
- tem2 = longest_to_int (exp->elts[pc2 + 1].longconst);
- *pos += 3 + BYTES_TO_EXP_ELEM (tem2 + 1);
- if (noside == EVAL_SKIP)
- goto nosideret;
-
- if (op == STRUCTOP_STRUCT)
- {
- /* If v is a variable in a register, and the user types
- v.method (), this will produce an error, because v has
- no address.
-
- A possible way around this would be to allocate a
- copy of the variable on the stack, copy in the
- contents, call the function, and copy out the
- contents. I.e. convert this from call by reference
- to call by copy-return (or whatever it's called).
- However, this does not work because it is not the
- same: the method being called could stash a copy of
- the address, and then future uses through that address
- (after the method returns) would be expected to
- use the variable itself, not some copy of it. */
- arg2 = evaluate_subexp_for_address (exp, pos, noside);
- }
- else
- {
- arg2 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
-
- /* Check to see if the operator '->' has been
- overloaded. If the operator has been overloaded
- replace arg2 with the value returned by the custom
- operator and continue evaluation. */
- while (unop_user_defined_p (op, arg2))
- {
- volatile struct gdb_exception except;
- struct value *value = NULL;
- TRY_CATCH (except, RETURN_MASK_ERROR)
- {
- value = value_x_unop (arg2, op, noside);
- }
-
- if (except.reason < 0)
- {
- if (except.error == NOT_FOUND_ERROR)
- break;
- else
- throw_exception (except);
- }
- arg2 = value;
- }
- }
- /* Now, say which argument to start evaluating from. */
- tem = 2;
- }
- else if (op == OP_SCOPE
- && overload_resolution
- && (exp->language_defn->la_language == language_cplus))
- {
- /* Unpack it locally so we can properly handle overload
- resolution. */
- char *name;
- int local_tem;
-
- pc2 = (*pos)++;
- local_tem = longest_to_int (exp->elts[pc2 + 2].longconst);
- (*pos) += 4 + BYTES_TO_EXP_ELEM (local_tem + 1);
- type = exp->elts[pc2 + 1].type;
- name = &exp->elts[pc2 + 3].string;
-
- function = NULL;
- function_name = NULL;
- if (TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
- {
- function = cp_lookup_symbol_namespace (TYPE_TAG_NAME (type),
- name,
- get_selected_block (0),
- VAR_DOMAIN);
- if (function == NULL)
- error (_("No symbol \"%s\" in namespace \"%s\"."),
- name, TYPE_TAG_NAME (type));
-
- tem = 1;
- }
- else
- {
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION);
- function_name = name;
-
- arg2 = value_zero (type, lval_memory);
- ++nargs;
- tem = 2;
- }
- }
- else if (op == OP_ADL_FUNC)
- {
- /* Save the function position and move pos so that the arguments
- can be evaluated. */
- int func_name_len;
-
- save_pos1 = *pos;
- tem = 1;
-
- func_name_len = longest_to_int (exp->elts[save_pos1 + 3].longconst);
- (*pos) += 6 + BYTES_TO_EXP_ELEM (func_name_len + 1);
- }
- else
- {
- /* Non-method function call. */
- save_pos1 = *pos;
- tem = 1;
-
- /* If this is a C++ function wait until overload resolution. */
- if (op == OP_VAR_VALUE
- && overload_resolution
- && (exp->language_defn->la_language == language_cplus))
- {
- (*pos) += 4; /* Skip the evaluation of the symbol. */
- argvec[0] = NULL;
- }
- else
- {
- argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside);
- type = value_type (argvec[0]);
- if (type && TYPE_CODE (type) == TYPE_CODE_PTR)
- type = TYPE_TARGET_TYPE (type);
- if (type && TYPE_CODE (type) == TYPE_CODE_FUNC)
- {
- for (; tem <= nargs && tem <= TYPE_NFIELDS (type); tem++)
- {
- argvec[tem] = evaluate_subexp (TYPE_FIELD_TYPE (type,
- tem - 1),
- exp, pos, noside);
- }
- }
- }
- }
-
- /* Evaluate arguments. */
- for (; tem <= nargs; tem++)
- {
- /* Ensure that array expressions are coerced into pointer
- objects. */
- argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
- }
-
- /* Signal end of arglist. */
- argvec[tem] = 0;
- if (op == OP_ADL_FUNC)
- {
- struct symbol *symp;
- char *func_name;
- int name_len;
- int string_pc = save_pos1 + 3;
-
- /* Extract the function name. */
- name_len = longest_to_int (exp->elts[string_pc].longconst);
- func_name = (char *) alloca (name_len + 1);
- strcpy (func_name, &exp->elts[string_pc + 1].string);
-
- find_overload_match (&argvec[1], nargs, func_name,
- NON_METHOD, /* not method */
- NULL, NULL, /* pass NULL symbol since
- symbol is unknown */
- NULL, &symp, NULL, 0);
-
- /* Now fix the expression being evaluated. */
- exp->elts[save_pos1 + 2].symbol = symp;
- argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
- }
-
- if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR
- || (op == OP_SCOPE && function_name != NULL))
- {
- int static_memfuncp;
- char *tstr;
-
- /* Method invocation : stuff "this" as first parameter. */
- argvec[1] = arg2;