/* Implement classes and message passing for Objective C.
- Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Steve Naroff.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
GNU General Public License for more details.
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. */
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
/* Purpose: This module implements the Objective-C 4.0 language.
#include "debug.h"
#include "target.h"
#include "diagnostic.h"
+#include "intl.h"
#include "cgraph.h"
#include "tree-iterator.h"
#include "libfuncs.h"
static unsigned int should_call_super_dealloc = 0;
+/* When building Objective-C++, we need in_late_binary_op. */
+#ifdef OBJCPLUS
+bool in_late_binary_op = false;
+#endif /* OBJCPLUS */
+
/* When building Objective-C++, we are not linking against the C front-end
and so need to replicate the C tree-construction functions in some way. */
#ifdef OBJCPLUS
/* Utilities for debugging and error diagnostics. */
-static void warn_with_method (const char *, int, tree);
static char *gen_type_name (tree);
static char *gen_type_name_0 (tree);
static char *gen_method_decl (tree);
/* Store all constructed constant strings in a hash table so that
they get uniqued properly. */
-struct string_descriptor GTY(())
-{
+struct GTY(()) string_descriptor {
/* The literal argument . */
tree literal;
static GTY((param_is (struct string_descriptor))) htab_t string_htab;
/* Store the EH-volatilized types in a hash table, for easy retrieval. */
-struct volatilized_type GTY(())
-{
+struct GTY(()) volatilized_type {
tree type;
};
static int generating_instance_variables = 0;
+/* For building an objc struct. These may not be used when this file
+ is compiled as part of obj-c++. */
+
+static bool objc_building_struct;
+static bool objc_in_struct ATTRIBUTE_UNUSED;
+static VEC(tree,heap) *objc_struct_types ATTRIBUTE_UNUSED;
+
+/* Start building a struct for objc. */
+
+static tree
+objc_start_struct (tree name)
+{
+ gcc_assert (!objc_building_struct);
+ objc_building_struct = true;
+ return start_struct (RECORD_TYPE, name, &objc_in_struct, &objc_struct_types,
+ UNKNOWN_LOCATION);
+}
+
+/* Finish building a struct for objc. */
+
+static tree
+objc_finish_struct (tree type, tree fieldlist)
+{
+ gcc_assert (objc_building_struct);
+ objc_building_struct = false;
+ return finish_struct (type, fieldlist, NULL_TREE, objc_in_struct,
+ objc_struct_types);
+}
+
/* Some platforms pass small structures through registers versus
through an invisible pointer. Determine at what size structure is
the transition point between the two possibilities. */
char buffer[5];
/* Create an unnamed struct that has `i' character components */
- type = start_struct (RECORD_TYPE, NULL_TREE);
+ type = objc_start_struct (NULL_TREE);
strcpy (buffer, "c1");
field_decl = create_field_decl (char_type_node,
buffer);
chainon (field_decl_chain, field_decl);
}
- finish_struct (type, field_decl_chain, NULL_TREE);
+ objc_finish_struct (type, field_decl_chain);
aggregate_in_mem[i] = aggregate_value_p (type, 0);
if (!aggregate_in_mem[i])
#endif
return false;
-#ifndef USE_MAPPED_LOCATION
- /* Force the line number back to 0; check_newline will have
- raised it to 1, which will make the builtin functions appear
- not to be built in. */
- input_line = 0;
-#endif
-
/* If gen_declaration desired, open the output file. */
if (flag_gen_declaration)
{
if (gen_declaration_file)
fclose (gen_declaration_file);
-
-#ifdef OBJCPLUS
- cp_finish_file ();
-#endif
}
\f
/* Return the first occurrence of a method declaration corresponding
}
void
-objc_start_class_interface (tree class, tree super_class, tree protos)
+objc_start_class_interface (tree klass, tree super_class, tree protos)
{
objc_interface_context
= objc_ivar_context
- = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
+ = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
objc_public_flag = 0;
}
void
-objc_start_category_interface (tree class, tree categ, tree protos)
+objc_start_category_interface (tree klass, tree categ, tree protos)
{
objc_interface_context
- = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
+ = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
objc_ivar_chain
= continue_class (objc_interface_context);
}
}
void
-objc_start_class_implementation (tree class, tree super_class)
+objc_start_class_implementation (tree klass, tree super_class)
{
objc_implementation_context
= objc_ivar_context
- = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
+ = start_class (CLASS_IMPLEMENTATION_TYPE, klass, super_class, NULL_TREE);
objc_public_flag = 0;
}
void
-objc_start_category_implementation (tree class, tree categ)
+objc_start_category_implementation (tree klass, tree categ)
{
objc_implementation_context
- = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
+ = start_class (CATEGORY_IMPLEMENTATION_TYPE, klass, categ, NULL_TREE);
objc_ivar_chain
= continue_class (objc_implementation_context);
}
unsigned char code = C_RID_CODE (ident);
return (OBJC_IS_AT_KEYWORD (code)
-#ifdef OBJCPLUS
|| code == RID_CLASS || code == RID_PUBLIC
|| code == RID_PROTECTED || code == RID_PRIVATE
- || code == RID_TRY || code == RID_THROW || code == RID_CATCH
-#endif
- );
+ || code == RID_TRY || code == RID_THROW || code == RID_CATCH);
}
/* Return true if TYPE is 'id'. */
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 KLASS, 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 klass, tree fields, tree super_name)
{
- tree s = start_struct (RECORD_TYPE, name);
+ tree name = CLASS_NAME (klass);
+ tree s = objc_start_struct (name);
tree super = (super_name ? xref_tag (RECORD_TYPE, super_name) : NULL_TREE);
+ tree t, objc_info = NULL_TREE;
if (super)
{
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. */
+ 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;
}
- s = finish_struct (s, fields, NULL_TREE);
+ /* 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) = klass;
+
+ s = objc_finish_struct (s, fields);
+
+ 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) = klass;
+ }
/* 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 (klass) = 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;
+
+ /* Set up the canonical type information. */
+ if (TYPE_STRUCTURAL_EQUALITY_P (type))
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
+ else if (TYPE_CANONICAL (type) != type)
+ TYPE_CANONICAL (t) = objc_build_volatilized_type (TYPE_CANONICAL (type));
+ else
+ TYPE_CANONICAL (t) = t;
+
+ 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);
}
/* Check if protocol PROTO is adopted (directly or indirectly) by class CLS
- (including its categoreis and superclasses) or by object type TYP.
+ (including its categories and superclasses) or by object type TYP.
Issue a warning if PROTO is not adopted anywhere and WARN is set. */
static bool
if (warn)
{
- strcpy (errbuf, class_type ? "class \'" : "type \'");
+ *errbuf = 0;
gen_type_name_0 (class_type ? typ : TYPE_POINTER_TO (typ));
- strcat (errbuf, "\' does not ");
/* NB: Types 'id' and 'Class' cannot reasonably be described as
"implementing" a given protocol, since they do not have an
implementation. */
- strcat (errbuf, class_type ? "implement" : "conform to");
- strcat (errbuf, " the \'");
- strcat (errbuf, IDENTIFIER_POINTER (PROTOCOL_NAME (proto)));
- strcat (errbuf, "\' protocol");
- warning (0, errbuf);
+ if (class_type)
+ warning (0, "class %qs does not implement the %qE protocol",
+ identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
+ else
+ warning (0, "type %qs does not conform to the %qE protocol",
+ identifier_to_locale (errbuf), PROTOCOL_NAME (proto));
}
return false;
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,
+ tf_warning_or_error);
#else
return build_component_ref (datum, component);
#endif
static hashval_t
volatilized_hash (const void *ptr)
{
- tree typ = ((struct volatilized_type *)ptr)->type;
+ const_tree const typ = ((const struct volatilized_type *)ptr)->type;
- return (hashval_t) typ;
+ return htab_hash_pointer(typ);
}
static int
volatilized_eq (const void *ptr1, const void *ptr2)
{
- tree typ1 = ((struct volatilized_type *)ptr1)->type;
- tree typ2 = ((struct volatilized_type *)ptr2)->type;
+ const_tree const typ1 = ((const struct volatilized_type *)ptr1)->type;
+ const_tree const typ2 = ((const struct volatilized_type *)ptr2)->type;
return typ1 == typ2;
}
if (TREE_CODE (type) != RECORD_TYPE)
return;
if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
- error ("statically allocated instance of Objective-C class %qs",
- IDENTIFIER_POINTER (type));
+ error ("statically allocated instance of Objective-C class %qE",
+ type);
}
/* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
to the pointee. */
if (is_ptr)
{
- TREE_TYPE (type) = build_variant_type_copy (TREE_TYPE (type));
+ tree orig_pointee_type = TREE_TYPE (type);
+ TREE_TYPE (type) = build_variant_type_copy (orig_pointee_type);
+
+ /* Set up the canonical type information. */
+ TYPE_CANONICAL (type)
+ = TYPE_CANONICAL (TYPE_POINTER_TO (orig_pointee_type));
+
TYPE_POINTER_TO (TREE_TYPE (type)) = type;
type = TREE_TYPE (type);
}
pp = lookup_protocol (pp);
if (pp == proto)
- fatal_error ("protocol %qs has circular dependency",
- IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
+ fatal_error ("protocol %qE has circular dependency",
+ PROTOCOL_NAME (pp));
if (pp)
check_protocol_recursively (proto, PROTOCOL_LIST (pp));
}
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 %qE",
+ ident);
}
return return_value;
static void
finish_var_decl (tree var, tree initializer)
{
- finish_decl (var, initializer, NULL_TREE);
+ finish_decl (var, initializer, NULL_TREE, NULL_TREE);
/* Ensure that the variable actually gets output. */
mark_decl_referenced (var);
/* Mark the decl to avoid "defined but not used" warning. */
/* %s in format will provide room for terminating null */
length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
+ strlen (constant_string_class_name);
- name = xmalloc (length);
+ name = XNEWVEC (char, length);
sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
constant_string_class_name);
constant_string_global_id = get_identifier (name);
const struct gcc_debug_hooks *const save_hooks = debug_hooks;
/* Suppress outputting debug symbols, because
- dbxout_init hasn'r been called yet. */
+ dbxout_init hasn't been called yet. */
write_symbols = NO_DEBUG;
debug_hooks = &do_nothing_debug_hooks;
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);
type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
objc_object_name,
objc_object_type));
- DECL_IN_SYSTEM_HEADER (type) = 1;
+ TREE_NO_WARNING (type) = 1;
type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
objc_class_name,
objc_class_type));
- DECL_IN_SYSTEM_HEADER (type) = 1;
+ TREE_NO_WARNING (type) = 1;
/* Forward-declare '@interface Protocol'. */
(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)
tree_cons (NULL_TREE, objc_object_type,
tree_cons (NULL_TREE, objc_selector_type,
NULL_TREE)));
- umsg_decl = builtin_function (TAG_MSGSEND,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
- umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
- umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
- umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ umsg_decl = add_builtin_function (TAG_MSGSEND,
+ type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ umsg_nonnil_decl = add_builtin_function (TAG_MSGSEND_NONNIL,
+ type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ umsg_stret_decl = add_builtin_function (TAG_MSGSEND_STRET,
+ type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ umsg_nonnil_stret_decl = add_builtin_function (TAG_MSGSEND_NONNIL_STRET,
+ 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"),
+ umsg_fast_decl = add_builtin_function (TAG_MSGSEND_FAST,
+ type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ 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
- /* No direct dispatch availible. */
+ /* No direct dispatch available. */
umsg_fast_decl = umsg_decl;
#endif
tree_cons (NULL_TREE, objc_super_type,
tree_cons (NULL_TREE, objc_selector_type,
NULL_TREE)));
- umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
- umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
- type, 0, NOT_BUILT_IN, 0,
- NULL_TREE);
+ umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
+ type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
+ umsg_super_stret_decl = add_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
tree_cons (NULL_TREE, objc_object_type,
tree_cons (NULL_TREE, objc_selector_type,
OBJC_VOID_AT_END)));
- umsg_decl = builtin_function (TAG_MSGSEND,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ umsg_decl = add_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
tree_cons (NULL_TREE, objc_super_type,
tree_cons (NULL_TREE, objc_selector_type,
OBJC_VOID_AT_END)));
- umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ umsg_super_decl = add_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:
= build_function_type (void_type_node,
tree_cons (NULL_TREE, ptr_type_node,
OBJC_VOID_AT_END));
- execclass_decl = builtin_function (TAG_EXECCLASS,
- type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ execclass_decl = add_builtin_function (TAG_EXECCLASS,
+ type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
}
/* id objc_getClass (const char *); */
OBJC_VOID_AT_END));
objc_get_class_decl
- = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
/* id objc_getMetaClass (const char *); */
objc_get_meta_class_decl
- = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
build_class_template ();
build_super_template ();
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)
{
- tree str = ((struct string_descriptor *)ptr)->literal;
+ const_tree const str = ((const struct string_descriptor *)ptr)->literal;
const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
int i, len = TREE_STRING_LENGTH (str);
hashval_t h = len;
static int
string_eq (const void *ptr1, const void *ptr2)
{
- tree str1 = ((struct string_descriptor *)ptr1)->literal;
- tree str2 = ((struct string_descriptor *)ptr2)->literal;
+ const_tree const str1 = ((const struct string_descriptor *)ptr1)->literal;
+ const_tree const str2 = ((const struct string_descriptor *)ptr2)->literal;
int len1 = TREE_STRING_LENGTH (str1);
return (len1 == TREE_STRING_LENGTH (str2)
{
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
= CLASS_STATIC_TEMPLATE (constant_string_class)))
- error ("cannot find interface declaration for %qs",
- IDENTIFIER_POINTER (constant_string_id));
+ error ("cannot find interface declaration for %qE",
+ constant_string_id);
/* The NSConstantString/NXConstantString ivar layout is now known. */
else if (!check_string_class_template ())
- error ("interface %qs does not have valid constant string layout",
- IDENTIFIER_POINTER (constant_string_id));
+ error ("interface %qE does not have valid constant string layout",
+ constant_string_id);
/* For the NeXT runtime, we can generate a literal reference
to the string class, don't need to run a constructor. */
else if (flag_next_runtime && !setup_string_decl ())
- error ("cannot find reference tag for class %qs",
- IDENTIFIER_POINTER (constant_string_id));
+ error ("cannot find reference tag for class %qE",
+ constant_string_id);
else
{
string_layout_checked = 1; /* Success! */
/* Perhaps we already constructed a constant string just like this one? */
key.literal = string;
loc = htab_find_slot (string_htab, &key, INSERT);
- desc = *loc;
+ desc = (struct string_descriptor *) *loc;
if (!desc)
{
tree var;
- *loc = desc = ggc_alloc (sizeof (*desc));
+ *loc = desc = GGC_NEW (struct string_descriptor);
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
- ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
+ ? build_unary_op (input_location,
+ ADDR_EXPR, string_class_decl, 0)
: build_int_cst (NULL_TREE, 0));
fields = TREE_CHAIN (fields);
- initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
+ initlist = tree_cons (fields, build_unary_op (input_location,
+ ADDR_EXPR, string, 1),
initlist);
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;
if (!flag_next_runtime)
constructor
desc->constructor = constructor;
}
- addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
+ addr = convert (build_pointer_type (constant_string_type),
+ build_unary_op (input_location,
+ ADDR_EXPR, desc->constructor, 1));
return addr;
}
DECL_COMMON (decl) = 1;
TREE_STATIC (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
+ TREE_USED (decl) = 1;
DECL_INITIAL (decl) = constructor;
/* We may be writing something else just now.
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;
/* Adjust for impedance mismatch. We should figure out how to build
CONSTRUCTORs that consistently please both the C and C++ gods. */
if (!TREE_PURPOSE (elts))
- TREE_TYPE (constructor) = NULL_TREE;
- TREE_HAS_CONSTRUCTOR (constructor) = 1;
+ TREE_TYPE (constructor) = init_list_type_node;
#endif
return constructor;
{
tree field_decl, field_decl_chain;
- objc_symtab_template
- = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
+ objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
/* long sel_ref_cnt; */
field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
chainon (field_decl_chain, field_decl);
}
- finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_symtab_template, field_decl_chain);
}
/* Create the initial value for the `defs' field of _objc_symtab.
{
if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
{
- expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, impent->class_decl, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
}
{
if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
{
- expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, impent->class_decl, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
}
tree expr;
if (static_instances_decl)
- expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, static_instances_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
initlist
= tree_cons (NULL_TREE,
convert (build_pointer_type (objc_selector_type),
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
UOBJC_SELECTOR_TABLE_decl, 1)),
initlist);
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, ... } */
if (UOBJC_SYMBOLS_decl)
- expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
push_lang_context (lang_name_c); /* extern "C" */
#endif
- objc_module_template
- = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
+ objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
/* long version; */
field_decl = create_field_decl (long_integer_type_node, "version");
"symtab");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_module_template, field_decl_chain);
/* Create an instance of "_objc_module". */
UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
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),
(execclass_decl,
build_tree_list
(NULL_TREE,
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
UOBJC_MODULES_decl, 0))));
add_stmt (c_end_compound_stmt (body, true));
generate_static_references (void)
{
tree decls = NULL_TREE, expr = NULL_TREE;
- tree class_name, class, decl, initlist;
+ tree class_name, klass, decl, initlist;
tree cl_chain, in_chain, type
= build_array_type (build_pointer_type (void_type_node), NULL_TREE);
int num_inst, num_class;
decl = start_var_decl (type, buf);
/* Output {class_name, ...}. */
- class = TREE_VALUE (cl_chain);
- class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
+ klass = TREE_VALUE (cl_chain);
+ class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
initlist = build_tree_list (NULL_TREE,
- build_unary_op (ADDR_EXPR, class_name, 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, class_name, 1));
/* Output {..., instance, ...}. */
for (in_chain = TREE_PURPOSE (cl_chain);
in_chain; in_chain = TREE_CHAIN (in_chain))
{
- expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, TREE_VALUE (in_chain), 1);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
finish_var_decl (decl, expr);
decls
- = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
+ = tree_cons (NULL_TREE, build_unary_op (input_location,
+ ADDR_EXPR, decl, 1), decls);
}
decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
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),
*chain = tree_cons (prototype, ident, NULL_TREE);
return_at_index:
- expr = build_unary_op (ADDR_EXPR,
+ expr = build_unary_op (input_location, ADDR_EXPR,
build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index)),
+ build_int_cst (NULL_TREE, index),
+ input_location),
1);
return convert (objc_selector_type, expr);
}
return (flag_next_runtime
? TREE_PURPOSE (*chain)
: build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index)));
+ build_int_cst (NULL_TREE, index),
+ input_location));
index++;
chain = &TREE_CHAIN (*chain);
return (flag_next_runtime
? expr
: build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index)));
+ build_int_cst (NULL_TREE, index),
+ input_location));
}
static GTY(()) int class_reference_idx;
if (local_scope || !(ident = objc_is_class_name (ident)))
{
- error ("%qs is not an Objective-C class name or alias",
- IDENTIFIER_POINTER (orig_ident));
+ error ("%qE is not an Objective-C class name or alias",
+ orig_ident);
return error_mark_node;
}
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;
{
if (TREE_VALUE (*chain) == ident)
return convert (string_type_node,
- build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, TREE_PURPOSE (*chain), 1));
chain = &TREE_CHAIN (*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));
+ return convert (string_type_node, build_unary_op (input_location,
+ ADDR_EXPR, decl, 1));
}
static GTY(()) int class_names_idx;
DECL_ARTIFICIAL (decl) = 1;
#ifdef OBJCPLUS
DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
-#endif
+#endif
make_decl_rtl (decl);
pushdecl_top_level (decl);
#endif /* OBJCPLUS */
if (!(underlying_class = objc_is_class_name (class_ident)))
- warning (0, "cannot find class %qs", IDENTIFIER_POINTER (class_ident));
+ warning (0, "cannot find class %qE", class_ident);
else if (objc_is_class_name (alias_ident))
- warning (0, "class %qs already exists", IDENTIFIER_POINTER (alias_ident));
+ warning (0, "class %qE already exists", alias_ident);
else
{
/* Implement @compatibility_alias as a typedef. */
if (!TYPE_HAS_OBJC_INFO (type)
|| !TYPE_OBJC_INTERFACE (type))
{
- error ("%qs redeclared as different kind of symbol",
- IDENTIFIER_POINTER (ident));
- error ("%Jprevious declaration of '%D'",
- record, record);
+ error ("%qE redeclared as different kind of symbol",
+ ident);
+ 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;
return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
newexpr),
- TREE_OPERAND (expr, 1));
+ TREE_OPERAND (expr, 1),
+ input_location);
case INDIRECT_REF:
- return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
+ return build_indirect_ref (input_location,
+ objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
newexpr), "->");
default:
? objc_assign_ivar_fast_decl
: objc_assign_ivar_decl);
- offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
+ offs = convert (integer_type_node, build_unary_op (input_location,
+ 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 (input_location, ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_global_decl);
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 (input_location, ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_strong_cast_decl);
outer = TREE_OPERAND (lhs, 0);
while (!strong_cast_p
- && (TREE_CODE (outer) == CONVERT_EXPR
- || TREE_CODE (outer) == NOP_EXPR
+ && (CONVERT_EXPR_P (outer)
|| TREE_CODE (outer) == NON_LVALUE_EXPR))
{
tree lhstype = TREE_TYPE (outer);
}
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)
return result;
}
-struct interface_tuple GTY(())
-{
+struct GTY(()) interface_tuple {
tree id;
tree class_name;
};
static hashval_t
hash_interface (const void *p)
{
- const struct interface_tuple *d = p;
- return htab_hash_pointer (d->id);
+ const struct interface_tuple *d = (const struct interface_tuple *) p;
+ return IDENTIFIER_HASH_VALUE (d->id);
}
static int
eq_interface (const void *p1, const void *p2)
{
- const struct interface_tuple *d = p1;
+ const struct interface_tuple *d = (const struct interface_tuple *) p1;
return d->id == p2;
}
{
slot = (struct interface_tuple **)
htab_find_slot_with_hash (interface_htab, ident,
- htab_hash_pointer (ident),
+ IDENTIFIER_HASH_VALUE (ident),
NO_INSERT);
if (slot && *slot)
i = (*slot)->class_name;
if (interface)
return get_class_ivars (interface, true);
- error ("cannot find interface declaration for %qs",
- IDENTIFIER_POINTER (class_name));
+ error ("cannot find interface declaration for %qE",
+ class_name);
return error_mark_node;
}
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 = c_common_truthvalue_conversion (cond);
+ cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
+ cond = c_common_truthvalue_conversion (input_location, 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 = 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 = c_common_truthvalue_conversion (t);
+ cond = c_common_truthvalue_conversion (input_location, 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);
{
struct _objc_exception_data _stack;
- id volatile _rethrow = 0;
+ id _rethrow = 0;
try
{
objc_exception_try_enter (&_stack);
rethrow_decl = objc_create_temporary_var (objc_object_type);
cur_try_context->rethrow_decl = rethrow_decl;
- TREE_THIS_VOLATILE (rethrow_decl) = 1;
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));
/* Build the complete FINALLY statement list. */
t = next_sjlj_build_try_exit ();
t = build_stmt (COND_EXPR,
- c_common_truthvalue_conversion (rethrow_decl),
+ c_common_truthvalue_conversion
+ (input_location, 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,
- c_common_truthvalue_conversion (rethrow_decl),
+ c_common_truthvalue_conversion (input_location,
+ rethrow_decl),
t, NULL);
SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
void
objc_begin_try_stmt (location_t try_locus, tree body)
{
- struct objc_try_context *c = xcalloc (1, sizeof (*c));
+ struct objc_try_context *c = XCNEW (struct objc_try_context);
c->outer = cur_try_context;
c->try_body = body;
c->try_locus = try_locus;
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);
}
/* If we're doing Darwin setjmp exceptions, build the big nasty. */
if (flag_objc_sjlj_exceptions)
{
+ bool save = in_late_binary_op;
+ in_late_binary_op = true;
if (!cur_try_context->finally_body)
{
cur_try_context->finally_locus = input_location;
cur_try_context->end_finally_locus = input_location;
}
stmt = next_sjlj_build_try_catch_finally ();
+ in_late_binary_op = save;
}
else
{
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
tree field_decl, field_decl_chain, index, temp_type;
objc_exception_data_template
- = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
+ = objc_start_struct (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;
"pointers");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_exception_data_template, field_decl_chain);
/* int _setjmp(...); */
/* If the user includes <setjmp.h>, this shall be superseded by
'int _setjmp(jmp_buf);' */
temp_type = build_function_type (integer_type_node, NULL_TREE);
objc_setjmp_decl
- = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
/* id objc_exception_extract(struct _objc_exception_data *); */
temp_type
build_pointer_type (objc_exception_data_template),
OBJC_VOID_AT_END));
objc_exception_extract_decl
- = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL,
+ NULL_TREE);
/* void objc_exception_try_enter(struct _objc_exception_data *); */
/* void objc_exception_try_exit(struct _objc_exception_data *); */
temp_type
build_pointer_type (objc_exception_data_template),
OBJC_VOID_AT_END));
objc_exception_try_enter_decl
- = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL,
+ NULL_TREE);
objc_exception_try_exit_decl
- = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_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_VOID_AT_END)));
objc_exception_match_decl
- = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL,
+ NULL_TREE);
/* id objc_assign_ivar (id, id, unsigned int); */
/* id objc_assign_ivar_Fast (id, id, unsigned int)
unsigned_type_node,
OBJC_VOID_AT_END))));
objc_assign_ivar_decl
- = builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
- NULL, NULL_TREE);
+ = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN,
+ NULL, NULL_TREE);
#ifdef OFFS_ASSIGNIVAR_FAST
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"),
+ = add_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"),
build_int_cst (NULL_TREE, OFFS_ASSIGNIVAR_FAST),
NULL_TREE);
#else
tree_cons (NULL_TREE, build_pointer_type (objc_object_type),
OBJC_VOID_AT_END)));
objc_assign_global_decl
- = builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL,
+ NULL_TREE);
objc_assign_strong_cast_decl
- = builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
+ = add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL,
+ NULL_TREE);
}
static void
tree_cons (NULL_TREE, objc_object_type,
OBJC_VOID_AT_END));
objc_exception_throw_decl
- = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
- noreturn_list);
+ = add_builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
+ noreturn_list);
objc_sync_enter_decl
- = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
- NULL, nothrow_list);
+ = add_builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
+ NULL, nothrow_list);
objc_sync_exit_decl
- = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
- NULL, nothrow_list);
+ = add_builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
+ NULL, nothrow_list);
}
/* Construct a C struct corresponding to ObjC class CLASS, with the same
}; */
static void
-build_private_template (tree class)
+build_private_template (tree klass)
{
- if (!CLASS_STATIC_TEMPLATE (class))
+ if (!CLASS_STATIC_TEMPLATE (klass))
{
- tree record = objc_build_struct (CLASS_NAME (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;
+ tree record = objc_build_struct (klass,
+ get_class_ivars (klass, false),
+ CLASS_SUPER_NAME (klass));
/* Set the TREE_USED bit for this struct, so that stab generator
can emit stabs for this struct type. */
{
tree field_decl, field_decl_chain;
- objc_protocol_template = start_struct (RECORD_TYPE,
- get_identifier (UTAG_PROTOCOL));
+ objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
/* struct _objc_class *isa; */
field_decl = create_field_decl (build_pointer_type
"class_methods");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_protocol_template, field_decl_chain);
}
static tree
/* Generate an unnamed struct definition. */
- objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+ objc_ivar_list_record = objc_start_struct (NULL_TREE);
/* int method_count; */
field_decl = create_field_decl (integer_type_node, "method_count");
"method_list");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_ivar_list_record, field_decl_chain);
return objc_ivar_list_record;
}
tree proto_record;
tree field_decl, field_decl_chain;
- proto_record
- = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
+ proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
/* SEL _cmd; */
field_decl = create_field_decl (objc_selector_type, "_cmd");
field_decl = create_field_decl (string_type_node, "method_types");
chainon (field_decl_chain, field_decl);
- finish_struct (proto_record, field_decl_chain, NULL_TREE);
+ objc_finish_struct (proto_record, field_decl_chain);
return proto_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;
finish_encoding:
obstack_1grow (&util_obstack, '\0');
- result = get_identifier (obstack_finish (&util_obstack));
+ result = get_identifier (XOBFINISH (&util_obstack, char *));
obstack_free (&util_obstack, util_firstobj);
return result;
}
/* Call the ivar's default constructor or destructor. Do not
call the destructor unless a corresponding constructor call
has also been made (or is not needed). */
- if (IS_AGGR_TYPE (type)
+ if (MAYBE_CLASS_TYPE_P (type)
&& (dtor
? (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
&& (!TYPE_NEEDS_CONSTRUCTING (type)
(build_special_member_call
(build_ivar_reference (DECL_NAME (ivar)),
dtor ? complete_dtor_identifier : complete_ctor_identifier,
- NULL_TREE, type, LOOKUP_NORMAL));
+ NULL, type, LOOKUP_NORMAL, tf_warning_or_error));
}
}
{
tree type = TREE_TYPE (ivar);
- if (IS_AGGR_TYPE (type))
+ if (MAYBE_CLASS_TYPE_P (type))
{
if (TYPE_NEEDS_CONSTRUCTING (type)
&& TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
if (refs_decl)
refs_expr = convert (build_pointer_type (build_pointer_type
(objc_protocol_template)),
- build_unary_op (ADDR_EXPR, refs_decl, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, refs_decl, 0));
else
refs_expr = build_int_cst (NULL_TREE, 0);
else
{
expr = convert (objc_method_proto_list_ptr,
- build_unary_op (ADDR_EXPR, instance_methods, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
else
{
expr = convert (objc_method_proto_list_ptr,
- build_unary_op (ADDR_EXPR, class_methods, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, class_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
{
tree field_decl, field_decl_chain;
- objc_category_template = start_struct (RECORD_TYPE,
- get_identifier (UTAG_CATEGORY));
+ objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
/* char *category_name; */
field_decl = create_field_decl (string_type_node, "category_name");
"protocol_list");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_category_template, field_decl_chain);
}
/* struct _objc_selector {
static void
build_selector_template (void)
{
-
tree field_decl, field_decl_chain;
- objc_selector_template
- = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
+ objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
/* SEL sel_id; */
field_decl = create_field_decl (objc_selector_type, "sel_id");
field_decl = create_field_decl (string_type_node, "sel_type");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_selector_template, field_decl_chain);
}
/* struct _objc_class {
{
tree field_decl, field_decl_chain;
- objc_class_template
- = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
+ objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
/* struct _objc_class *isa; */
field_decl = create_field_decl (build_pointer_type (objc_class_template),
"gc_object_type");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_class_template, field_decl_chain);
}
/* Generate appropriate forward declarations for an implementation. */
error_with_ivar (const char *message, tree decl)
{
error ("%J%s %qs", decl,
- message, gen_declaration (decl));
+ message, identifier_to_locale (gen_declaration (decl)));
}
{
tree field_decl, field_decl_chain;
- objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
+ objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
/* struct _objc_object *self; */
field_decl = create_field_decl (objc_object_type, "self");
"super_class");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_super_template, field_decl_chain);
}
/* struct _objc_ivar {
tree field_decl, field_decl_chain;
objc_ivar_id = get_identifier (UTAG_IVAR);
- objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
+ objc_ivar_record = objc_start_struct (objc_ivar_id);
/* char *ivar_name; */
field_decl = create_field_decl (string_type_node, "ivar_name");
field_decl = create_field_decl (integer_type_node, "ivar_offset");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_ivar_record, field_decl_chain);
return objc_ivar_record;
}
tree objc_ivar_list_record;
tree field_decl, field_decl_chain;
- objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+ objc_ivar_list_record = objc_start_struct (NULL_TREE);
/* int ivar_count; */
field_decl = create_field_decl (integer_type_node, "ivar_count");
"ivar_list");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_ivar_list_record, field_decl_chain);
return objc_ivar_list_record;
}
tree objc_ivar_list_record;
tree field_decl, field_decl_chain;
- objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
+ objc_ivar_list_record = objc_start_struct (NULL_TREE);
/* struct _objc__method_prototype_list *method_next; */
field_decl = create_field_decl (objc_method_proto_list_ptr,
"method_list");
chainon (field_decl_chain, field_decl);
- finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
+ objc_finish_struct (objc_ivar_list_record, field_decl_chain);
return objc_ivar_list_record;
}
ivar
= tree_cons
(NULL_TREE,
- add_objc_string (get_identifier (obstack_finish (&util_obstack)),
+ add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
meth_var_types),
ivar);
obstack_free (&util_obstack, util_firstobj);
}
/* Count only the fields occurring in T. */
+
static int
ivar_list_length (tree t)
{
elemlist
= tree_cons (NULL_TREE,
- convert (ptr_type_node,
- build_unary_op (ADDR_EXPR,
+ convert (ptr_type_node,
+ build_unary_op (input_location, ADDR_EXPR,
METHOD_DEFINITION (entries), 1)),
elemlist);
tree _SLT_record;
tree field_decl, field_decl_chain;
- _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
+ _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
/* SEL _cmd; */
field_decl = create_field_decl (objc_selector_type, "_cmd");
"_imp");
chainon (field_decl_chain, field_decl);
- finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
+ objc_finish_struct (_SLT_record, field_decl_chain);
return _SLT_record;
}
if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
&& PROTOCOL_FORWARD_DECL (pval))
{
- e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
+ e = build_unary_op (input_location, ADDR_EXPR,
+ PROTOCOL_FORWARD_DECL (pval), 0);
initlist = tree_cons (NULL_TREE, e, initlist);
}
}
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, instance_methods, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
if (!class_methods)
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, class_methods, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ class_methods, 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));
+ build_unary_op (input_location, ADDR_EXPR,
+ protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
else
{
expr = convert (objc_ivar_list_ptr,
- build_unary_op (ADDR_EXPR, ivar_list, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ ivar_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, dispatch_table, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ dispatch_table, 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));
+ build_unary_op (input_location, ADDR_EXPR,
+ protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
/* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
static inline tree
-lookup_category (tree class, tree cat_name)
+lookup_category (tree klass, tree cat_name)
{
- tree category = CLASS_CATEGORY_LIST (class);
+ tree category = CLASS_CATEGORY_LIST (klass);
while (category && CLASS_SUPER_NAME (category) != cat_name)
category = CLASS_CATEGORY_LIST (category);
initlist
= build_shared_structure_initializer
(TREE_TYPE (decl),
- build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
+ build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
super_expr, name_expr,
convert (integer_type_node,
TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
}
issue_warning:
- warning (0, "multiple %s named %<%c%s%> found",
- methods ? "methods" : "selectors",
- (is_class ? '+' : '-'),
- IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
-
- warn_with_method (methods ? "using" : "found",
- ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
- ? '-'
- : '+'),
- meth);
+ if (methods)
+ {
+ bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
+
+ warning (0, "multiple methods named %<%c%E%> found",
+ (is_class ? '+' : '-'),
+ METHOD_SEL_NAME (meth));
+ inform (0, "%Jusing %<%c%s%>", meth,
+ (type ? '-' : '+'),
+ identifier_to_locale (gen_method_decl (meth)));
+ }
+ else
+ {
+ bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
+
+ warning (0, "multiple selectors named %<%c%E%> found",
+ (is_class ? '+' : '-'),
+ METHOD_SEL_NAME (meth));
+ inform (0, "%Jfound %<%c%s%>", meth,
+ (type ? '-' : '+'),
+ identifier_to_locale (gen_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);
+ {
+ bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
+
+ inform (0, "%Jalso found %<%c%s%>", loop->value,
+ (type ? '-' : '+'),
+ identifier_to_locale (gen_method_decl (loop->value)));
+ }
}
}
return meth;
/* The receiver is a function call that returns an id. Check if
it is a call to objc_getClass, if so, pick up the class name. */
if (TREE_CODE (receiver) == CALL_EXPR
- && (exp = TREE_OPERAND (receiver, 0))
+ && (exp = CALL_EXPR_FN (receiver))
&& TREE_CODE (exp) == ADDR_EXPR
&& (exp = TREE_OPERAND (exp, 0))
&& TREE_CODE (exp) == FUNCTION_DECL
&& TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
&& !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
/* We have a call to objc_get_class/objc_getClass! */
- && (arg = TREE_OPERAND (receiver, 1))
- && TREE_CODE (arg) == TREE_LIST
- && (arg = TREE_VALUE (arg)))
+ && (arg = CALL_EXPR_ARG (receiver, 0)))
{
STRIP_NOPS (arg);
if (TREE_CODE (arg) == ADDR_EXPR
if (!is_class)
method_prototype = hash_lookup (nst_method_hash_list,
sel_name);
-
+
if (!method_prototype)
{
method_prototype = hash_lookup (cls_method_hash_list,
rtype = receiver;
while (TREE_CODE (rtype) == COMPOUND_EXPR
|| TREE_CODE (rtype) == MODIFY_EXPR
- || TREE_CODE (rtype) == NOP_EXPR
- || TREE_CODE (rtype) == CONVERT_EXPR
+ || CONVERT_EXPR_P (rtype)
|| TREE_CODE (rtype) == COMPONENT_REF)
rtype = TREE_OPERAND (rtype, 0);
self = (rtype == self_decl);
{
if (!CLASS_SUPER_NAME (implementation_template))
{
- error ("no super class declared in @interface for %qs",
- IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
+ error ("no super class declared in @interface for %qE",
+ CLASS_NAME (implementation_template));
return error_mark_node;
}
rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
= lookup_method_in_protocol_list (rprotos, sel_name, 0);
if (method_prototype)
- warning (0, "found %<-%s%> instead of %<+%s%> in protocol(s)",
- IDENTIFIER_POINTER (sel_name),
- IDENTIFIER_POINTER (sel_name));
+ warning (0, "found %<-%E%> instead of %<+%E%> in protocol(s)",
+ sel_name, sel_name);
}
}
}
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
else
{
warning (0, "invalid receiver type %qs",
- gen_type_name (orig_rtype));
+ identifier_to_locale (gen_type_name (orig_rtype)));
/* After issuing the "invalid receiver" warning, perform method
lookup as if we were messaging 'id'. */
rtype = rprotos = NULL_TREE;
}
- }
+ }
/* For 'id' or 'Class' receivers, search in the global hash table
if (!method_prototype)
{
if (rprotos)
- warning (0, "%<%c%s%> not found in protocol(s)",
+ warning (0, "%<%c%E%> not found in protocol(s)",
(class_tree ? '+' : '-'),
- IDENTIFIER_POINTER (sel_name));
+ sel_name);
if (!rtype)
method_prototype
static bool warn_missing_methods = false;
if (rtype)
- warning (0, "%qs may not respond to %<%c%s%>",
- IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
+ warning (0, "%qE may not respond to %<%c%E%>",
+ OBJC_TYPE_NAME (rtype),
(class_tree ? '+' : '-'),
- IDENTIFIER_POINTER (sel_name));
+ sel_name);
/* If we are messaging an 'id' or 'Class' object and made it here,
then we have failed to find _any_ instance or class method,
respectively. */
else
- warning (0, "no %<%c%s%> method found",
+ warning (0, "no %<%c%E%> method found",
(class_tree ? '+' : '-'),
- IDENTIFIER_POINTER (sel_name));
+ sel_name);
if (!warn_missing_methods)
{
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
if (!p)
{
- error ("cannot find protocol declaration for %qs",
- IDENTIFIER_POINTER (protoname));
+ error ("cannot find protocol declaration for %qE",
+ protoname);
return error_mark_node;
}
if (!PROTOCOL_FORWARD_DECL (p))
build_protocol_reference (p);
- expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
/* ??? Ideally we'd build the reference with objc_protocol_type directly,
if we have it, rather than converting it here. */
/* If still not found, print out a warning. */
if (!hsh)
{
- warning (0, "undeclared selector %qs", IDENTIFIER_POINTER (selname));
+ warning (0, "undeclared selector %qE", selname);
}
}
encode_type (type, obstack_object_size (&util_obstack),
OBJC_ENCODE_INLINE_DEFS);
obstack_1grow (&util_obstack, 0); /* null terminate string */
- string = obstack_finish (&util_obstack);
+ string = XOBFINISH (&util_obstack, const char *);
/* Synthesize a string that represents the encoded struct/union. */
result = my_build_string (strlen (string) + 1, string);
to an instance variable. It's better to catch the cases
where this is done unknowingly than to support the above
paradigm. */
- warning (0, "instance variable %qs accessed in class method",
- IDENTIFIER_POINTER (id));
+ warning (0, "instance variable %qE accessed in class method",
+ id);
self_decl = convert (objc_instance_type, self_decl); /* cast */
}
- return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
+ return objc_build_component_ref (build_indirect_ref (input_location,
+ self_decl, "->"), id);
}
\f
/* Compute a hash value for a given method SEL_NAME. */
/* 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)
{
}
static tree
-objc_add_method (tree class, tree method, int is_class)
+objc_add_method (tree klass, tree method, int is_class)
{
tree mth;
if (!(mth = lookup_method (is_class
- ? CLASS_CLS_METHODS (class)
- : CLASS_NST_METHODS (class), method)))
+ ? CLASS_CLS_METHODS (klass)
+ : CLASS_NST_METHODS (klass), method)))
{
/* put method on list in reverse order */
if (is_class)
{
- TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
- CLASS_CLS_METHODS (class) = method;
+ TREE_CHAIN (method) = CLASS_CLS_METHODS (klass);
+ CLASS_CLS_METHODS (klass) = method;
}
else
{
- TREE_CHAIN (method) = CLASS_NST_METHODS (class);
- CLASS_NST_METHODS (class) = method;
+ TREE_CHAIN (method) = CLASS_NST_METHODS (klass);
+ CLASS_NST_METHODS (klass) = method;
}
}
else
and/or return types. We do not do this for @implementations, because
C/C++ will do it for us (i.e., there will be duplicate function
definition errors). */
- if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
- || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
+ if ((TREE_CODE (klass) == CLASS_INTERFACE_TYPE
+ || TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE)
&& !comp_proto_with_proto (method, mth, 1))
- error ("duplicate declaration of method %<%c%s%>",
- is_class ? '+' : '-',
- IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
+ error ("duplicate declaration of method %<%c%E%>",
+ is_class ? '+' : '-',
+ METHOD_SEL_NAME (mth));
}
if (is_class)
instance methods listed in @protocol declarations to
the class hash table, on the assumption that @protocols
may be adopted by root classes or categories. */
- if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
- || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
- class = lookup_interface (CLASS_NAME (class));
+ if (TREE_CODE (klass) == CATEGORY_INTERFACE_TYPE
+ || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
+ klass = lookup_interface (CLASS_NAME (klass));
- if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
- || !CLASS_SUPER_NAME (class))
+ if (TREE_CODE (klass) == PROTOCOL_INTERFACE_TYPE
+ || !CLASS_SUPER_NAME (klass))
add_method_to_hash_list (cls_method_hash_list, method);
}
interface_htab = htab_create_ggc (31, hash_interface, eq_interface, NULL);
slot = (struct interface_tuple **)
htab_find_slot_with_hash (interface_htab, name,
- htab_hash_pointer (name),
+ IDENTIFIER_HASH_VALUE (name),
INSERT);
if (!*slot)
{
}
static void
-add_category (tree class, tree category)
+add_category (tree klass, tree category)
{
/* Put categories on list in reverse order. */
- tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
+ tree cat = lookup_category (klass, CLASS_SUPER_NAME (category));
if (cat)
{
- warning (0, "duplicate interface declaration for category %<%s(%s)%>",
- IDENTIFIER_POINTER (CLASS_NAME (class)),
- IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
+ warning (0, "duplicate interface declaration for category %<%E(%E)%>",
+ CLASS_NAME (klass),
+ CLASS_SUPER_NAME (category));
}
else
{
- CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
- CLASS_CATEGORY_LIST (class) = category;
+ CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (klass);
+ CLASS_CATEGORY_LIST (klass) = category;
}
}
/* Called after parsing each instance variable declaration. Necessary to
preserve typedefs and implement public/private...
- PUBLIC is 1 for public, 0 for protected, and 2 for private. */
+ VISIBILITY is 1 for public, 0 for protected, and 2 for private. */
static tree
-add_instance_variable (tree class, int public, tree field_decl)
+add_instance_variable (tree klass, int visibility, tree field_decl)
{
tree field_type = TREE_TYPE (field_decl);
const char *ivar_name = DECL_NAME (field_decl)
- ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
- : "<unnamed>";
+ ? identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (field_decl)))
+ : _("<unnamed>");
#ifdef OBJCPLUS
if (TREE_CODE (field_type) == REFERENCE_TYPE)
error ("illegal reference type specified for instance variable %qs",
ivar_name);
/* Return class as is without adding this ivar. */
- return class;
+ return klass;
}
#endif
{
error ("instance variable %qs has unknown size", ivar_name);
/* Return class as is without adding this ivar. */
- return class;
+ return klass;
}
#ifdef OBJCPLUS
need to either (1) warn the user about it or (2) generate suitable
constructor/destructor call from '- .cxx_construct' or '- .cxx_destruct'
methods (if '-fobjc-call-cxx-cdtors' was specified). */
- if (IS_AGGR_TYPE (field_type)
+ if (MAYBE_CLASS_TYPE_P (field_type)
&& (TYPE_NEEDS_CONSTRUCTING (field_type)
|| TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type)
|| TYPE_POLYMORPHIC_P (field_type)))
{
- const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
+ tree type_name = OBJC_TYPE_NAME (field_type);
if (flag_objc_call_cxx_cdtors)
{
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 %qE 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 %qE 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 %qE has virtual member functions", type_name);
+ error ("illegal aggregate type %qE specified "
+ "for instance variable %qs",
type_name, ivar_name);
/* Return class as is without adding this ivar. */
- return class;
+ return klass;
}
/* 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 %qE 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 %qE has a user-defined destructor", type_name);
if (!warn_cxx_ivars)
{
#endif
/* Overload the public attribute, it is not used for FIELD_DECLs. */
- switch (public)
+ switch (visibility)
{
case 0:
TREE_PUBLIC (field_decl) = 0;
}
- CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
+ CLASS_RAW_IVARS (klass) = chainon (CLASS_RAW_IVARS (klass), field_decl);
- return class;
+ return klass;
}
\f
static tree
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)
{
if (TYPE_HAS_OBJC_INFO (basetype) && TYPE_OBJC_INTERFACE (basetype))
{
- tree class = lookup_interface (OBJC_TYPE_NAME (basetype));
+ tree klass = lookup_interface (OBJC_TYPE_NAME (basetype));
- if (!class)
+ if (!klass)
{
- error ("cannot find interface declaration for %qs",
- IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
+ error ("cannot find interface declaration for %qE",
+ OBJC_TYPE_NAME (basetype));
return 0;
}
- if ((decl = is_ivar (get_class_ivars (class, true), identifier)))
+ if ((decl = is_ivar (get_class_ivars (klass, true), identifier)))
{
if (TREE_PUBLIC (decl))
return 1;
if (basetype == curtype
|| DERIVED_FROM_P (basetype, curtype))
{
- int private = is_private (decl);
+ int priv = is_private (decl);
- if (private)
- error ("instance variable %qs is declared private",
- IDENTIFIER_POINTER (DECL_NAME (decl)));
+ if (priv)
+ error ("instance variable %qE is declared private",
+ DECL_NAME (decl));
- return !private;
+ return !priv;
}
}
non-@public ivars. We will let this slide for now... */
if (!objc_method_context)
{
- warning (0, "instance variable %qs is %s; "
+ warning (0, "instance variable %qE is %s; "
"this will be a hard error in the future",
- IDENTIFIER_POINTER (identifier),
+ identifier,
TREE_PRIVATE (decl) ? "@private" : "@protected");
return 1;
}
-
- error ("instance variable %qs is declared %s",
- IDENTIFIER_POINTER (identifier),
+
+ error ("instance variable %qE is declared %s",
+ identifier,
TREE_PRIVATE (decl) ? "private" : "protected");
return 0;
}
{
if (TREE_CODE (objc_implementation_context)
== CLASS_IMPLEMENTATION_TYPE)
- warning (0, "incomplete implementation of class %qs",
- IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
+ warning (0, "incomplete implementation of class %qE",
+ CLASS_NAME (objc_implementation_context));
else if (TREE_CODE (objc_implementation_context)
== CATEGORY_IMPLEMENTATION_TYPE)
- warning (0, "incomplete implementation of category %qs",
- IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
+ warning (0, "incomplete implementation of category %qE",
+ CLASS_SUPER_NAME (objc_implementation_context));
first = 0;
}
- warning (0, "method definition for %<%c%s%> not found",
- mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
+ warning (0, "method definition for %<%c%E%> not found",
+ mtype, METHOD_SEL_NAME (chain));
}
chain = TREE_CHAIN (chain);
return first;
}
-/* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
+/* Check if KLASS, or its superclasses, explicitly conforms to PROTOCOL. */
static int
-conforms_to_protocol (tree class, tree protocol)
+conforms_to_protocol (tree klass, tree protocol)
{
if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
{
- tree p = CLASS_PROTOCOL_LIST (class);
+ tree p = CLASS_PROTOCOL_LIST (klass);
while (p && TREE_VALUE (p) != protocol)
p = TREE_CHAIN (p);
if (!p)
{
- tree super = (CLASS_SUPER_NAME (class)
- ? lookup_interface (CLASS_SUPER_NAME (class))
+ tree super = (CLASS_SUPER_NAME (klass)
+ ? lookup_interface (CLASS_SUPER_NAME (klass))
: NULL_TREE);
int tmp = super ? conforms_to_protocol (super, protocol) : 0;
if (!tmp)
{
if (TREE_CODE (objc_implementation_context)
== CLASS_IMPLEMENTATION_TYPE)
- warning (0, "incomplete implementation of class %qs",
- IDENTIFIER_POINTER
- (CLASS_NAME (objc_implementation_context)));
+ warning (0, "incomplete implementation of class %qE",
+ CLASS_NAME (objc_implementation_context));
else if (TREE_CODE (objc_implementation_context)
== CATEGORY_IMPLEMENTATION_TYPE)
- warning (0, "incomplete implementation of category %qs",
- IDENTIFIER_POINTER
- (CLASS_SUPER_NAME (objc_implementation_context)));
+ warning (0, "incomplete implementation of category %qE",
+ CLASS_SUPER_NAME (objc_implementation_context));
first = 0;
}
- warning (0, "method definition for %<%c%s%> not found",
- mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
+ warning (0, "method definition for %<%c%E%> not found",
+ mtype, METHOD_SEL_NAME (chain));
}
chain = TREE_CHAIN (chain); /* next method... */
with any protocols that P inherits. */
static void
-check_protocol (tree p, const char *type, const char *name)
+check_protocol (tree p, const char *type, tree name)
{
if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
{
}
if (!f1 || !f2)
- warning (0, "%s %qs does not fully implement the %qs protocol",
- type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
+ warning (0, "%s %qE does not fully implement the %qE protocol",
+ type, name, PROTOCOL_NAME (p));
}
/* Check protocols recursively. */
in PROTO_LIST. */
static void
-check_protocols (tree proto_list, const char *type, const char *name)
+check_protocols (tree proto_list, const char *type, tree name)
{
for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
{
start_class (enum tree_code code, tree class_name, tree super_name,
tree protocol_list)
{
- tree class, decl;
+ tree klass, decl;
#ifdef OBJCPLUS
if (current_namespace != global_namespace) {
objc_implementation_context = NULL_TREE;
}
- class = make_node (code);
- TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
+ klass = make_node (code);
+ TYPE_LANG_SLOT_1 (klass) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
/* Check for existence of the super class, if one was specified. Note
that we must have seen an @interface, not just a @class. If we
if (!super || !lookup_interface (super))
{
- error ("cannot find interface declaration for %qs, superclass of %qs",
- IDENTIFIER_POINTER (super ? super : super_name),
- IDENTIFIER_POINTER (class_name));
+ error ("cannot find interface declaration for %qE, superclass of %qE",
+ super ? super : super_name,
+ class_name);
super_name = NULL_TREE;
}
else
super_name = super;
}
- CLASS_NAME (class) = class_name;
- CLASS_SUPER_NAME (class) = super_name;
- CLASS_CLS_METHODS (class) = NULL_TREE;
+ CLASS_NAME (klass) = class_name;
+ CLASS_SUPER_NAME (klass) = super_name;
+ CLASS_CLS_METHODS (klass) = NULL_TREE;
if (! objc_is_class_name (class_name)
&& (decl = lookup_name (class_name)))
{
- error ("%qs redeclared as different kind of symbol",
- IDENTIFIER_POINTER (class_name));
- error ("%Jprevious declaration of '%D'",
- decl, decl);
+ error ("%qE redeclared as different kind of symbol",
+ class_name);
+ error ("previous declaration of %q+D",
+ decl);
}
if (code == CLASS_IMPLEMENTATION_TYPE)
for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
if (TREE_VALUE (chain) == class_name)
{
- error ("reimplementation of class %qs",
- IDENTIFIER_POINTER (class_name));
+ error ("reimplementation of class %qE",
+ class_name);
return error_mark_node;
}
implemented_classes = tree_cons (NULL_TREE, class_name,
/* Reset for multiple classes per file. */
method_slot = 0;
- objc_implementation_context = class;
+ objc_implementation_context = klass;
/* Lookup the interface for this implementation. */
if (!(implementation_template = lookup_interface (class_name)))
{
- warning (0, "cannot find interface declaration for %qs",
- IDENTIFIER_POINTER (class_name));
+ warning (0, "cannot find interface declaration for %qE",
+ class_name);
add_class (implementation_template = objc_implementation_context,
class_name);
}
&& (super_name != CLASS_SUPER_NAME (implementation_template)))
{
tree previous_name = CLASS_SUPER_NAME (implementation_template);
- const char *const name =
- previous_name ? IDENTIFIER_POINTER (previous_name) : "";
- error ("conflicting super class name %qs",
- IDENTIFIER_POINTER (super_name));
- error ("previous declaration of %qs", name);
+ error ("conflicting super class name %qE",
+ super_name);
+ if (previous_name)
+ error ("previous declaration of %qE", previous_name);
+ else
+ error ("previous declaration");
}
else if (! super_name)
{
if (lookup_interface (class_name))
#ifdef OBJCPLUS
- error ("duplicate interface declaration for class %qs",
+ error ("duplicate interface declaration for class %qE",
#else
- warning (0, "duplicate interface declaration for class %qs",
-#endif
- IDENTIFIER_POINTER (class_name));
+ warning (0, "duplicate interface declaration for class %qE",
+#endif
+ class_name);
else
- add_class (class, class_name);
+ add_class (klass, class_name);
if (protocol_list)
- CLASS_PROTOCOL_LIST (class)
+ CLASS_PROTOCOL_LIST (klass)
= lookup_and_install_protocols (protocol_list);
}
if (!(class_category_is_assoc_with = lookup_interface (class_name)))
{
- error ("cannot find interface declaration for %qs",
- IDENTIFIER_POINTER (class_name));
+ error ("cannot find interface declaration for %qE",
+ class_name);
exit (FATAL_EXIT_CODE);
}
else
- add_category (class_category_is_assoc_with, class);
+ add_category (class_category_is_assoc_with, klass);
if (protocol_list)
- CLASS_PROTOCOL_LIST (class)
+ CLASS_PROTOCOL_LIST (klass)
= lookup_and_install_protocols (protocol_list);
}
/* Reset for multiple classes per file. */
method_slot = 0;
- objc_implementation_context = class;
+ objc_implementation_context = klass;
/* For a category, class_name is really the name of the class that
the following set of methods will be associated with. We must
if (!(implementation_template = lookup_interface (class_name)))
{
- error ("cannot find interface declaration for %qs",
- IDENTIFIER_POINTER (class_name));
+ error ("cannot find interface declaration for %qE",
+ class_name);
exit (FATAL_EXIT_CODE);
}
}
- return class;
+ return klass;
}
static tree
-continue_class (tree class)
+continue_class (tree klass)
{
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
- || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
+ if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE
+ || TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
{
struct imp_entry *imp_entry;
/* Check consistency of the instance variables. */
- if (CLASS_RAW_IVARS (class))
- check_ivars (implementation_template, class);
+ if (CLASS_RAW_IVARS (klass))
+ check_ivars (implementation_template, klass);
/* code generation */
imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
imp_entry->next = imp_list;
- imp_entry->imp_context = class;
+ imp_entry->imp_context = klass;
imp_entry->imp_template = implementation_template;
synth_forward_declarations ();
/* Append to front and increment count. */
imp_list = imp_entry;
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
imp_count++;
else
cat_count++;
return get_class_ivars (implementation_template, true);
}
- else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
+ else if (TREE_CODE (klass) == CLASS_INTERFACE_TYPE)
{
#ifdef OBJCPLUS
push_lang_context (lang_name_c);
#endif /* OBJCPLUS */
- build_private_template (class);
+ build_private_template (klass);
#ifdef OBJCPLUS
pop_lang_context ();
/* This is called once we see the "@end" in an interface/implementation. */
static void
-finish_class (tree class)
+finish_class (tree klass)
{
- if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
+ if (TREE_CODE (klass) == CLASS_IMPLEMENTATION_TYPE)
{
/* All code generation is done in finish_objc. */
if (CLASS_PROTOCOL_LIST (implementation_template))
check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
"class",
- IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
+ CLASS_NAME (objc_implementation_context));
}
}
- else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
+ else if (TREE_CODE (klass) == CATEGORY_IMPLEMENTATION_TYPE)
{
- tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
+ tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (klass));
if (category)
{
if (CLASS_PROTOCOL_LIST (category))
check_protocols (CLASS_PROTOCOL_LIST (category),
"category",
- IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
+ CLASS_SUPER_NAME (objc_implementation_context));
}
}
}
}
else
{
- warning (0, "duplicate declaration for protocol %qs",
- IDENTIFIER_POINTER (name));
+ warning (0, "duplicate declaration for protocol %qE",
+ name);
}
return protocol;
}
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);
}
enum tree_code code = TREE_CODE (type);
char c;
+ if (type == error_mark_node)
+ return;
+
if (TYPE_READONLY (type))
obstack_1grow (&util_obstack, 'r');
{
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
static void
objc_push_parm (tree parm)
{
+ bool relayout_needed = false;
+
+ if (TREE_TYPE (parm) == error_mark_node)
+ {
+ objc_parmlist = chainon (objc_parmlist, parm);
+ return;
+ }
+
/* 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)));
+ {
+ TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
+ relayout_needed = true;
+ }
else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
- TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
+ {
+ TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
+ relayout_needed = true;
+ }
+
+ if (relayout_needed)
+ relayout_decl (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);
+ finish_decl (parm_info, NULL_TREE, NULL_TREE, NULL_TREE);
parm_info = next;
}
arg_info = get_parm_info (have_ellipsis);
{
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));
really_start_method (objc_method_context, parm_info);
}
-static void
-warn_with_method (const char *message, int mtype, tree method)
-{
- /* Add a readable method name to the warning. */
- warning (0, "%J%s %<%c%s%>", method,
- message, mtype, gen_method_decl (method));
-}
-
/* Return 1 if TYPE1 is equivalent to TYPE2
for purposes of method overloading. */
{
if (!comp_proto_with_proto (method, proto, 1))
{
- char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
-
- warn_with_method ("conflicting types for", type, method);
- warn_with_method ("previous declaration of", type, proto);
+ bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
+
+ warning (0, "%Jconflicting types for %<%c%s%>", method,
+ (type ? '-' : '+'),
+ identifier_to_locale (gen_method_decl (method)));
+ inform (0, "%Jprevious declaration of %<%c%s%>", proto,
+ (type ? '-' : '+'),
+ identifier_to_locale (gen_method_decl (proto)));
}
}
else
/* This prevents `unused variable' warnings when compiling with -Wall. */
TREE_USED (UOBJC_SUPER_decl) = 1;
lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
- finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
+ finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE, NULL_TREE);
UOBJC_SUPER_scope = objc_get_current_scope ();
}
/* Set receiver to self. */
super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
- super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
+ super_expr = build_modify_expr (input_location, super_expr, NULL_TREE,
+ NOP_EXPR, self_decl, NULL_TREE);
super_expr_list = super_expr;
/* Set class to begin searching. */
/* [_cls, __cls]Super are "pre-built" in
synth_forward_declarations. */
- super_expr = build_modify_expr (super_expr, NOP_EXPR,
+ super_expr = build_modify_expr (input_location, super_expr,
+ NULL_TREE, NOP_EXPR,
((TREE_CODE (objc_method_context)
== INSTANCE_METHOD_DECL)
? ucls_super_ref
- : uucls_super_ref));
+ : uucls_super_ref),
+ NULL_TREE);
}
else
/* Barf if super used in a category of Object. */
if (!super_name)
{
- error ("no super class declared in interface for %qs",
- IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
+ error ("no super class declared in interface for %qE",
+ CLASS_NAME (implementation_template));
return error_mark_node;
}
"isa" is the first ivar in a class (which it must be). */
super_class
= build_indirect_ref
- (build_c_cast (build_pointer_type (objc_class_type),
- super_class), "unary *");
+ (input_location,
+ build_c_cast (build_pointer_type (objc_class_type),
+ super_class), "unary *");
}
else
{
(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
- = build_modify_expr (super_expr, NOP_EXPR,
+ = build_modify_expr (input_location, super_expr, NULL_TREE,
+ NOP_EXPR,
build_c_cast (TREE_TYPE (super_expr),
- super_class));
+ super_class),
+ NULL_TREE);
}
super_expr_list = build_compound_expr (super_expr_list, super_expr);
- super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
+ super_expr = build_unary_op (input_location,
+ ADDR_EXPR, UOBJC_SUPER_decl, 0);
super_expr_list = build_compound_expr (super_expr_list, super_expr);
return super_expr_list;
/* We cannot validly inline ObjC methods, at least not without a language
extension to declare that a method need not be dynamically
dispatched, so suppress all thoughts of doing so. */
- DECL_INLINE (fndecl) = 0;
DECL_UNINLINABLE (fndecl) = 1;
#ifndef OBJCPLUS
warning (0, "method possibly missing a [super dealloc] call");
}
-#if 0
-int
-lang_report_error_function (tree decl)
-{
- if (objc_method_context)
- {
- fprintf (stderr, "In method %qs\n",
- IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
- return 1;
- }
-
- else
- return 0;
-}
-#endif
-
/* Given a tree DECL node, produce a printable description of it in the given
buffer, overwriting the buffer. */
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);
&& !DECL_FILE_SCOPE_P (other))
#endif
{
- warning (0, "local declaration of %qs hides instance variable",
- IDENTIFIER_POINTER (id));
+ warning (0, "local declaration of %qE hides instance variable",
+ id);
return other;
}
needs to be done if we are calling a function through a cast. */
tree
-objc_rewrite_function_call (tree function, tree params)
+objc_rewrite_function_call (tree function, tree first_param)
{
if (TREE_CODE (function) == NOP_EXPR
&& TREE_CODE (TREE_OPERAND (function, 0)) == ADDR_EXPR
&& 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),
+ first_param, size_zero_node);
}
return function;
of its cousins). */
enum gimplify_status
-objc_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+objc_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
enum gimplify_status r0, r1;
if (TREE_CODE (*expr_p) == OBJ_TYPE_REF
}
#ifdef OBJCPLUS
- return cp_gimplify_expr (expr_p, pre_p, post_p);
+ return (enum gimplify_status) cp_gimplify_expr (expr_p, pre_p, post_p);
#else
- return c_gimplify_expr (expr_p, pre_p, post_p);
+ return (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
#endif
}
-/* Given a CALL expression, find the function being called. The ObjC
- version looks for the OBJ_TYPE_REF_EXPR which is used for objc_msgSend. */
-
-tree
-objc_get_callee_fndecl (tree call_expr)
-{
- tree addr = TREE_OPERAND (call_expr, 0);
- if (TREE_CODE (addr) != OBJ_TYPE_REF)
- return 0;
-
- addr = OBJ_TYPE_REF_EXPR (addr);
-
- /* If the address is just `&f' for some function `f', then we know
- that `f' is being called. */
- if (TREE_CODE (addr) == ADDR_EXPR
- && TREE_CODE (TREE_OPERAND (addr, 0)) == FUNCTION_DECL)
- return TREE_OPERAND (addr, 0);
-
- return 0;
-}
-
#include "gt-objc-objc-act.h"