diff options
Diffstat (limited to 'gcc-4.8/gcc/objc/objc-next-runtime-abi-01.c')
| -rw-r--r-- | gcc-4.8/gcc/objc/objc-next-runtime-abi-01.c | 2953 | 
1 files changed, 0 insertions, 2953 deletions
| diff --git a/gcc-4.8/gcc/objc/objc-next-runtime-abi-01.c b/gcc-4.8/gcc/objc/objc-next-runtime-abi-01.c deleted file mode 100644 index 63af0e4..0000000 --- a/gcc-4.8/gcc/objc/objc-next-runtime-abi-01.c +++ /dev/null @@ -1,2953 +0,0 @@ -/* Next Runtime (ABI-0/1) private. -   Copyright (C) 2011-2013 Free Software Foundation, Inc. -   Contributed by Iain Sandoe (split from objc-act.c) - -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 3, or (at your option) -any later version. - -GCC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -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 COPYING3.  If not see -<http://www.gnu.org/licenses/>.  */ - -/* This implements the original NeXT ABI (0) used for m32 code and -   indicated by module version 6.  It also implements the small number -   of additions made for properties and optional protocol methods as -   ABI=1 (module version 7).  */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tree.h" - -#ifdef OBJCPLUS -#include "cp/cp-tree.h" -#else -#include "c/c-tree.h" -#include "c/c-lang.h" -#endif -#include "langhooks.h" -#include "c-family/c-objc.h" -#include "objc-act.h" - -/* 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 -#define OBJCP_REMAP_FUNCTIONS -#include "objcp-decl.h" -#endif  /* OBJCPLUS */ - -#include "ggc.h" -#include "target.h" -#include "c-family/c-target.h" -#include "tree-iterator.h" - -#include "objc-runtime-hooks.h" -#include "objc-runtime-shared-support.h" -#include "objc-encoding.h" - -/* NeXT ABI 0 and 1 private definitions.  */ -#define DEF_CONSTANT_STRING_CLASS_NAME "NSConstantString" - -#define TAG_GETCLASS			"objc_getClass" -#define TAG_GETMETACLASS		"objc_getMetaClass" - -#define TAG_MSGSEND			"objc_msgSend" -#define TAG_MSGSENDSUPER		"objc_msgSendSuper" -#define TAG_MSGSEND_STRET		"objc_msgSend_stret" -#define TAG_MSGSENDSUPER_STRET		"objc_msgSendSuper_stret" - -/* NeXT-specific tags.  */ - -#define TAG_MSGSEND_NONNIL		"objc_msgSendNonNil" -#define TAG_MSGSEND_NONNIL_STRET	"objc_msgSendNonNil_stret" -#define TAG_EXCEPTIONEXTRACT		"objc_exception_extract" -#define TAG_EXCEPTIONTRYENTER		"objc_exception_try_enter" -#define TAG_EXCEPTIONTRYEXIT		"objc_exception_try_exit" -#define TAG_EXCEPTIONMATCH		"objc_exception_match" -#define TAG_SETJMP			"_setjmp" - -#define TAG_ASSIGNIVAR			"objc_assign_ivar" -#define TAG_ASSIGNGLOBAL		"objc_assign_global" -#define TAG_ASSIGNSTRONGCAST		"objc_assign_strongCast" - -/* Branch entry points.  All that matters here are the addresses; -   functions with these names do not really exist in libobjc.  */ - -#define TAG_MSGSEND_FAST		"objc_msgSend_Fast" -#define TAG_ASSIGNIVAR_FAST		"objc_assign_ivar_Fast" - -/* The version identifies which language generation and runtime the -   module (file) was compiled for, and is recorded in the module -   descriptor.  */ -#define OBJC_VERSION			(flag_objc_abi >= 1 ? 7 : 6) - -#define UTAG_CLASS_EXT			"_objc_class_ext" -#define UTAG_PROPERTY_LIST		"_prop_list_t" -#define UTAG_PROTOCOL_EXT		"_objc_protocol_extension" - -#define CLS_HAS_CXX_STRUCTORS		0x2000L - -/* rt_trees identifiers - shared between NeXT implementations.  These -   allow the FE to tag meta-data in a manner that survives LTO and can -   be used when the runtime requires that certain meta-data items -   appear in particular named sections.  */ - -#include "objc-next-metadata-tags.h" -extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX]; - -static void next_runtime_01_initialize (void); - -static tree next_runtime_abi_01_super_superclassfield_id (void); - -static tree next_runtime_abi_01_class_decl (tree); -static tree next_runtime_abi_01_metaclass_decl (tree); -static tree next_runtime_abi_01_category_decl (tree); -static tree next_runtime_abi_01_protocol_decl (tree); -static tree next_runtime_abi_01_string_decl (tree, const char *, string_section); - -static tree next_runtime_abi_01_get_class_reference (tree); -static tree next_runtime_abi_01_build_selector_reference (location_t, tree, tree); -static tree next_runtime_abi_01_get_protocol_reference (location_t, tree); -static tree next_runtime_abi_01_build_ivar_ref (location_t, tree, tree); -static tree next_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool); -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, 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); -static tree next_runtime_abi_01_build_const_string_constructor (location_t, tree, int); - -static void objc_generate_v1_next_metadata (void); - -static void build_next_objc_exception_stuff (void); -static tree objc_eh_runtime_type (tree type); -static tree objc_eh_personality (void); -static tree build_throw_stmt (location_t, tree, bool); -static tree objc_build_exc_ptr (struct objc_try_context **); -static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool); -static void finish_catch (struct objc_try_context **, tree); -static tree finish_try_stmt (struct objc_try_context **); - -bool -objc_next_runtime_abi_01_init (objc_runtime_hooks *rthooks) -{ -  if (flag_objc_exceptions -      && !flag_objc_sjlj_exceptions) -    { -      warning_at (UNKNOWN_LOCATION, OPT_Wall, -		"%<-fobjc-sjlj-exceptions%> is the only supported exceptions " -		"system for %<-fnext-runtime%> with %<-fobjc-abi-version%> < 2"); -    } - -  rthooks->initialize = next_runtime_01_initialize; -  rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME; -  rthooks->tag_getclass = TAG_GETCLASS; -  rthooks->super_superclassfield_ident = next_runtime_abi_01_super_superclassfield_id; - -  rthooks->class_decl = next_runtime_abi_01_class_decl; -  rthooks->metaclass_decl = next_runtime_abi_01_metaclass_decl; -  rthooks->category_decl = next_runtime_abi_01_category_decl; -  rthooks->protocol_decl = next_runtime_abi_01_protocol_decl; -  rthooks->string_decl = next_runtime_abi_01_string_decl; - -  rthooks->get_class_reference = next_runtime_abi_01_get_class_reference; -  rthooks->build_selector_reference = next_runtime_abi_01_build_selector_reference; -  rthooks->get_protocol_reference = next_runtime_abi_01_get_protocol_reference; -  rthooks->build_ivar_reference = next_runtime_abi_01_build_ivar_ref; -  rthooks->get_class_super_ref = next_runtime_abi_01_get_class_super_ref; -  rthooks->get_category_super_ref = next_runtime_abi_01_get_category_super_ref; - -  rthooks->receiver_is_class_object = next_runtime_abi_01_receiver_is_class_object; -  rthooks->get_arg_type_list_base = next_runtime_abi_01_get_arg_type_list_base; -  rthooks->build_objc_method_call = next_runtime_abi_01_build_objc_method_call; - -  rthooks->setup_const_string_class_decl = -				next_runtime_abi_01_setup_const_string_class_decl; -  rthooks->build_const_string_constructor = -				next_runtime_abi_01_build_const_string_constructor; - -  rthooks->build_throw_stmt = build_throw_stmt; -  rthooks->build_exc_ptr = objc_build_exc_ptr; -  rthooks->begin_catch = begin_catch; -  rthooks->finish_catch = finish_catch; -  rthooks->finish_try_stmt = finish_try_stmt; - -  rthooks->generate_metadata = objc_generate_v1_next_metadata; -  return true; -} - -/* We need a way to convey what kind of meta-data are represented by a -   given variable, since each type is expected (by the runtime) to be -   found in a specific named section.  The solution must be usable -   with LTO. - -   The scheme used for NeXT ABI 0/1 (partial matching of variable -   names) is not satisfactory for LTO & ABI-2.  We now tag ObjC -   meta-data with identification attributes in the front end.  The -   back-end may choose to act on these as it requires.  */ - -static void -next_runtime_abi_01_init_metadata_attributes (void) -{ -  if (!objc_meta) -    objc_meta = get_identifier ("OBJC1META"); - -  if (!meta_base) -    meta_base = get_identifier ("V1_BASE"); - -  meta_class = get_identifier ("V1_CLAS"); -  meta_metaclass = get_identifier ("V1_META"); -  meta_category = get_identifier ("V1_CATG"); -  meta_protocol = get_identifier ("V1_PROT"); - -  meta_clac_vars = get_identifier ("V1_CLCV"); -  meta_clai_vars = get_identifier ("V1_CLIV"); - -  meta_clac_meth = get_identifier ("V1_CLCM"); -  meta_clai_meth = get_identifier ("V1_CLIM"); -  meta_catc_meth = get_identifier ("V1_CACM"); -  meta_cati_meth = get_identifier ("V1_CAIM"); -  meta_proto_cls_meth = get_identifier ("V1_PCLM"); -  meta_proto_nst_meth = get_identifier ("V1_PNSM"); - -  meta_clas_prot = get_identifier ("V1_CLPR"); -  meta_catg_prot = get_identifier ("V1_CAPR"); - -  meta_class_reference = get_identifier ("V1_CLRF"); -  meta_proto_ref = get_identifier ("V1_PRFS"); -  meta_sel_refs = get_identifier ("V1_SRFS"); - -  meta_class_name = get_identifier ("V1_CLSN"); -  meta_meth_name = get_identifier ("V1_METN"); -  meta_meth_type = get_identifier ("V1_METT"); -  meta_prop_name_attr = get_identifier ("V1_STRG"); - -  meta_modules = get_identifier ("V1_MODU"); -  meta_symtab = get_identifier ("V1_SYMT"); -  meta_info = get_identifier ("V1_INFO"); - -  meta_proplist = get_identifier ("V1_PLST"); -  meta_protocol_extension = get_identifier ("V1_PEXT"); -  meta_class_extension = get_identifier ("V1_CEXT"); - -  meta_const_str = get_identifier ("V1_CSTR"); -} - -static void build_v1_class_template (void); -static void build_v1_category_template (void); -static void build_v1_protocol_template (void); - -static void next_runtime_01_initialize (void) -{ -  tree type; - -#ifdef OBJCPLUS -  /* For all NeXT objc ABIs -fobjc-call-cxx-cdtors is on by -     default.  */ -  if (!global_options_set.x_flag_objc_call_cxx_cdtors) -    global_options.x_flag_objc_call_cxx_cdtors = 1; -#endif - -  /* Set up attributes to be attached to the meta-data so that they -     will be placed in the correct sections.  */ -  next_runtime_abi_01_init_metadata_attributes (); - -  if (flag_objc_abi >= 1) -    objc_prop_list_ptr = build_pointer_type (xref_tag (RECORD_TYPE, -					     get_identifier ("_prop_list_t"))); - - /* Declare type of selector-objects that represent an operation -    name.  */ -  /* `struct objc_selector *' */ -  objc_selector_type = build_pointer_type (xref_tag (RECORD_TYPE, -					   get_identifier (TAG_SELECTOR))); - -  build_v1_class_template (); -  build_super_template (); -  build_v1_protocol_template (); -  build_v1_category_template (); - -  /* NB: In order to call one of the ..._stret (struct-returning) -     functions, the function *MUST* first be cast to a signature that -     corresponds to the actual ObjC method being invoked.  This is -     what is done by the build_objc_method_call() routine below.  */ - -  /* id objc_msgSend (id, SEL, ...); */ -  /* id objc_msgSendNonNil (id, SEL, ...); */ -  /* id objc_msgSend_stret (id, SEL, ...); */ -  /* id objc_msgSendNonNil_stret (id, SEL, ...); */ -  type = build_varargs_function_type_list (objc_object_type, -					   objc_object_type, -					   objc_selector_type, -					   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 = 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 available.  */ -  umsg_fast_decl = umsg_decl; -#endif - -  /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */ -  /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */ -  type = build_varargs_function_type_list (objc_object_type, -                                            objc_super_type, -                                            objc_selector_type, -                                            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; - -  type = build_function_type_list (objc_object_type, -                                   const_string_type_node, -                                   NULL_TREE); - -  /* id objc_getClass (const char *); */ -  objc_get_class_decl -    = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN, -			    NULL, NULL_TREE); - -  /* id objc_getMetaClass (const char *); */ -  objc_get_meta_class_decl -    = add_builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE); - -  /* This is the type of all of the following functions -     objc_copyStruct().  */ -  type = build_function_type_list (void_type_node, -				   ptr_type_node, -				   const_ptr_type_node, -				   ptrdiff_type_node, -				   boolean_type_node, -				   boolean_type_node, -				   NULL_TREE); -  /* Declare the following function: -	 void -         objc_copyStruct (void *destination, const void *source, -	                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */ -  objc_copyStruct_decl = add_builtin_function ("objc_copyStruct", -						   type, 0, NOT_BUILT_IN, -						   NULL, NULL_TREE); -  TREE_NOTHROW (objc_copyStruct_decl) = 0; -  objc_getPropertyStruct_decl = NULL_TREE; -  objc_setPropertyStruct_decl = NULL_TREE; - -  build_next_objc_exception_stuff (); -  if (flag_objc_exceptions && !flag_objc_sjlj_exceptions) -    using_eh_for_cleanups (); -  lang_hooks.eh_runtime_type = objc_eh_runtime_type; -  lang_hooks.eh_personality = objc_eh_personality; -} - -/* --- templates --- */ - -/* struct _objc_class -   { -     struct _objc_class *isa; -     struct _objc_class *super_class; -     char *name; -     long version; -     long info; -     long instance_size; -     struct _objc_ivar_list *ivars; -     struct _objc_method_list *methods; -     struct objc_cache *cache; -     struct _objc_protocol_list *protocols; -   #if ABI=1 -     const char *ivar_layout; -     struct _objc_class_ext *ext; -   #else -     void *sel_id; -     void *gc_object_type; -    #endif -   }; */ - -/* The 'sel_id' & 'gc_object_type' fields are not used by the NeXT -   runtime.  We generate them for ABI==0 to maintain backward binary -   compatibility.  */ - -static void -build_v1_class_template (void) -{ -  tree ptype, decls, *chain = NULL; - -  objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS)); - -  /* struct _objc_class *isa; */ -  decls = add_field_decl (build_pointer_type (objc_class_template), -			  "isa", &chain); - -  /* struct _objc_class *super_class; */ -  add_field_decl (build_pointer_type (objc_class_template), -		  "super_class", &chain); - -  /* char *name; */ -  add_field_decl (string_type_node, "name", &chain); - -  /* long version; */ -  add_field_decl (long_integer_type_node, "version", &chain); - -  /* long info; */ -  add_field_decl (long_integer_type_node, "info", &chain); - -  /* long instance_size; */ -  add_field_decl (long_integer_type_node, "instance_size", &chain); - -  /* struct _objc_ivar_list *ivars; */ -  add_field_decl (objc_ivar_list_ptr,"ivars", &chain); - -  /* struct _objc_method_list *methods; */ -  add_field_decl (objc_method_list_ptr, "methods", &chain); - -  /* struct objc_cache *cache; */ -  ptype = build_pointer_type (xref_tag (RECORD_TYPE, -					    get_identifier ("objc_cache"))); -  add_field_decl (ptype, "cache", &chain); - -  /* struct _objc_protocol **protocol_list; */ -  ptype = build_pointer_type (build_pointer_type -			      (xref_tag (RECORD_TYPE, -					 get_identifier (UTAG_PROTOCOL)))); -  add_field_decl (ptype, "protocol_list", &chain); - -  if (flag_objc_abi >= 1) -    { -      /* const char *ivar_layout; */ -      add_field_decl (const_string_type_node, "ivar_layout", &chain); - -      /* struct _objc_class_ext *ext; */ -      ptype = build_pointer_type (xref_tag (RECORD_TYPE, -					    get_identifier (UTAG_CLASS_EXT))); -      add_field_decl (ptype, "ext", &chain); -    } -  else -    { -      /* void *sel_id; */ -      add_field_decl (build_pointer_type (void_type_node), "sel_id", &chain); -      /* void *gc_object_type; */ -      add_field_decl (build_pointer_type (void_type_node), "gc_object_type", -		      &chain); -    } - -  objc_finish_struct (objc_class_template, decls); -} - -/* struct _objc_category -   { -     char *category_name; -     char *class_name; -     struct _objc_method_list *instance_methods; -     struct _objc_method_list *class_methods; -     struct _objc_protocol_list *protocols; -   #if ABI=1 -     uint32_t size;	// sizeof (struct _objc_category) -     struct _objc_property_list *instance_properties;  // category's own @property decl. -   #endif -   };   */ - -static void -build_v1_category_template (void) -{ -  tree ptype, decls, *chain = NULL; - -  objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY)); - -  /* char *category_name; */ -  decls = add_field_decl (string_type_node, "category_name", &chain); - -  /* char *class_name; */ -  add_field_decl (string_type_node, "class_name", &chain); - -  /* struct _objc_method_list *instance_methods; */ -  add_field_decl (objc_method_list_ptr, "instance_methods", &chain); - -  /* struct _objc_method_list *class_methods; */ -  add_field_decl (objc_method_list_ptr, "class_methods", &chain); - -  /* struct _objc_protocol **protocol_list; */ -  ptype = build_pointer_type (build_pointer_type (objc_protocol_template)); -  add_field_decl (ptype, "protocol_list", &chain); - -  if (flag_objc_abi >= 1) -    { -      add_field_decl (integer_type_node, "size", &chain); - -      /* struct _objc_property_list *instance_properties; -         This field describes a category's @property declarations. -         Properties from inherited protocols are not included.  */ -      ptype = build_pointer_type (xref_tag (RECORD_TYPE, -					    get_identifier (UTAG_PROPERTY_LIST))); -      add_field_decl (ptype, "instance_properties", &chain); -    } -  objc_finish_struct (objc_category_template, decls); -} - -/* Begin code generation for protocols... -   Modified for ObjC #1 extensions.  */ - -/* struct _objc_protocol -   { -   #if ABI=1 -     struct _objc_protocol_extension *isa; -   #else -     struct _objc_class *isa; -   #endif - -     char *protocol_name; -     struct _objc_protocol **protocol_list; -     struct _objc__method_prototype_list *instance_methods; -     struct _objc__method_prototype_list *class_methods; -   }; */ - -static void -build_v1_protocol_template (void) -{ -  tree ptype, decls, *chain = NULL; - -  objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL)); - -  if (flag_objc_abi >= 1) -    /* struct _objc_protocol_extension *isa; */ -    ptype = build_pointer_type (xref_tag (RECORD_TYPE, -					  get_identifier (UTAG_PROTOCOL_EXT))); -  else -    /* struct _objc_class *isa; */ -    ptype = build_pointer_type (xref_tag (RECORD_TYPE, -					get_identifier (UTAG_CLASS))); - -  decls = add_field_decl (ptype, "isa", &chain); - -  /* char *protocol_name; */ -  add_field_decl (string_type_node, "protocol_name", &chain); - -  /* struct _objc_protocol **protocol_list; */ -  ptype = build_pointer_type (build_pointer_type (objc_protocol_template)); -  add_field_decl (ptype, "protocol_list", &chain); - -  /* struct _objc__method_prototype_list *instance_methods; */ -  add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain); - -  /* struct _objc__method_prototype_list *class_methods; */ -  add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain); - -  objc_finish_struct (objc_protocol_template, decls); -} - -/* --- names, decls identifers --- */ - -static tree -next_runtime_abi_01_super_superclassfield_id (void) -{ -  if (!super_superclassfield_id) -    super_superclassfield_id = get_identifier ("super_class"); -  return super_superclassfield_id; -} - -static tree -next_runtime_abi_01_class_decl (tree klass) -{ -  tree decl; -  char buf[BUFSIZE]; -  snprintf (buf, BUFSIZE, "_OBJC_Class_%s", -	    IDENTIFIER_POINTER (CLASS_NAME (klass))); -  decl = start_var_decl (objc_class_template, buf); -  OBJCMETA (decl, objc_meta, meta_class); -  return decl; -} - -static tree -next_runtime_abi_01_metaclass_decl (tree klass) -{ -  tree decl; -  char buf[BUFSIZE]; -  snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s", -	    IDENTIFIER_POINTER (CLASS_NAME (klass))); -  decl = start_var_decl (objc_class_template, buf); -  OBJCMETA (decl, objc_meta, meta_metaclass); -  return decl; -} - -static tree -next_runtime_abi_01_category_decl (tree klass) -{ -  tree decl; -  char buf[BUFSIZE]; -  snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s", -	    IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)), -	    IDENTIFIER_POINTER (CLASS_NAME (klass))); -  decl = start_var_decl (objc_category_template, buf); -  OBJCMETA (decl, objc_meta, meta_category); -  return decl; -} - -static tree -next_runtime_abi_01_protocol_decl (tree p) -{ -  tree decl; -  char buf[BUFSIZE]; - -  /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */ - -  snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s", -	    IDENTIFIER_POINTER (PROTOCOL_NAME (p))); -  decl = start_var_decl (objc_protocol_template, buf); -  OBJCMETA (decl, objc_meta, meta_protocol); -  return decl; -} - -static tree -next_runtime_abi_01_string_decl (tree type, const char *name,  string_section where) -{ -  tree var = start_var_decl (type, name); -  switch (where) -    { -      case class_names: -	OBJCMETA (var, objc_meta, meta_class_name); -	break; -      case meth_var_names: -	OBJCMETA (var, objc_meta, meta_meth_name); -	break; -      case meth_var_types: -	OBJCMETA (var, objc_meta, meta_meth_type); -	break; -      case prop_names_attr: -	OBJCMETA (var, objc_meta, meta_prop_name_attr); -	break; -      default: -	OBJCMETA (var, objc_meta, meta_base); -	break; -    } -  return var; -} - -/* --- entry --- */ - -static GTY(()) int class_reference_idx; - -static tree -build_class_reference_decl (void) -{ -  tree decl; -  char buf[BUFSIZE]; - -  sprintf (buf, "_OBJC_ClassRefs_%d", class_reference_idx++); -  decl = start_var_decl (objc_class_type, buf); - -  return decl; -} - -static tree -next_runtime_abi_01_get_class_reference (tree ident) -{ -  if (!flag_zero_link) -    { -      tree *chain; -      tree decl; - -      for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain)) -	if (TREE_VALUE (*chain) == ident) -	  { -	    if (! TREE_PURPOSE (*chain)) -	      TREE_PURPOSE (*chain) = build_class_reference_decl (); - -	    return TREE_PURPOSE (*chain); -	  } - -      decl = build_class_reference_decl (); -      *chain = tree_cons (decl, ident, NULL_TREE); -      return decl; -    } -  else -    { -      tree params; - -      add_class_reference (ident); - -      params = build_tree_list (NULL_TREE, -				my_build_string_pointer -				(IDENTIFIER_LENGTH (ident) + 1, -				 IDENTIFIER_POINTER (ident))); - -      return build_function_call (input_location, objc_get_class_decl, params); -    } -} - -/* Used by build_function_type_for_method.  Append the types for -   receiver & _cmd at the start of a method argument list to ARGTYPES. -   CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are -   trying to define a method or call one.  SUPERFLAG says this is for a -   send to super.  METH may be NULL, in the case that there is no -   prototype.  */ - -static void -next_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes, -					    tree meth, int context, -					    int superflag) -{ -  tree receiver_type; - -  if (superflag) -    receiver_type = objc_super_type; -  else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL) -    receiver_type = objc_instance_type; -  else -    receiver_type = objc_object_type; - -  vec_safe_push (*argtypes, receiver_type); -  /* Selector type - will eventually change to `int'.  */ -  vec_safe_push (*argtypes, objc_selector_type); -} - -static tree -next_runtime_abi_01_receiver_is_class_object (tree receiver) -{ -  if (TREE_CODE (receiver) == VAR_DECL -      && IS_CLASS (TREE_TYPE (receiver))) -    { -      /* The receiver is a variable created by build_class_reference_decl.  */ -      tree chain = cls_ref_chain ; -      /* Look up the identifier in the relevant chain.  */ -      for (; chain; chain = TREE_CHAIN (chain)) -	if (TREE_PURPOSE (chain) == receiver) -	  return TREE_VALUE (chain); -    } -  return NULL_TREE; -} - -static tree -build_selector_reference_decl (tree ident) -{ -  tree decl; -  char *t, buf[BUFSIZE]; - -  snprintf (buf, BUFSIZE, "_OBJC_SelRef_%s", IDENTIFIER_POINTER (ident)); -  t = buf; -  while (*t) -    { -      if (*t==':') -        *t = '$'; /* Underscore would clash between foo:bar and foo_bar.  */ -      t++; -    } -  decl = start_var_decl (objc_selector_type, buf); -  OBJCMETA (decl, objc_meta, meta_sel_refs); -  return decl; -} - -static tree -next_runtime_abi_01_build_selector_reference (location_t loc ATTRIBUTE_UNUSED, -					      tree ident, -					      tree proto ATTRIBUTE_UNUSED) -{ -  tree *chain = &sel_ref_chain; -  tree expr; - -  while (*chain) -    { -      if (TREE_VALUE (*chain) == ident) -	return TREE_PURPOSE (*chain); - -      chain = &TREE_CHAIN (*chain); -    } - -  expr = build_selector_reference_decl (ident); - -  *chain = tree_cons (expr, ident, NULL_TREE); - -  return expr; -} - -/* Build a tree expression to send OBJECT the operation SELECTOR, -   looking up the method on object LOOKUP_OBJECT (often same as OBJECT), -   assuming the method has prototype METHOD_PROTOTYPE. -   (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.) -   LOC is the location of the expression to build. -   Use METHOD_PARAMS as list of args to pass to the method. -   If SUPER_FLAG is nonzero, we look up the superclass's method.  */ - -static tree -build_objc_method_call (location_t loc, int super_flag, tree method_prototype, -			tree lookup_object, tree selector, -			tree method_params) -{ -  tree sender, sender_cast, method, t; -  tree rcv_p = (super_flag ? objc_super_type : objc_object_type); -  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 -     the sender's return type and arguments to match that of the method. -     Otherwise, leave sender as is.  */ -  tree ret_type -    = (method_prototype -       ? TREE_VALUE (TREE_TYPE (method_prototype)) -       : objc_object_type); -  tree ftype = build_function_type_for_method (ret_type, method_prototype, -					       METHOD_REF, super_flag); - -  if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype)) -    ftype = build_type_attribute_variant (ftype, -					  METHOD_TYPE_ATTRIBUTES -					  (method_prototype)); - -  sender_cast = build_pointer_type (ftype); - -  lookup_object = build_c_cast (loc, rcv_p, lookup_object); - -  /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */ -  lookup_object = save_expr (lookup_object); - -  /* Param list + 2 slots for object and selector.  */ -  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 -     argument, then change which messenger entry point this -     expr will call.  NB: Note that sender_cast remains -     unchanged (it already has a struct return type).  */ -  if (!targetm.calls.struct_value_rtx (0, 0) -      && (TREE_CODE (ret_type) == RECORD_TYPE -	  || TREE_CODE (ret_type) == UNION_TYPE) -      && targetm.calls.return_in_memory (ret_type, 0)) -    sender = (super_flag ? umsg_super_stret_decl -			 : flag_nil_receivers ? umsg_stret_decl -					      : umsg_nonnil_stret_decl); -  else -    sender = (super_flag ? umsg_super_decl -			 : (flag_nil_receivers  ? (flag_objc_direct_dispatch -							? umsg_fast_decl -							: umsg_decl) -						: umsg_nonnil_decl)); -  method = build_fold_addr_expr_loc (loc, sender); - -  /* Pass the object to the method.  */ -  parms->quick_push (lookup_object); -  /* Pass the selector to the method.  */ -  parms->quick_push (selector); -  /* Now append the remainder of the parms.  */ -  if (nparm) -    for (; method_params; method_params = TREE_CHAIN (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 (parms); -  return t; -} - -static tree -next_runtime_abi_01_build_objc_method_call (location_t loc, -					    tree method_prototype, -					    tree receiver, -					    tree rtype ATTRIBUTE_UNUSED, -					    tree sel_name, -					    tree method_params, -					    int super) -{ -  tree selector = next_runtime_abi_01_build_selector_reference (loc, sel_name, -								NULL_TREE); - -  return build_objc_method_call (loc, super, method_prototype, -				 receiver, selector, method_params); -} - -static tree -next_runtime_abi_01_get_protocol_reference (location_t loc, tree p) -{ -  tree expr; - -  if (!PROTOCOL_FORWARD_DECL (p)) -    PROTOCOL_FORWARD_DECL (p) = next_runtime_abi_01_protocol_decl (p); - -  expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); -  return convert (objc_protocol_type, expr); -} - -/* For ABI 0/1 and IVAR is just a fixed offset in the class struct.  */ - -static tree -next_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED, -				   tree base, tree id) -{ -  return objc_build_component_ref (base, id); -} - -/* We build super class references as we need them (but keep them once -   built for the sake of efficiency).  */ - -static tree -next_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED, -					 struct imp_entry *imp, bool inst_meth) -{ -  if (inst_meth) -    { -      if (!ucls_super_ref) -	ucls_super_ref = -		objc_build_component_ref (imp->class_decl, -					  get_identifier ("super_class")); -	return ucls_super_ref; -    } -  else -    { -      if (!uucls_super_ref) -	uucls_super_ref = -		objc_build_component_ref (imp->meta_decl, -					  get_identifier ("super_class")); -	return uucls_super_ref; -    } -} - -static tree -next_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED, -					   struct imp_entry *imp, bool inst_meth) -{ -  tree super_name = CLASS_SUPER_NAME (imp->imp_template); -  tree super_class; - -  if (!flag_zero_link) -    { -      super_class = objc_get_class_reference (super_name); - -      if (!inst_meth) - -	/* If we are in a class method, we must retrieve the -	   _metaclass_ for the current class, pointed at by -	   the class's "isa" pointer.  The following assumes that -	   "isa" is the first ivar in a class (which it must be).  */ -	   super_class = -		build_indirect_ref (input_location, -				    build_c_cast (input_location, -					build_pointer_type (objc_class_type), -					super_class), -				    RO_UNARY_STAR); -      return super_class; -    } - -  /* else do it the slow way.  */ -  add_class_reference (super_name); -  super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl); -  super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1, -					IDENTIFIER_POINTER (super_name)); -  /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */ -  return build_function_call (input_location, -			      super_class, -			      build_tree_list (NULL_TREE, super_name)); -} - -static bool -next_runtime_abi_01_setup_const_string_class_decl (void) -{ -  if (!constant_string_global_id) -    { -      /* Hopefully, this should not represent a serious limitation.  */ -      char buf[BUFSIZE]; -      snprintf (buf, BUFSIZE, "_%sClassReference", constant_string_class_name); -      constant_string_global_id = get_identifier (buf); -    } - -  string_class_decl = lookup_name (constant_string_global_id); - -  return (string_class_decl != NULL_TREE); -} - -static tree -next_runtime_abi_01_build_const_string_constructor (location_t loc, tree string, -						   int length) -{ -  tree constructor, fields, var; -  vec<constructor_elt, va_gc> *v = NULL; - -  /* NeXT:   (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length })   */ -  fields = TYPE_FIELDS (internal_const_str_type); -  CONSTRUCTOR_APPEND_ELT (v, fields, -			  build_unary_op (loc, ADDR_EXPR, string_class_decl, 0)); - -  fields = DECL_CHAIN (fields); -  CONSTRUCTOR_APPEND_ELT (v, fields, -			  build_unary_op (loc, ADDR_EXPR, string, 1)); - -  /* ??? check if this should be long.  */ -  fields = DECL_CHAIN (fields); -  CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length)); -  constructor = objc_build_constructor (internal_const_str_type, v); - -  var = build_decl (input_location, CONST_DECL, NULL, TREE_TYPE (constructor)); -  DECL_INITIAL (var) = constructor; -  TREE_STATIC (var) = 1; -  DECL_CONTEXT (var) = NULL; -  OBJCMETA (var, objc_meta, meta_const_str); -  return var; -} - -/* ---  metadata templates --- */ - -/* This routine builds the following type: -   struct _prop_t { -     const char * const name;			// property name -     const char * const attributes;		// comma-delimited, encoded, -						// property attributes -   }; -*/ - -static GTY(()) tree objc_v1_property_template; - -static tree -build_v1_property_template (void) -{ -  tree prop_record; -  tree decls, *chain = NULL; - -  prop_record = objc_start_struct (get_identifier ("_prop_t")); -  /* const char * name */ -  decls = add_field_decl (string_type_node, "name", &chain); - -  /* const char * attribute */ -  add_field_decl (string_type_node, "attribute", &chain); - -  objc_finish_struct (prop_record, decls); -  return prop_record; -} - -/* Build the following type: - -  struct _objc_protocol_extension -    { -      uint32_t size;	// sizeof (struct _objc_protocol_extension) -      struct objc_method_list	*optional_instance_methods; -      struct objc_method_list   *optional_class_methods; -      struct objc_prop_list	*instance_properties; -    } -*/ - -static GTY(()) tree objc_protocol_extension_template; - -static void -build_v1_objc_protocol_extension_template (void) -{ -  tree decls, *chain = NULL; - -  objc_protocol_extension_template = -	objc_start_struct (get_identifier (UTAG_PROTOCOL_EXT)); - -  /*  uint32_t size; */ -  decls = add_field_decl (integer_type_node, "size", &chain); - -  /* struct objc_method_list   *optional_instance_methods; */ -  add_field_decl (objc_method_list_ptr, "optional_instance_methods", &chain); - -  /* struct objc_method_list   *optional_class_methods; */ -  add_field_decl (objc_method_list_ptr, "optional_class_methods", &chain); - -  /* struct objc_prop_list     *instance_properties; */ -  add_field_decl (objc_prop_list_ptr, "instance_properties", &chain); - -  objc_finish_struct (objc_protocol_extension_template, decls); -} - -/* This routine build following struct type: -   struct _objc_class_ext -     { -       uint32_t size;	// sizeof(struct _objc_class_ext) -       const char *weak_ivar_layout; -       struct _prop_list_t *properties; -     } -*/ - -static GTY(()) tree objc_class_ext_template; - -static void -build_objc_class_ext_template (void) -{ -  tree ptrt, decls, *chain = NULL; - -  objc_class_ext_template = objc_start_struct (get_identifier (UTAG_CLASS_EXT)); - -  /* uint32_t size; */ -  decls = add_field_decl (integer_type_node, "size", &chain); - -  /* const char *weak_ivar_layout; */ -  add_field_decl (const_string_type_node, "weak_ivar_layout", &chain); - -  /* struct _prop_list_t *properties; */ -  ptrt = build_pointer_type (xref_tag (RECORD_TYPE, -			     get_identifier(UTAG_PROPERTY_LIST))); -  add_field_decl (ptrt, "properties", &chain); - -  objc_finish_struct (objc_class_ext_template, decls); -} - -static void -build_metadata_templates (void) -{ - -  if (!objc_method_template) -    objc_method_template = build_method_template (); - - - -} - -/* --- emit metadata --- */ - -static tree -generate_v1_meth_descriptor_table (tree chain, tree protocol, -				   const char *prefix, tree attr) -{ -  tree method_list_template, initlist, decl; -  int size; -  vec<constructor_elt, va_gc> *v = NULL; -  char buf[BUFSIZE]; - -  if (!chain || !prefix) -    return NULL_TREE; - -  if (!objc_method_prototype_template) -    objc_method_prototype_template = build_method_prototype_template (); - -  size = list_length (chain); -  method_list_template = -	build_method_prototype_list_template (objc_method_prototype_template, -					      size); -  snprintf (buf, BUFSIZE, "%s_%s", prefix, -	    IDENTIFIER_POINTER (PROTOCOL_NAME (protocol))); - -  decl = start_var_decl (method_list_template, buf); - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); -  initlist = -	build_descriptor_table_initializer (objc_method_prototype_template, -					    chain); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); -  /* Get into the right section.  */ -  OBJCMETA (decl, objc_meta, attr); -  finish_var_decl (decl, objc_build_constructor (method_list_template, v)); -  return decl; -} - -/* Build protocol ext = -   {size, opt_instance_meth, opt_class_meth, instance_props}; -   or NULL_TREE if none are present.  */ - -static tree -generate_v1_objc_protocol_extension (tree proto_interface, -				     tree opt_instance_meth, -				     tree opt_class_meth, -				     tree instance_props) -{ -  int size; -  location_t loc; -  vec<constructor_elt, va_gc> *v = NULL; -  tree decl, expr; -  char buf[BUFSIZE]; - -  /* If there are no extensions, then don't bother... */ -  if (!opt_instance_meth && !opt_class_meth && !instance_props) -    return NULL_TREE; - -  if (!objc_protocol_extension_template) -    build_v1_objc_protocol_extension_template (); - -  /* uint32_t size */ -  size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_protocol_extension_template)); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); - -  /* Try for meaningful diagnostics.  */ -  loc = DECL_SOURCE_LOCATION (PROTOCOL_FORWARD_DECL (proto_interface)); - -  /* struct objc_method_list *optional_instance_methods; */ -  if (opt_instance_meth) -    expr = convert (objc_method_list_ptr, -		    build_unary_op (loc, ADDR_EXPR, opt_instance_meth, 0)); -  else -    expr = convert (objc_method_list_ptr, null_pointer_node); - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  /* struct objc_method_list *optional_class_methods; */ -  if (opt_class_meth) -    expr = convert (objc_method_list_ptr, -		    build_unary_op (loc, ADDR_EXPR, opt_class_meth, 0)); -  else -    expr = convert (objc_method_list_ptr, null_pointer_node); - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -  /* struct objc_prop_list *instance_properties; */ -  if (instance_props) -      expr = convert (objc_prop_list_ptr, -		      build_unary_op (loc, ADDR_EXPR, instance_props, 0)); -  else -    expr = convert (objc_prop_list_ptr, null_pointer_node); - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -  snprintf (buf, BUFSIZE, "_OBJC_ProtocolExt_%s", -	    IDENTIFIER_POINTER (PROTOCOL_NAME (proto_interface))); - -  decl = start_var_decl (objc_protocol_extension_template, buf); -  expr = objc_build_constructor (TREE_TYPE (decl), v); -  OBJCMETA (decl, objc_meta, meta_protocol_extension); -  finish_var_decl (decl, expr); -  return decl; -} - -/* This routine builds the following type: -   struct _prop_list_t { -     uint32_t entsize;			// sizeof (struct _prop_t) -     uint32_t prop_count; -     struct _prop_t prop_list [prop_count]; -   } -*/ - -static tree -build_v1_property_list_template (tree list_type, int size) -{ -  tree property_list_t_record; -  tree array_type, decls, *chain = NULL; - -  /* anonymous.  */ -  property_list_t_record = objc_start_struct (NULL_TREE); - -  /* uint32_t const entsize */ -  decls = add_field_decl (integer_type_node, "entsize", &chain); - -  /* int prop_count */ -  add_field_decl (integer_type_node, "prop_count", &chain); - -  /* struct _prop_t prop_list[]; */ -  array_type = build_sized_array_type (list_type, size); -  add_field_decl (array_type, "prop_list", &chain); - -  objc_finish_struct (property_list_t_record, decls); -  return property_list_t_record; -} - -/* This routine builds the initializer list to initialize the -   'struct _prop_t prop_list[]'  field of 'struct _prop_list_t' meta-data. */ - -static tree -build_v1_property_table_initializer (tree type, tree context) -{ -  tree x; -  vec<constructor_elt, va_gc> *inits = NULL; - -  if (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE) -    x = CLASS_PROPERTY_DECL (context); -  else -    x = IMPL_PROPERTY_DECL (context); - -  for (; x; x = TREE_CHAIN (x)) -    { -      vec<constructor_elt, va_gc> *elemlist = NULL; -      tree attribute, name_ident = PROPERTY_NAME (x); - -      CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE, -			      add_objc_string (name_ident, prop_names_attr)); - -      attribute = objc_v2_encode_prop_attr (x); -      CONSTRUCTOR_APPEND_ELT (elemlist, NULL_TREE, -			      add_objc_string (attribute, prop_names_attr)); - -      CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, -			      objc_build_constructor (type, elemlist)); -    } - -  return objc_build_constructor (build_array_type (type, 0),inits); -} - -/* This routine builds the 'struct _prop_list_t' variable declaration and -   initializes it with its initializer list. TYPE is 'struct _prop_list_t', -   NAME is the internal name of this variable, SIZE is number of properties -   for this class and LIST is the initializer list for its 'prop_list' field. */ - -static tree -generate_v1_property_table (tree context, tree klass_ctxt) -{ -  tree x, decl, initlist, property_list_template; -  bool is_proto = false; -  vec<constructor_elt, va_gc> *inits = NULL; -  int init_val, size = 0; -  char buf[BUFSIZE]; - -  if (context) -    { -      gcc_assert (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE); -      x = CLASS_PROPERTY_DECL (context); -      is_proto = true; -    } -  else -    x = IMPL_PROPERTY_DECL (klass_ctxt); - -  for (; x; x = TREE_CHAIN (x)) -    size++; - -  if (size == 0) -    return NULL_TREE; - -  if (!objc_v1_property_template) -    objc_v1_property_template = build_v1_property_template (); - -  property_list_template = -	build_v1_property_list_template (objc_v1_property_template, -					 size); -  initlist = build_v1_property_table_initializer (objc_v1_property_template, -						  is_proto ? context -							   : klass_ctxt); - -  init_val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_v1_property_template)); -  if (is_proto) -    snprintf (buf, BUFSIZE, "_OBJC_ProtocolPropList_%s", -	      IDENTIFIER_POINTER (PROTOCOL_NAME (context))); -  else -    snprintf (buf, BUFSIZE, "_OBJC_ClassPropList_%s", -	      IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt))); - -  decl = start_var_decl (property_list_template, buf); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, init_val)); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size)); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); -  x = objc_build_constructor (TREE_TYPE (decl), inits); -  OBJCMETA (decl, objc_meta, meta_proplist); -  finish_var_decl (decl, x); -  return decl; -} - -static tree -generate_v1_protocol_list (tree i_or_p, tree klass_ctxt) -{ -  tree array_type, ptype, refs_decl, lproto, e, plist, attr; -  int size = 0; -  vec<constructor_elt, va_gc> *v = NULL; -  char buf[BUFSIZE]; - -  switch (TREE_CODE (i_or_p)) -    { -    case CLASS_INTERFACE_TYPE: -    case CATEGORY_INTERFACE_TYPE: -      plist = CLASS_PROTOCOL_LIST (i_or_p); -      break; -    case PROTOCOL_INTERFACE_TYPE: -      plist = PROTOCOL_LIST (i_or_p); -      break; -    default: -      gcc_unreachable (); -    } - -  /* Compute size.  */ -  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) -    if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE -	&& PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) -      size++; - -  /* Build initializer.  */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0)); -  e = build_int_cst (build_pointer_type (objc_protocol_template), size); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); - -  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) -    { -      tree pval = TREE_VALUE (lproto); - -      if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE -	  && PROTOCOL_FORWARD_DECL (pval)) -	{ -	  tree fwref = PROTOCOL_FORWARD_DECL (pval); -	  location_t loc = DECL_SOURCE_LOCATION (fwref) ; -	  e = build_unary_op (loc, ADDR_EXPR, fwref, 0); -          CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e); -	} -    } - -  /* static struct objc_protocol *refs[n]; */ -  switch (TREE_CODE (i_or_p)) -    { -    case PROTOCOL_INTERFACE_TYPE: -      snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s", -		IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p))); -      attr = meta_proto_ref; -      break; -    case CLASS_INTERFACE_TYPE: -      snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s", -		IDENTIFIER_POINTER (CLASS_NAME (i_or_p))); -      attr = meta_clas_prot; -      break; -    case CATEGORY_INTERFACE_TYPE: -      snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s", -		IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)), -		IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt))); -      attr = meta_catg_prot; -      break; -    default: -      gcc_unreachable (); -    } - -  ptype = build_pointer_type (objc_protocol_template); -  array_type = build_sized_array_type (ptype, size + 3); -  refs_decl = start_var_decl (array_type, buf); - -  OBJCMETA (refs_decl, objc_meta, attr); -  finish_var_decl (refs_decl, -                   objc_build_constructor (TREE_TYPE (refs_decl), v)); - -  return refs_decl; -} - -static tree -build_v1_protocol_initializer (tree type, tree protocol_name, tree protocol_list, -			       tree inst_methods, tree class_methods, -			       tree protocol_ext) -{ -  tree expr, ttyp; -  location_t loc; -  vec<constructor_elt, va_gc> *inits = NULL; - -  if (!objc_protocol_extension_template) -    build_v1_objc_protocol_extension_template (); - -  /* TODO: find a better representation of location from the inputs.  */ -  loc = UNKNOWN_LOCATION; -  ttyp = build_pointer_type (objc_protocol_extension_template); -  /* Instead of jamming the protocol version number into the isa, we pass -     either a pointer to the protocol extension - or NULL.  */ -  if (protocol_ext) -    expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, protocol_ext, 0)); -  else -    expr = convert (ttyp, null_pointer_node); - -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list); - -  ttyp = objc_method_proto_list_ptr; -  if (inst_methods) -    expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); -  else -    expr = convert (ttyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); - -  if (class_methods) -    expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); -  else -    expr = convert (ttyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr); - -  return objc_build_constructor (type, inits); -} - -/* An updated version of generate_protocols () that emit the protocol -   extension for ABI=1.  */ - -/* For each protocol which was referenced either from a @protocol() -   expression, or because a class/category implements it (then a -   pointer to the protocol is stored in the struct describing the -   class/category), we create a statically allocated instance of the -   Protocol class.  The code is written in such a way as to generate -   as few Protocol objects as possible; we generate a unique Protocol -   instance for each protocol, and we don't generate a Protocol -   instance if the protocol is never referenced (either from a -   @protocol() or from a class/category implementation).  These -   statically allocated objects can be referred to via the static -   (that is, private to this module) symbols _OBJC_PROTOCOL_n. - -   The statically allocated Protocol objects that we generate here -   need to be fixed up at runtime in order to be used: the 'isa' -   pointer of the objects need to be set up to point to the 'Protocol' -   class, as known at runtime. - -   The NeXT runtime fixes up all protocols at program startup time, -   before main() is entered.  It uses a low-level trick to look up all -   those symbols, then loops on them and fixes them up.  */ - -/* TODO: finish getting rid of passing stuff around in globals.  */ - -static GTY(()) tree V1_Protocol_OPT_NST_METHODS_decl; -static GTY(()) tree V1_Protocol_OPT_CLS_METHODS_decl; -static GTY(()) tree V1_ProtocolExt_decl; -static GTY(()) tree V1_Property_decl; - -static void -generate_v1_protocols (void) -{ -  tree p; - -  /* If a protocol was directly referenced, pull in indirect references.  */ -  for (p = protocol_chain; p; p = TREE_CHAIN (p)) -    if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p)) -      generate_protocol_references (PROTOCOL_LIST (p)); - -  for (p = protocol_chain; p; p = TREE_CHAIN (p)) -    { -      tree decl, encoding, initlist, protocol_name_expr; -      tree refs_type, refs_decl, refs_expr; -      location_t loc; -      tree nst_methods = PROTOCOL_NST_METHODS (p); -      tree cls_methods = PROTOCOL_CLS_METHODS (p); - -      /* If protocol wasn't referenced, don't generate any code.  */ -      decl = PROTOCOL_FORWARD_DECL (p); - -      if (!decl) -	continue; - -      /* Make sure we link in the Protocol class.  */ -      add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); - -      while (nst_methods) -	{ -	  if (! METHOD_ENCODING (nst_methods)) -	    { -	      encoding = encode_method_prototype (nst_methods); -	      METHOD_ENCODING (nst_methods) = encoding; -	    } -	  nst_methods = TREE_CHAIN (nst_methods); -	} - -      UOBJC_INSTANCE_METHODS_decl = -	generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p, -					   "_OBJC_ProtocolInstanceMethods", -					   meta_proto_nst_meth); - -      while (cls_methods) -	{ -	  if (! METHOD_ENCODING (cls_methods)) -	    { -	      encoding = encode_method_prototype (cls_methods); -	      METHOD_ENCODING (cls_methods) = encoding; -	    } - -	  cls_methods = TREE_CHAIN (cls_methods); -	} - -      UOBJC_CLASS_METHODS_decl = -	generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p, -					   "_OBJC_ProtocolClassMethods", -					   meta_proto_cls_meth); - -      /* There should be no optional methods for ABI-0 - but we need to -         check all this here before the lists are made.  */ -      nst_methods = PROTOCOL_OPTIONAL_NST_METHODS (p); -      while (nst_methods) -        { -          if (! METHOD_ENCODING (nst_methods)) -            { -              encoding = encode_method_prototype (nst_methods); -              METHOD_ENCODING (nst_methods) = encoding; -            } -          nst_methods = TREE_CHAIN (nst_methods); -        } - -      V1_Protocol_OPT_NST_METHODS_decl = -	generate_v1_meth_descriptor_table (PROTOCOL_OPTIONAL_NST_METHODS (p), p, -					   "_OBJC_OptionalProtocolInstanceMethods", -					   meta_proto_nst_meth); - -      cls_methods = PROTOCOL_OPTIONAL_CLS_METHODS (p); -      while (cls_methods) -        { -          if (! METHOD_ENCODING (cls_methods)) -            { -              encoding = encode_method_prototype (cls_methods); -              METHOD_ENCODING (cls_methods) = encoding; -            } - -          cls_methods = TREE_CHAIN (cls_methods); -        } - -      V1_Protocol_OPT_CLS_METHODS_decl = -	generate_v1_meth_descriptor_table (PROTOCOL_OPTIONAL_CLS_METHODS (p), p, -					   "_OBJC_OptionalProtocolClassMethods", -					   meta_proto_cls_meth); - -      if (PROTOCOL_LIST (p)) -	refs_decl = generate_v1_protocol_list (p, objc_implementation_context); -      else -	refs_decl = 0; - -      /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */ -      protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names); -      /* TODO: more locations to be fixed up... */ -      loc = UNKNOWN_LOCATION; -      refs_type = -	build_pointer_type (build_pointer_type (objc_protocol_template)); -      if (refs_decl) -	refs_expr = convert (refs_type, -			     build_unary_op (loc, ADDR_EXPR, refs_decl, 0)); -      else -        refs_expr = convert (refs_type, null_pointer_node); - -      if (flag_objc_abi < 1) -	{ -	  /* Original ABI.  */ -	  initlist = -		build_protocol_initializer (TREE_TYPE (decl), -					    protocol_name_expr, refs_expr, -					    UOBJC_INSTANCE_METHODS_decl, -					    UOBJC_CLASS_METHODS_decl); -	  finish_var_decl (decl, initlist); -          continue; -	} - -      /* else - V1 extensions.  */ - -      V1_Property_decl = -		generate_v1_property_table (p, NULL_TREE); - -      V1_ProtocolExt_decl = -	generate_v1_objc_protocol_extension (p, -					     V1_Protocol_OPT_NST_METHODS_decl, -					     V1_Protocol_OPT_CLS_METHODS_decl, -					     V1_Property_decl); - -      initlist = build_v1_protocol_initializer (TREE_TYPE (decl), -						protocol_name_expr, refs_expr, -						UOBJC_INSTANCE_METHODS_decl, -						UOBJC_CLASS_METHODS_decl, -						V1_ProtocolExt_decl); -      finish_var_decl (decl, initlist); -    } -} - -static tree -generate_dispatch_table (tree chain, const char *name, tree attr) -{ -  tree decl, method_list_template, initlist; -  vec<constructor_elt, va_gc> *v = NULL; -  int size;; - -  if (!chain || !name || !(size = list_length (chain))) -    return NULL_TREE; - -  if (!objc_method_template) -    objc_method_template = build_method_template (); - -  method_list_template = build_method_list_template (objc_method_template, -						     size); -  initlist = build_dispatch_table_initializer (objc_method_template, chain); - -  decl = start_var_decl (method_list_template, name); - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -			  build_int_cst (integer_type_node, size)); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist); - -  OBJCMETA (decl, objc_meta, attr); -  finish_var_decl (decl, -		   objc_build_constructor (TREE_TYPE (decl), v)); - -  return decl; -} - -/* Init a category.  */ -static tree -build_v1_category_initializer (tree type, tree cat_name, tree class_name, -				tree inst_methods, tree class_methods, -				tree protocol_list, tree property_list, -				location_t loc) -{ -  tree expr, ltyp; -  vec<constructor_elt, va_gc> *v = NULL; - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name); - -  ltyp = objc_method_list_ptr; -  if (inst_methods) -    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0)); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  if (class_methods) -    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0)); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  /* protocol_list = */ -  ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); -  if (protocol_list) -    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0)); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  if (flag_objc_abi >= 1) -    { -      int val = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_category_template)); -      expr = build_int_cst (NULL_TREE, val); -      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -      ltyp = objc_prop_list_ptr; -      if (property_list) -	expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); -      else -	expr = convert (ltyp, null_pointer_node); -      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -    } - -  return objc_build_constructor (type, v); -} - -/* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */ -/* TODO: get rid of passing stuff around in globals.  */ -static void -generate_v1_category (struct imp_entry *impent) -{ -  tree initlist, cat_name_expr, class_name_expr; -  tree protocol_decl, category, cat_decl; -  tree inst_methods = NULL_TREE, class_methods = NULL_TREE; -  tree cat = impent->imp_context; -  location_t loc; -  char buf[BUFSIZE]; - -  cat_decl = impent->class_decl; -  loc = DECL_SOURCE_LOCATION (cat_decl); - -  add_class_reference (CLASS_NAME (cat)); -  cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names); -  class_name_expr = add_objc_string (CLASS_NAME (cat), class_names); - -  category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat)); - -  if (category && CLASS_PROTOCOL_LIST (category)) -    { -      generate_protocol_references (CLASS_PROTOCOL_LIST (category)); -      protocol_decl = generate_v1_protocol_list (category, cat); -    } -  else -    protocol_decl = 0; - -  if (flag_objc_abi >= 1) -    V1_Property_decl = generate_v1_property_table (NULL_TREE, cat); -  else -    V1_Property_decl = NULL_TREE; - -  if (CLASS_NST_METHODS (cat)) -    { -      snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s", -		IDENTIFIER_POINTER (CLASS_NAME (cat)), -		IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))); -      inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf, -					      meta_cati_meth); -    } - -  if (CLASS_CLS_METHODS (cat)) -    { -      snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s", -		IDENTIFIER_POINTER (CLASS_NAME (cat)), -		IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat))); -      class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf, -					       meta_catc_meth); -    } - -  initlist = build_v1_category_initializer (TREE_TYPE (cat_decl), -					    cat_name_expr, class_name_expr, -					    inst_methods, class_methods, -					    protocol_decl, V1_Property_decl, -					    loc); - -  finish_var_decl (cat_decl, initlist); -  impent->class_decl = cat_decl; -} - -/* This routine builds the class extension used by v1 NeXT.  */ - -static tree -generate_objc_class_ext (tree property_list, tree context) -{ -  tree decl, expr, ltyp; -  tree weak_ivar_layout_tree; -  int size; -  location_t loc; -  vec<constructor_elt, va_gc> *v = NULL; -  char buf[BUFSIZE]; - -  /* TODO: pass the loc in or find it from args.  */ -  loc = UNKNOWN_LOCATION; - -  /* const char *weak_ivar_layout -     TODO: Figure the ivar layouts out... */ -  weak_ivar_layout_tree = NULL_TREE; - -  if (!property_list && !weak_ivar_layout_tree) -    return NULL_TREE; - -  if (!objc_class_ext_template) -    build_objc_class_ext_template (); - -  /* uint32_t size */ -  size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (objc_class_ext_template)); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size)); - -  ltyp = const_string_type_node; -  if (weak_ivar_layout_tree) -    expr = convert (ltyp, weak_ivar_layout_tree); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  /* struct _prop_list_t *properties; */ -  ltyp = objc_prop_list_ptr; -  if (property_list) -     expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, property_list, 0)); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  snprintf (buf, BUFSIZE, "_OBJC_ClassExt_%s", -	    IDENTIFIER_POINTER (CLASS_NAME (context))); -  decl = start_var_decl (objc_class_ext_template, buf); -  expr = objc_build_constructor (TREE_TYPE (decl), v); -  OBJCMETA (decl, objc_meta, meta_class_extension); -  finish_var_decl (decl, expr); -  return decl; -} - -/* struct _objc_class { -     struct objc_class *isa; -     struct objc_class *super_class; -     char *name; -     long version; -     long info; -     long instance_size; -     struct objc_ivar_list *ivars; -     struct objc_method_list *methods; -     struct objc_cache *cache; -     struct objc_protocol_list *protocols; -  #if ABI >= 1 -     const char *ivar_layout; -     struct _objc_class_ext *ext; -  #else -     void *sel_id; -     void *gc_object_type; -  #endif -   }; */ - -static tree -build_v1_shared_structure_initializer (tree type, tree isa, tree super, -				    tree name, tree size, int status, -				    tree dispatch_table, tree ivar_list, -				    tree protocol_list, tree class_ext) -{ -  tree expr, ltyp; -  location_t loc; -  vec<constructor_elt, va_gc> *v = NULL; - -  /* TODO: fish the location out of the input data.  */ -  loc = UNKNOWN_LOCATION; - -  /* isa = */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa); - -  /* super_class = */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super); - -  /* name = */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name)); - -  /* version = */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -                          build_int_cst (long_integer_type_node, 0)); - -  /* info = */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -                          build_int_cst (long_integer_type_node, status)); - -  /* instance_size = */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -                          convert (long_integer_type_node, size)); - -  /* objc_ivar_list = */ -  ltyp = objc_ivar_list_ptr; -  if (ivar_list) -    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, ivar_list, 0)); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  /* objc_method_list = */ -  ltyp = objc_method_list_ptr; -  if (dispatch_table) -    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, dispatch_table, 0)); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  ltyp = build_pointer_type (xref_tag (RECORD_TYPE, -					get_identifier ("objc_cache"))); -  /* method_cache = */ -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node)); - -  /* protocol_list = */ -  ltyp = build_pointer_type (build_pointer_type (objc_protocol_template)); -  if (protocol_list) -    expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,  protocol_list, 0)); -  else -    expr = convert (ltyp, null_pointer_node); -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); - -  if (flag_objc_abi >= 1) -    { -      /* TODO: figure out the ivar_layout stuff.  */ -      expr = convert (const_string_type_node, null_pointer_node); -      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -      if (!objc_class_ext_template) -	build_objc_class_ext_template (); -      ltyp = build_pointer_type (objc_class_ext_template); -      if (class_ext) -	expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_ext, 0)); -      else -	expr = convert (ltyp, null_pointer_node); -      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -    } -  else -    { -      /* sel_id = NULL */ -      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_pointer_node); - -      /* gc_object_type = NULL */ -      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_pointer_node); -    } -  return objc_build_constructor (type, v); -} - -static tree -generate_ivars_list (tree chain, const char *name, tree attr) -{ -  tree initlist, ivar_list_template, decl; -  int size; -  vec<constructor_elt, va_gc> *inits = NULL; - -  if (!chain) -    return NULL_TREE; - -  if (!objc_ivar_template) -    objc_ivar_template = build_ivar_template (); - -  size = ivar_list_length (chain); - -  generating_instance_variables = 1; -  ivar_list_template = build_ivar_list_template (objc_ivar_template, size); -  initlist = build_ivar_list_initializer (objc_ivar_template, chain); -  generating_instance_variables = 0; - -  decl = start_var_decl (ivar_list_template, name); - -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size)); -  CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist); - -  OBJCMETA (decl, objc_meta, attr); -  finish_var_decl (decl, -		   objc_build_constructor (TREE_TYPE (decl), inits)); - -  return decl; -} - -/* static struct objc_class _OBJC_METACLASS_Foo={ ... }; -   static struct objc_class _OBJC_CLASS_Foo={ ... }; */ - -static void -generate_v1_class_structs (struct imp_entry *impent) -{ -  tree name_expr, super_expr, root_expr, class_decl, meta_decl; -  tree my_root_id, my_super_id; -  tree cast_type, initlist, protocol_decl; -  tree class_ext_decl = NULL_TREE, props = NULL_TREE; -  tree inst_methods = NULL_TREE, class_methods = NULL_TREE; -  tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE; -  int cls_flags; -  location_t loc; -  char buf[BUFSIZE]; - -/*  objc_implementation_context = impent->imp_context; -  implementation_template = impent->imp_template;*/ -  class_decl = impent->class_decl; -  meta_decl = impent->meta_decl; -  cls_flags = impent->has_cxx_cdtors ? CLS_HAS_CXX_STRUCTORS : 0 ; - -  loc = DECL_SOURCE_LOCATION (impent->class_decl); - -  if (flag_objc_abi >= 1) -    { -      /* ABI=1 additions.  */ -      props = generate_v1_property_table (NULL_TREE, impent->imp_context); -      class_ext_decl = generate_objc_class_ext (props, impent->imp_context); -    } - -  my_super_id = CLASS_SUPER_NAME (impent->imp_template); -  if (my_super_id) -    { -      add_class_reference (my_super_id); - -      /* Compute "my_root_id" - this is required for code generation. -         the "isa" for all meta class structures points to the root of -         the inheritance hierarchy (e.g. "__Object")...  */ -      my_root_id = my_super_id; -      do -	{ -	  tree my_root_int = lookup_interface (my_root_id); - -	  if (my_root_int && CLASS_SUPER_NAME (my_root_int)) -	    my_root_id = CLASS_SUPER_NAME (my_root_int); -	  else -	    break; -	} -      while (1); -      super_expr = add_objc_string (my_super_id, class_names); -    } -  else -    { -      /* No super class.  */ -      my_root_id = CLASS_NAME (impent->imp_template); -      super_expr = null_pointer_node; -    } - -  /* Install class `isa' and `super' pointers at runtime.  */ -  cast_type = build_pointer_type (objc_class_template); -  super_expr = build_c_cast (loc, cast_type, super_expr); - -  root_expr = add_objc_string (my_root_id, class_names); -  root_expr = build_c_cast (loc, cast_type, root_expr); - -  if (CLASS_PROTOCOL_LIST (impent->imp_template)) -    { -      generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template)); -      protocol_decl = generate_v1_protocol_list (impent->imp_template, -						 impent->imp_context); -    } -  else -    protocol_decl = NULL_TREE; - -  if (CLASS_CLS_METHODS (impent->imp_context)) -    { -      snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s", -		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); -      class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context), -					       buf, meta_clac_meth); -    } - -  if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE -      && (chain = TYPE_FIELDS (objc_class_template))) -    { -      snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s", -		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); -      class_ivars = generate_ivars_list (chain, buf, meta_clac_vars); -    } -  /* TODO: get rid of hidden passing of stuff in globals.  */ -  /* UOBJC_INSTANCE/CLASS_Variables_decl made in generate_ivarlists().  */ - -  name_expr = add_objc_string (CLASS_NAME (impent->imp_template), class_names); - -  /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */ - -  initlist = build_v1_shared_structure_initializer -		(TREE_TYPE (meta_decl), -		root_expr, super_expr, name_expr, -		convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)), -		CLS_META, class_methods, class_ivars, -		protocol_decl, NULL_TREE); - -  finish_var_decl (meta_decl, initlist); -  impent->meta_decl = meta_decl; - -  /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ -  if (CLASS_NST_METHODS (impent->imp_context)) -    { -      snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s", -		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); -      inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context), -					      buf, meta_clai_meth); -    } - -  if ((chain = CLASS_IVARS (impent->imp_template))) -    { -      snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s", -		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context))); -      inst_ivars = generate_ivars_list (chain, buf, meta_clai_vars); -    } - -  initlist = build_v1_shared_structure_initializer -		(TREE_TYPE (class_decl), -		build_unary_op (loc, ADDR_EXPR, meta_decl, 0), -		super_expr, name_expr, -		convert (integer_type_node, -			 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE (impent->imp_template))), -		CLS_FACTORY | cls_flags, inst_methods, inst_ivars, -		protocol_decl, class_ext_decl); - -  finish_var_decl (class_decl, initlist); -  impent->class_decl = class_decl; -} - -/* --- Output NeXT V1 Metadata --- */ - -/* Create the initial value for the `defs' field of _objc_symtab. -   This is a CONSTRUCTOR.  */ - -static tree -init_def_list (tree type) -{ -  tree expr; -  location_t loc; -  struct imp_entry *impent; -  vec<constructor_elt, va_gc> *v = NULL; - -  if (imp_count) -    for (impent = imp_list; impent; impent = impent->next) -      { -	if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) -	  { -	    loc = DECL_SOURCE_LOCATION (impent->class_decl); -	    expr = build_unary_op (loc, -				   ADDR_EXPR, impent->class_decl, 0); -	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -	  } -      } - -  if (cat_count) -    for (impent = imp_list; impent; impent = impent->next) -      { -	if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) -	  { -	    loc = DECL_SOURCE_LOCATION (impent->class_decl); -	    expr = build_unary_op (loc, -				   ADDR_EXPR, impent->class_decl, 0); -	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr); -	  } -      } - -  return objc_build_constructor (type, v); -} - -/* Take care of defining and initializing _OBJC_SYMBOLS.  */ - -/* Predefine the following data type: - -   struct _objc_symtab -   { -     long sel_ref_cnt; -     SEL *refs; -     short cls_def_cnt; -     short cat_def_cnt; -     void *defs[cls_def_cnt + cat_def_cnt]; -   }; */ - -static void -build_objc_symtab_template (void) -{ -  tree fields, *chain = NULL; - -  objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB)); - -  /* long sel_ref_cnt; */ -  fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain); - -  /* SEL *refs; */ -  add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain); - -  /* short cls_def_cnt; */ -  add_field_decl (short_integer_type_node, "cls_def_cnt", &chain); - -  /* short cat_def_cnt; */ -  add_field_decl (short_integer_type_node, "cat_def_cnt", &chain); - -  if (imp_count || cat_count) -    { -      /* void *defs[imp_count + cat_count (+ 1)]; */ -      /* NB: The index is one less than the size of the array.  */ -      int index = imp_count + cat_count; -      tree array_type = build_sized_array_type (ptr_type_node, index); -      add_field_decl (array_type, "defs", &chain); -    } - -  objc_finish_struct (objc_symtab_template, fields); -} -/* Construct the initial value for all of _objc_symtab.  */ - -static tree -init_objc_symtab (tree type) -{ -  vec<constructor_elt, va_gc> *v = NULL; - -  /* sel_ref_cnt = { ..., 5, ... } */ - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -			  build_int_cst (long_integer_type_node, 0)); - -  /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -			  convert (build_pointer_type (objc_selector_type), -							integer_zero_node)); - -  /* cls_def_cnt = { ..., 5, ... } */ - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -			  build_int_cst (short_integer_type_node, imp_count)); - -  /* cat_def_cnt = { ..., 5, ... } */ - -  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, -			  build_int_cst (short_integer_type_node, cat_count)); - -  /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ - -  if (imp_count || cat_count) -    { -      tree field = TYPE_FIELDS (type); -      field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field)))); - -      CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field))); -    } - -  return objc_build_constructor (type, v); -} - -/* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab' -   and initialized appropriately.  */ - -static void -generate_objc_symtab_decl (void) -{ -  build_objc_symtab_template (); -  UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_Symbols"); -  /* Allow the runtime to mark meta-data such that it can be assigned to target -     specific sections by the back-end.  */ -  OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_symtab); -  finish_var_decl (UOBJC_SYMBOLS_decl, -		   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 ATTRIBUTE_UNUSED) -{ -  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 ATTRIBUTE_UNUSED) -{ -  if (targetcm.objc_declare_class_definition) -    { -      char buf[BUFSIZE]; - -      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 -generate_classref_translation_entry (tree chain) -{ -  tree expr, decl, type; - -  decl = TREE_PURPOSE (chain); -  type = TREE_TYPE (decl); - -  expr = add_objc_string (TREE_VALUE (chain), class_names); -  expr = convert (type, expr); /* cast! */ - -  /* This is a class reference.  It is re-written by the runtime, -     but will be optimized away unless we force it.  */ -  DECL_PRESERVE_P (decl) = 1; -  OBJCMETA (decl, objc_meta, meta_class_reference); -  finish_var_decl (decl, expr); -  return; -} - -static void -objc_generate_v1_next_metadata (void) -{ -  struct imp_entry *impent; -  tree chain, attr; -  long vers; - -  /* FIXME: Make sure that we generate no metadata if there is nothing -     to put into it.  */ - -  if (objc_static_instances) -    gcc_unreachable (); /* Not for NeXT */ - -  build_metadata_templates (); -  objc_implementation_context = -  implementation_template = -  UOBJC_CLASS_decl = -  UOBJC_METACLASS_decl = NULL_TREE; - -  for (impent = imp_list; impent; impent = impent->next) -    { - -      /* If -gen-decls is present, Dump the @interface of each class. -	 TODO: Dump the classes in the  order they were found, rather than in -	 reverse order as we are doing now.  */ -      if (flag_gen_declaration) -	dump_interface (gen_declaration_file, impent->imp_context); - -      /* all of the following reference the string pool...  */ -      if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) -	generate_v1_class_structs (impent); -      else -	generate_v1_category (impent); -    } - -  /* If we are using an array of selectors, we must always -     finish up the array decl even if no selectors were used.  */ -  build_next_selector_translation_table (); - -  if (protocol_chain) -    generate_v1_protocols (); - -  /* Pass summary information to the runtime.  */ -  if (imp_count || cat_count) -    generate_objc_symtab_decl (); - -  vers = OBJC_VERSION; -  attr = build_tree_list (objc_meta, meta_modules); -  build_module_descriptor (vers, attr); - -  /* Dump the class references.  This forces the appropriate classes -     to be linked into the executable image, preserving unix archive -     semantics.  */ -  for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) -    { -      handle_next_class_ref (chain); -      if (TREE_PURPOSE (chain)) -	generate_classref_translation_entry (chain); -    } - -  for (impent = imp_list; impent; impent = impent->next) -    handle_next_impent (impent); - -  /* Emit the strings tables.  */ -  generate_strings (); -} - -/* --- exceptions stuff --- */ - -/* Predefine the following data type: - -   struct _objc_exception_data -   { -     int buf[OBJC_JBLEN]; -     void *pointers[4]; -   }; */ - -/* The following yuckiness should prevent users from having to #include -   <setjmp.h> in their code... */ - -/* Define to a harmless positive value so the below code doesn't die.  */ -#ifndef OBJC_JBLEN -#define OBJC_JBLEN 18 -#endif - -static void -build_next_objc_exception_stuff (void) -{ -  tree decls, temp_type, *chain = NULL; - -  objc_exception_data_template -    = objc_start_struct (get_identifier (UTAG_EXCDATA)); - -  /* int buf[OBJC_JBLEN]; */ - -  temp_type = build_sized_array_type (integer_type_node, OBJC_JBLEN); -  decls = add_field_decl (temp_type, "buf", &chain); - -  /* void *pointers[4]; */ - -  temp_type = build_sized_array_type (ptr_type_node, 4); -  add_field_decl (temp_type, "pointers", &chain); - -  objc_finish_struct (objc_exception_data_template, decls); - -  /* int _setjmp(...); */ -  /* If the user includes <setjmp.h>, this shall be superseded by -     'int _setjmp(jmp_buf);' */ -  temp_type = build_varargs_function_type_list (integer_type_node, NULL_TREE); -  objc_setjmp_decl -    = 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_function_type_list (objc_object_type, -                                build_pointer_type (objc_exception_data_template), -                                NULL_TREE); -  objc_exception_extract_decl -    = 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_function_type_list (void_type_node, -                                build_pointer_type (objc_exception_data_template), -                                NULL_TREE); -  objc_exception_try_enter_decl -    = add_builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, -			    NULL_TREE); -  objc_exception_try_exit_decl -    = add_builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, -			    NULL_TREE); - -  /* int objc_exception_match(id, id); */ -  temp_type -    = build_function_type_list (integer_type_node, -                                objc_object_type, objc_object_type, NULL_TREE); -  objc_exception_match_decl -    = 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) -       __attribute__ ((hard_coded_address (OFFS_ASSIGNIVAR_FAST))); */ -  temp_type -    = build_function_type_list (objc_object_type, -                                objc_object_type, -                                objc_object_type, -                                unsigned_type_node, -                                NULL_TREE); -  objc_assign_ivar_decl -    = add_builtin_function (TAG_ASSIGNIVAR, temp_type, 0, NOT_BUILT_IN, -			    NULL, NULL_TREE); -#ifdef OFFS_ASSIGNIVAR_FAST -  objc_assign_ivar_fast_decl -    = 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 -  /* Default to slower ivar method.  */ -  objc_assign_ivar_fast_decl = objc_assign_ivar_decl; -#endif - -  /* id objc_assign_global (id, id *); */ -  /* id objc_assign_strongCast (id, id *); */ -  temp_type = build_function_type_list (objc_object_type, -                                        objc_object_type, -                                        build_pointer_type (objc_object_type), -                                        NULL_TREE); -  objc_assign_global_decl -	= add_builtin_function (TAG_ASSIGNGLOBAL, temp_type, 0, NOT_BUILT_IN, NULL, -				NULL_TREE); -  objc_assign_strong_cast_decl -	= add_builtin_function (TAG_ASSIGNSTRONGCAST, temp_type, 0, NOT_BUILT_IN, NULL, -				NULL_TREE); -} - -/* --- NeXT V1 SJLJ Exceptions --- */ - -/* Build "objc_exception_try_exit(&_stack)".  */ - -static tree -next_sjlj_build_try_exit (struct objc_try_context **ctcp) -{ -  tree t; -  t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl); -  t = tree_cons (NULL, t, NULL); -  t = build_function_call (input_location, -			   objc_exception_try_exit_decl, t); -  return t; -} - -/* Build -	objc_exception_try_enter (&_stack); -	if (_setjmp(&_stack.buf)) -	  ; -	else -	  ; -   Return the COND_EXPR.  Note that the THEN and ELSE fields are left -   empty, ready for the caller to fill them in.  */ - -static tree -next_sjlj_build_enter_and_setjmp (struct objc_try_context **ctcp) -{ -  tree t, enter, sj, cond; - -  t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl); -  t = tree_cons (NULL, t, NULL); -  enter = build_function_call (input_location, -			       objc_exception_try_enter_decl, t); - -  t = objc_build_component_ref ((*ctcp)->stack_decl, -				get_identifier ("buf")); -  t = build_fold_addr_expr_loc (input_location, t); -#ifdef OBJCPLUS -  /* Convert _setjmp argument to type that is expected.  */ -  if (prototype_p (TREE_TYPE (objc_setjmp_decl))) -    t = convert (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl))), t); -  else -    t = convert (ptr_type_node, t); -#else -  t = convert (ptr_type_node, t); -#endif -  t = tree_cons (NULL, t, NULL); -  sj = build_function_call (input_location, -			    objc_setjmp_decl, t); - -  cond = build2 (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj); -  cond = c_common_truthvalue_conversion (input_location, cond); - -  return build3 (COND_EXPR, void_type_node, cond, NULL, NULL); -} - -/* Build: - -   DECL = objc_exception_extract(&_stack); */ - -static tree -next_sjlj_build_exc_extract (struct objc_try_context **ctcp, tree decl) -{ -  tree t; - -  t = build_fold_addr_expr_loc (input_location, (*ctcp)->stack_decl); -  t = tree_cons (NULL, t, NULL); -  t = build_function_call (input_location, -			   objc_exception_extract_decl, t); -  t = convert (TREE_TYPE (decl), t); -  t = build2 (MODIFY_EXPR, void_type_node, decl, t); - -  return t; -} - -/* Build -	if (objc_exception_match(obj_get_class(TYPE), _caught) -	  BODY -	else if (...) -	  ... -	else -	  { -	    _rethrow = _caught; -	    objc_exception_try_exit(&_stack); -	  } -   from the sequence of CATCH_EXPRs in the current try context.  */ - -static tree -next_sjlj_build_catch_list (struct objc_try_context **ctcp) -{ -  tree_stmt_iterator i = tsi_start ((*ctcp)->catch_list); -  tree catch_seq, t; -  tree *last = &catch_seq; -  bool saw_id = false; - -  for (; !tsi_end_p (i); tsi_next (&i)) -    { -      tree stmt = tsi_stmt (i); -      tree type = CATCH_TYPES (stmt); -      tree body = CATCH_BODY (stmt); - -      if (type != error_mark_node -	  && objc_is_object_id (TREE_TYPE (type))) -	{ -	  *last = body; -	  saw_id = true; -	  break; -	} -      else -	{ -	  tree args, cond; - -	  if (type == error_mark_node) -	    cond = error_mark_node; -	  else -	    { -	      args = tree_cons (NULL, (*ctcp)->caught_decl, NULL); -	      t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type))); -	      args = tree_cons (NULL, t, args); -	      t = build_function_call (input_location, -				       objc_exception_match_decl, args); -	      cond = c_common_truthvalue_conversion (input_location, t); -	    } -	  t = build3 (COND_EXPR, void_type_node, cond, body, NULL); -	  SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt)); - -	  *last = t; -	  last = &COND_EXPR_ELSE (t); -	} -    } - -  if (!saw_id) -    { -      t = build2 (MODIFY_EXPR, void_type_node, (*ctcp)->rethrow_decl, -		  (*ctcp)->caught_decl); -      SET_EXPR_LOCATION (t, (*ctcp)->end_catch_locus); -      append_to_statement_list (t, last); - -      t = next_sjlj_build_try_exit (ctcp); -      SET_EXPR_LOCATION (t, (*ctcp)->end_catch_locus); -      append_to_statement_list (t, last); -    } - -  return catch_seq; -} - -/* Build a complete @try-@catch-@finally block for legacy Darwin setjmp -   exception handling.  We aim to build: - -	{ -	  struct _objc_exception_data _stack; -	  id _rethrow = 0; -	  try -	    { -	      objc_exception_try_enter (&_stack); -	      if (_setjmp(&_stack.buf)) -	        { -		  id _caught = objc_exception_extract(&_stack); -		  objc_exception_try_enter (&_stack); -		  if (_setjmp(&_stack.buf)) -		    _rethrow = objc_exception_extract(&_stack); -		  else -		    CATCH-LIST -	        } -	      else -		TRY-BLOCK -	    } -	  finally -	    { -	      if (!_rethrow) -		objc_exception_try_exit(&_stack); -	      FINALLY-BLOCK -	      if (_rethrow) -		objc_exception_throw(_rethrow); -	    } -	} - -   If CATCH-LIST is empty, we can omit all of the block containing -   "_caught" except for the setting of _rethrow.  Note the use of -   a real TRY_FINALLY_EXPR here, which is not involved in EH per-se, -   but handles goto and other exits from the block.  */ - -static tree -next_sjlj_build_try_catch_finally (struct objc_try_context **ctcp) -{ -  tree rethrow_decl, stack_decl, t; -  tree catch_seq, try_fin, bind; -  struct objc_try_context *cur_try_context = *ctcp; - -  /* Create the declarations involved.  */ -  t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA)); -  stack_decl = objc_create_temporary_var (t, NULL); -  cur_try_context->stack_decl = stack_decl; - -  rethrow_decl = objc_create_temporary_var (objc_object_type, NULL); -  cur_try_context->rethrow_decl = rethrow_decl; -  TREE_CHAIN (rethrow_decl) = stack_decl; - -  /* Build the outermost variable binding level.  */ -  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 = 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 = 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)); - -  /* Create the complete catch sequence.  */ -  if (cur_try_context->catch_list) -    { -      tree caught_decl = objc_build_exc_ptr (ctcp); -      catch_seq = build_stmt (input_location, BIND_EXPR, caught_decl, NULL, NULL); -      TREE_SIDE_EFFECTS (catch_seq) = 1; - -      t = next_sjlj_build_exc_extract (ctcp, caught_decl); -      append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq)); - -      t = next_sjlj_build_enter_and_setjmp (ctcp); -      COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (ctcp, rethrow_decl); -      COND_EXPR_ELSE (t) = next_sjlj_build_catch_list (ctcp); -      append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq)); -    } -  else -    catch_seq = next_sjlj_build_exc_extract (ctcp, rethrow_decl); -  SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus); - -  /* Build the main register-and-try if statement.  */ -  t = next_sjlj_build_enter_and_setjmp (ctcp); -  SET_EXPR_LOCATION (t, cur_try_context->try_locus); -  COND_EXPR_THEN (t) = catch_seq; -  COND_EXPR_ELSE (t) = cur_try_context->try_body; -  TREE_OPERAND (try_fin, 0) = t; - -  /* Build the complete FINALLY statement list.  */ -  t = next_sjlj_build_try_exit (ctcp); -  t = build_stmt (input_location, COND_EXPR, -		  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)); - -  append_to_statement_list (cur_try_context->finally_body, -			    &TREE_OPERAND (try_fin, 1)); - -  t = tree_cons (NULL, rethrow_decl, NULL); -  t = build_function_call (input_location, -			   objc_exception_throw_decl, t); -  t = build_stmt (input_location, COND_EXPR, -		  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)); - -  return bind; -} - -/* We do not expect this to be used at the moment. -   If (a) it is possible to implement unwinder exceptions. -      (b) we do it... then it might be possibly useful. -*/ -static GTY(()) tree objc_eh_personality_decl; - -static tree -objc_eh_runtime_type (tree type) -{ -  tree ident, eh_id, decl, str; - -  gcc_unreachable (); -  if (type == error_mark_node) -    { -      /* Use 'ErrorMarkNode' as class name when error_mark_node is found -	 to prevent an ICE.  Note that we know that the compiler will -	 terminate with an error and this 'ErrorMarkNode' class name will -	 never be actually used.  */ -      ident = get_identifier ("ErrorMarkNode"); -      goto make_err_class; -    } - -  if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type))) -    { -      ident = get_identifier ("id"); -      goto make_err_class; -    } - -  if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type))) -    { -#ifdef OBJCPLUS -      /* This routine is also called for c++'s catch clause; in which case, -	 we use c++'s typeinfo decl. */ -      return build_eh_type_type (type); -#else -      error ("non-objective-c type '%T' cannot be caught", type); -      ident = get_identifier ("ErrorMarkNode"); -      goto make_err_class; -#endif -    } -  else -    ident = OBJC_TYPE_NAME (TREE_TYPE (type)); - -make_err_class: -  /* If this class was already referenced, then it will be output during -     meta-data emission, so we don't need to do it here.  */ -  decl = get_objc_string_decl (ident, class_names); -  eh_id = add_objc_string (ident, class_names); -  if (!decl) -    { -      /* Not found ... so we need to build it - from the freshly-entered id.  */ -      decl = get_objc_string_decl (ident, class_names); -      str = my_build_string (IDENTIFIER_LENGTH (ident) + 1, -			     IDENTIFIER_POINTER (ident)); -      /* We have to finalize this var here, because this might be called after -	 all the other metadata strings have been emitted.  */ -      finish_var_decl (decl, str); -    } -  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 ("gcc"); -#else -    objc_eh_personality_decl = build_personality_function ("gxx"); -#endif -  return objc_eh_personality_decl; -} - -/* --- interfaces --- */ - -static tree -build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED) -{ -  tree t; -  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.  */ -  parms->quick_push (throw_expr); -  t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL); -  vec_free (parms); -  return add_stmt (t); -} - -/* Build __builtin_eh_pointer, or the moral equivalent.  In the case -   of Darwin, we'll arrange for it to be initialized (and associated -   with a binding) later.  */ - -static tree -objc_build_exc_ptr (struct objc_try_context **cur_try_context) -{ -  if (flag_objc_sjlj_exceptions) -    { -      tree var = (*cur_try_context)->caught_decl; -      if (!var) -	{ -	  var = objc_create_temporary_var (objc_object_type, NULL); -	  (*cur_try_context)->caught_decl = var; -	} -      return var; -    } -  else -    { -      tree t; -      t = builtin_decl_explicit (BUILT_IN_EH_POINTER); -      t = build_call_expr (t, 1, integer_zero_node); -      return fold_convert (objc_object_type, t); -    } -} - -static tree -begin_catch (struct objc_try_context **cur_try_context, tree type, -	     tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED) -{ -  tree t; -  /* Record the data for the catch in the try context so that we can -     finalize it later.  We treat ellipsis the same way as catching -     with 'id xyz'.  */ -  t = build_stmt (input_location, CATCH_EXPR, type, compound); -  (*cur_try_context)->current_catch = t; - -  /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */ -  t = objc_build_exc_ptr (cur_try_context); -  t = convert (TREE_TYPE (decl), t); -  return build2 (MODIFY_EXPR, void_type_node, decl, t); -} - -static void -finish_catch (struct objc_try_context **cur_try_context, tree current_catch) -{ -  append_to_statement_list (current_catch, &((*cur_try_context)->catch_list)); -} - -static tree -finish_try_stmt (struct objc_try_context **cur_try_context) -{ -  tree stmt; -  struct objc_try_context *c = *cur_try_context; -  /* 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 (!c->finally_body) -	{ -	  c->finally_locus = input_location; -	  c->end_finally_locus = input_location; -	} -      stmt = next_sjlj_build_try_catch_finally (cur_try_context); -      in_late_binary_op = save; -    } -  else -    /* This doesn't happen at the moment... but maybe one day... */ -    { -      /* Otherwise, nest the CATCH inside a FINALLY.  */ -      stmt = c->try_body; -      if (c->catch_list) -	stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list); -      if (c->finally_body) -	stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body); -    } -  return stmt; -} - -#include "gt-objc-objc-next-runtime-abi-01.h" | 
