aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorZiemowit Laski <zlaski@apple.com>2004-10-31 06:17:55 +0000
committerZiemowit Laski <zlaski@gcc.gnu.org>2004-10-31 06:17:55 +0000
commit16b34ad6620d4c6c692bdc5c739ba4241987d346 (patch)
treefd41069a69da16dfa7e8da375572cb0cbfc16ce8 /gcc
parent7fe63418838e0fade217715817d1349e206d5117 (diff)
downloadgcc-16b34ad6620d4c6c692bdc5c739ba4241987d346.zip
gcc-16b34ad6620d4c6c692bdc5c739ba4241987d346.tar.gz
gcc-16b34ad6620d4c6c692bdc5c739ba4241987d346.tar.bz2
c-common.h (objc_lookup_ivar): Add second parameter to prototype.
[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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-common.h2
-rw-r--r--gcc/c-typeck.c21
-rw-r--r--gcc/objc/ChangeLog8
-rw-r--r--gcc/objc/objc-act.c46
-rw-r--r--gcc/stub-objc.c5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/objc.dg/local-decl-2.m42
8 files changed, 108 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a689a2a..8fd5efb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-common.h b/gcc/c-common.h
index 95aaf8c..1406177 100644
--- a/gcc/c-common.h
+++ b/gcc/c-common.h
@@ -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);
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index 7d599bc..728e768 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -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);
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 7bb40f7..700cb04 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -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
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 7b21ede..3474ded 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -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"
diff --git a/gcc/stub-objc.c b/gcc/stub-objc.c
index 9e874a2..f01fd9b 100644
--- a/gcc/stub-objc.c
+++ b/gcc/stub-objc.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 98b107f..d4ecff0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..41c4206
--- /dev/null
+++ b/gcc/testsuite/objc.dg/local-decl-2.m
@@ -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