]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/objc/objc-next-runtime-abi-02.c
Update copyright years.
[thirdparty/gcc.git] / gcc / objc / objc-next-runtime-abi-02.c
index e7570c7e4b25e5b7093cf175bb6a07e1c89c91ab..e401906ed012d69d1a0f76ac9fa2e3cd35e6f84d 100644 (file)
@@ -1,5 +1,5 @@
 /* Next Runtime (ABI-2) private.
-   Copyright (C) 2011 Free Software Foundation, Inc.
+   Copyright (C) 2011-2020 Free Software Foundation, Inc.
 
    Contributed by Iain Sandoe and based, in part, on an implementation in
    'branches/apple/trunk' contributed by Apple Computer Inc.
@@ -28,14 +28,15 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
 #include "tree.h"
+#include "stringpool.h"
+#include "attribs.h"
 
 #ifdef OBJCPLUS
-#include "cp-tree.h"
+#include "cp/cp-tree.h"
 #else
-#include "c-tree.h"
-#include "c-lang.h"
+#include "c/c-tree.h"
+#include "c/c-lang.h"
 #endif
 #include "langhooks.h"
 #include "c-family/c-objc.h"
@@ -48,15 +49,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "objcp-decl.h"
 #endif  /* OBJCPLUS */
 
-#include "ggc.h"
 #include "target.h"
-#include "obstack.h"
 #include "tree-iterator.h"
 
-/* These are only used for encoding ivars.  */
-extern struct obstack util_obstack;
-extern char *util_firstobj;
-
 #include "objc-runtime-hooks.h"
 #include "objc-runtime-shared-support.h"
 #include "objc-encoding.h"
@@ -213,8 +208,8 @@ static tree next_runtime_abi_02_get_class_super_ref (location_t, struct imp_entr
 static tree next_runtime_abi_02_get_category_super_ref (location_t, struct imp_entry *, bool);
 
 static tree next_runtime_abi_02_receiver_is_class_object (tree);
-static void next_runtime_abi_02_get_arg_type_list_base (VEC(tree,gc) **, tree,
-                                                       int, int);
+static void next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **,
+                                                       tree, int, int);
 static tree next_runtime_abi_02_build_objc_method_call (location_t, tree, tree,
                                                        tree, tree, tree, int);
 static bool next_runtime_abi_02_setup_const_string_class_decl (void);
@@ -236,17 +231,20 @@ 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 **);
 
+/* TODO: Use an objc-map.  */
 static GTY ((length ("SIZEHASHTABLE"))) hash *extern_names;
 
 bool
 objc_next_runtime_abi_02_init (objc_runtime_hooks *rthooks)
 {
-  extern_names = ggc_alloc_cleared_vec_hash (SIZEHASHTABLE);
+  extern_names = ggc_cleared_vec_alloc<hash> (SIZEHASHTABLE);
 
   if (flag_objc_exceptions && flag_objc_sjlj_exceptions)
     {
-      inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for "
-                               "%<-fnext-runtime%> when %<-fobjc-abi-version%> >= 2");
+      inform (UNKNOWN_LOCATION,
+             "%<-fobjc-sjlj-exceptions%> is ignored for "
+             "%<-fnext-runtime%> when %<-fobjc-abi-version%> "
+             "greater than 1");
       flag_objc_sjlj_exceptions = 0;
     }
 
@@ -347,6 +345,8 @@ next_runtime_abi_02_init_metadata_attributes (void)
   meta_ehtype = get_identifier ("V2_EHTY");
 
   meta_const_str = get_identifier ("V2_CSTR");
+
+  meta_ivar_ref = get_identifier ("V2_IVRF");
 }
 
 static void next_runtime_02_initialize (void)
@@ -860,7 +860,7 @@ hash_name_enter (hash *hashlist, tree id)
   hash obj;
   int slot = IDENTIFIER_HASH_VALUE (DECL_NAME (id)) % SIZEHASHTABLE;
 
-  obj = ggc_alloc_hashed_entry ();
+  obj = ggc_alloc<hashed_entry> ();
   obj->list = 0;
   obj->next = hashlist[slot];
   obj->key = id;
@@ -1015,12 +1015,10 @@ next_runtime_abi_02_string_decl (tree type, const char *name,  string_section wh
 
 /* NOTE --- entry --- */
 
-typedef struct GTY(()) ident_data_tuple {
+struct GTY(()) ident_data_tuple {
   tree ident;
   tree data;
-} ident_data_tuple ;
-DEF_VEC_O(ident_data_tuple);
-DEF_VEC_ALLOC_O(ident_data_tuple, gc);
+};
 
 /* This routine creates a file scope static variable of type 'Class'
    to hold the address of a class.  */
@@ -1042,7 +1040,7 @@ build_v2_class_reference_decl (tree ident)
    ident is replaced with address of the class metadata (of type
    'Class') in the output routine.  */
 
-static GTY (()) VEC (ident_data_tuple, gc) * classrefs;
+static GTY (()) vec<ident_data_tuple, va_gc> *classrefs;
 
 static tree
 objc_v2_get_class_reference (tree ident)
@@ -1053,7 +1051,7 @@ objc_v2_get_class_reference (tree ident)
     {
       int count;
       ident_data_tuple *ref;
-      FOR_EACH_VEC_ELT (ident_data_tuple, classrefs, count, ref)
+      FOR_EACH_VEC_ELT (*classrefs, count, ref)
        {
          if (ref->ident == ident)
            {
@@ -1065,14 +1063,14 @@ objc_v2_get_class_reference (tree ident)
     }
   else
     /* Somewhat arbitrary initial provision.  */
-    classrefs = VEC_alloc (ident_data_tuple, gc, 16);
+    vec_alloc (classrefs, 16);
 
   /* We come here if we don't find the entry - or if the table was yet
      to be created.  */
   decl = build_v2_class_reference_decl (ident);
   e.ident = ident;
   e.data = decl;
-  VEC_safe_push (ident_data_tuple, gc, classrefs, &e);
+  vec_safe_push (classrefs, e);
   return decl;
 }
 
@@ -1084,17 +1082,18 @@ next_runtime_abi_02_get_class_reference (tree ident)
   else
     {
       /* We fall back to using objc_getClass ().  */
-      VEC(tree,gc) *vec =  VEC_alloc (tree, gc, 1);
+      vec<tree, va_gc> *v;
+      vec_alloc (v, 1);
       tree t;
       /* ??? add_class_reference (ident); - is pointless, since the
          system lib does not export the equivalent symbols.  Maybe we
          need to build a class ref anyway.  */
       t = my_build_string_pointer (IDENTIFIER_LENGTH (ident) + 1,
                                   IDENTIFIER_POINTER (ident));
-      VEC_quick_push (tree, vec, t);
-      t = build_function_call_vec (input_location, objc_get_class_decl,
-                                  vec, NULL);
-      VEC_free (tree, gc, vec);
+      v->quick_push (t);
+      t = build_function_call_vec (input_location, vNULL, objc_get_class_decl,
+                                  v, 0);
+      vec_free (v);
       return t;
     }
 }
@@ -1107,8 +1106,9 @@ next_runtime_abi_02_get_class_reference (tree ident)
    prototype.  */
 
 static void
-next_runtime_abi_02_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
-                                           int context, int superflag)
+next_runtime_abi_02_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
+                                           tree meth, int context,
+                                           int superflag)
 {
   tree receiver_type;
 
@@ -1119,12 +1119,11 @@ next_runtime_abi_02_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
   else
     receiver_type = objc_object_type;
 
-  VEC_safe_push (tree, gc, *argtypes, receiver_type);
+  vec_safe_push (*argtypes, receiver_type);
   /* Selector type - will eventually change to `int'.  */
-  VEC_safe_push (tree, gc, *argtypes,
-                (superflag
-                 ? objc_v2_super_selector_type
-                 : objc_v2_selector_type));
+  vec_safe_push (*argtypes,
+                superflag ? objc_v2_super_selector_type
+                          : objc_v2_selector_type);
 }
 
 /* TODO: Merge this with the message refs.  */
@@ -1200,15 +1199,13 @@ build_v2_message_reference_decl (tree sel_name, tree message_func_ident)
   return decl;
 }
 
-typedef struct GTY(()) msgref_entry {
+struct GTY(()) msgref_entry {
   tree func;
   tree selname;
   tree refdecl;
-} msgref_entry;
-DEF_VEC_O(msgref_entry);
-DEF_VEC_ALLOC_O(msgref_entry, gc);
+};
 
-static GTY (()) VEC (msgref_entry, gc) * msgrefs;
+static GTY (()) vec<msgref_entry, va_gc> *msgrefs;
 
 /* Build the list of (objc_msgSend_fixup_xxx, selector name), used
    later on to initialize the table of 'struct message_ref_t'
@@ -1223,13 +1220,13 @@ build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl)
     {
       int count;
       msgref_entry *ref;
-      FOR_EACH_VEC_ELT (msgref_entry, msgrefs, count, ref)
+      FOR_EACH_VEC_ELT (*msgrefs, count, ref)
        if (ref->func == message_func_decl && ref->selname == sel_name)
          return ref->refdecl;
     }
   else
     /* Somewhat arbitrary initial provision.  */
-    msgrefs = VEC_alloc (msgref_entry, gc, 32);
+    vec_alloc (msgrefs, 32);
 
   /* We come here if we don't find a match or at the start.  */
   decl = build_v2_message_reference_decl (sel_name,
@@ -1237,7 +1234,7 @@ build_v2_selector_messenger_reference (tree sel_name, tree message_func_decl)
   e.func = message_func_decl;
   e.selname = sel_name;
   e.refdecl = decl;
-  VEC_safe_push (msgref_entry, gc, msgrefs, &e);
+  vec_safe_push (msgrefs, e);
   return decl;
 }
 
@@ -1258,13 +1255,11 @@ build_v2_protocollist_ref_decl (tree protocol)
   return decl;
 }
 
-typedef struct GTY(()) prot_list_entry {
+struct GTY(()) prot_list_entry {
   tree id;
   tree refdecl;
-} prot_list_entry;
-DEF_VEC_O(prot_list_entry);
-DEF_VEC_ALLOC_O(prot_list_entry, gc);
-static GTY (()) VEC (prot_list_entry, gc) * protrefs;
+};
+static GTY (()) vec<prot_list_entry, va_gc> *protrefs;
 
 static tree
 objc_v2_get_protocol_reference (tree ident)
@@ -1275,7 +1270,7 @@ objc_v2_get_protocol_reference (tree ident)
     {
       int count;
       prot_list_entry *ref;
-      FOR_EACH_VEC_ELT (prot_list_entry, protrefs, count, ref)
+      FOR_EACH_VEC_ELT (*protrefs, count, ref)
        {
          if (ref->id == ident)
            {
@@ -1287,14 +1282,14 @@ objc_v2_get_protocol_reference (tree ident)
     }
   else
     /* Somewhat arbitrary initial provision.  */
-    protrefs = VEC_alloc (prot_list_entry, gc, 32);
+    vec_alloc (protrefs, 32);
 
   /* We come here if we don't find the entry - or if the table was yet
      to be created.  */
   decl = build_v2_protocollist_ref_decl (ident);
   e.id = ident;
   e.refdecl = decl;
-  VEC_safe_push (prot_list_entry, gc, protrefs, &e);
+  vec_safe_push (protrefs, e);
   return decl;
 }
 
@@ -1386,8 +1381,7 @@ objc_v2_build_ivar_ref (tree datum, tree component)
                       string_type_node, build_fold_addr_expr (datum));
 
   /* (char*)datum + offset */
-  expr = fold_build2_loc (input_location,
-                         POINTER_PLUS_EXPR, string_type_node, expr, offset);
+  expr = fold_build_pointer_plus_loc (input_location, expr, offset);
 
   /* (ftype*)((char*)datum + offset) */
   expr = build_c_cast (input_location, build_pointer_type (ftype), expr);
@@ -1415,7 +1409,7 @@ objc_v2_build_ivar_ref (tree datum, tree component)
 
 /* IVAR refs are made via an externally referenceable offset and built
    on the fly.  That is, unless they refer to (private) fields in  the
-   class stucture.  */
+   class structure.  */
 static tree
 next_runtime_abi_02_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
                                   tree base, tree id)
@@ -1441,8 +1435,8 @@ build_v2_superclass_ref_decl (tree ident, bool inst)
   return decl;
 }
 
-static GTY (()) VEC (ident_data_tuple, gc) * class_super_refs;
-static GTY (()) VEC (ident_data_tuple, gc) * metaclass_super_refs;
+static GTY (()) vec<ident_data_tuple, va_gc> *class_super_refs;
+static GTY (()) vec<ident_data_tuple, va_gc> *metaclass_super_refs;
 
 static tree
 next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
@@ -1451,14 +1445,14 @@ next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
   tree decl;
   ident_data_tuple e;
   tree id = CLASS_NAME (imp->imp_context);
-  VEC (ident_data_tuple, gc) *list = inst_meth  ? class_super_refs
+  vec<ident_data_tuple, va_gc> *list = inst_meth  ? class_super_refs
                                                : metaclass_super_refs;
 
   if (list)
     {
       int count;
       ident_data_tuple *ref;
-      FOR_EACH_VEC_ELT (ident_data_tuple, list, count, ref)
+      FOR_EACH_VEC_ELT (*list, count, ref)
        {
          if (ref->ident == id)
            {
@@ -1472,16 +1466,22 @@ next_runtime_abi_02_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
     {
       /* Somewhat arbitrary initial provision.  */
       if (inst_meth)
-        list = class_super_refs = VEC_alloc (ident_data_tuple, gc, 16);
+       {
+         vec_alloc (class_super_refs, 16);
+         list = class_super_refs;
+       }
       else
-        list = metaclass_super_refs = VEC_alloc (ident_data_tuple, gc, 16);
+       {
+         vec_alloc (metaclass_super_refs, 16);
+         list = metaclass_super_refs;
+       }
     }
   /* We come here if we don't find the entry - or if the table was yet
      to be created.  */
   decl = build_v2_superclass_ref_decl (id, inst_meth);
   e.ident = id;
   e.data = decl;
-  VEC_safe_push (ident_data_tuple, gc, list, &e);
+  vec_safe_push (list, e);
   return decl;
 }
 
@@ -1514,7 +1514,6 @@ next_runtime_abi_02_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
   /* ??? Do we need to add the class ref anway for zero-link?  */
   /* else do it the slow way.  */
   super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
-  /* assemble_external (super_class); */
   super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
                                        IDENTIFIER_POINTER (super_name));
   /* super_class = objc_get{Meta}Class("CLASS_SUPER_NAME"); */
@@ -1528,13 +1527,12 @@ next_runtime_abi_02_receiver_is_class_object (tree receiver)
 {
   if (TREE_CODE (receiver) == VAR_DECL
       && IS_CLASS (TREE_TYPE (receiver))
-      && classrefs
-      && VEC_length (ident_data_tuple, classrefs))
+      && vec_safe_length (classrefs))
     {
       int count;
       ident_data_tuple *ref;
       /* The receiver is a variable created by build_class_reference_decl.  */
-      FOR_EACH_VEC_ELT (ident_data_tuple, classrefs, count, ref)
+      FOR_EACH_VEC_ELT (*classrefs, count, ref)
        if (ref->data == receiver)
          return ref->ident;
     }
@@ -1632,7 +1630,7 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
       if (TREE_CODE (ret_type) == RECORD_TYPE
          || TREE_CODE (ret_type) == UNION_TYPE)
        {
-         VEC(constructor_elt,gc) *rtt = NULL;
+         vec<constructor_elt, va_gc> *rtt = NULL;
          /* ??? CHECKME. hmmm..... think we need something more
             here.  */
          CONSTRUCTOR_APPEND_ELT (rtt, NULL_TREE, NULL_TREE);
@@ -1646,13 +1644,15 @@ build_v2_build_objc_method_call (int super_flag, tree method_prototype,
                               fold_convert (rcv_p, integer_zero_node), 1);
 
 #ifdef OBJCPLUS
-      ret_val = build_conditional_expr (ifexp, ret_val, ftree, tf_warning_or_error);
+      ret_val = build_conditional_expr (input_location,
+                                       ifexp, ret_val, ftree,
+                                       tf_warning_or_error);
 #else
      /* ??? CHECKME.   */
       ret_val = build_conditional_expr (input_location,
                                        ifexp, 1,
-                                       ret_val, NULL_TREE,
-                                       ftree, NULL_TREE);
+                                       ret_val, NULL_TREE, input_location,
+                                       ftree, NULL_TREE, input_location);
 #endif
     }
   return ret_val;
@@ -1754,7 +1754,7 @@ next_runtime_abi_02_build_const_string_constructor (location_t loc, tree string,
                                                   int length)
 {
   tree constructor, fields, var;
-  VEC(constructor_elt,gc) *v = NULL;
+  vec<constructor_elt, va_gc> *v = NULL;
 
   /* NeXT: (NSConstantString *) & ((__builtin_ObjCString) { isa, string, length }) */
   fields = TYPE_FIELDS (internal_const_str_type);
@@ -1902,12 +1902,12 @@ void build_v2_message_ref_translation_table (void)
   int count;
   msgref_entry *ref;
 
-  if (!msgrefs || !VEC_length (msgref_entry,msgrefs))
+  if (!vec_safe_length (msgrefs))
     return;
 
-  FOR_EACH_VEC_ELT (msgref_entry, msgrefs, count, ref)
+  FOR_EACH_VEC_ELT (*msgrefs, count, ref)
     {
-      VEC(constructor_elt,gc) *initializer;
+      vec<constructor_elt, va_gc> *initializer;
       tree expr, constructor;
       tree struct_type = TREE_TYPE (ref->refdecl);
       location_t loc = DECL_SOURCE_LOCATION (ref->refdecl);
@@ -1935,10 +1935,10 @@ build_v2_classrefs_table (void)
   int count;
   ident_data_tuple *ref;
 
-  if (!classrefs || !VEC_length (ident_data_tuple, classrefs))
+  if (!vec_safe_length (classrefs))
     return;
 
-  FOR_EACH_VEC_ELT (ident_data_tuple, classrefs, count, ref)
+  FOR_EACH_VEC_ELT (*classrefs, count, ref)
     {
       tree expr = ref->ident;
       tree decl = ref->data;
@@ -1966,13 +1966,13 @@ build_v2_super_classrefs_table (bool metaclass)
 {
   int count;
   ident_data_tuple *ref;
-  VEC (ident_data_tuple, gc) *list = metaclass  ? metaclass_super_refs
+  vec<ident_data_tuple, va_gc> *list = metaclass  ? metaclass_super_refs
                                                : class_super_refs;
 
-  if (!list || !VEC_length (ident_data_tuple, list))
+  if (!vec_safe_length (list))
     return;
 
-  FOR_EACH_VEC_ELT (ident_data_tuple, list, count, ref)
+  FOR_EACH_VEC_ELT (*list, count, ref)
     {
       tree expr = ref->ident;
       tree decl = ref->data;
@@ -1992,17 +1992,15 @@ build_v2_super_classrefs_table (bool metaclass)
 /* Add the global class meta-data declaration to the list which later
    on ends up in the __class_list section.  */
 
-static GTY(()) VEC(tree,gc) *class_list;
+static GTY(()) vec<tree, va_gc> *class_list;
 
 static void
 objc_v2_add_to_class_list (tree global_class_decl)
 {
-  if (!class_list)
-    class_list = VEC_alloc (tree, gc, imp_count?imp_count:1);
-  VEC_safe_push (tree, gc, class_list, global_class_decl);
+  vec_safe_push (class_list, global_class_decl);
 }
 
-static GTY(()) VEC(tree,gc) *nonlazy_class_list;
+static GTY(()) vec<tree, va_gc> *nonlazy_class_list;
 
 /* Add the global class meta-data declaration to the list which later
    on ends up in the __nonlazy_class section.  */
@@ -2010,12 +2008,10 @@ static GTY(()) VEC(tree,gc) *nonlazy_class_list;
 static void
 objc_v2_add_to_nonlazy_class_list (tree global_class_decl)
 {
-  if (!nonlazy_class_list)
-    nonlazy_class_list = VEC_alloc (tree, gc, imp_count?imp_count:1);
-  VEC_safe_push (tree, gc, nonlazy_class_list, global_class_decl);
+  vec_safe_push (nonlazy_class_list, global_class_decl);
 }
 
-static GTY(()) VEC(tree,gc) *category_list;
+static GTY(()) vec<tree, va_gc> *category_list;
 
 /* Add the category meta-data declaration to the list which later on
    ends up in the __nonlazy_category section.  */
@@ -2023,12 +2019,10 @@ static GTY(()) VEC(tree,gc) *category_list;
 static void
 objc_v2_add_to_category_list (tree decl)
 {
-  if (!category_list)
-    category_list = VEC_alloc (tree, gc, cat_count?cat_count:1);
-  VEC_safe_push (tree, gc, category_list, decl);
+  vec_safe_push (category_list, decl);
 }
 
-static GTY(()) VEC(tree,gc) *nonlazy_category_list;
+static GTY(()) vec<tree, va_gc> *nonlazy_category_list;
 
 /* Add the category meta-data declaration to the list which later on
    ends up in the __category_list section.  */
@@ -2036,9 +2030,7 @@ static GTY(()) VEC(tree,gc) *nonlazy_category_list;
 static void
 objc_v2_add_to_nonlazy_category_list (tree decl)
 {
-  if (!nonlazy_category_list)
-    nonlazy_category_list = VEC_alloc (tree, gc, cat_count?cat_count:1);
-  VEC_safe_push (tree, gc, nonlazy_category_list, decl);
+  vec_safe_push (nonlazy_category_list, decl);
 }
 
 static bool
@@ -2060,16 +2052,16 @@ has_load_impl (tree clsmeth)
    all @implemented {class,category} meta-data.  */
 
 static void
-build_v2_address_table (VEC(tree,gc) *src, const char *nam, tree attr)
+build_v2_address_table (vec<tree, va_gc> *src, const char *nam, tree attr)
 {
   int count=0;
   tree type, decl, expr;
-  VEC(constructor_elt,gc) *initlist = NULL;
+  vec<constructor_elt, va_gc> *initlist = NULL;
 
-  if (!src || !VEC_length(tree,src))
+  if (!vec_safe_length (src))
     return;
 
-  FOR_EACH_VEC_ELT (tree, src, count, decl)
+  FOR_EACH_VEC_ELT (*src, count, decl)
     {
 #ifndef OBJCPLUS
       tree purpose = build_int_cst (NULL_TREE, count);
@@ -2104,7 +2096,7 @@ build_v2_protocol_list_translation_table (void)
   if (!protrefs)
     return;
 
-  FOR_EACH_VEC_ELT (prot_list_entry, protrefs, count, ref)
+  FOR_EACH_VEC_ELT (*protrefs, count, ref)
     {
       char buf[BUFSIZE];
       tree expr;
@@ -2118,7 +2110,7 @@ build_v2_protocol_list_translation_table (void)
   /* TODO: Maybe we could explicitly delete the vec. now?  */
 }
 
-static GTY (()) VEC (prot_list_entry, gc) * protlist;
+static GTY (()) vec<prot_list_entry, va_gc> *protlist;
 
 /* Add the local protocol meta-data declaration to the list which
    later on ends up in the __protocol_list section.  */
@@ -2129,10 +2121,10 @@ objc_add_to_protocol_list (tree protocol_interface_decl, tree protocol_decl)
   prot_list_entry e;
   if (!protlist)
     /* Arbitrary init count.  */
-    protlist = VEC_alloc (prot_list_entry, gc, 32);
+    vec_alloc (protlist, 32);
   e.id = protocol_interface_decl;
   e.refdecl = protocol_decl;
-  VEC_safe_push (prot_list_entry, gc, protlist, &e);
+  vec_safe_push (protlist, e);
 }
 
 /* Build the __protocol_list section table containing address of all
@@ -2143,10 +2135,10 @@ build_v2_protocol_list_address_table (void)
 {
   int count;
   prot_list_entry *ref;
-  if (!protlist || !VEC_length (prot_list_entry, protlist))
+  if (!vec_safe_length (protlist))
     return;
 
-  FOR_EACH_VEC_ELT (prot_list_entry, protlist, count, ref)
+  FOR_EACH_VEC_ELT (*protlist, count, ref)
     {
       tree decl, expr;
       char buf[BUFSIZE];
@@ -2171,7 +2163,7 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt)
 {
   tree refs_decl, lproto, e, plist, ptempl_p_t;
   int size = 0;
-  VEC(constructor_elt,gc) *initlist = NULL;
+  vec<constructor_elt, va_gc> *initlist = NULL;
   char buf[BUFSIZE];
 
   if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
@@ -2243,16 +2235,16 @@ generate_v2_protocol_list (tree i_or_p, tree klass_ctxt)
    that the old ABI is supposed to build 'struct objc_method' which
    has 3 fields, but it does not build the initialization expression
    for 'method_imp' which for protocols is NULL any way.  To be
-   consistant with declaration of 'struct method_t', in the new ABI we
+   consistent with declaration of 'struct method_t', in the new ABI we
    set the method_t.imp to NULL.  */
 
 static tree
 build_v2_descriptor_table_initializer (tree type, tree entries)
 {
-  VEC(constructor_elt,gc) *initlist = NULL;
+  vec<constructor_elt, va_gc> *initlist = NULL;
   do
     {
-      VEC(constructor_elt,gc) *eltlist = NULL;
+      vec<constructor_elt, va_gc> *eltlist = NULL;
       CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,
                              build_selector (METHOD_SEL_NAME (entries)));
       CONSTRUCTOR_APPEND_ELT (eltlist, NULL_TREE,
@@ -2307,7 +2299,7 @@ generate_v2_meth_descriptor_table (tree chain, tree protocol,
 {
   tree method_list_template, initlist, decl, methods;
   int size, entsize;
-  VEC(constructor_elt,gc) *v = NULL;
+  vec<constructor_elt, va_gc> *v = NULL;
   char buf[BUFSIZE];
 
   if (!chain || !prefix)
@@ -2351,7 +2343,7 @@ static tree
 build_v2_property_table_initializer (tree type, tree context)
 {
   tree x;
-  VEC(constructor_elt,gc) *inits = NULL;
+  vec<constructor_elt, va_gc> *inits = NULL;
   if (TREE_CODE (context) == PROTOCOL_INTERFACE_TYPE)
     x = CLASS_PROPERTY_DECL (context);
   else
@@ -2359,7 +2351,7 @@ build_v2_property_table_initializer (tree type, tree context)
 
   for (; x; x = TREE_CHAIN (x))
     {
-      VEC(constructor_elt,gc) *elemlist = NULL;
+      vec<constructor_elt, va_gc> *elemlist = NULL;
       /* NOTE! sections where property name/attribute go MUST change
         later.  */
       tree attribute, name_ident = PROPERTY_NAME (x);
@@ -2418,7 +2410,7 @@ generate_v2_property_table (tree context, tree klass_ctxt)
 {
   tree x, decl, initlist, property_list_template;
   bool is_proto = false;
-  VEC(constructor_elt,gc) *inits = NULL;
+  vec<constructor_elt, va_gc> *inits = NULL;
   int init_val, size = 0;
   char buf[BUFSIZE];
 
@@ -2474,7 +2466,7 @@ build_v2_protocol_initializer (tree type, tree protocol_name, tree protocol_list
 {
   tree expr, ttyp;
   location_t loc;
-  VEC(constructor_elt,gc) *inits = NULL;
+  vec<constructor_elt, va_gc> *inits = NULL;
 
   /* TODO: find a better representation of location from the inputs.  */
   loc = UNKNOWN_LOCATION;
@@ -2621,7 +2613,7 @@ static tree
 generate_v2_dispatch_table (tree chain, const char *name, tree attr)
 {
   tree decl, method_list_template, initlist;
-  VEC(constructor_elt,gc) *v = NULL;
+  vec<constructor_elt, va_gc> *v = NULL;
   int size, init_val;
 
   if (!chain || !name || !(size = list_length (chain)))
@@ -2655,7 +2647,7 @@ build_v2_category_initializer (tree type, tree cat_name, tree class_name,
                                location_t loc)
 {
   tree expr, ltyp;
-  VEC(constructor_elt,gc) *v = NULL;
+  vec<constructor_elt, va_gc> *v = NULL;
 
   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
@@ -2767,15 +2759,13 @@ generate_v2_category (struct imp_entry *impent)
 /* This routine declares a variable to hold the offset for ivar
    FIELD_DECL.  Variable name is .objc_ivar.ClassName.IvarName.  */
 
-typedef struct GTY(()) ivarref_entry
+struct GTY(()) ivarref_entry
 {
   tree decl;
   tree offset;
-} ivarref_entry;
-DEF_VEC_O(ivarref_entry);
-DEF_VEC_ALLOC_O(ivarref_entry, gc);
+};
 
-static GTY (()) VEC (ivarref_entry, gc) * ivar_offset_refs;
+static GTY (()) vec<ivarref_entry, va_gc> *ivar_offset_refs;
 
 static tree
 ivar_offset_ref (tree class_name, tree field_decl)
@@ -2792,13 +2782,13 @@ ivar_offset_ref (tree class_name, tree field_decl)
     {
       int count;
       ivarref_entry *ref;
-      FOR_EACH_VEC_ELT (ivarref_entry, ivar_offset_refs, count, ref)
+      FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)
        if (DECL_NAME (ref->decl) == field_decl_id)
          return ref->decl;
     }
   else
     /* Somewhat arbitrary initial provision.  */
-    ivar_offset_refs = VEC_alloc (ivarref_entry, gc, 32);
+    vec_alloc (ivar_offset_refs, 32);
 
   /* We come here if we don't find a match or at the start.  */
   global_var = (TREE_PUBLIC (field_decl) || TREE_PROTECTED (field_decl));
@@ -2807,12 +2797,12 @@ ivar_offset_ref (tree class_name, tree field_decl)
   else
     decl = create_hidden_decl (TREE_TYPE (size_zero_node), buf);
 
-  /* Make sure it ends up in an ObjC section.  */
-  OBJCMETA (decl, objc_meta, meta_base);
+  /* Identify so that we can indirect these where the ABI requires.  */
+  OBJCMETA (decl, objc_meta, meta_ivar_ref);
 
   e.decl = decl;
   e.offset = byte_position (field_decl);
-  VEC_safe_push (ivarref_entry, gc, ivar_offset_refs, &e);
+  vec_safe_push (ivar_offset_refs, e);
   return decl;
 }
 
@@ -2824,11 +2814,11 @@ ivar_offset_ref (tree class_name, tree field_decl)
 static tree
 build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
 {
-  VEC(constructor_elt,gc) *inits = NULL;
+  vec<constructor_elt, va_gc> *inits = NULL;
 
   do
     {
-      VEC(constructor_elt,gc) *ivar = NULL;
+      vec<constructor_elt, va_gc> *ivar = NULL;
       int val;
       tree id;
 
@@ -2852,15 +2842,9 @@ build_v2_ivar_list_initializer (tree class_name, tree type, tree field_decl)
                                                meth_var_names));
 
       /* Set type.  */
-      encode_field_decl (field_decl,
-                        obstack_object_size (&util_obstack),
-                        OBJC_ENCODE_DONT_INLINE_DEFS);
-      /* Null terminate string.  */
-      obstack_1grow (&util_obstack, 0);
-      id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
+      id = add_objc_string (encode_field_decl (field_decl),
                             meth_var_types);
       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
-      obstack_free (&util_obstack, util_firstobj);
 
       /* Set alignment.  */
       val = DECL_ALIGN_UNIT (field_decl);
@@ -2926,7 +2910,7 @@ static tree
 generate_v2_ivars_list (tree chain, const char *name, tree attr, tree templ)
 {
   tree decl, initlist, ivar_list_template;
-  VEC(constructor_elt,gc) *inits = NULL;
+  vec<constructor_elt, va_gc> *inits = NULL;
   int size, ivar_t_size;
 
   if (!chain || !name || !(size = ivar_list_length (chain)))
@@ -2959,7 +2943,7 @@ static tree
 build_v2_class_t_initializer (tree type, tree isa, tree superclass,
                              tree ro, tree cache, tree vtable)
 {
-  VEC(constructor_elt,gc) *initlist = NULL;
+  vec<constructor_elt, va_gc> *initlist = NULL;
 
   /* isa */
   CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, isa);
@@ -2997,7 +2981,7 @@ build_v2_class_ro_t_initializer (tree type, tree name,
 {
   tree expr, unsigned_char_star, ltyp;
   location_t loc;
-  VEC(constructor_elt,gc) *initlist = NULL;
+  vec<constructor_elt, va_gc> *initlist = NULL;
 
   /* TODO: fish out the real location from somewhere.  */
   loc = UNKNOWN_LOCATION;
@@ -3071,7 +3055,7 @@ build_v2_class_ro_t_initializer (tree type, tree name,
   return objc_build_constructor (type, initlist);
 }
 
-static GTY (()) VEC (ident_data_tuple, gc) * ehtype_list;
+static GTY (()) vec<ident_data_tuple, va_gc> *ehtype_list;
 
 /* Record a name as needing a catcher.  */
 static void
@@ -3083,18 +3067,18 @@ objc_v2_add_to_ehtype_list (tree name)
       int count = 0;
       ident_data_tuple *ref;
 
-      FOR_EACH_VEC_ELT (ident_data_tuple, ehtype_list, count, ref)
+      FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
        if (ref->ident == name)
          return; /* Already entered.  */
      }
   else
     /* Arbitrary initial count.  */
-    ehtype_list = VEC_alloc (ident_data_tuple, gc, 8);
+    vec_alloc (ehtype_list, 8);
 
   /* Not found, or new list.  */
   e.ident = name;
   e.data = NULL_TREE;
-  VEC_safe_push (ident_data_tuple, gc, ehtype_list, &e);
+  vec_safe_push (ehtype_list, e);
 }
 
 static void
@@ -3288,7 +3272,7 @@ generate_v2_class_structs (struct imp_entry *impent)
 
   if (field && TREE_CODE (field) == FIELD_DECL)
     instanceSize = int_byte_position (field) * BITS_PER_UNIT
-                  + tree_low_cst (DECL_SIZE (field), 0);
+                  + tree_to_shwi (DECL_SIZE (field));
   else
     instanceSize = 0;
   instanceSize /= BITS_PER_UNIT;
@@ -3345,38 +3329,13 @@ build_v2_ivar_offset_ref_table (void)
   int count;
   ivarref_entry *ref;
 
-  if (!ivar_offset_refs || !VEC_length (ivarref_entry, ivar_offset_refs))
+  if (!vec_safe_length (ivar_offset_refs))
     return;
 
-  FOR_EACH_VEC_ELT (ivarref_entry, ivar_offset_refs, count, ref)
+  FOR_EACH_VEC_ELT (*ivar_offset_refs, count, ref)
     finish_var_decl (ref->decl, ref->offset);
 }
 
-/* static int _OBJC_IMAGE_INFO[2] = { 0, 16 | flags }; */
-
-static void
-generate_v2_objc_image_info (void)
-{
-  tree decl, array_type;
-  VEC(constructor_elt,gc) *v = NULL;
-  int flags =
-       ((flag_replace_objc_classes && imp_count ? 1 : 0)
-         | (flag_objc_gc ? 2 : 0));
-
-  flags |= 16;
-
-  array_type  = build_sized_array_type (integer_type_node, 2);
-
-  decl = start_var_decl (array_type, "_OBJC_ImageInfo");
-
-  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
-  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (integer_type_node, flags));
-  /* The Runtime wants this.  */
-  DECL_PRESERVE_P (decl) = 1;
-  OBJCMETA (decl, objc_meta, meta_info);
-  finish_var_decl (decl, objc_build_constructor (TREE_TYPE (decl), v));
-}
-
 static void
 objc_generate_v2_next_metadata (void)
 {
@@ -3428,9 +3387,6 @@ objc_generate_v2_next_metadata (void)
   build_v2_address_table (nonlazy_category_list, "_OBJC_NonLazyCategoryList$",
                          meta_label_nonlazy_categorylist);
 
-  /* This conveys information on GC usage and zero-link.  */
-  generate_v2_objc_image_info ();
-
   /* Generate catch objects for eh, if any are needed.  */
   build_v2_eh_catch_objects ();
 
@@ -3479,7 +3435,7 @@ build_v2_ehtype_template (void)
 static tree
 objc2_build_ehtype_initializer (tree name, tree cls)
 {
-  VEC(constructor_elt,gc) *initlist = NULL;
+  vec<constructor_elt, va_gc> *initlist = NULL;
   tree addr, offs;
 
   /* This is done the same way as c++, missing the two first entries
@@ -3497,7 +3453,7 @@ objc2_build_ehtype_initializer (tree name, tree cls)
     }
   addr = build_fold_addr_expr_with_type (next_v2_ehvtable_decl, ptr_type_node);
   offs = size_int (2 * int_cst_value (TYPE_SIZE_UNIT (ptr_type_node)));
-  addr = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, addr, offs);
+  addr = fold_build_pointer_plus (addr, offs);
 
   CONSTRUCTOR_APPEND_ELT (initlist, NULL_TREE, addr);
 
@@ -3567,10 +3523,10 @@ static void build_v2_eh_catch_objects (void)
   int count=0;
   ident_data_tuple *ref;
 
-  if (!ehtype_list || !VEC_length (ident_data_tuple, ehtype_list))
+  if (!vec_safe_length (ehtype_list))
     return;
 
-  FOR_EACH_VEC_ELT (ident_data_tuple, ehtype_list, count, ref)
+  FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
     {
       char buf[BUFSIZE];
       bool impl = is_implemented (ref->ident);
@@ -3591,10 +3547,10 @@ lookup_ehtype_ref (tree id)
   int count=0;
   ident_data_tuple *ref;
 
-  if (!ehtype_list || !VEC_length (ident_data_tuple, ehtype_list))
+  if (!vec_safe_length (ehtype_list))
     return NULL_TREE;
 
-  FOR_EACH_VEC_ELT (ident_data_tuple, ehtype_list, count, ref)
+  FOR_EACH_VEC_ELT (*ehtype_list, count, ref)
     if (ref->ident == id)
       return ref->data;
   return NULL_TREE;
@@ -3634,7 +3590,7 @@ next_runtime_02_eh_type (tree type)
         case, we use c++'s typeinfo decl.  */
       return build_eh_type_type (type);
 #else
-      error ("non-objective-c type '%T' cannot be caught", type);
+      error ("non-objective-c type %qT cannot be caught", type);
       goto err_mark_in;
 #endif
     }
@@ -3670,14 +3626,17 @@ build_throw_stmt (location_t loc, tree throw_expr, bool rethrown)
   tree t;
   if (rethrown)
     /* We have a separate re-throw entry.  */
-    t = build_function_call_vec (loc, objc_rethrow_exception_decl, NULL, NULL);
+    t = build_function_call_vec (loc, vNULL, objc_rethrow_exception_decl,
+                                NULL, NULL);
   else
     {
       /* Throw like the others...  */
-      VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
-      VEC_quick_push (tree, parms, throw_expr);
-      t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
-      VEC_free (tree, gc, parms);
+      vec<tree, va_gc> *parms;
+      vec_alloc (parms, 1);
+      parms->quick_push (throw_expr);
+      t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl,
+                                  parms, 0);
+      vec_free (parms);
     }
   return add_stmt (t);
 }
@@ -3688,7 +3647,7 @@ static tree
 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
 {
   tree t;
-  t = built_in_decls[BUILT_IN_EH_POINTER];
+  t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
   t = build_call_expr (t, 1, integer_zero_node);
   return fold_convert (objc_object_type, t);
 }
@@ -3755,7 +3714,8 @@ finish_catch (struct objc_try_context **cur_try_context, tree curr_catch)
 
   /* Pick up the new context we made in begin_try above...  */
   ct = *cur_try_context;
-  func = build_function_call_vec (loc, objc2_end_catch_decl, NULL, NULL);
+  func = build_function_call_vec (loc, vNULL, objc2_end_catch_decl, NULL,
+                                 NULL);
   append_to_statement_list (func, &ct->finally_body);
   try_exp = build_stmt (loc, TRY_FINALLY_EXPR, ct->try_body, ct->finally_body);
   *cur_try_context = ct->outer;