/* Implement classes and message passing for Objective C.
Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Steve Naroff.
This file is part of GCC.
#include "tree-iterator.h"
#include "libfuncs.h"
#include "hashtab.h"
+#include "langhooks-def.h"
#define OBJC_VOID_AT_END void_list_node
#ifdef OBJCPLUS
/* We need to instantiate templates _before_ we emit ObjC metadata;
if we do not, some metadata (such as selectors) may go missing. */
+ at_eof = 1;
instantiate_pending_templates (0);
#endif
#ifdef OBJCPLUS
cp_finish_file ();
-#else
- maybe_apply_pending_pragma_weaks ();
#endif
}
\f
return OBJC_TYPE_NAME (type) == objc_class_id;
}
+
+int
+objc_types_compatible_p (tree type1, tree type2)
+{
+
+ if (objc_is_object_ptr (type1) || objc_is_object_ptr (type2)
+ || objc_is_class_name (type1) || objc_is_class_name (type2))
+ {
+ return lhd_types_compatible_p (type1, type2);
+ }
+ else
+ {
+#ifdef OBJCPLUS
+ return cxx_types_compatible_p (type1, type2);
+#else
+ return c_types_compatible_p (type1, type2);
+#endif
+ }
+}
+
+
/* Return 1 if LHS and RHS are compatible types for assignment or
various other operations. Return 0 if they are incompatible, and
return -1 if we choose to not decide (because the types are really
}
}
if (!found)
- warning ("%Jcreating selector for nonexistent method %qE",
- TREE_PURPOSE (chain), TREE_VALUE (chain));
+ {
+ location_t *loc;
+ if (flag_next_runtime && TREE_PURPOSE (chain))
+ loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
+ else
+ loc = &input_location;
+ warning ("%Hcreating selector for nonexistent method %qE",
+ loc, TREE_VALUE (chain));
+ }
}
expr = build_selector (TREE_VALUE (chain));
sj = build_function_call (objc_setjmp_decl, t);
cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
- cond = lang_hooks.truthvalue_conversion (cond);
+ cond = c_common_truthvalue_conversion (cond);
return build (COND_EXPR, void_type_node, cond, NULL, NULL);
}
t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
args = tree_cons (NULL, t, args);
t = build_function_call (objc_exception_match_decl, args);
- cond = lang_hooks.truthvalue_conversion (t);
+ cond = c_common_truthvalue_conversion (t);
}
t = build (COND_EXPR, void_type_node, cond, body, NULL);
SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
/* Build the complete FINALLY statement list. */
t = next_sjlj_build_try_exit ();
t = build_stmt (COND_EXPR,
- lang_hooks.truthvalue_conversion (rethrow_decl),
+ c_common_truthvalue_conversion (rethrow_decl),
NULL, t);
SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
t = tree_cons (NULL, rethrow_decl, NULL);
t = build_function_call (objc_exception_throw_decl, t);
t = build_stmt (COND_EXPR,
- lang_hooks.truthvalue_conversion (rethrow_decl),
+ c_common_truthvalue_conversion (rethrow_decl),
t, NULL);
SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
{
tree arg_type = TREE_VALUE (TREE_TYPE (akey));
+ /* Decay arrays and functions into pointers. */
+ if (TREE_CODE (arg_type) == ARRAY_TYPE)
+ arg_type = build_pointer_type (TREE_TYPE (arg_type));
+ else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
+ arg_type = build_pointer_type (arg_type);
+
chainon (arglist, build_tree_list (NULL_TREE, arg_type));
}
static void
objc_push_parm (tree parm)
{
- /* Convert array parameters of unknown size into pointers. */
- if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
- && !TYPE_SIZE (TREE_TYPE (parm)))
+ /* Decay arrays and functions into pointers. */
+ if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
-
+ else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
+ TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
+
+ DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
+ DECL_ARG_TYPE (parm)
+ = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
+
+ /* Record constancy and volatility. */
+ c_apply_type_quals_to_decl
+ ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
+ | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
+ | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
+
objc_parmlist = chainon (objc_parmlist, parm);
}
tree next = TREE_CHAIN (parm_info);
TREE_CHAIN (parm_info) = NULL_TREE;
- pushdecl (parm_info);
+ parm_info = pushdecl (parm_info);
+ finish_decl (parm_info, NULL_TREE, NULL_TREE);
parm_info = next;
}
arg_info = get_parm_info (have_ellipsis);
parmlist = METHOD_SEL_ARGS (method);
while (parmlist)
{
- tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
- TREE_VALUE (TREE_TYPE (parmlist)));
+ tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
+ parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
objc_push_parm (parm);
parmlist = TREE_CHAIN (parmlist);
}
#ifdef OBJCPLUS
DECL_ARGUMENTS (fndecl) = params;
-#endif
DECL_INITIAL (fndecl) = error_mark_node;
DECL_EXTERNAL (fndecl) = 0;
TREE_STATIC (fndecl) = 1;
-
-#ifdef OBJCPLUS
retrofit_lang_decl (fndecl);
cplus_decl_attributes (&fndecl, attrs, 0);
start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
#else
+ struct c_label_context *nstack;
+ nstack = XOBNEW (&parser_obstack, struct c_label_context);
+ nstack->labels_def = NULL;
+ nstack->labels_used = NULL;
+ nstack->next = label_context_stack;
+ label_context_stack = nstack;
decl_attributes (&fndecl, attrs, 0);
announce_function (fndecl);
+ DECL_INITIAL (fndecl) = error_mark_node;
+ DECL_EXTERNAL (fndecl) = 0;
+ TREE_STATIC (fndecl) = 1;
current_function_decl = pushdecl (fndecl);
push_scope ();
declare_parm_level ();
DECL_RESULT (current_function_decl)
= build_decl (RESULT_DECL, NULL_TREE,
TREE_TYPE (TREE_TYPE (current_function_decl)));
+ DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
+ DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
start_fname_decls ();
store_parm_decls_from (params);
#endif
if (TYPE_P (type) && TYPE_NAME (type))
type = TYPE_NAME (type);
- else if (POINTER_TYPE_P (type))
+ else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
{
- gen_type_name_0 (TREE_TYPE (type));
+ tree inner = TREE_TYPE (type);
+
+ while (TREE_CODE (inner) == ARRAY_TYPE)
+ inner = TREE_TYPE (inner);
+
+ gen_type_name_0 (inner);
- if (!POINTER_TYPE_P (TREE_TYPE (type)))
+ if (!POINTER_TYPE_P (inner))
strcat (errbuf, " ");
- strcat (errbuf, "*");
+ if (POINTER_TYPE_P (type))
+ strcat (errbuf, "*");
+ else
+ while (type != inner)
+ {
+ strcat (errbuf, "[");
+
+ if (TYPE_DOMAIN (type))
+ {
+ char sz[20];
+
+ sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
+ (TREE_INT_CST_LOW
+ (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
+ strcat (errbuf, sz);
+ }
+
+ strcat (errbuf, "]");
+ type = TREE_TYPE (type);
+ }
+
goto exit_function;
}