+2011-05-05 Nathan Froyd <froydnj@codesourcery.com>
+
+ * objc-runtime-shared-support.h (get_arg_type_list): Delete.
+ (build_function_type_for_method): Declare.
+ * objc-runtime-hooks.h (struct _objc_runtime_hooks_r): Change
+ type of get_arg_type_base_list field.
+ * objc-act.h (OBJC_VOID_AT_END): Delete.
+ * objc-act.c (get_arg_type_list): Delete.
+ (build_function_type_for_method): New function.
+ (objc_decl_method_attributes): Call build_function_type_for_method.
+ (really_start_method): Likewise.
+ * objc-gnu-runtime-abi-01.c
+ (gnu_runtime_abi_01_get_type_arg_list_base): Change prototype and
+ adjust function accordingly. Update header comment.
+ (build_objc_method_call): Call build_function_type_for_method.
+ * objc-next-runtime-abi-01.c
+ (next_runtime_abi_01_get_type_arg_list_base): Change prototype and
+ adjust function accordingly. Update header comment.
+ (build_objc_method_call): Call build_function_type_for_method.
+ * objc-next-runtime-abi-02.c
+ (next_runtime_abi_02_get_type_arg_list_base): Change prototype and
+ adjust function accordingly. Update header comment.
+ (objc_copy_to_temp_side_effect_params): Take fntype instead of a
+ typelist. Use function_args_iterator for traversing fntype.
+ (build_v2_build_objc_method_call): Adjust call to it.
+ Call build_function_type_for_method
+
2011-05-05 Joseph Myers <joseph@codesourcery.com>
* objc-act.c (objc_start_method_definition): Add parameter expr.
(by setting TREE_DEPRECATED and TREE_THIS_VOLATILE) so there
is nothing to do. */
tree saved_type = TREE_TYPE (*node);
- TREE_TYPE (*node) = build_function_type
- (TREE_VALUE (saved_type), get_arg_type_list (*node, METHOD_REF, 0));
+ TREE_TYPE (*node)
+ = build_function_type_for_method (TREE_VALUE (saved_type), *node,
+ METHOD_REF, 0);
decl_attributes (node, filtered_attributes, flags);
METHOD_TYPE_ATTRIBUTES (*node) = TYPE_ATTRIBUTES (TREE_TYPE (*node));
TREE_TYPE (*node) = saved_type;
return opcode == INSTANCE_METHOD_DECL || opcode == CLASS_METHOD_DECL;
}
-/* Used by `build_objc_method_call'. Return an argument list for
- method METH. CONTEXT is either METHOD_DEF or METHOD_REF, saying
- whether we are trying to define a method or call one. SUPERFLAG
- says this is for a send to super; this makes a difference for the
- NeXT calling sequence in which the lookup and the method call are
- done together. If METH is null, user-defined arguments (i.e.,
- beyond self and _cmd) shall be represented by `...'. */
+/* Return a function type for METHOD with RETURN_TYPE. CONTEXT is
+ either METHOD_DEF or METHOD_REF, indicating whether we are defining a
+ method or calling one. SUPER_FLAG indicates whether this is a send
+ to super; this makes a difference for the NeXT calling sequence in
+ which the lookup and the method call are done together. If METHOD is
+ NULL, user-defined arguments (i.e., beyond self and _cmd) shall be
+ represented as varargs. */
tree
-get_arg_type_list (tree meth, int context, int superflag)
+build_function_type_for_method (tree return_type, tree method,
+ int context, bool super_flag)
{
- tree arglist, akey;
+ VEC(tree,gc) *argtypes = make_tree_vector ();
+ tree t, ftype;
+ bool is_varargs = false;
- /* Receiver & _cmd types are runtime-dependent. */
- arglist = (*runtime.get_arg_type_list_base) (meth, context, superflag);
+ (*runtime.get_arg_type_list_base) (&argtypes, method, context, super_flag);
- /* No actual method prototype given -- assume that remaining arguments
- are `...'. */
- if (!meth)
- return arglist;
+ /* No actual method prototype given; remaining args passed as varargs. */
+ if (method == NULL_TREE)
+ {
+ is_varargs = true;
+ goto build_ftype;
+ }
- /* Build a list of argument types. */
- for (akey = METHOD_SEL_ARGS (meth); akey; akey = DECL_CHAIN (akey))
+ for (t = METHOD_SEL_ARGS (method); t; t = DECL_CHAIN (t))
{
- tree arg_type = TREE_VALUE (TREE_TYPE (akey));
+ tree arg_type = TREE_VALUE (TREE_TYPE (t));
- /* Decay argument types for the underlying C function as appropriate. */
+ /* Decay argument types for the underlying C function as
+ appropriate. */
arg_type = objc_decay_parm_type (arg_type);
- chainon (arglist, build_tree_list (NULL_TREE, arg_type));
+ VEC_safe_push (tree, gc, argtypes, arg_type);
}
- if (METHOD_ADD_ARGS (meth))
+ if (METHOD_ADD_ARGS (method))
{
- for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
- akey; akey = TREE_CHAIN (akey))
+ for (t = TREE_CHAIN (METHOD_ADD_ARGS (method));
+ t; t = TREE_CHAIN (t))
{
- tree arg_type = TREE_TYPE (TREE_VALUE (akey));
+ tree arg_type = TREE_TYPE (TREE_VALUE (t));
arg_type = objc_decay_parm_type (arg_type);
- chainon (arglist, build_tree_list (NULL_TREE, arg_type));
+ VEC_safe_push (tree, gc, argtypes, arg_type);
}
- if (!METHOD_ADD_ARGS_ELLIPSIS_P (meth))
- goto lack_of_ellipsis;
+ if (METHOD_ADD_ARGS_ELLIPSIS_P (method))
+ is_varargs = true;
}
+
+ build_ftype:
+ if (is_varargs)
+ ftype = build_varargs_function_type_vec (return_type, argtypes);
else
- {
- lack_of_ellipsis:
- chainon (arglist, OBJC_VOID_AT_END);
- }
+ ftype = build_function_type_vec (return_type, argtypes);
- return arglist;
+ release_tree_vector (argtypes);
+ return ftype;
}
static tree
push_lang_context (lang_name_c);
#endif
- meth_type
- = build_function_type (ret_type,
- get_arg_type_list (method, METHOD_DEF, 0));
+ meth_type = build_function_type_for_method (ret_type, method, METHOD_DEF, 0);
objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
/* Set self_decl from the first argument. */
#define OBJC_MODIFIER_TRANSIENT 0x00000200
#define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
-#define OBJC_VOID_AT_END void_list_node
-
/* Exception handling constructs. We begin by having the parser do most
of the work and passing us blocks.
This allows us to handle different exceptions implementations. */
static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
-static tree gnu_runtime_abi_01_get_arg_type_list_base (tree, int, int);
+static void gnu_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **, tree,
+ int, int);
static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
tree, tree, tree, int);
return build_function_call (input_location, objc_get_class_decl, params);
}
-/* Used by get_arg_type_list.
- Return the types for receiver & _cmd at the start of a method argument list.
- context is either METHOD_DEF or METHOD_REF, saying whether we are trying
- to define a method or call one. superflag says this is for a send to super.
- meth may be NULL, in the case that there is no prototype. */
+/* Used by build_function_type_for_method. Append the types for
+ receiver & _cmd at the start of a method argument list to ARGTYPES.
+ CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
+ trying to define a method or call one. SUPERFLAG says this is for a
+ send to super. METH may be NULL, in the case that there is no
+ prototype. */
-static tree
-gnu_runtime_abi_01_get_arg_type_list_base (tree meth, int context,
+static void
+gnu_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
+ int context,
int superflag ATTRIBUTE_UNUSED)
{
- tree arglist;
+ tree receiver_type;
- /* Receiver type. */
if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
- arglist = build_tree_list (NULL_TREE, objc_instance_type);
+ receiver_type = objc_instance_type;
else
- arglist = build_tree_list (NULL_TREE, objc_object_type);
+ receiver_type = objc_object_type;
+ VEC_safe_push (tree, gc, *argtypes, receiver_type);
/* Selector type - will eventually change to `int'. */
- chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
- return arglist;
+ VEC_safe_push (tree, gc, *argtypes, objc_selector_type);
}
/* Unused for GNU runtime. */
= (method_prototype
? TREE_VALUE (TREE_TYPE (method_prototype))
: objc_object_type);
-
- tree method_param_types =
- get_arg_type_list (method_prototype, METHOD_REF, super_flag);
- tree ftype = build_function_type (ret_type, method_param_types);
+ tree ftype
+ = build_function_type_for_method (ret_type, method_prototype,
+ METHOD_REF, super_flag);
tree sender_cast;
tree method, t;
static tree next_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
static tree next_runtime_abi_01_receiver_is_class_object (tree);
-static tree next_runtime_abi_01_get_arg_type_list_base (tree, int, int);
+static void next_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **, tree,
+ int, int);
static tree next_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
tree, tree, tree, int);
static bool next_runtime_abi_01_setup_const_string_class_decl (void);
}
}
-/* Used by get_arg_type_list.
- Return the types for receiver & _cmd at the start of a method argument list.
- context is either METHOD_DEF or METHOD_REF, saying whether we are trying
- to define a method or call one. superflag says this is for a send to super.
- meth may be NULL, in the case that there is no prototype. */
+/* Used by build_function_type_for_method. Append the types for
+ receiver & _cmd at the start of a method argument list to ARGTYPES.
+ CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
+ trying to define a method or call one. SUPERFLAG says this is for a
+ send to super. METH may be NULL, in the case that there is no
+ prototype. */
-static tree
-next_runtime_abi_01_get_arg_type_list_base (tree meth, int context, int superflag)
+static void
+next_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
+ int context, int superflag)
{
- tree arglist;
+ tree receiver_type;
- /* Receiver type. */
if (superflag)
- arglist = build_tree_list (NULL_TREE, objc_super_type);
+ receiver_type = objc_super_type;
else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
- arglist = build_tree_list (NULL_TREE, objc_instance_type);
+ receiver_type = objc_instance_type;
else
- arglist = build_tree_list (NULL_TREE, objc_object_type);
+ receiver_type = objc_object_type;
+ VEC_safe_push (tree, gc, *argtypes, receiver_type);
/* Selector type - will eventually change to `int'. */
- chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
- return arglist;
+ VEC_safe_push (tree, gc, *argtypes, objc_selector_type);
}
static tree
= (method_prototype
? TREE_VALUE (TREE_TYPE (method_prototype))
: objc_object_type);
-
- tree method_param_types =
- get_arg_type_list (method_prototype, METHOD_REF, super_flag);
- tree ftype = build_function_type (ret_type, method_param_types);
+ tree ftype = build_function_type_for_method (ret_type, method_prototype,
+ METHOD_REF, super_flag);
if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
ftype = build_type_attribute_variant (ftype,
static tree next_runtime_abi_02_get_category_super_ref (location_t, struct imp_entry *, bool);
static tree next_runtime_abi_02_receiver_is_class_object (tree);
-static tree next_runtime_abi_02_get_arg_type_list_base (tree, int, int);
+static void next_runtime_abi_02_get_arg_type_list_base (VEC(tree,gc) **, tree,
+ int, int);
static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree,
tree, tree, tree, int);
static bool next_runtime_abi_02_setup_const_string_class_decl (void);
}
}
-/* Used by get_arg_type_list.
- Return the types for receiver & _cmd at the start of a method
- argument list. context is either METHOD_DEF or METHOD_REF, saying
- whether we are trying to define a method or call one. superflag
- says this is for a send to super. meth may be NULL, in the case
- that there is no prototype. */
+/* Used by build_function_type_for_method. Append the types for
+ receiver & _cmd at the start of a method argument list to ARGTYPES.
+ CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
+ trying to define a method or call one. SUPERFLAG says this is for a
+ send to super. METH may be NULL, in the case that there is no
+ prototype. */
-static tree
-next_runtime_abi_02_get_arg_type_list_base (tree meth, int context, int superflag)
+static void
+next_runtime_abi_02_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
+ int context, int superflag)
{
- tree arglist;
+ tree receiver_type;
- /* Receiver type. */
if (superflag)
- arglist = build_tree_list (NULL_TREE, objc_super_type);
+ receiver_type = objc_super_type;
else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
- arglist = build_tree_list (NULL_TREE, objc_instance_type);
+ receiver_type = objc_instance_type;
else
- arglist = build_tree_list (NULL_TREE, objc_object_type);
+ receiver_type = objc_object_type;
+ VEC_safe_push (tree, gc, *argtypes, receiver_type);
/* Selector type - will eventually change to `int'. */
- chainon (arglist, build_tree_list (NULL_TREE,
- (superflag ? objc_v2_super_selector_type
- : objc_v2_selector_type)));
- return arglist;
+ VEC_safe_push (tree, gc, *argtypes,
+ (superflag
+ ? objc_v2_super_selector_type
+ : objc_v2_selector_type));
}
/* TODO: Merge this with the message refs. */
return NULL_TREE;
}
-/* Assign all arguments in VALUES which have side-effect to a
- temporary and replaced that argument in VALUES list with the
- temporary. TYPELIST is the list of argument types. */
+/* Assign all arguments in VALUES which have side-effect to a temporary
+ and replaced that argument in VALUES list with the temporary. The
+ arguments will be passed to a function with FNTYPE. */
static tree
-objc_copy_to_temp_side_effect_params (tree typelist, tree values)
+objc_copy_to_temp_side_effect_params (tree fntype, tree values)
{
- tree valtail, typetail;
+ tree valtail;
+ function_args_iterator iter;
+
/* Skip over receiver and the &_msf_ref types. */
- gcc_assert (TREE_CHAIN (typelist));
- typetail = TREE_CHAIN (TREE_CHAIN (typelist));
+ function_args_iter_init (&iter, fntype);
+ function_args_iter_next (&iter);
+ function_args_iter_next (&iter);
for (valtail = values; valtail;
- valtail = TREE_CHAIN (valtail), typetail = TREE_CHAIN (typetail))
+ valtail = TREE_CHAIN (valtail), function_args_iter_next (&iter))
{
tree value = TREE_VALUE (valtail);
- tree type = typetail ? TREE_VALUE (typetail) : NULL_TREE;
+ tree type = function_args_iter_cond (&iter);
if (type == NULL_TREE)
break;
if (!TREE_SIDE_EFFECTS (value))
= (method_prototype
? TREE_VALUE (TREE_TYPE (method_prototype))
: objc_object_type);
- tree method_param_types = get_arg_type_list (method_prototype,
+ tree ftype = build_function_type_for_method (ret_type, method_prototype,
METHOD_REF, super_flag);
-
- tree ftype = build_function_type (ret_type, method_param_types);
tree sender_cast;
if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
sender_cast = build_pointer_type (ftype);
if (check_for_nil)
- method_params = objc_copy_to_temp_side_effect_params (method_param_types,
+ method_params = objc_copy_to_temp_side_effect_params (ftype,
method_params);
/* Get &message_ref_t.messenger. */
/* Receiver is class Object, check runtime-specific. */
tree (*receiver_is_class_object) (tree);
/* Get the start of a method argument type list (receiver, _cmd). */
- tree (*get_arg_type_list_base) (tree, int, int);
+ void (*get_arg_type_list_base) (VEC(tree,gc) **, tree, int, int);
/* Build method call. */
tree (*build_objc_method_call) (location_t, tree, tree, tree, tree, tree, int);
extern struct c_arg_info *objc_get_parm_info (int, tree);
#endif
extern void objc_push_parm (tree);
-extern tree get_arg_type_list (tree, int, int);
+
+extern tree build_function_type_for_method (tree, tree, int, bool);
/* Stuff that should be migrated to shared support (or some v1-only file). */
extern void build_super_template (void);