OSDN Git Service

PR objc/25965
authornicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Sep 2010 18:51:34 +0000 (18:51 +0000)
committernicola <nicola@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Sep 2010 18:51:34 +0000 (18:51 +0000)
In gcc/objc/:
       * objc-act.c (objc_get_interface_ivars): New function.
       (objc_collecting_ivars): New variable.
       (continue_class): Set and reset objc_collecting_ivars for context.
In gcc/:
       * c-decl.c (detect_field_duplicates): If compiling Objective-C,
       call objc_get_interface_ivars ().
       * c-family/c-common.h (objc_get_interface_ivars): New declaration.
       * c-family/stub-objc.c (objc_get_interface_ivars): New stub.
In gcc/objcp/:
       * objcp-decl.c (objcp_finish_struct): Call
       objc_get_interface_ivars() and check for duplicate ivars.

In gcc/testsuite/:
       Merge from 'apple/trunk' branch on FSF servers.

       2005-10-11  Fariborz Jahanian <fjahanian@apple.com>

               Radar 4291785

               objc.dg/naming-4.m: New
               objc.dg/naming-5.m: New
               obj-c++.dg/naming-1.mm: New
               obj-c++.dg/naming-2.mm: New

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164491 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
gcc/ChangeLog
gcc/c-decl.c
gcc/c-family/c-common.h
gcc/c-family/stub-objc.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/objcp/ChangeLog
gcc/objcp/objcp-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/naming-1.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/naming-2.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/naming-4.m [new file with mode: 0644]
gcc/testsuite/objc.dg/naming-5.m [new file with mode: 0644]

index 07cea55..eb4e36a 100644 (file)
@@ -1,3 +1,11 @@
+2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       PR objc/25965
+       * c-decl.c (detect_field_duplicates): If compiling Objective-C,
+       call objc_get_interface_ivars ().
+       * c-family/c-common.h (objc_get_interface_ivars): New declaration.
+       * c-family/stub-objc.c (objc_get_interface_ivars): New stub.
+       
 2010-09-21  Kai Tietz  <kai.tietz@onevision.com>
 
        PR target/45694
index 6c65b27..f8be06b 100644 (file)
@@ -6718,6 +6718,17 @@ detect_field_duplicates (tree fieldlist)
   tree x, y;
   int timeout = 10;
 
+  /* If the struct is the list of instance variables of an Objective-C
+     class, then we need to add all the instance variables of
+     superclasses before checking for duplicates (since you can't have
+     an instance variable in a subclass with the same name as an
+     instance variable in a superclass).  objc_get_interface_ivars()
+     leaves fieldlist unchanged if we are not in this case, so in that
+     case nothing changes compared to C.
+  */
+  if (c_dialect_objc ())
+    fieldlist = objc_get_interface_ivars (fieldlist);
+
   /* First, see if there are more than "a few" fields.
      This is trivially true if there are zero or one fields.  */
   if (!fieldlist)
index 378b68a..ae31b7c 100644 (file)
@@ -962,6 +962,7 @@ extern tree objc_build_string_object (tree);
 extern tree objc_get_protocol_qualified_type (tree, tree);
 extern tree objc_get_class_reference (tree);
 extern tree objc_get_class_ivars (tree);
+extern tree objc_get_interface_ivars (tree);
 extern void objc_start_class_interface (tree, tree, tree);
 extern void objc_start_category_interface (tree, tree, tree);
 extern void objc_start_protocol (tree, tree);
index b7748f7..3cb45d0 100644 (file)
@@ -248,6 +248,12 @@ objc_get_class_reference (tree ARG_UNUSED (name))
 }
 
 tree
+objc_get_interface_ivars (tree ARG_UNUSED (fieldlist))
+{
+  return 0;
+}
+
+tree
 objc_get_protocol_qualified_type (tree ARG_UNUSED (name),
                                  tree ARG_UNUSED (protos))
 {
index 132679b..87dcec8 100644 (file)
@@ -1,3 +1,10 @@
+2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       PR objc/25965
+       * objc-act.c (objc_get_interface_ivars): New function.
+       (objc_collecting_ivars): New variable.
+       (continue_class): Set and reset objc_collecting_ivars for context.
+       
 2010-09-15  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        Merge from 'apple/trunk' branch on FSF servers.
index d8fbe36..5794238 100644 (file)
@@ -371,6 +371,8 @@ int objc_public_flag;
 /* Use to generate method labels.  */
 static int method_slot = 0;
 
+static int objc_collecting_ivars = 0;
+
 #define BUFSIZE                1024
 
 static char *errbuf;   /* Buffer for error diagnostics */
@@ -3453,6 +3455,21 @@ objc_get_class_ivars (tree class_name)
   return error_mark_node;
 }
 
+/* Called when checking the variables in a struct.  If we are not
+   doing the ivars list inside an @interface context, then returns
+   fieldlist unchanged.  Else, returns the list of class ivars.
+*/
+tree
+objc_get_interface_ivars (tree fieldlist)
+{
+  if (!objc_collecting_ivars || !objc_interface_context 
+      || TREE_CODE (objc_interface_context) != CLASS_INTERFACE_TYPE
+      || CLASS_SUPER_NAME (objc_interface_context) == NULL_TREE)
+    return fieldlist;
+
+  return get_class_ivars (objc_interface_context, true);
+}
+
 /* Used by: build_private_template, continue_class,
    and for @defs constructs.  */
 
@@ -7714,7 +7731,9 @@ continue_class (tree klass)
       push_lang_context (lang_name_c);
 #endif /* OBJCPLUS */
 
+      objc_collecting_ivars = 1;
       build_private_template (klass);
+      objc_collecting_ivars = 0;
 
 #ifdef OBJCPLUS
       pop_lang_context ();
index 109d232..e7fe12b 100644 (file)
@@ -1,3 +1,9 @@
+2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       PR objc/25965   
+       * objcp-decl.c (objcp_finish_struct): Call
+       objc_get_interface_ivars() and check for duplicate ivars.
+
 2010-06-28  Steven Bosscher  <steven@gcc.gnu.org>
 
        * objcp-lang.c: Do not include except.h.
index 8c68876..af19a05 100644 (file)
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "cp-tree.h"
+#include "hashtab.h"
 
 #include "objc-act.h"
 #include "objcp-decl.h"
@@ -63,6 +64,39 @@ objcp_finish_struct (location_t loc ATTRIBUTE_UNUSED,
     finish_member_declaration (field);
   }
   t = finish_struct (t, attributes);
+
+  /* If we are inside an @interface and are generating the list of
+     ivars, we need to check for duplicate ivars.
+  */
+  if (fieldlist)
+    {
+      tree original_fieldlist = fieldlist;
+      fieldlist = objc_get_interface_ivars (fieldlist);
+      if (fieldlist != original_fieldlist)
+       {
+         /* Minimal implementation of the equivalent of the C
+            front-end's detect_field_duplicates().
+         */
+         htab_t htab = htab_create (37, htab_hash_pointer, htab_eq_pointer, NULL);
+         tree x, y;
+         void **slot;
+         
+         for (x = fieldlist; x ; x = DECL_CHAIN (x))
+           if ((y = DECL_NAME (x)) != 0)
+             {
+               slot = htab_find_slot (htab, y, INSERT);
+               if (*slot)
+                 {
+                   error ("duplicate member %q+D", x);
+                   DECL_NAME (x) = NULL_TREE;
+                 }
+               *slot = y;
+             }
+         
+         htab_delete (htab);
+       }
+    }
+
   pop_lang_context ();
 
   return t;
index fd14eab..b9ca99d 100644 (file)
@@ -1,3 +1,16 @@
+2010-09-21  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       Merge from 'apple/trunk' branch on FSF servers.
+
+       2005-10-11  Fariborz Jahanian <fjahanian@apple.com>
+
+               Radar 4291785
+               
+               objc.dg/naming-4.m: New
+               objc.dg/naming-5.m: New
+               obj-c++.dg/naming-1.mm: New
+               obj-c++.dg/naming-2.mm: New
+
 2010-09-21  Jonathan Wakely  <redi@gcc.gnu.org>
            Jack Howarth  <howarth@bromo.med.uc.edu>
 
diff --git a/gcc/testsuite/obj-c++.dg/naming-1.mm b/gcc/testsuite/obj-c++.dg/naming-1.mm
new file mode 100644 (file)
index 0000000..aed2fd5
--- /dev/null
@@ -0,0 +1,26 @@
+/* Testing for detecting duplicate ivars. */
+/* { dg-do compile } */
+
+typedef struct S { int i; } NSDictionary;
+
+@interface A 
+{
+    NSDictionary * _userInfo;
+}
+@end
+
+@interface B : A
+{
+    NSDictionary * _userInfo;  /* { dg-error "duplicate member" } */
+}
+@end
+
+@interface C : A
+@end
+
+@interface D : C
+{
+    NSDictionary * _userInfo;   /* { dg-error "duplicate member" } */
+}
+@end
+
diff --git a/gcc/testsuite/obj-c++.dg/naming-2.mm b/gcc/testsuite/obj-c++.dg/naming-2.mm
new file mode 100644 (file)
index 0000000..4b7860e
--- /dev/null
@@ -0,0 +1,40 @@
+/* Testing for detecting duplicate ivars. */
+/* { dg-do compile } */
+
+typedef struct S { int i; } NSDictionary;
+
+@interface A 
+{
+    NSDictionary * _userInfo;
+    int i1;
+    int i2;
+    int i3;
+    int i4;
+    int i5;
+    int i6;
+    int i7;
+}
+@end
+
+@interface B : A
+{
+    NSDictionary * _userInfo;  /* { dg-error "duplicate member" } */
+    int ii1;
+    int ii2;
+    int ii3;
+    int ii4;
+    int ii5;
+    int ii6;
+    int ii7;
+}      
+@end
+
+@interface C : A
+@end
+
+@interface D : C
+{
+    NSDictionary * _userInfo;   /* { dg-error "duplicate member" } */
+}
+@end
+
diff --git a/gcc/testsuite/objc.dg/naming-4.m b/gcc/testsuite/objc.dg/naming-4.m
new file mode 100644 (file)
index 0000000..9a85229
--- /dev/null
@@ -0,0 +1,27 @@
+/* Testing for detecting duplicate ivars. */
+/* { dg-do compile } */
+
+typedef struct S { int i; } NSDictionary;
+
+@interface A 
+{
+    NSDictionary * _userInfo;
+}
+@end
+
+@interface B : A
+{
+    NSDictionary * _userInfo;  /* { dg-error "duplicate member" } */
+    NSDictionary * _userInfo;  /* { dg-error "duplicate member" } */
+}
+@end
+
+@interface C : A
+@end
+
+@interface D : C
+{
+    NSDictionary * _userInfo;   /* { dg-error "duplicate member" } */
+    NSDictionary * _userInfo;   /* { dg-error "duplicate member" } */
+}
+@end
diff --git a/gcc/testsuite/objc.dg/naming-5.m b/gcc/testsuite/objc.dg/naming-5.m
new file mode 100644 (file)
index 0000000..2e2786c
--- /dev/null
@@ -0,0 +1,42 @@
+/* Testing for detecting duplicate ivars. */
+/* { dg-do compile } */
+
+typedef struct S { int i; } NSDictionary;
+
+@interface A 
+{
+    NSDictionary * _userInfo;
+    int i1;
+    int i2;
+    int i3;
+    int i4;
+    int i5;
+    int i6;
+    int i7;
+}
+@end
+
+@interface B : A
+{
+    NSDictionary * _userInfo;  /* { dg-error "duplicate member" } */
+    int ii1;
+    int ii2;
+    int ii3;
+    int ii4;
+    int ii5;
+    int ii6;
+    int ii7;
+    NSDictionary * _userInfo;  /* { dg-error "duplicate member" } */
+}
+@end
+
+@interface C : A
+@end
+
+@interface D : C
+{
+    NSDictionary * _userInfo;   /* { dg-error "duplicate member" } */
+    NSDictionary * _userInfo;   /* { dg-error "duplicate member" } */
+}      
+@end
+