c-common.h (objc_lookup_ivar): Add second parameter to prototype.
authorZiemowit Laski <zlaski@apple.com>
Sun, 31 Oct 2004 06:17:55 +0000 (06:17 +0000)
committerZiemowit Laski <zlaski@gcc.gnu.org>
Sun, 31 Oct 2004 06:17:55 +0000 (06:17 +0000)
[gcc/ChangeLog]
2004-10-30  Ziemowit Laski  <zlaski@apple.com>

        * c-common.h (objc_lookup_ivar): Add second parameter to
        prototype.
        * c-typeck.c (build_external_ref): After looking up symbol,
        pass it to objc_lookup_ivar() to decide whether it or the
        ivar should be used, rather than deciding the issue locally.
        * stub-objc.c (objc_lookup_ivar): Add an OTHER parameter,
        which is simply returned in the non-ObjC case.

[gcc/objc/ChangeLog]
2004-10-30  Ziemowit Laski  <zlaski@apple.com>

        * objc-act.c (objc_lookup_ivar): The new OTHER parameter
        contains the result of the ID lookup by the C or C++
        front-end; in class methods, use OTHER if it exists;
        in instance methods, use OTHER only if it is locally
        declared.

[gcc/testsuite/ChangeLog]
2004-10-30  Ziemowit Laski  <zlaski@apple.com>

        * objc.dg/local-decl-1.m: New test.

From-SVN: r89912

gcc/ChangeLog
gcc/c-common.h
gcc/c-typeck.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/stub-objc.c
gcc/testsuite/ChangeLog
gcc/testsuite/objc.dg/local-decl-2.m [new file with mode: 0644]

index a689a2a2c260077e6298acbc65184492ae233c64..8fd5efb79f49fb2e391d27773d7bc2a44164e2d6 100644 (file)
@@ -1,3 +1,13 @@
+2004-10-30  Ziemowit Laski  <zlaski@apple.com>
+
+       * c-common.h (objc_lookup_ivar): Add second parameter to
+       prototype.
+       * c-typeck.c (build_external_ref): After looking up symbol,
+       pass it to objc_lookup_ivar() to decide whether it or the
+       ivar should be used, rather than deciding the issue locally.
+       * stub-objc.c (objc_lookup_ivar): Add an OTHER parameter,
+       which is simply returned in the non-ObjC case.
+
 2004-10-30  Danny Smith  <dannysmith@users.sourceforge.net>
 
        * sdbout.c (sdbout_symbol): Do not output type .def statements
index 95aaf8c115aaa8138cae6d7041e1b61711b3f091..1406177514e28ecde57459764ceabcc255eaefa4 100644 (file)
@@ -905,7 +905,7 @@ extern void objc_check_decl (tree);
 extern int objc_is_reserved_word (tree);
 extern int objc_comptypes (tree, tree, int);
 extern tree objc_message_selector (void);
-extern tree objc_lookup_ivar (tree);
+extern tree objc_lookup_ivar (tree, tree);
 extern void objc_clear_super_receiver (void);
 extern int objc_is_public (tree, tree);
 extern tree objc_is_id (tree);
index 7d599bce05ca58fe12666689a8936f8bcda025a1..728e768a7f63ee23218a60b055353c6d830af7e5 100644 (file)
@@ -1724,24 +1724,13 @@ build_external_ref (tree id, int fun)
 {
   tree ref;
   tree decl = lookup_name (id);
-  tree objc_ivar = objc_lookup_ivar (id);
+
+  /* In Objective-C, an instance variable (ivar) may be preferred to
+     whatever lookup_name() found.  */
+  decl = objc_lookup_ivar (decl, id);
 
   if (decl && decl != error_mark_node)
-    {
-      /* Properly declared variable or function reference.  */
-      if (!objc_ivar)
-       ref = decl;
-      else if (decl != objc_ivar && !DECL_FILE_SCOPE_P (decl))
-       {
-         warning ("local declaration of %qs hides instance variable",
-                  IDENTIFIER_POINTER (id));
-         ref = decl;
-       }
-      else
-       ref = objc_ivar;
-    }
-  else if (objc_ivar)
-    ref = objc_ivar;
+    ref = decl;
   else if (fun)
     /* Implicit function declaration.  */
     ref = implicitly_declare (id);
index 7bb40f7cac9882f5e3d58b4a8552e1b4492b2e87..700cb04fea3ef4f28da98d70737d45b24089ea21 100644 (file)
@@ -1,3 +1,11 @@
+2004-10-30  Ziemowit Laski  <zlaski@apple.com>
+
+       * objc-act.c (objc_lookup_ivar): The new OTHER parameter
+       contains the result of the ID lookup by the C or C++
+       front-end; in class methods, use OTHER if it exists;
+       in instance methods, use OTHER only if it is locally
+       declared.
+
 2004-10-26  Ziemowit Laski  <zlaski@apple.com>
 
        * objc-act.c (finish_class): Do not synthesize bogus
index 7b21ede8cdf8e7708e97387a84b692e5c4a9ff9c..3474ded418fb00c679a4e5237acc8c61f6320c1b 100644 (file)
@@ -8435,25 +8435,49 @@ generate_objc_image_info (void)
   finish_var_decl (decl, initlist);
 }
 
-/* Look up ID as an instance variable.  */
+/* Look up ID as an instance variable.  OTHER contains the result of
+   the C or C++ lookup, which we may want to use instead.  */
 
 tree
-objc_lookup_ivar (tree id)
+objc_lookup_ivar (tree other, tree id)
 {
-  tree decl;
+  tree ivar;
+
+  /* If we are not inside of an ObjC method, ivar lookup makes no sense.  */
+  if (!objc_method_context)
+    return other;
 
-  if (objc_method_context && !strcmp (IDENTIFIER_POINTER (id), "super"))
+  if (!strcmp (IDENTIFIER_POINTER (id), "super"))
     /* We have a message to super.  */
     return get_super_receiver ();
-  else if (objc_method_context && (decl = is_ivar (objc_ivar_chain, id)))
+
+  /* In a class method, look up an instance variable only as a last
+     resort.  */
+  if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
+      && other && other != error_mark_node)
+    return other;
+
+  /* Look up the ivar, but do not use it if it is not accessible.  */
+  ivar = is_ivar (objc_ivar_chain, id);
+
+  if (!ivar || is_private (ivar))
+    return other;
+
+  /* In an instance method, a local variable (or parameter) may hide the
+     instance variable.  */
+  if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
+      && other && other != error_mark_node && !DECL_FILE_SCOPE_P (other))
     {
-      if (is_private (decl))
-       return 0;
-      else
-        return build_ivar_reference (id);
+      warning ("local declaration of %qs hides instance variable",
+              IDENTIFIER_POINTER (id));
+
+      return other;
     }
-  else
-    return 0;
+
+  /* At this point, we are either in an instance method with no obscuring
+     local definitions, or in a class method with no alternate definitions
+     at all.  */
+  return build_ivar_reference (id);
 }
 
 #include "gt-objc-objc-act.h"
index 9e874a2507eee454578464ff3798f2d29a90713f..f01fd9b424928279105e8a260b8fd04f7f01aed8 100644 (file)
@@ -46,9 +46,10 @@ objc_is_object_ptr (tree ARG_UNUSED (arg))
 }
 
 tree
-objc_lookup_ivar (tree ARG_UNUSED (arg))
+objc_lookup_ivar (tree other, tree ARG_UNUSED (arg))
 {
-  return 0;
+  /* Just use whatever C/C++ found.  */
+  return other;
 }
 
 void
index 98b107fc85367e8f9dcf89264b90b51adcf38bf6..d4ecff0e4bf24a2c8a5e364c8a3e94adf162aa61 100644 (file)
@@ -1,3 +1,7 @@
+2004-10-30  Ziemowit Laski  <zlaski@apple.com>
+
+       * objc.dg/local-decl-1.m: New test.
+
 2004-10-30  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * gcc.dg/20040910-1.c: Adjust regex.
diff --git a/gcc/testsuite/objc.dg/local-decl-2.m b/gcc/testsuite/objc.dg/local-decl-2.m
new file mode 100644 (file)
index 0000000..41c4206
--- /dev/null
@@ -0,0 +1,42 @@
+/* Test for ivar access inside of class methods.  It should be allowed (with a warning), but only
+   if no other declarations with the same name are seen.  */
+/* Author: Ziemowit Laski <zlaski@apple.com>.  */
+/* { dg-do compile } */
+
+#include <objc/Object.h>
+
+@interface Sprite: Object {
+  int sprite, spree;
+}
++ (void)setFoo:(int)foo;
++ (void)setSprite:(int)sprite;
+- (void)setFoo:(int)foo;
+- (void)setSprite:(int)sprite;
+@end
+
+int spree = 23;
+
+@implementation Sprite
++ (void)setFoo:(int)foo {
+  sprite = foo;  /* { dg-warning "instance variable .sprite. accessed in class method" } */
+  spree = foo;
+}
++ (void)setSprite:(int)sprite {
+  int spree;
+  sprite = 15;
+  spree = 17;
+  ((Sprite *)self)->sprite = 16;   /* NB: This is how one _should_ access */
+  ((Sprite *)self)->spree = 18;    /* ivars from within class methods!    */
+}
+- (void)setFoo:(int)foo {
+  sprite = foo;
+  spree = foo;
+}
+- (void)setSprite:(int)sprite {
+  int spree;
+  sprite = 15;  /* { dg-warning "local declaration of .sprite. hides instance variable" } */
+  self->sprite = 16;
+  spree = 17;  /* { dg-warning "local declaration of .spree. hides instance variable" } */
+  self->spree = 18;
+}   
+@end