/* Next Runtime (ABI-0/1) private.
- Copyright (C) 2011 Free Software Foundation, Inc.
+ Copyright (C) 2011-2020 Free Software Foundation, Inc.
Contributed by Iain Sandoe (split from objc-act.c)
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
#include "tree.h"
+#include "stringpool.h"
+#include "attribs.h"
#ifdef OBJCPLUS
-#include "cp-tree.h"
+#include "cp/cp-tree.h"
#else
-#include "c-tree.h"
-#include "c-lang.h"
+#include "c/c-tree.h"
+#include "c/c-lang.h"
#endif
#include "langhooks.h"
#include "c-family/c-objc.h"
#include "objcp-decl.h"
#endif /* OBJCPLUS */
-#include "ggc.h"
#include "target.h"
-#include "output.h"
+#include "c-family/c-target.h"
#include "tree-iterator.h"
#include "objc-runtime-hooks.h"
static tree next_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
static tree next_runtime_abi_01_receiver_is_class_object (tree);
-static void next_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **, tree,
- int, int);
+static void next_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
+ tree, int, int);
static tree next_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
tree, tree, tree, int);
static bool next_runtime_abi_01_setup_const_string_class_decl (void);
{
warning_at (UNKNOWN_LOCATION, OPT_Wall,
"%<-fobjc-sjlj-exceptions%> is the only supported exceptions "
- "system for %<-fnext-runtime%> with %<-fobjc-abi-version%> < 2");
+ "system for %<-fnext-runtime%> with %<-fobjc-abi-version%> "
+ "argument less than 2");
}
rthooks->initialize = next_runtime_01_initialize;
objc_finish_struct (objc_protocol_template, decls);
}
-/* --- names, decls identifers --- */
+/* --- names, decls identifiers --- */
static tree
next_runtime_abi_01_super_superclassfield_id (void)
prototype. */
static void
-next_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
- int context, int superflag)
+next_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
+ tree meth, int context,
+ int superflag)
{
tree receiver_type;
else
receiver_type = objc_object_type;
- VEC_safe_push (tree, gc, *argtypes, receiver_type);
+ vec_safe_push (*argtypes, receiver_type);
/* Selector type - will eventually change to `int'. */
- VEC_safe_push (tree, gc, *argtypes, objc_selector_type);
+ vec_safe_push (*argtypes, objc_selector_type);
}
static tree
{
tree sender, sender_cast, method, t;
tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
- VEC(tree, gc) *parms;
+ vec<tree, va_gc> *parms;
unsigned nparm = (method_params ? list_length (method_params) : 0);
/* If a prototype for the method to be called exists, then cast
lookup_object = save_expr (lookup_object);
/* Param list + 2 slots for object and selector. */
- parms = VEC_alloc (tree, gc, nparm + 2);
+ vec_alloc (parms, nparm + 2);
/* If we are returning a struct in memory, and the address
of that memory location is passed as a hidden first
method = build_fold_addr_expr_loc (loc, sender);
/* Pass the object to the method. */
- VEC_quick_push (tree, parms, lookup_object);
+ parms->quick_push (lookup_object);
/* Pass the selector to the method. */
- VEC_quick_push (tree, parms, selector);
+ parms->quick_push (selector);
/* Now append the remainder of the parms. */
if (nparm)
for (; method_params; method_params = TREE_CHAIN (method_params))
- VEC_quick_push (tree, parms, TREE_VALUE (method_params));
+ parms->quick_push (TREE_VALUE (method_params));
/* Build an obj_type_ref, with the correct cast for the method call. */
t = build3 (OBJ_TYPE_REF, sender_cast, method,
lookup_object, size_zero_node);
- t = build_function_call_vec (loc, t, parms, NULL);
- VEC_free (tree, gc, parms);
+ t = build_function_call_vec (loc, vNULL, t, parms, NULL);
+ vec_free (parms);
return t;
}
/* else do it the slow way. */
add_class_reference (super_name);
super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
-/* assemble_external (super_class);*/
super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
IDENTIFIER_POINTER (super_name));
/* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
int length)
{
tree constructor, fields, var;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
/* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
fields = TYPE_FIELDS (internal_const_str_type);
{
tree method_list_template, initlist, decl;
int size;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
char buf[BUFSIZE];
if (!chain || !prefix)
{
int size;
location_t loc;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
tree decl, expr;
char buf[BUFSIZE];
build_v1_property_table_initializer (tree type, tree context)
{
tree x;
- VEC(constructor_elt,gc) *inits = NULL;
+ vec<constructor_elt, va_gc> *inits = NULL;
if (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE)
x = CLASS_PROPERTY_DECL (context);
for (; x; x = TREE_CHAIN (x))
{
- VEC(constructor_elt,gc) *elemlist = NULL;
+ vec<constructor_elt, va_gc> *elemlist = NULL;
tree attribute, name_ident = PROPERTY_NAME (x);
CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE,
{
tree x, decl, initlist, property_list_template;
bool is_proto = false;
- VEC(constructor_elt,gc) *inits = NULL;
+ vec<constructor_elt, va_gc> *inits = NULL;
int init_val, size = 0;
char buf[BUFSIZE];
{
tree array_type, ptype, refs_decl, lproto, e, plist, attr;
int size = 0;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
char buf[BUFSIZE];
switch (TREE_CODE (i_or_p))
{
tree expr, ttyp;
location_t loc;
- VEC(constructor_elt,gc) *inits = NULL;
+ vec<constructor_elt, va_gc> *inits = NULL;
if (!objc_protocol_extension_template)
build_v1_objc_protocol_extension_template ();
generate_dispatch_table (tree chain, const char *name, tree attr)
{
tree decl, method_list_template, initlist;
- VEC(constructor_elt,gc) *v = NULL;
- int size;;
+ vec<constructor_elt, va_gc> *v = NULL;
+ int size;
if (!chain || !name || !(size = list_length (chain)))
return NULL_TREE;
location_t loc)
{
tree expr, ltyp;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
tree weak_ivar_layout_tree;
int size;
location_t loc;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
char buf[BUFSIZE];
/* TODO: pass the loc in or find it from args. */
{
tree expr, ltyp;
location_t loc;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
/* TODO: fish the location out of the input data. */
loc = UNKNOWN_LOCATION;
{
tree initlist, ivar_list_template, decl;
int size;
- VEC(constructor_elt,gc) *inits = NULL;
+ vec<constructor_elt, va_gc> *inits = NULL;
if (!chain)
return NULL_TREE;
tree expr;
location_t loc;
struct imp_entry *impent;
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
if (imp_count)
for (impent = imp_list; impent; impent = impent->next)
static tree
init_objc_symtab (tree type)
{
- VEC(constructor_elt,gc) *v = NULL;
+ vec<constructor_elt, va_gc> *v = NULL;
/* sel_ref_cnt = { ..., 5, ... } */
init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
}
+/* Any target implementing NeXT ObjC m32 ABI has to ensure that objects
+ refer to, and define, symbols that enforce linkage of classes into the
+ executable image, preserving unix archive semantics.
+
+ At present (4.8), the only targets implementing this are Darwin; these
+ use top level asms to implement a scheme (see config/darwin-c.c). The
+ latter method is a hack, but compatible with LTO see also PR48109 for
+ further discussion and other possible methods. */
static void
-handle_next_class_ref (tree chain)
+handle_next_class_ref (tree chain ATTRIBUTE_UNUSED)
{
- const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
- char *string = (char *) alloca (strlen (name) + 30);
-
- sprintf (string, ".objc_class_name_%s", name);
-
-#ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
- ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
-#else
- return ; /* NULL build for targets other than Darwin. */
-#endif
+ if (targetcm.objc_declare_unresolved_class_reference)
+ {
+ const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
+ char *string = (char *) alloca (strlen (name) + 30);
+ sprintf (string, ".objc_class_name_%s", name);
+ targetcm.objc_declare_unresolved_class_reference (string);
+ }
}
static void
-handle_next_impent (struct imp_entry *impent)
+handle_next_impent (struct imp_entry *impent ATTRIBUTE_UNUSED)
{
- char buf[BUFSIZE];
-
- switch (TREE_CODE (impent->imp_context))
+ if (targetcm.objc_declare_class_definition)
{
- case CLASS_IMPLEMENTATION_TYPE:
- snprintf (buf, BUFSIZE, ".objc_class_name_%s",
- IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
- break;
- case CATEGORY_IMPLEMENTATION_TYPE:
- snprintf (buf, BUFSIZE, "*.objc_category_name_%s_%s",
- IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)),
- IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)));
- break;
- default:
- return;
- }
+ char buf[BUFSIZE];
-#ifdef ASM_DECLARE_CLASS_REFERENCE
- ASM_DECLARE_CLASS_REFERENCE (asm_out_file, buf);
-#else
- return ; /* NULL build for targets other than Darwin. */
-#endif
+ switch (TREE_CODE (impent->imp_context))
+ {
+ case CLASS_IMPLEMENTATION_TYPE:
+ snprintf (buf, BUFSIZE, ".objc_class_name_%s",
+ IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
+ break;
+ case CATEGORY_IMPLEMENTATION_TYPE:
+ snprintf (buf, BUFSIZE, "*.objc_category_name_%s_%s",
+ IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)),
+ IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)));
+ break;
+ default:
+ return;
+ }
+ targetcm.objc_declare_class_definition (buf);
+ }
}
static void
return;
}
-
-/* The Fix-and-Continue functionality available in Mac OS X 10.3 and
- later requires that ObjC translation units participating in F&C be
- specially marked. The following routine accomplishes this. */
-
-/* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
-
-static void
-generate_objc_image_info (void)
-{
- tree decl;
- int flags
- = ((flag_replace_objc_classes && imp_count ? 1 : 0)
- | (flag_objc_gc ? 2 : 0));
- VEC(constructor_elt,gc) *v = NULL;
- tree array_type;
-
- array_type = build_sized_array_type (integer_type_node, 2);
-
- decl = start_var_decl (array_type, "_OBJC_ImageInfo");
-
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
- CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
- /* The runtime wants this and refers to it in a manner hidden from the compiler.
- So we must force the output. */
- DECL_PRESERVE_P (decl) = 1;
- OBJCMETA (decl, objc_meta, meta_info);
- finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
-}
-
static void
objc_generate_v1_next_metadata (void)
{
attr = build_tree_list (objc_meta, meta_modules);
build_module_descriptor (vers, attr);
- /* This conveys information on GC usage and zero-link. */
- generate_objc_image_info ();
-
/* Dump the class references. This forces the appropriate classes
to be linked into the executable image, preserving unix archive
- semantics. This can be removed when we move to a more dynamically
- linked environment. */
-
+ semantics. */
for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
{
handle_next_class_ref (chain);
we use c++'s typeinfo decl. */
return build_eh_type_type (type);
#else
- error ("non-objective-c type '%T' cannot be caught", type);
+ error ("non-objective-c type %qT cannot be caught", type);
ident = get_identifier ("ErrorMarkNode");
goto make_err_class;
#endif
return eh_id;
}
+/* For NeXT ABI 0 and 1, the personality routines are just those of the
+ underlying language. */
+
static tree
objc_eh_personality (void)
{
if (!objc_eh_personality_decl)
#ifndef OBJCPLUS
- objc_eh_personality_decl = build_personality_function ("objc");
+ objc_eh_personality_decl = build_personality_function ("gcc");
#else
objc_eh_personality_decl = build_personality_function ("gxx");
#endif
build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
{
tree t;
- VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
+ vec<tree, va_gc> *parms;
+ vec_alloc (parms, 1);
/* A throw is just a call to the runtime throw function with the
object as a parameter. */
- VEC_quick_push (tree, parms, throw_expr);
- t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
- VEC_free (tree, gc, parms);
+ parms->quick_push (throw_expr);
+ t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl, parms,
+ NULL);
+ vec_free (parms);
return add_stmt (t);
}
else
{
tree t;
- t = built_in_decls[BUILT_IN_EH_POINTER];
+ t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
t = build_call_expr (t, 1, integer_zero_node);
return fold_convert (objc_object_type, t);
}