OSDN Git Service

PR objc/43061
[pf3gnuchains/gcc-fork.git] / gcc / objc / objc-act.c
index e951b2a..10cc9bc 100644 (file)
@@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cp-tree.h"
 #else
 #include "c-tree.h"
+#include "c-lang.h"
 #endif
 
 #include "c-common.h"
@@ -870,9 +871,16 @@ objc_build_struct (tree klass, tree fields, tree super_name)
      finish_struct(), and then reinstate it afterwards.  */
 
   for (t = TYPE_NEXT_VARIANT (s); t; t = TYPE_NEXT_VARIANT (t))
-    objc_info
-      = chainon (objc_info,
-                build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
+    {
+      if (!TYPE_HAS_OBJC_INFO (t))
+       {
+         INIT_TYPE_OBJC_INFO (t);
+         TYPE_OBJC_INTERFACE (t) = klass;
+       }
+      objc_info
+       = chainon (objc_info,
+                  build_tree_list (NULL_TREE, TYPE_OBJC_INFO (t)));
+    }
 
   /* Point the struct at its related Objective-C class.  */
   INIT_TYPE_OBJC_INFO (s);
@@ -1516,6 +1524,9 @@ finish_var_decl (tree var, tree initializer)
   mark_decl_referenced (var);
   /* Mark the decl to avoid "defined but not used" warning.  */
   TREE_USED (var) = 1;
+  /* We reserve the right for the runtime to use/modify these variables
+     in ways that are opaque to us.  */
+  DECL_PRESERVE_P (var) = 1;
 }
 
 /* Find the decl for the constant string class reference.  This is only
@@ -2037,7 +2048,6 @@ objc_add_static_instance (tree constructor, tree class_decl)
   sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
   decl = build_decl (input_location,
                     VAR_DECL, get_identifier (buf), class_decl);
-  DECL_COMMON (decl) = 1;
   TREE_STATIC (decl) = 1;
   DECL_ARTIFICIAL (decl) = 1;
   TREE_USED (decl) = 1;
@@ -3108,7 +3118,7 @@ objc_substitute_decl (tree expr, tree oldexpr, tree newexpr)
       return build_indirect_ref (input_location,
                                 objc_substitute_decl (TREE_OPERAND (expr, 0),
                                                       oldexpr,
-                                                      newexpr), "->");
+                                                      newexpr), RO_ARROW);
     default:
       return expr;
     }
@@ -3474,7 +3484,7 @@ struct objc_try_context
   /* The CATCH_EXPR of an open @catch clause.  */
   tree current_catch;
 
-  /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR.  */
+  /* The VAR_DECL holding the Darwin equivalent of __builtin_eh_pointer.  */
   tree caught_decl;
   tree stack_decl;
   tree rethrow_decl;
@@ -3482,54 +3492,36 @@ struct objc_try_context
 
 static struct objc_try_context *cur_try_context;
 
+static GTY(()) tree objc_eh_personality_decl;
+
 /* This hook, called via lang_eh_runtime_type, generates a runtime object
    that represents TYPE.  For Objective-C, this is just the class name.  */
 /* ??? Isn't there a class object or some such?  Is it easy to get?  */
 
 #ifndef OBJCPLUS
-static tree
+tree
 objc_eh_runtime_type (tree type)
 {
   return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
 }
-#endif
-
-/* Initialize exception handling.  */
 
-static void
-objc_init_exceptions (void)
+tree
+objc_eh_personality (void)
 {
-  static bool done = false;
-  if (done)
-    return;
-  done = true;
+  if (!flag_objc_sjlj_exceptions
+      && !objc_eh_personality_decl)
+    objc_eh_personality_decl
+      = build_personality_function (USING_SJLJ_EXCEPTIONS
+                                   ? "__gnu_objc_personality_sj0"
+                                   : "__gnu_objc_personality_v0");
 
-  if (flag_objc_sjlj_exceptions)
-    {
-      /* On Darwin, ObjC exceptions require a sufficiently recent
-        version of the runtime, so the user must ask for them explicitly.  */
-      if (!flag_objc_exceptions)
-       warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
-                "exception syntax");
-    }
-#ifndef OBJCPLUS
-  else
-    {
-      c_eh_initialized_p = true;
-      eh_personality_libfunc
-       = init_one_libfunc (USING_SJLJ_EXCEPTIONS
-                           ? "__gnu_objc_personality_sj0"
-                           : "__gnu_objc_personality_v0");
-      default_init_unwind_resume_libfunc ();
-      using_eh_for_cleanups ();
-      lang_eh_runtime_type = objc_eh_runtime_type;
-    }
-#endif
+  return objc_eh_personality_decl;
 }
+#endif
 
-/* Build an EXC_PTR_EXPR, or the moral equivalent.  In the case of Darwin,
-   we'll arrange for it to be initialized (and associated with a binding)
-   later.  */
+/* 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 (void)
@@ -3545,7 +3537,12 @@ objc_build_exc_ptr (void)
       return var;
     }
   else
-    return build0 (EXC_PTR_EXPR, objc_object_type);
+    {
+      tree t;
+      t = built_in_decls[BUILT_IN_EH_POINTER];
+      t = build_call_expr (t, 1, integer_zero_node);
+      return fold_convert (objc_object_type, t);
+    }
 }
 
 /* Build "objc_exception_try_exit(&_stack)".  */
@@ -3554,7 +3551,7 @@ static tree
 next_sjlj_build_try_exit (void)
 {
   tree t;
-  t = build_fold_addr_expr (cur_try_context->stack_decl);
+  t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
   t = tree_cons (NULL, t, NULL);
   t = build_function_call (input_location,
                           objc_exception_try_exit_decl, t);
@@ -3575,14 +3572,14 @@ next_sjlj_build_enter_and_setjmp (void)
 {
   tree t, enter, sj, cond;
 
-  t = build_fold_addr_expr (cur_try_context->stack_decl);
+  t = build_fold_addr_expr_loc (input_location, cur_try_context->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 (cur_try_context->stack_decl,
                                get_identifier ("buf"));
-  t = build_fold_addr_expr (t);
+  t = build_fold_addr_expr_loc (input_location, t);
 #ifdef OBJCPLUS
   /* Convert _setjmp argument to type that is expected.  */
   if (TYPE_ARG_TYPES (TREE_TYPE (objc_setjmp_decl)))
@@ -3611,7 +3608,7 @@ next_sjlj_build_exc_extract (tree decl)
 {
   tree t;
 
-  t = build_fold_addr_expr (cur_try_context->stack_decl);
+  t = build_fold_addr_expr_loc (input_location, cur_try_context->stack_decl);
   t = tree_cons (NULL, t, NULL);
   t = build_function_call (input_location,
                           objc_exception_extract_decl, t);
@@ -3669,7 +3666,7 @@ next_sjlj_build_catch_list (void)
              cond = c_common_truthvalue_conversion (input_location, t);
            }
          t = build3 (COND_EXPR, void_type_node, cond, body, NULL);
-         SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
+         SET_EXPR_LOCATION (t, EXPR_LOCATION (stmt));
 
          *last = t;
          last = &COND_EXPR_ELSE (t);
@@ -3823,7 +3820,14 @@ objc_begin_try_stmt (location_t try_locus, tree body)
   c->end_try_locus = input_location;
   cur_try_context = c;
 
-  objc_init_exceptions ();
+  if (flag_objc_sjlj_exceptions)
+    {
+      /* On Darwin, ObjC exceptions require a sufficiently recent
+        version of the runtime, so the user must ask for them explicitly.  */
+      if (!flag_objc_exceptions)
+       warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
+                "exception syntax");
+    }
 
   if (flag_objc_sjlj_exceptions)
     objc_mark_locals_volatile (NULL);
@@ -3972,7 +3976,14 @@ objc_build_throw_stmt (location_t loc, tree throw_expr)
 {
   tree args;
 
-  objc_init_exceptions ();
+  if (flag_objc_sjlj_exceptions)
+    {
+      /* On Darwin, ObjC exceptions require a sufficiently recent
+        version of the runtime, so the user must ask for them explicitly.  */
+      if (!flag_objc_exceptions)
+       warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
+                "exception syntax");
+    }
 
   if (throw_expr == NULL)
     {
@@ -5015,8 +5026,8 @@ synth_forward_declarations (void)
 static void
 error_with_ivar (const char *message, tree decl)
 {
-  error ("%J%s %qs", decl,
-         message, identifier_to_locale (gen_declaration (decl)));
+  error_at (DECL_SOURCE_LOCATION (decl), "%s %qs",
+           message, identifier_to_locale (gen_declaration (decl)));
 
 }
 
@@ -5779,7 +5790,7 @@ generate_category (tree cat)
 static void
 generate_shared_structures (int cls_flags)
 {
-  tree sc_spec, decl_specs, decl;
+  tree decl;
   tree name_expr, super_expr, root_expr;
   tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
   tree cast_type, initlist, protocol_decl;
@@ -5836,9 +5847,6 @@ generate_shared_structures (int cls_flags)
 
   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
 
-  sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
-  decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
-
   decl = start_var_decl (objc_class_template,
                         IDENTIFIER_POINTER
                         (DECL_NAME (UOBJC_METACLASS_decl)));
@@ -6150,10 +6158,11 @@ check_duplicates (hash hsh, int methods, int is_class)
            {
              bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
 
-             warning (0, "multiple methods named %<%c%E%> found",
-                      (is_class ? '+' : '-'),
-                      METHOD_SEL_NAME (meth));
-             inform (0, "%Jusing %<%c%s%>", meth,
+             warning_at (input_location, 0,
+                         "multiple methods named %<%c%E%> found",
+                         (is_class ? '+' : '-'),
+                         METHOD_SEL_NAME (meth));
+             inform (DECL_SOURCE_LOCATION (meth), "using %<%c%s%>",
                      (type ? '-' : '+'),
                      identifier_to_locale (gen_method_decl (meth)));
            }
@@ -6161,10 +6170,11 @@ check_duplicates (hash hsh, int methods, int is_class)
            {
              bool type = TREE_CODE (meth) == INSTANCE_METHOD_DECL;
 
-             warning (0, "multiple selectors named %<%c%E%> found",
-                      (is_class ? '+' : '-'),
-                      METHOD_SEL_NAME (meth));
-             inform (0, "%Jfound %<%c%s%>", meth,
+             warning_at (input_location, 0,
+                         "multiple selectors named %<%c%E%> found",
+                         (is_class ? '+' : '-'),
+                         METHOD_SEL_NAME (meth));
+             inform (DECL_SOURCE_LOCATION (meth), "found %<%c%s%>",
                      (type ? '-' : '+'),
                      identifier_to_locale (gen_method_decl (meth)));
            }
@@ -6173,7 +6183,7 @@ check_duplicates (hash hsh, int methods, int is_class)
            {
              bool type = TREE_CODE (loop->value) == INSTANCE_METHOD_DECL;
 
-             inform (0, "%Jalso found %<%c%s%>", loop->value, 
+             inform (DECL_SOURCE_LOCATION (loop->value), "also found %<%c%s%>",
                      (type ? '-' : '+'),
                      identifier_to_locale (gen_method_decl (loop->value)));
            }
@@ -6259,7 +6269,6 @@ tree
 objc_build_message_expr (tree mess)
 {
   tree receiver = TREE_PURPOSE (mess);
-  location_t loc;
   tree sel_name;
 #ifdef OBJCPLUS
   tree args = TREE_PURPOSE (TREE_VALUE (mess));
@@ -6271,11 +6280,6 @@ objc_build_message_expr (tree mess)
   if (TREE_CODE (receiver) == ERROR_MARK || TREE_CODE (args) == ERROR_MARK)
     return error_mark_node;
 
-  if (CAN_HAVE_LOCATION_P (receiver))
-    loc = EXPR_LOCATION (receiver);
-  else
-    loc = input_location;
-
   /* Obtain the full selector name.  */
   if (TREE_CODE (args) == IDENTIFIER_NODE)
     /* A unary selector.  */
@@ -6438,7 +6442,7 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
     }
   else if (rtype)
     {
-      tree orig_rtype = rtype, saved_rtype;
+      tree orig_rtype = rtype;
 
       if (TREE_CODE (rtype) == POINTER_TYPE)
        rtype = TREE_TYPE (rtype);
@@ -6447,7 +6451,6 @@ objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
             && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
             && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
        rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
-      saved_rtype = rtype;
       if (TYPED_OBJECT (rtype))
        {
          rprotos = TYPE_OBJC_PROTOCOL_LIST (rtype);
@@ -6621,7 +6624,7 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
       method_params = tree_cons (NULL_TREE, lookup_object,
                                 tree_cons (NULL_TREE, selector,
                                            method_params));
-      method = build_fold_addr_expr (sender);
+      method = build_fold_addr_expr_loc (input_location, sender);
     }
   else
     {
@@ -6635,8 +6638,7 @@ build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
 
       t = tree_cons (NULL_TREE, selector, NULL_TREE);
       t = tree_cons (NULL_TREE, lookup_object, t);
-      method = build_function_call (loc,
-                                   sender, t);
+      method = build_function_call (loc, sender, t);
 
       /* Pass the object to the method.  */
       method_params = tree_cons (NULL_TREE, object,
@@ -6824,7 +6826,8 @@ build_ivar_reference (tree id)
     }
 
   return objc_build_component_ref (build_indirect_ref (input_location,
-                                                      self_decl, "->"), id);
+                                                      self_decl, RO_ARROW),
+                                  id);
 }
 \f
 /* Compute a hash value for a given method SEL_NAME.  */
@@ -8302,8 +8305,6 @@ encode_gnu_bitfield (int position, tree type, int size)
 static void
 encode_field_decl (tree field_decl, int curtype, int format)
 {
-  tree type;
-
 #ifdef OBJCPLUS
   /* C++ static members, and things that are not fields at all,
      should not appear in the encoding.  */
@@ -8311,8 +8312,6 @@ encode_field_decl (tree field_decl, int curtype, int format)
     return;
 #endif
 
-  type = TREE_TYPE (field_decl);
-
   /* Generate the bitfield typing information, if needed.  Note the difference
      between GNU and NeXT runtimes.  */
   if (DECL_BIT_FIELD_TYPE (field_decl))
@@ -8733,10 +8732,12 @@ really_start_method (tree method,
            {
              bool type = TREE_CODE (method) == INSTANCE_METHOD_DECL;
 
-             warning (0, "%Jconflicting types for %<%c%s%>", method,
-                      (type ? '-' : '+'),
-                      identifier_to_locale (gen_method_decl (method)));
-             inform (0, "%Jprevious declaration of %<%c%s%>", proto,
+             warning_at (DECL_SOURCE_LOCATION (method), 0,
+                         "conflicting types for %<%c%s%>",
+                         (type ? '-' : '+'),
+                         identifier_to_locale (gen_method_decl (method)));
+             inform (DECL_SOURCE_LOCATION (proto),
+                     "previous declaration of %<%c%s%>",
                      (type ? '-' : '+'),
                      identifier_to_locale (gen_method_decl (proto)));
            }
@@ -8844,7 +8845,7 @@ get_super_receiver (void)
                      (input_location,
                       build_c_cast (input_location,
                                     build_pointer_type (objc_class_type),
-                                    super_class), "unary *");
+                                    super_class), RO_UNARY_STAR);
            }
          else
            {