diff options
author | Ziemowit Laski <zlaski@apple.com> | 2004-10-31 06:17:55 +0000 |
---|---|---|
committer | Ziemowit Laski <zlaski@gcc.gnu.org> | 2004-10-31 06:17:55 +0000 |
commit | 16b34ad6620d4c6c692bdc5c739ba4241987d346 (patch) | |
tree | fd41069a69da16dfa7e8da375572cb0cbfc16ce8 /gcc | |
parent | 7fe63418838e0fade217715817d1349e206d5117 (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/c-common.h | 2 | ||||
-rw-r--r-- | gcc/c-typeck.c | 21 | ||||
-rw-r--r-- | gcc/objc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/objc/objc-act.c | 46 | ||||
-rw-r--r-- | gcc/stub-objc.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/objc.dg/local-decl-2.m | 42 |
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 |