You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
/* Purpose: This module implements the Objective-C 4.0 language.
return OBJC_TYPE_NAME (type) == objc_class_id;
}
-/* Construct a C struct with tag NAME, a base struct with tag
+/* Construct a C struct with same name as CLASS, a base struct with tag
SUPER_NAME (if any), and FIELDS indicated. */
static tree
-objc_build_struct (tree name, tree fields, tree super_name)
+objc_build_struct (tree class, tree fields, tree super_name)
{
+ tree name = CLASS_NAME (class);
tree s = start_struct (RECORD_TYPE, name);
tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
+ tree t, objc_info = NULL_TREE;
if (super)
{
&& TREE_CODE (TREE_CHAIN (field)) == FIELD_DECL)
field = TREE_CHAIN (field);
- /* For ObjC ABI purposes, the "packed" size of a base class is
- the the sum of the offset and the size (in bits) of the last
- field in the class. */
+ /* For ObjC ABI purposes, the "packed" size of a base class is the
+ the sum of the offset and the size (in bits) of the last field
+ in the class. */
DECL_SIZE (base)
= (field && TREE_CODE (field) == FIELD_DECL
- ? size_binop (PLUS_EXPR,
+ ? size_binop (PLUS_EXPR,
size_binop (PLUS_EXPR,
size_binop
(MULT_EXPR,
fields = base;
}
+ /* NB: Calling finish_struct() may cause type TYPE_LANG_SPECIFIC fields
+ in all variants of this RECORD_TYPE to be clobbered, but it is therein
+ that we store protocol conformance info (e.g., 'NSObject <MyProtocol>').
+ Hence, we must squirrel away the ObjC-specific information before calling
+ finish_struct(), and then reinstate it afterwards. */
+
+ for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
+ objc_info
+ = chainon (objc_info,
+ build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
+
+ /* Point the struct at its related Objective-C class. */
+ INIT_TYPE_OBJC_INFO (s);
+ TYPE_OBJC_INTERFACE (s) = class;
+
s = finish_struct (s, fields, NULL_TREE);
+ for (t = TYPE_NEXT_VARIANT (s); t;
+ t = TYPE_NEXT_VARIANT (t), objc_info = TREE_CHAIN (objc_info))
+ {
+ TYPE_OBJC_INFO (t) = TREE_VALUE (objc_info);
+ /* Replace the IDENTIFIER_NODE with an actual @interface. */
+ TYPE_OBJC_INTERFACE (t) = class;
+ }
+
/* Use TYPE_BINFO structures to point at the super class, if any. */
objc_xref_basetypes (s, super);
+ /* Mark this struct as a class template. */
+ CLASS_STATIC_TEMPLATE (class) = s;
+
return s;
}
+/* Build a type differing from TYPE only in that TYPE_VOLATILE is set.
+ Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the
+ process. */
+static tree
+objc_build_volatilized_type (tree type)
+{
+ tree t;
+
+ /* Check if we have not constructed the desired variant already. */
+ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+ {
+ /* The type qualifiers must (obviously) match up. */
+ if (!TYPE_VOLATILE (t)
+ || (TYPE_READONLY (t) != TYPE_READONLY (type))
+ || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type)))
+ continue;
+
+ /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC
+ info, if any) must match up. */
+ if (POINTER_TYPE_P (t)
+ && (TREE_TYPE (t) != TREE_TYPE (type)))
+ continue;
+
+ /* Everything matches up! */
+ return t;
+ }
+
+ /* Ok, we could not re-use any of the pre-existing variants. Create
+ a new one. */
+ t = build_variant_type_copy (type);
+ TYPE_VOLATILE (t) = 1;
+
+ return t;
+}
+
/* Mark DECL as being 'volatile' for purposes of Darwin
_setjmp()/_longjmp() exception handling. Called from
objc_mark_locals_volatile(). */
struct volatilized_type key;
void **loc;
- t = build_qualified_type (t, (TYPE_QUALS (t)
- | TYPE_QUAL_VOLATILE));
+ t = objc_build_volatilized_type (t);
key.type = t;
loc = htab_find_slot (volatilized_htab, &key, INSERT);
else
rcls = rproto = NULL_TREE;
+ /* If we could not find an @interface declaration, we must have
+ only seen a @class declaration; for purposes of type comparison,
+ treat it as a stand-alone (root) class. */
+
+ if (lcls && TREE_CODE (lcls) == IDENTIFIER_NODE)
+ lcls = NULL_TREE;
+
+ if (rcls && TREE_CODE (rcls) == IDENTIFIER_NODE)
+ rcls = NULL_TREE;
+
/* If either type is an unqualified 'id', we're done. */
if ((!lproto && objc_is_object_id (ltyp))
|| (!rproto && objc_is_object_id (rtyp)))
front-end, but 'finish_class_member_access_expr' seems to be
a worthy substitute. */
#ifdef OBJCPLUS
- return finish_class_member_access_expr (datum, component);
+ return finish_class_member_access_expr (datum, component, false);
#else
return build_component_ref (datum, component);
#endif
tree ident = TREE_VALUE (proto);
tree p = lookup_protocol (ident);
- if (!p)
- error ("cannot find protocol declaration for %qs",
- IDENTIFIER_POINTER (ident));
- else
+ if (p)
return_value = chainon (return_value,
build_tree_list (NULL_TREE, p));
+ else if (ident != error_mark_node)
+ error ("cannot find protocol declaration for %qs",
+ IDENTIFIER_POINTER (ident));
}
return return_value;
objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
-
+
objc_object_type = build_pointer_type (objc_object_reference);
objc_class_type = build_pointer_type (objc_class_reference);
(xref_tag (RECORD_TYPE,
get_identifier (UTAG_IVAR_LIST)));
+ /* TREE_NOTHROW is cleared for the message-sending functions,
+ because the function that gets called can throw in Obj-C++, or
+ could itself call something that can throw even in Obj-C. */
+
if (flag_next_runtime)
{
/* NB: In order to call one of the ..._stret (struct-returning)
type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
+ /* These can throw, because the function that gets called can throw
+ in Obj-C++, or could itself call something that can throw even
+ in Obj-C. */
+ TREE_NOTHROW (umsg_decl) = 0;
+ TREE_NOTHROW (umsg_nonnil_decl) = 0;
+ TREE_NOTHROW (umsg_stret_decl) = 0;
+ TREE_NOTHROW (umsg_nonnil_stret_decl) = 0;
+
/* id objc_msgSend_Fast (id, SEL, ...)
__attribute__ ((hard_coded_address (OFFS_MSGSEND_FAST))); */
#ifdef OFFS_MSGSEND_FAST
umsg_fast_decl = builtin_function (TAG_MSGSEND_FAST,
type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
- DECL_ATTRIBUTES (umsg_fast_decl)
- = tree_cons (get_identifier ("hard_coded_address"),
+ TREE_NOTHROW (umsg_fast_decl) = 0;
+ DECL_ATTRIBUTES (umsg_fast_decl)
+ = tree_cons (get_identifier ("hard_coded_address"),
build_int_cst (NULL_TREE, OFFS_MSGSEND_FAST),
NULL_TREE);
#else
umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
type, 0, NOT_BUILT_IN, 0,
NULL_TREE);
+ TREE_NOTHROW (umsg_super_decl) = 0;
+ TREE_NOTHROW (umsg_super_stret_decl) = 0;
}
else
{
/* typedef id (*IMP)(id, SEL, ...); */
tree IMP_type
= build_pointer_type
- (build_function_type (objc_object_type,
- tree_cons (NULL_TREE, objc_object_type,
- tree_cons (NULL_TREE, objc_selector_type,
- NULL_TREE))));
+ (build_function_type (objc_object_type,
+ tree_cons (NULL_TREE, objc_object_type,
+ tree_cons (NULL_TREE, objc_selector_type,
+ NULL_TREE))));
/* IMP objc_msg_lookup (id, SEL); */
type
umsg_decl = builtin_function (TAG_MSGSEND,
type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
+ TREE_NOTHROW (umsg_decl) = 0;
/* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
type
umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
type, 0, NOT_BUILT_IN,
NULL, NULL_TREE);
+ TREE_NOTHROW (umsg_super_decl) = 0;
/* The following GNU runtime entry point is called to initialize
each module:
static int
check_string_class_template (void)
{
- tree field_decl = TYPE_FIELDS (constant_string_type);
+ tree field_decl = objc_get_class_ivars (constant_string_id);
#define AT_LEAST_AS_LARGE_AS(F, T) \
(F && TREE_CODE (F) == FIELD_DECL \
- && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
+ && (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (F))) \
>= TREE_INT_CST_LOW (TYPE_SIZE (T))))
if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
/* Avoid calling `check_string_class_template ()' more than once. */
static GTY(()) int string_layout_checked;
+/* Construct an internal string layout to be used as a template for
+ creating NSConstantString/NXConstantString instances. */
+
+static tree
+objc_build_internal_const_str_type (void)
+{
+ tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
+ tree fields = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
+ tree field = build_decl (FIELD_DECL, NULL_TREE, ptr_type_node);
+
+ TREE_CHAIN (field) = fields; fields = field;
+ field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
+ TREE_CHAIN (field) = fields; fields = field;
+ /* NB: The finish_builtin_struct() routine expects FIELD_DECLs in
+ reverse order! */
+ finish_builtin_struct (type, "__builtin_ObjCString",
+ fields, NULL_TREE);
+
+ return type;
+}
+
/* Custom build_string which sets TREE_TYPE! */
static tree
return fix_string_type (build_string (len, str));
}
+/* Build a string with contents STR and length LEN and convert it to a
+ pointer. */
+
+static tree
+my_build_string_pointer (int len, const char *str)
+{
+ tree string = my_build_string (len, str);
+ tree ptrtype = build_pointer_type (TREE_TYPE (TREE_TYPE (string)));
+ return build1 (ADDR_EXPR, ptrtype, string);
+}
static hashval_t
string_hash (const void *ptr)
{
string_layout_checked = -1;
constant_string_class = lookup_interface (constant_string_id);
+ internal_const_str_type = objc_build_internal_const_str_type ();
if (!constant_string_class
|| !(constant_string_type
*loc = desc = ggc_alloc (sizeof (*desc));
desc->literal = string;
- /* GNU: & ((NXConstantString) { NULL, string, length }) */
- /* NeXT: & ((NSConstantString) { isa, string, length }) */
- fields = TYPE_FIELDS (constant_string_type);
+ /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
+ /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
+ fields = TYPE_FIELDS (internal_const_str_type);
initlist
= build_tree_list (fields,
flag_next_runtime
fields = TREE_CHAIN (fields);
initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
initlist);
- constructor = objc_build_constructor (constant_string_type,
+ constructor = objc_build_constructor (internal_const_str_type,
nreverse (initlist));
TREE_INVARIANT (constructor) = true;
desc->constructor = constructor;
}
- addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
+ addr = convert (build_pointer_type (constant_string_type),
+ build_unary_op (ADDR_EXPR, desc->constructor, 1));
return addr;
}
static tree
objc_build_constructor (tree type, tree elts)
{
- tree constructor = build_constructor (type, elts);
+ tree constructor = build_constructor_from_list (type, elts);
TREE_CONSTANT (constructor) = 1;
TREE_STATIC (constructor) = 1;
size_in_bytes (objc_module_template));
initlist = tree_cons (NULL_TREE, expr, initlist);
- /* name = { ..., "foo.m", ... } */
+ /* Don't provide any file name for security reasons. */
+ /* name = { ..., "", ... } */
- expr = add_objc_string (get_identifier (input_filename), class_names);
+ expr = add_objc_string (get_identifier (""), class_names);
initlist = tree_cons (NULL_TREE, expr, initlist);
/* symtab = { ..., _OBJC_SYMBOLS, ... } */
static void __objc_gnu_init (void) {
__objc_exec_class (&L_OBJC_MODULES);
- } */
+ } */
static void
build_module_initializer_routine (void)
#ifdef OBJCPLUS
push_lang_context (lang_name_c); /* extern "C" */
-#endif
+#endif
objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
objc_start_function (get_identifier (TAG_GNUINIT),
finish_var_decl (static_instances_decl, expr);
}
-/* Output all strings. */
-
-static void
-generate_strings (void)
-{
- tree chain, string_expr;
- tree string, decl, type;
-
- for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
- {
- string = TREE_VALUE (chain);
- decl = TREE_PURPOSE (chain);
- type = build_array_type
- (char_type_node,
- build_index_type
- (build_int_cst (NULL_TREE,
- IDENTIFIER_LENGTH (string))));
- decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
- string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
- IDENTIFIER_POINTER (string));
- finish_var_decl (decl, string_expr);
- }
-
- for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
- {
- string = TREE_VALUE (chain);
- decl = TREE_PURPOSE (chain);
- type = build_array_type
- (char_type_node,
- build_index_type
- (build_int_cst (NULL_TREE,
- IDENTIFIER_LENGTH (string))));
- decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
- string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
- IDENTIFIER_POINTER (string));
- finish_var_decl (decl, string_expr);
- }
-
- for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
- {
- string = TREE_VALUE (chain);
- decl = TREE_PURPOSE (chain);
- type = build_array_type
- (char_type_node,
- build_index_type
- (build_int_cst (NULL_TREE,
- IDENTIFIER_LENGTH (string))));
- decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
- string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
- IDENTIFIER_POINTER (string));
- finish_var_decl (decl, string_expr);
- }
-}
-
static GTY(()) int selector_reference_idx;
static tree
tree_cons (NULL_TREE,
build_int_cst (NULL_TREE, 0),
tree_cons (NULL_TREE,
- build_int_cst (NULL_TREE, 0),
+ build_int_cst (NULL_TREE, 0),
NULL_TREE)))
: build_int_cst (NULL_TREE, 0), initlist);
initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
add_class_reference (ident);
params = build_tree_list (NULL_TREE,
- my_build_string (IDENTIFIER_LENGTH (ident) + 1,
- IDENTIFIER_POINTER (ident)));
+ my_build_string_pointer
+ (IDENTIFIER_LENGTH (ident) + 1,
+ IDENTIFIER_POINTER (ident)));
assemble_external (objc_get_class_decl);
return build_function_call (objc_get_class_decl, params);
static tree
add_objc_string (tree ident, enum string_section section)
{
- tree *chain, decl;
+ tree *chain, decl, type, string_expr;
if (section == class_names)
chain = &class_names_chain;
decl = build_objc_string_decl (section);
+ type = build_array_type
+ (char_type_node,
+ build_index_type
+ (build_int_cst (NULL_TREE,
+ IDENTIFIER_LENGTH (ident))));
+ decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
+ string_expr = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
+ IDENTIFIER_POINTER (ident));
+ finish_var_decl (decl, string_expr);
+
*chain = tree_cons (decl, ident, NULL_TREE);
return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
DECL_ARTIFICIAL (decl) = 1;
#ifdef OBJCPLUS
DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
-#endif
+#endif
make_decl_rtl (decl);
pushdecl_top_level (decl);
{
error ("%qs redeclared as different kind of symbol",
IDENTIFIER_POINTER (ident));
- error ("%Jprevious declaration of '%D'",
- record, record);
+ error ("previous declaration of %q+D",
+ record);
}
}
return (objc_object_type && type
&& (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
? type
- : NULL_TREE);
+ : NULL_TREE);
}
/* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
static int
objc_is_gcable_type (tree type, int or_strong_p)
{
- tree name;
+ tree name;
if (!TYPE_P (type))
return 0;
offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
offs = fold (offs);
- func_params = tree_cons (NULL_TREE,
+ func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (objc_object_type, outervar),
tree_cons (NULL_TREE, offs,
tree func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
- build_unary_op (ADDR_EXPR, lhs, 0)),
+ build_unary_op (ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_strong_cast_decl);
}
outer_gc_p = objc_is_gcable_p (outer);
-
+
/* Handle ivar assignments. */
if (objc_is_ivar_reference_p (lhs))
{
}
/* Likewise, intercept assignment to global/static variables if their type is
- GC-marked. */
+ GC-marked. */
if (objc_is_global_reference_p (outer))
{
if (indirect_p)
objc_create_temporary_var (tree type)
{
tree decl;
-
+
decl = build_decl (VAR_DECL, NULL_TREE, type);
TREE_USED (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
= init_one_libfunc (USING_SJLJ_EXCEPTIONS
? "__gnu_objc_personality_sj0"
: "__gnu_objc_personality_v0");
+ default_init_unwind_resume_libfunc ();
using_eh_for_cleanups ();
lang_eh_runtime_type = objc_eh_runtime_type;
}
return var;
}
else
- return build (EXC_PTR_EXPR, objc_object_type);
+ return build0 (EXC_PTR_EXPR, objc_object_type);
}
/* Build "objc_exception_try_exit(&_stack)". */
t = tree_cons (NULL, t, NULL);
sj = build_function_call (objc_setjmp_decl, t);
- cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
+ cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
cond = c_common_truthvalue_conversion (cond);
- return build (COND_EXPR, void_type_node, cond, NULL, NULL);
+ return build3 (COND_EXPR, void_type_node, cond, NULL, NULL);
}
-/* Build
- DECL = objc_exception_extract(&_stack);
-*/
-
+/* Build:
+
+ DECL = objc_exception_extract(&_stack); */
+
static tree
next_sjlj_build_exc_extract (tree decl)
{
t = tree_cons (NULL, t, NULL);
t = build_function_call (objc_exception_extract_decl, t);
t = convert (TREE_TYPE (decl), t);
- t = build (MODIFY_EXPR, void_type_node, decl, t);
+ t = build2 (MODIFY_EXPR, void_type_node, decl, t);
return t;
}
t = build_function_call (objc_exception_match_decl, args);
cond = c_common_truthvalue_conversion (t);
}
- t = build (COND_EXPR, void_type_node, cond, body, NULL);
+ t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
*last = t;
if (!saw_id)
{
- t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
- cur_try_context->caught_decl);
+ t = build2 (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
+ cur_try_context->caught_decl);
SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
append_to_statement_list (t, last);
TREE_CHAIN (rethrow_decl) = stack_decl;
/* Build the outermost variable binding level. */
- bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
+ bind = build3 (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
TREE_SIDE_EFFECTS (bind) = 1;
/* Initialize rethrow_decl. */
- t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
- convert (objc_object_type, null_pointer_node));
+ t = build2 (MODIFY_EXPR, void_type_node, rethrow_decl,
+ convert (objc_object_type, null_pointer_node));
SET_EXPR_LOCATION (t, cur_try_context->try_locus);
append_to_statement_list (t, &BIND_EXPR_BODY (bind));
/* Build the outermost TRY_FINALLY_EXPR. */
- try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
+ try_fin = build2 (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
TREE_SIDE_EFFECTS (try_fin) = 1;
append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
{
tree caught_decl = objc_build_exc_ptr ();
catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
+ TREE_SIDE_EFFECTS (catch_seq) = 1;
t = next_sjlj_build_exc_extract (caught_decl);
append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
objc_mark_locals_volatile (NULL);
}
-/* Called just after parsing "@catch (parm)". Open a binding level,
+/* Called just after parsing "@catch (parm)". Open a binding level,
enter DECL into the binding level, and initialize it. Leave the
binding level open while the body of the compound statement is parsed. */
-
+
void
objc_begin_catch_clause (tree decl)
{
/* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
t = objc_build_exc_ptr ();
t = convert (TREE_TYPE (decl), t);
- t = build (MODIFY_EXPR, void_type_node, decl, t);
+ t = build2 (MODIFY_EXPR, void_type_node, decl, t);
add_stmt (t);
}
struct _objc_exception_data
{
- int buf[_JBLEN];
+ int buf[OBJC_JBLEN];
void *pointers[4];
}; */
/* The following yuckiness should prevent users from having to #include
<setjmp.h> in their code... */
-#ifdef TARGET_POWERPC
-/* snarfed from /usr/include/ppc/setjmp.h */
-#define _JBLEN (26 + 36 + 129 + 1)
-#else
-/* snarfed from /usr/include/i386/{setjmp,signal}.h */
-#define _JBLEN 18
+/* Define to a harmless positive value so the below code doesn't die. */
+#ifndef OBJC_JBLEN
+#define OBJC_JBLEN 18
#endif
static void
objc_exception_data_template
= start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
- /* int buf[_JBLEN]; */
+ /* int buf[OBJC_JBLEN]; */
- index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
+ index = build_index_type (build_int_cst (NULL_TREE, OBJC_JBLEN - 1));
field_decl = create_field_decl (build_array_type (integer_type_node, index),
"buf");
field_decl_chain = field_decl;
= builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
/* int objc_exception_match(id, id); */
- temp_type
+ temp_type
= build_function_type (integer_type_node,
tree_cons (NULL_TREE, objc_object_type,
tree_cons (NULL_TREE, objc_object_type,
objc_assign_ivar_fast_decl
= builtin_function (TAG_ASSIGNIVAR_FAST, temp_type, 0,
NOT_BUILT_IN, NULL, NULL_TREE);
- DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
- = tree_cons (get_identifier ("hard_coded_address"),
+ DECL_ATTRIBUTES (objc_assign_ivar_fast_decl)
+ = tree_cons (get_identifier ("hard_coded_address"),
build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
NULL_TREE);
#else
{
if (!CLASS_STATIC_TEMPLATE (class))
{
- tree record = objc_build_struct (CLASS_NAME (class),
+ tree record = objc_build_struct (class,
get_class_ivars (class, false),
CLASS_SUPER_NAME (class));
- /* mark this record as class template - for class type checking */
- INIT_TYPE_OBJC_INFO (record);
- TYPE_OBJC_INTERFACE (record) = class;
- CLASS_STATIC_TEMPLATE (class) = record;
-
/* Set the TREE_USED bit for this struct, so that stab generator
can emit stabs for this struct type. */
if (flag_debug_only_used_symbols && TYPE_STUB_DECL (record))
/* If a type size is not known, bail out. */
if (sz < 0)
{
- error ("%Jtype '%D' does not have a known size",
- type, type);
+ error ("type %q+D does not have a known size",
+ type);
/* Pretend that the encoding succeeded; the compilation will
fail nevertheless. */
goto finish_encoding;
}
/* Count only the fields occurring in T. */
+
static int
ivar_list_length (tree t)
{
elemlist
= tree_cons (NULL_TREE,
- convert (ptr_type_node,
+ convert (ptr_type_node,
build_unary_op (ADDR_EXPR,
METHOD_DEFINITION (entries), 1)),
elemlist);
else
{
expr = convert (build_pointer_type
- (build_pointer_type
+ (build_pointer_type
(objc_protocol_template)),
build_unary_op (ADDR_EXPR, protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
else
{
expr = convert (build_pointer_type
- (build_pointer_type
+ (build_pointer_type
(objc_protocol_template)),
build_unary_op (ADDR_EXPR, protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
warn_with_method (methods ? "using" : "found",
((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
? '-'
- : '+'),
+ : '+'),
meth);
for (loop = hsh->list; loop; loop = loop->next)
warn_with_method ("also found",
((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
- ? '-'
+ ? '-'
: '+'),
loop->value);
}
if (!is_class)
method_prototype = hash_lookup (nst_method_hash_list,
sel_name);
-
+
if (!method_prototype)
{
method_prototype = hash_lookup (cls_method_hash_list,
exist locally as part of the @implementation. */
if (!method_prototype && objc_implementation_context
&& CLASS_NAME (objc_implementation_context)
- == OBJC_TYPE_NAME (rtype))
+ == OBJC_TYPE_NAME (rtype))
method_prototype
= lookup_method
((class_tree
lookup as if we were messaging 'id'. */
rtype = rprotos = NULL_TREE;
}
- }
+ }
/* For 'id' or 'Class' receivers, search in the global hash table
tree method, t;
lookup_object = build_c_cast (rcv_p, lookup_object);
-
+
/* Use SAVE_EXPR to avoid evaluating the receiver twice. */
lookup_object = save_expr (lookup_object);
/* First, call the lookup function to get a pointer to the method,
then cast the pointer, then call it with the method arguments. */
-
+
object = (super_flag ? self_decl : lookup_object);
t = tree_cons (NULL_TREE, selector, NULL_TREE);
/* ??? Selector is not at this point something we can use inside
the compiler itself. Set it to garbage for the nonce. */
- t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
+ t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
return build_function_call (t, method_params);
}
\f
/* Look up a class (if OBJC_LOOKUP_CLASS is set in FLAGS) or instance method
in INTERFACE, along with any categories and protocols attached thereto.
If method is not found, and the OBJC_LOOKUP_NO_SUPER is _not_ set in FLAGS,
- recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
+ recursively examine the INTERFACE's superclass. If OBJC_LOOKUP_CLASS is
set, OBJC_LOOKUP_NO_SUPER is cleared, and no suitable class method could
be found in INTERFACE or any of its superclasses, look for an _instance_
method of the same name in the root class as a last resort.
If a suitable method cannot be found, return NULL_TREE. */
-
+
static tree
lookup_method_static (tree interface, tree ident, int flags)
{
/* Add the method to the hash list if it doesn't contain an identical
method already. */
+
static void
add_method_to_hash_list (hash *hash_list, tree method)
{
|| TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
&& !comp_proto_with_proto (method, mth, 1))
error ("duplicate declaration of method %<%c%s%>",
- is_class ? '+' : '-',
+ is_class ? '+' : '-',
IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
}
if (TYPE_NEEDS_CONSTRUCTING (field_type)
&& !TYPE_HAS_DEFAULT_CONSTRUCTOR (field_type))
{
- warning (0, "type `%s' has no default constructor to call",
+ warning (0, "type %qs has no default constructor to call",
type_name);
/* If we cannot call a constructor, we should also avoid
calling the destructor, for symmetry. */
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
- warning (0, "destructor for `%s' shall not be run either",
+ warning (0, "destructor for %qs shall not be run either",
type_name);
}
}
{
/* Vtable pointers are Real Bad(tm), since Obj-C cannot
initialize them. */
- error ("type `%s' has virtual member functions", type_name);
- error ("illegal aggregate type `%s' specified "
- "for instance variable `%s'",
+ error ("type %qs has virtual member functions", type_name);
+ error ("illegal aggregate type %qs specified "
+ "for instance variable %qs",
type_name, ivar_name);
/* Return class as is without adding this ivar. */
return class;
/* User-defined constructors and destructors are not known to Obj-C
and hence will not be called. This may or may not be a problem. */
if (TYPE_NEEDS_CONSTRUCTING (field_type))
- warning (0, "type `%s' has a user-defined constructor", type_name);
+ warning (0, "type %qs has a user-defined constructor", type_name);
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
- warning (0, "type `%s' has a user-defined destructor", type_name);
+ warning (0, "type %qs has a user-defined destructor", type_name);
if (!warn_cxx_ivars)
{
return 1;
#endif
+ if (TREE_TYPE (expr) == error_mark_node)
+ return 1;
+
basetype = TYPE_MAIN_VARIANT (TREE_TYPE (expr));
if (basetype && TREE_CODE (basetype) == RECORD_TYPE)
TREE_PRIVATE (decl) ? "@private" : "@protected");
return 1;
}
-
+
error ("instance variable %qs is declared %s",
IDENTIFIER_POINTER (identifier),
TREE_PRIVATE (decl) ? "private" : "protected");
{
error ("%qs redeclared as different kind of symbol",
IDENTIFIER_POINTER (class_name));
- error ("%Jprevious declaration of '%D'",
- decl, decl);
+ error ("previous declaration of %q+D",
+ decl);
}
if (code == CLASS_IMPLEMENTATION_TYPE)
error ("duplicate interface declaration for class %qs",
#else
warning (0, "duplicate interface declaration for class %qs",
-#endif
+#endif
IDENTIFIER_POINTER (class_name));
else
add_class (class, class_name);
return;
}
- sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
- (TREE_INT_CST_LOW (an_int_cst)
- / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
+ if (TREE_INT_CST_LOW (TYPE_SIZE (array_of)) == 0)
+ sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)0);
+ else
+ sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
+ TREE_INT_CST_LOW (an_int_cst)
+ / TREE_INT_CST_LOW (TYPE_SIZE (array_of)));
obstack_grow (&util_obstack, buffer, strlen (buffer));
encode_type (array_of, curtype, format);
#endif
/* Recursively encode fields of embedded base classes. */
- if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
+ if (DECL_ARTIFICIAL (field) && !DECL_NAME (field)
&& TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
{
encode_aggregate_fields (TREE_TYPE (field),
original struct and its tag name (if any). */
type = TYPE_MAIN_VARIANT (type);
name = OBJC_TYPE_NAME (type);
- /* Open parenth/bracket. */
+ /* Open parenth/bracket. */
obstack_1grow (&util_obstack, left);
/* Encode the struct/union tag name, or '?' if a tag was
obstack_1grow (&util_obstack, '=');
encode_aggregate_fields (type, pointed_to, curtype, format);
}
- /* Close parenth/bracket. */
+ /* Close parenth/bracket. */
obstack_1grow (&util_obstack, right);
}
{
case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
- case 32:
+ case 32:
if (type == long_unsigned_type_node
|| type == long_integer_type_node)
c = TYPE_UNSIGNED (type) ? 'L' : 'l';
else if (code == FUNCTION_TYPE) /* '?' */
obstack_1grow (&util_obstack, '?');
+
+ else if (code == COMPLEX_TYPE)
+ {
+ obstack_1grow (&util_obstack, 'j');
+ encode_type (TREE_TYPE (type), curtype, format);
+ }
}
static void
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));
((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;
+ TREE_CHAIN (parm_info) = NULL_TREE;
parm_info = pushdecl (parm_info);
finish_decl (parm_info, NULL_TREE, NULL_TREE);
parm_info = next;
{
tree akey;
- for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
+ for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
akey; akey = TREE_CHAIN (akey))
{
objc_push_parm (TREE_VALUE (akey));
(super_class,
build_tree_list
(NULL_TREE,
- my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
- IDENTIFIER_POINTER (super_name))));
+ my_build_string_pointer
+ (IDENTIFIER_LENGTH (super_name) + 1,
+ IDENTIFIER_POINTER (super_name))));
}
super_expr
sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
TREE_INT_CST_LOW (DECL_INITIAL (decl)));
}
-
+
return errbuf;
}
inner = TREE_TYPE (inner);
gen_type_name_0 (inner);
-
+
if (!POINTER_TYPE_P (inner))
strcat (errbuf, " ");
char sz[20];
sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
- (TREE_INT_CST_LOW
+ (TREE_INT_CST_LOW
(TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
strcat (errbuf, sz);
}
if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
type = DECL_NAME (type);
- strcat (errbuf, IDENTIFIER_POINTER (type));
+ strcat (errbuf, TREE_CODE (type) == IDENTIFIER_NODE
+ ? IDENTIFIER_POINTER (type)
+ : "");
/* For 'id' and 'Class', adopted protocols are stored in the pointee. */
if (objc_is_id (orig))
orig = TREE_TYPE (orig);
-
+
proto = TYPE_HAS_OBJC_INFO (orig) ? TYPE_OBJC_PROTOCOL_LIST (orig) : NULL_TREE;
if (proto)
strcat (errbuf, " <");
while (proto) {
- strcat (errbuf,
+ strcat (errbuf,
IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
proto = TREE_CHAIN (proto);
strcat (errbuf, proto ? ", " : ">");
(mangled[1] == 'i' || mangled[1] == 'c') &&
mangled[2] == '_')
{
- cp = demangled = xmalloc(strlen(mangled) + 2);
+ cp = demangled = XNEWVEC (char, strlen(mangled) + 2);
if (mangled[1] == 'i')
*cp++ = '-'; /* for instance method */
else
gcc_obstack_init (&util_obstack);
util_firstobj = (char *) obstack_finish (&util_obstack);
- errbuf = (char *) xmalloc (1024 * 10);
+ errbuf = XNEWVEC (char, 1024 * 10);
hash_init ();
synth_module_prologue ();
}
for (impent = imp_list; impent; impent = impent->next)
handle_impent (impent);
- /* Dump the string table last. */
-
- generate_strings ();
-
if (warn_selector)
{
int slot;
DECL_INITIAL (decl) = exp;
TREE_STATIC (decl) = 1;
TREE_USED (decl) = 1;
+ /* Force the output of the decl as this forces the reference of the class. */
+ mark_decl_referenced (decl);
pushdecl (decl);
rest_of_decl_compilation (decl, 0, 0);
&& TREE_CODE (TREE_OPERAND (TREE_OPERAND (function, 0), 0))
== FUNCTION_DECL)
{
- function = build (OBJ_TYPE_REF, TREE_TYPE (function),
- TREE_OPERAND (function, 0),
- TREE_VALUE (params), size_zero_node);
+ function = build3 (OBJ_TYPE_REF, TREE_TYPE (function),
+ TREE_OPERAND (function, 0),
+ TREE_VALUE (params), size_zero_node);
}
return function;