OSDN Git Service

PR c/772
[pf3gnuchains/gcc-fork.git] / gcc / objc / objc-act.c
index b77e441..2c8a738 100644 (file)
@@ -1,6 +1,6 @@
 /* Implement classes and message passing for Objective C.
    Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Steve Naroff.
 
 This file is part of GCC.
@@ -73,6 +73,7 @@ Boston, MA 02111-1307, USA.  */
 #include "tree-iterator.h"
 #include "libfuncs.h"
 #include "hashtab.h"
+#include "langhooks-def.h"
 
 #define OBJC_VOID_AT_END       void_list_node
 
@@ -590,6 +591,7 @@ objc_finish_file (void)
 #ifdef OBJCPLUS
   /* We need to instantiate templates _before_ we emit ObjC metadata;
      if we do not, some metadata (such as selectors) may go missing.  */
+  at_eof = 1;
   instantiate_pending_templates (0);
 #endif
 
@@ -603,8 +605,6 @@ objc_finish_file (void)
 
 #ifdef OBJCPLUS
   cp_finish_file ();
-#else
-  maybe_apply_pending_pragma_weaks ();
 #endif
 }
 \f
@@ -838,6 +838,27 @@ objc_is_class_id (tree type)
   return OBJC_TYPE_NAME (type) == objc_class_id;
 }
 
+
+int
+objc_types_compatible_p (tree type1, tree type2)
+{
+
+  if (objc_is_object_ptr (type1) || objc_is_object_ptr (type2)
+      || objc_is_class_name (type1) || objc_is_class_name (type2))
+    {
+      return lhd_types_compatible_p (type1, type2);
+    }
+  else
+    {
+#ifdef OBJCPLUS
+      return cxx_types_compatible_p (type1, type2);
+#else
+      return c_types_compatible_p (type1, type2);
+#endif
+    }
+}
+
+
 /* Return 1 if LHS and RHS are compatible types for assignment or
    various other operations.  Return 0 if they are incompatible, and
    return -1 if we choose to not decide (because the types are really
@@ -2344,8 +2365,15 @@ build_selector_translation_table (void)
               }
           }
         if (!found)
-         warning ("%Jcreating selector for nonexistent method %qE",
-                  TREE_PURPOSE (chain), TREE_VALUE (chain));
+         {
+           location_t *loc;
+           if (flag_next_runtime && TREE_PURPOSE (chain))
+             loc = &DECL_SOURCE_LOCATION (TREE_PURPOSE (chain));
+           else
+             loc = &input_location;
+           warning ("%Hcreating selector for nonexistent method %qE",
+                    loc, TREE_VALUE (chain));
+         }
       }
 
       expr = build_selector (TREE_VALUE (chain));
@@ -2991,7 +3019,7 @@ next_sjlj_build_enter_and_setjmp (void)
   sj = build_function_call (objc_setjmp_decl, t);
 
   cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
-  cond = lang_hooks.truthvalue_conversion (cond);
+  cond = c_common_truthvalue_conversion (cond);
 
   return build (COND_EXPR, void_type_node, cond, NULL, NULL);
 }
@@ -3058,7 +3086,7 @@ next_sjlj_build_catch_list (void)
              t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
              args = tree_cons (NULL, t, args);
              t = build_function_call (objc_exception_match_decl, args);
-             cond = lang_hooks.truthvalue_conversion (t);
+             cond = c_common_truthvalue_conversion (t);
            }
          t = build (COND_EXPR, void_type_node, cond, body, NULL);
          SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
@@ -3180,7 +3208,7 @@ next_sjlj_build_try_catch_finally (void)
   /* Build the complete FINALLY statement list.  */
   t = next_sjlj_build_try_exit ();
   t = build_stmt (COND_EXPR,
-                 lang_hooks.truthvalue_conversion (rethrow_decl),
+                 c_common_truthvalue_conversion (rethrow_decl),
                  NULL, t);
   SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
@@ -3191,7 +3219,7 @@ next_sjlj_build_try_catch_finally (void)
   t = tree_cons (NULL, rethrow_decl, NULL);
   t = build_function_call (objc_exception_throw_decl, t);
   t = build_stmt (COND_EXPR,
-                 lang_hooks.truthvalue_conversion (rethrow_decl),
+                 c_common_truthvalue_conversion (rethrow_decl),
                  t, NULL);
   SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
   append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
@@ -5300,6 +5328,12 @@ get_arg_type_list (tree meth, int context, int superflag)
     {
       tree arg_type = TREE_VALUE (TREE_TYPE (akey));
 
+      /* Decay arrays and functions into pointers.  */
+      if (TREE_CODE (arg_type) == ARRAY_TYPE)
+       arg_type = build_pointer_type (TREE_TYPE (arg_type));
+      else if (TREE_CODE (arg_type) == FUNCTION_TYPE)
+       arg_type = build_pointer_type (arg_type);
+
       chainon (arglist, build_tree_list (NULL_TREE, arg_type));
     }
 
@@ -7377,11 +7411,22 @@ static GTY(()) tree objc_parmlist = NULL_TREE;
 static void
 objc_push_parm (tree parm)
 {
-  /* Convert array parameters of unknown size into pointers.  */
-  if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
-      && !TYPE_SIZE (TREE_TYPE (parm)))
+  /* Decay arrays and functions into pointers.  */
+  if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE)
     TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
-
+  else if (TREE_CODE (TREE_TYPE (parm)) == FUNCTION_TYPE)
+    TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (parm));
+
+  DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm);
+  DECL_ARG_TYPE (parm)
+    = lang_hooks.types.type_promotes_to (TREE_TYPE (parm));
+
+  /* Record constancy and volatility.  */
+  c_apply_type_quals_to_decl
+  ((TYPE_READONLY (TREE_TYPE (parm)) ? TYPE_QUAL_CONST : 0)
+   | (TYPE_RESTRICT (TREE_TYPE (parm)) ? TYPE_QUAL_RESTRICT : 0)
+   | (TYPE_VOLATILE (TREE_TYPE (parm)) ? TYPE_QUAL_VOLATILE : 0), parm);
+  
   objc_parmlist = chainon (objc_parmlist, parm);
 }
 
@@ -7413,7 +7458,8 @@ objc_get_parm_info (int have_ellipsis)
       tree next = TREE_CHAIN (parm_info);
 
       TREE_CHAIN (parm_info) = NULL_TREE; 
-      pushdecl (parm_info);
+      parm_info = pushdecl (parm_info);
+      finish_decl (parm_info, NULL_TREE, NULL_TREE);
       parm_info = next;
     }
   arg_info = get_parm_info (have_ellipsis);
@@ -7473,9 +7519,9 @@ start_method_def (tree method)
   parmlist = METHOD_SEL_ARGS (method);
   while (parmlist)
     {
-      tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
-                             TREE_VALUE (TREE_TYPE (parmlist)));
+      tree type = TREE_VALUE (TREE_TYPE (parmlist)), parm;
 
+      parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist), type);
       objc_push_parm (parm);
       parmlist = TREE_CHAIN (parmlist);
     }
@@ -7613,24 +7659,32 @@ objc_start_function (tree name, tree type, tree attrs,
 
 #ifdef OBJCPLUS
   DECL_ARGUMENTS (fndecl) = params;
-#endif
   DECL_INITIAL (fndecl) = error_mark_node;
   DECL_EXTERNAL (fndecl) = 0;
   TREE_STATIC (fndecl) = 1;
-
-#ifdef OBJCPLUS
   retrofit_lang_decl (fndecl);
   cplus_decl_attributes (&fndecl, attrs, 0);
   start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
 #else
+  struct c_label_context *nstack;
+  nstack = XOBNEW (&parser_obstack, struct c_label_context);
+  nstack->labels_def = NULL;
+  nstack->labels_used = NULL;
+  nstack->next = label_context_stack;
+  label_context_stack = nstack;
   decl_attributes (&fndecl, attrs, 0);
   announce_function (fndecl);
+  DECL_INITIAL (fndecl) = error_mark_node;
+  DECL_EXTERNAL (fndecl) = 0;
+  TREE_STATIC (fndecl) = 1;
   current_function_decl = pushdecl (fndecl);
   push_scope ();
   declare_parm_level ();
   DECL_RESULT (current_function_decl)
     = build_decl (RESULT_DECL, NULL_TREE,
                  TREE_TYPE (TREE_TYPE (current_function_decl)));
+  DECL_ARTIFICIAL (DECL_RESULT (current_function_decl)) = 1;
+  DECL_IGNORED_P (DECL_RESULT (current_function_decl)) = 1;
   start_fname_decls ();
   store_parm_decls_from (params);
 #endif
@@ -7941,14 +7995,39 @@ gen_type_name_0 (tree type)
 
   if (TYPE_P (type) && TYPE_NAME (type))
     type = TYPE_NAME (type);
-  else if (POINTER_TYPE_P (type))
+  else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
     {
-      gen_type_name_0 (TREE_TYPE (type));
+      tree inner = TREE_TYPE (type);
+
+      while (TREE_CODE (inner) == ARRAY_TYPE)
+       inner = TREE_TYPE (inner);
+
+      gen_type_name_0 (inner);
       
-      if (!POINTER_TYPE_P (TREE_TYPE (type)))
+      if (!POINTER_TYPE_P (inner))
        strcat (errbuf, " ");
 
-      strcat (errbuf, "*");
+      if (POINTER_TYPE_P (type))
+       strcat (errbuf, "*");
+      else
+       while (type != inner)
+         {
+           strcat (errbuf, "[");
+
+           if (TYPE_DOMAIN (type))
+             {
+               char sz[20];
+
+               sprintf (sz, HOST_WIDE_INT_PRINT_DEC,
+                        (TREE_INT_CST_LOW 
+                         (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1));
+               strcat (errbuf, sz);
+             }
+
+           strcat (errbuf, "]");
+           type = TREE_TYPE (type);
+         }
+
       goto exit_function;
     }