In gcc/: 2010-11-04 Nicola Pero <nicola.pero@meta-innovation.com>
authorNicola Pero <nicola.pero@meta-innovation.com>
Thu, 4 Nov 2010 20:59:47 +0000 (20:59 +0000)
committerNicola Pero <nicola@gcc.gnu.org>
Thu, 4 Nov 2010 20:59:47 +0000 (20:59 +0000)
In gcc/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * c-parser.c (c_parser_next_token_starts_declspecs): In
        Objective-C, detect Objective-C 2.0 dot-syntax with a class name.
        (c_parser_next_token_starts_declaration): Same.
        (c_parser_postfix_expression): Parse the Objective-C 2.0
        dot-syntax with a class name.

In gcc/cp/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * parser.c (cp_parser_primary_expression): Recognize Objective-C
        2.0 dot-syntax with class names and process it.
        (cp_parser_nonclass_name): Recognize Objective-C 2.0 dot-syntax
        with class names.
        (cp_parser_class_name): Same change.
        (cp_parser_simple_type_specifier): Tidied comments.

In gcc/c-family/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * c-common.h (objc_build_class_component_ref): New.
        * stub-objc.c (objc_build_class_component_ref): New.

In gcc/objc/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * objc-act.c (objc_build_class_component_ref): New.

In gcc/testsuite/:
2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>

        Fixed using the Objective-C 2.0 dot-syntax with class names.
        * objc.dg/property/dotsyntax-3.m: New.
        * objc.dg/property/dotsyntax-4.m: New.
        * obj-c++.dg/property/dotsyntax-3.mm: New.
        * obj-c++.dg/property/dotsyntax-4.mm: New.

        * objc.dg/fobjc-std-1.m: Added test for warnings when the
        Objective-C 2.0 dot-syntax is used with class names.
        * obj-c++.dg/fobjc-std-1.mm: Same change.

From-SVN: r166333

16 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.h
gcc/c-family/stub-objc.c
gcc/c-parser.c
gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/testsuite/ChangeLog
gcc/testsuite/obj-c++.dg/fobjc-std-1.mm
gcc/testsuite/obj-c++.dg/property/dotsyntax-3.mm [new file with mode: 0644]
gcc/testsuite/obj-c++.dg/property/dotsyntax-4.mm [new file with mode: 0644]
gcc/testsuite/objc.dg/fobjc-std-1.m
gcc/testsuite/objc.dg/property/dotsyntax-3.m [new file with mode: 0644]
gcc/testsuite/objc.dg/property/dotsyntax-4.m [new file with mode: 0644]

index 0ec1c15773265851ae7bbaccb5e3b8b544d2ee5c..d89ecd1dbe2c62a039b74cab87ce1d19a0acc23a 100644 (file)
@@ -1,3 +1,12 @@
+2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       Fixed using the Objective-C 2.0 dot-syntax with class names.
+       * c-parser.c (c_parser_next_token_starts_declspecs): In
+       Objective-C, detect Objective-C 2.0 dot-syntax with a class name.
+       (c_parser_next_token_starts_declaration): Same.
+       (c_parser_postfix_expression): Parse the Objective-C 2.0
+       dot-syntax with a class name.
+
 2010-11-04  Pat Haugen  <pthaugen@us.ibm.com>
 
        * final.c (compute_alignments): Compute/free loop info all the time.
index fc3a89564042c64441d32f0351a89ea2477c4645..c613ab36b8b484ce9286661ef84ed1a4f2999e1b 100644 (file)
@@ -1,3 +1,9 @@
+2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       Fixed using the Objective-C 2.0 dot-syntax with class names.    
+       * c-common.h (objc_build_class_component_ref): New.
+       * stub-objc.c (objc_build_class_component_ref): New.
+
 2010-11-03  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * c.opt (Wproperty-assign-default): New option.
index 7a04d10e8977dbde30da6ff9862078fb1f0b4c2e..13d9227ddca8580055487ece619df992b00c099a 100644 (file)
@@ -1037,6 +1037,7 @@ extern bool  objc_method_decl (enum tree_code);
 extern void objc_add_property_declaration (location_t, tree, bool, bool, bool, 
                                           bool, bool, bool, tree, tree);
 extern tree objc_maybe_build_component_ref (tree, tree);
+extern tree objc_build_class_component_ref (tree, tree);
 extern tree objc_maybe_build_modify_expr (tree, tree);
 extern void objc_add_synthesize_declaration (location_t, tree);
 extern void objc_add_dynamic_declaration (location_t, tree);
index 52ecc99025064ff85b194cef60e11c0e4b966d0b..1f3b854f0c070dd2933cb7886e17767875e6451e 100644 (file)
@@ -349,6 +349,12 @@ objc_maybe_build_component_ref (tree ARG_UNUSED (datum), tree ARG_UNUSED (compon
   return 0;
 }
 
+tree
+objc_build_class_component_ref (tree ARG_UNUSED (datum), tree ARG_UNUSED (component))
+{
+  return 0;
+}
+
 tree
 objc_maybe_build_modify_expr (tree ARG_UNUSED (lhs), tree ARG_UNUSED (rhs))
 {
index 0e56b1898cae3e8eead947b68dfac9adc558755a..78ccdd4ebfc24b19ee0cf5185c77dab5fb859faa 100644 (file)
@@ -598,6 +598,19 @@ static inline bool
 c_parser_next_token_starts_declspecs (c_parser *parser)
 {
   c_token *token = c_parser_peek_token (parser);
+
+  /* In Objective-C, a classname normally starts a declspecs unless it
+     is immediately followed by a dot.  In that case, it is the
+     Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
+     setter/getter on the class.  c_token_starts_declspecs() can't
+     differentiate between the two cases because it only checks the
+     current token, so we have a special check here.  */
+  if (c_dialect_objc () 
+      && token->type == CPP_NAME
+      && token->id_kind == C_ID_CLASSNAME 
+      && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
+    return false;
+
   return c_token_starts_declspecs (token);
 }
 
@@ -607,6 +620,14 @@ static inline bool
 c_parser_next_token_starts_declaration (c_parser *parser)
 {
   c_token *token = c_parser_peek_token (parser);
+
+  /* Same as above.  */
+  if (c_dialect_objc () 
+      && token->type == CPP_NAME
+      && token->id_kind == C_ID_CLASSNAME 
+      && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
+    return false;
+
   return c_token_starts_declaration (token);
 }
 
@@ -5821,6 +5842,7 @@ c_parser_alignof_expression (c_parser *parser)
      @protocol ( identifier )
      @encode ( type-name )
      objc-string-literal
+     Classname . identifier
 */
 
 static struct c_expr
@@ -5867,20 +5889,48 @@ c_parser_postfix_expression (c_parser *parser)
       c_parser_consume_token (parser);
       break;
     case CPP_NAME:
-      if (c_parser_peek_token (parser)->id_kind != C_ID_ID)
+      switch (c_parser_peek_token (parser)->id_kind)
        {
+       case C_ID_ID:
+         {
+           tree id = c_parser_peek_token (parser)->value;
+           c_parser_consume_token (parser);
+           expr.value = build_external_ref (loc, id,
+                                            (c_parser_peek_token (parser)->type
+                                             == CPP_OPEN_PAREN),
+                                            &expr.original_type);
+           break;
+         }
+       case C_ID_CLASSNAME:
+         {
+           /* Here we parse the Objective-C 2.0 Class.name dot
+              syntax.  */
+           tree class_name = c_parser_peek_token (parser)->value;
+           tree component;
+           c_parser_consume_token (parser);
+           gcc_assert (c_dialect_objc ());
+           if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
+             {
+               expr.value = error_mark_node;
+               break;
+             }
+           if (c_parser_next_token_is_not (parser, CPP_NAME))
+             {
+               c_parser_error (parser, "expected identifier");
+               expr.value = error_mark_node;
+               break;
+             }
+           component = c_parser_peek_token (parser)->value;
+           c_parser_consume_token (parser);
+           expr.value = objc_build_class_component_ref (class_name, 
+                                                        component);
+           break;
+         }
+       default:
          c_parser_error (parser, "expected expression");
          expr.value = error_mark_node;
          break;
        }
-      {
-       tree id = c_parser_peek_token (parser)->value;
-       c_parser_consume_token (parser);
-       expr.value = build_external_ref (loc, id,
-                                        (c_parser_peek_token (parser)->type
-                                         == CPP_OPEN_PAREN),
-                                        &expr.original_type);
-      }
       break;
     case CPP_OPEN_PAREN:
       /* A parenthesized expression, statement expression or compound
index 7167992ae16c3a9bf4c437ec4ad7d0e639c0194b..b1c9e01e7b0b1ca965a1ad90a268f9e7967d7efb 100644 (file)
@@ -1,3 +1,13 @@
+2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       Fixed using the Objective-C 2.0 dot-syntax with class names.    
+       * parser.c (cp_parser_primary_expression): Recognize Objective-C
+       2.0 dot-syntax with class names and process it.
+       (cp_parser_nonclass_name): Recognize Objective-C 2.0 dot-syntax
+       with class names.
+       (cp_parser_class_name): Same change.
+       (cp_parser_simple_type_specifier): Tidied comments.
+       
 2010-11-04  Jason Merrill  <jason@redhat.com>
 
        PR c++/46298
index 864ec9b280651c6e245622cfbfa93852422b9c2d..6302864fd978599e553cfc2258471d463ff5e0d3 100644 (file)
@@ -3908,6 +3908,22 @@ cp_parser_primary_expression (cp_parser *parser,
            if (ambiguous_decls)
              return error_mark_node;
 
+           /* In Objective-C++, we may have an Objective-C 2.0
+              dot-syntax for classes here.  */
+           if (c_dialect_objc ()
+               && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
+               && TREE_CODE (decl) == TYPE_DECL
+               && objc_is_class_name (decl))
+             {
+               tree component;
+               cp_lexer_consume_token (parser->lexer);
+               component = cp_parser_identifier (parser);
+               if (component == error_mark_node)
+                 return error_mark_node;
+
+               return objc_build_class_component_ref (id_expression, component);
+             }
+
            /* In Objective-C++, an instance variable (ivar) may be preferred
               to whatever cp_parser_lookup_name() found.  */
            decl = objc_lookup_ivar (decl, id_expression);
@@ -12786,14 +12802,14 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       return error_mark_node;
     }
 
-  /* There is no valid C++ program where a non-template type is
-     followed by a "<".  That usually indicates that the user thought
-     that the type was a template.  */
   if (type && type != error_mark_node)
     {
-      /* As a last-ditch effort, see if TYPE is an Objective-C type.
-        If it is, then the '<'...'>' enclose protocol names rather than
-        template arguments, and so everything is fine.  */
+      /* See if TYPE is an Objective-C type, and if so, parse and
+        accept any protocol references following it.  Do this before
+        the cp_parser_check_for_invalid_template_id() call, because
+        Objective-C types can be followed by '<...>' which would
+        enclose protocol names rather than template arguments, and so
+        everything is fine.  */
       if (c_dialect_objc () && !parser->scope
          && (objc_is_id (type) || objc_is_class_name (type)))
        {
@@ -12808,6 +12824,9 @@ cp_parser_simple_type_specifier (cp_parser* parser,
          return qual_type;
        }
 
+      /* There is no valid C++ program where a non-template type is
+        followed by a "<".  That usually indicates that the user
+        thought that the type was a template.  */
       cp_parser_check_for_invalid_template_id (parser, TREE_TYPE (type),
                                               token->location);
     }
@@ -12888,9 +12907,17 @@ cp_parser_nonclass_name (cp_parser* parser)
       if (type)
        type_decl = TYPE_NAME (type);
     }
-  
+
   /* Issue an error if we did not find a type-name.  */
-  if (TREE_CODE (type_decl) != TYPE_DECL)
+  if (TREE_CODE (type_decl) != TYPE_DECL
+      /* In Objective-C, we have the complication that class names are
+        normally type names and start declarations (eg, the
+        "NSObject" in "NSObject *object;"), but can be used in an
+        Objective-C 2.0 dot-syntax (as in "NSObject.version") which
+        is an expression.  So, a classname followed by a dot is not a
+        valid type-name.  */
+      || (objc_is_class_name (TREE_TYPE (type_decl))
+         && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT))
     {
       if (!cp_parser_simulate_error (parser))
        cp_parser_name_lookup_error (parser, identifier, type_decl,
@@ -16714,7 +16741,12 @@ cp_parser_class_name (cp_parser *parser,
     }
   else if (TREE_CODE (decl) != TYPE_DECL
           || TREE_TYPE (decl) == error_mark_node
-          || !MAYBE_CLASS_TYPE_P (TREE_TYPE (decl)))
+          || !MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))
+          /* In Objective-C 2.0, a classname followed by '.' starts a
+             dot-syntax expression, and it's not a type-name.  */
+          || (c_dialect_objc ()
+              && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT 
+              && objc_is_class_name (decl)))
     decl = error_mark_node;
 
   if (decl == error_mark_node)
index bc9aebc85634234f7e0e686c683f6ba0ada6a1c1..dc4cffd1e53180ff255311530442fe7db80625a9 100644 (file)
@@ -1,3 +1,8 @@
+2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       Fixed using the Objective-C 2.0 dot-syntax with class names.    
+       * objc-act.c (objc_build_class_component_ref): New.
+
 2010-11-03  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        * objc-act.c (objc_add_dynamic_declaration): Allow @dynamic in a
index 40ecc4cb580bbfeeed1e031afe143abb20667b2f..aa4c2e392b8545fc8984b59e9522c627953725c5 100644 (file)
@@ -1301,6 +1301,79 @@ objc_maybe_build_component_ref (tree object, tree property_ident)
   return NULL_TREE;
 }
 
+/* This hook routine is invoked by the parser when an expression such
+   as 'xxx.yyy' is parsed, and 'xxx' is a class name.  This is the
+   Objective-C 2.0 dot-syntax applied to classes, so we need to
+   convert it into a setter/getter call on the class.  */
+tree
+objc_build_class_component_ref (tree class_name, tree property_ident)
+{
+  tree x = NULL_TREE;
+  tree object, rtype;
+  
+  if (flag_objc1_only)
+    error_at (input_location, "the dot syntax is not available in Objective-C 1.0");
+  
+  if (class_name == NULL_TREE || class_name == error_mark_node
+      || TREE_CODE (class_name) != IDENTIFIER_NODE)
+    return error_mark_node;
+  
+  if (property_ident == NULL_TREE || property_ident == error_mark_node
+      || TREE_CODE (property_ident) != IDENTIFIER_NODE)
+    return NULL_TREE;
+  
+  object = objc_get_class_reference (class_name);
+  if (!object)
+    {
+      /* We know that 'class_name' is an Objective-C class name as the
+        parser won't call this function if it is not.  This is only a
+        double-check for safety.  */
+      error_at (input_location, "could not find class %qE", class_name); 
+      return error_mark_node;
+    }
+
+  rtype = lookup_interface (class_name);
+  if (!rtype)
+    {
+      /* Again, this should never happen, but we do check.  */
+      error_at (input_location, "could not find interface for class %qE", class_name); 
+      return error_mark_node;
+    }
+
+  x = maybe_make_artificial_property_decl (rtype, NULL_TREE,
+                                          property_ident,
+                                          true);
+  
+  if (x)
+    {
+      tree expression;
+
+      if (TREE_DEPRECATED (x))
+       warn_deprecated_use (x, NULL_TREE);
+
+      expression = build2 (PROPERTY_REF, TREE_TYPE(x), object, x);
+      SET_EXPR_LOCATION (expression, input_location);
+      TREE_SIDE_EFFECTS (expression) = 1;
+      /* See above for why we do this.  */
+      if (!PROPERTY_HAS_NO_GETTER (x))
+       objc_finish_message_expr (object,
+                                 PROPERTY_GETTER_NAME (x),
+                                 NULL_TREE);
+      
+      return expression;
+    }
+  else
+    {
+      error_at (input_location, "could not find setter/getter for %qE in class %qE", 
+               property_ident, class_name); 
+      return error_mark_node;
+    }
+
+  return NULL_TREE;
+}
+
+
+
 /* This is used because we don't want to expose PROPERTY_REF to the
    C/C++ frontends.  Maybe we should!  */
 bool
index 766163452ac2cdf04ade1dcdffa59c67b7653bd7..3b1dcab040546653fbfd81adce037e07147fc825 100644 (file)
@@ -1,3 +1,15 @@
+2010-11-04  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       Fixed using the Objective-C 2.0 dot-syntax with class names.
+       * objc.dg/property/dotsyntax-3.m: New.
+       * objc.dg/property/dotsyntax-4.m: New.
+       * obj-c++.dg/property/dotsyntax-3.mm: New.
+       * obj-c++.dg/property/dotsyntax-4.mm: New.      
+
+       * objc.dg/fobjc-std-1.m: Added test for warnings when the
+       Objective-C 2.0 dot-syntax is used with class names.
+       * obj-c++.dg/fobjc-std-1.mm: Same change.
+       
 2010-11-04  Pat Haugen  <pthaugen@us.ibm.com>
 
        * gcc.target/powerpc/loop_align.c: New.
index b8234ee0ccd7a313330baba1a67328b176d327c3..b6ae044df3d794e145847bf6c8236e30c8015b45 100644 (file)
@@ -13,6 +13,7 @@ __attribute__ ((deprecated))
   int b;
 }
 + (id) alloc __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */
++ (id) name;
 - (id) init;
 - (id) testMe: (id) __attribute__((unused)) argument; /* { dg-error "not available in Objective.C 1.0" } */
 @property (nonatomic) int a; /* { dg-error "not available in Objective.C 1.0" } */
@@ -21,6 +22,7 @@ __attribute__ ((deprecated))
 
 @implementation MyRootClass
 + (id) alloc { return self; }
++ (id) name { return self; }
 - (id) init  { return self; }
 - (id) testMe: (id) __attribute__((unused)) argument { return self; } /* { dg-error "not available in Objective.C 1.0" } */
 @synthesize a; /* { dg-error "not available in Objective.C 1.0" } */
@@ -52,4 +54,9 @@ int array_length (NSArray *array)
       
   return i;
 }
-#endif
\ No newline at end of file
+#endif
+
+id test (void)
+{
+  return MyRootClass.name; /* { dg-error "not available in Objective.C 1.0" } */
+}
\ No newline at end of file
diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-3.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-3.mm
new file mode 100644 (file)
index 0000000..5991962
--- /dev/null
@@ -0,0 +1,63 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do run } */
+
+/* Test the 'dot syntax' without a declarated property.  This tests the case where
+   the object is a Class.  */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int a;
+static id b;
+
+@interface MyRootClass
+{
+  Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (int) count;
++ (void) setCount: (int)value;
++ (id) next;
++ (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (int) count
+{
+  return a;
+}
++ (void) setCount: (int)value
+{
+  a = value;
+}
++ (id) next
+{
+  return b;
+}
++ (void) setNext: (id)value
+{
+  b = value;
+}
+@end
+
+int main (void)
+{
+  MyRootClass *object = [[MyRootClass alloc] init];
+
+  MyRootClass.count = 40;
+  if (MyRootClass.count != 40)
+    abort ();
+
+  MyRootClass.next = object;
+  if (MyRootClass.next != object)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/obj-c++.dg/property/dotsyntax-4.mm b/gcc/testsuite/obj-c++.dg/property/dotsyntax-4.mm
new file mode 100644 (file)
index 0000000..af41018
--- /dev/null
@@ -0,0 +1,69 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+/* Test the 'dot syntax' without a declarated property.  This tests
+   syntax errors in the case where the object is a Class.  */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int a;
+static id b;
+
+@interface MyRootClass
+{
+  Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (int) count;
++ (void) setCount: (int)value;
++ (id) next;
++ (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (int) count
+{
+  return a;
+}
++ (void) setCount: (int)value
+{
+  a = value;
+}
++ (id) next
+{
+  return b;
+}
++ (void) setNext: (id)value
+{
+  b = value;
+}
+@end
+
+int main (void)
+{
+  MyRootClass *object = [[MyRootClass alloc] init];
+
+  MyRootClass.invalid = 40;      /* { dg-error "could not find setter.getter" } */
+  if (MyRootClass.invalid != 40) /* { dg-error "could not find setter.getter" } */
+    abort ();
+
+  MyRootClass.;           /* { dg-error "expected identifier" } */
+  if (MyRootClass.)       /* { dg-error "expected identifier" } */
+    abort ();
+
+  MyRootClass.int;        /* { dg-error "expected identifier" } */
+                          /* { dg-error "expected" "" { target *-*-* } 62 } */
+  if (MyRootClass.int)    /* { dg-error "expected identifier" } */
+                          /* { dg-error "expected" "" { target *-*-* } 64 } */
+    abort ();
+
+  return 0;
+}
index 3ef4857b2e57e3cf61e84e6152283fa72f8e82a4..4f0a7e6e63e90c69be072c314b665a6e977dd534 100644 (file)
@@ -13,6 +13,7 @@ __attribute__ ((deprecated))
   int b;
 }
 + (id) alloc __attribute__ ((deprecated)); /* { dg-error "not available in Objective.C 1.0" } */
++ (id) name;
 - (id) init;
 - (id) testMe: (id) __attribute__((unused)) argument; /* { dg-error "not available in Objective.C 1.0" } */
 @property (nonatomic) int a; /* { dg-error "not available in Objective.C 1.0" } */
@@ -21,6 +22,7 @@ __attribute__ ((deprecated))
 
 @implementation MyRootClass
 + (id) alloc { return self; }
++ (id) name { return self; }
 - (id) init  { return self; }
 - (id) testMe: (id) __attribute__((unused)) argument { return self; } /* { dg-error "not available in Objective.C 1.0" } */
 @synthesize a; /* { dg-error "not available in Objective.C 1.0" } */
@@ -52,3 +54,8 @@ int array_length (NSArray *array)
       
   return i;
 }
+
+id test (void)
+{
+  return MyRootClass.name; /* { dg-error "not available in Objective.C 1.0" } */
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-3.m b/gcc/testsuite/objc.dg/property/dotsyntax-3.m
new file mode 100644 (file)
index 0000000..5991962
--- /dev/null
@@ -0,0 +1,63 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do run } */
+
+/* Test the 'dot syntax' without a declarated property.  This tests the case where
+   the object is a Class.  */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int a;
+static id b;
+
+@interface MyRootClass
+{
+  Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (int) count;
++ (void) setCount: (int)value;
++ (id) next;
++ (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (int) count
+{
+  return a;
+}
++ (void) setCount: (int)value
+{
+  a = value;
+}
++ (id) next
+{
+  return b;
+}
++ (void) setNext: (id)value
+{
+  b = value;
+}
+@end
+
+int main (void)
+{
+  MyRootClass *object = [[MyRootClass alloc] init];
+
+  MyRootClass.count = 40;
+  if (MyRootClass.count != 40)
+    abort ();
+
+  MyRootClass.next = object;
+  if (MyRootClass.next != object)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/objc.dg/property/dotsyntax-4.m b/gcc/testsuite/objc.dg/property/dotsyntax-4.m
new file mode 100644 (file)
index 0000000..d890f3b
--- /dev/null
@@ -0,0 +1,67 @@
+/* Contributed by Nicola Pero <nicola.pero@meta-innovation.com>, November 2010.  */
+/* { dg-do compile } */
+
+/* Test the 'dot syntax' without a declarated property.  This tests
+   syntax errors in the case where the object is a Class.  */
+
+
+#include <stdlib.h>
+#include <objc/objc.h>
+#include <objc/runtime.h>
+
+static int a;
+static id b;
+
+@interface MyRootClass
+{
+  Class isa;
+}
++ (id) initialize;
++ (id) alloc;
+- (id) init;
++ (int) count;
++ (void) setCount: (int)value;
++ (id) next;
++ (void) setNext: (id)value;
+@end
+
+@implementation MyRootClass
++ (id) initialize { return self; }
++ (id) alloc { return class_createInstance (self, 0); }
+- (id) init { return self; }
++ (int) count
+{
+  return a;
+}
++ (void) setCount: (int)value
+{
+  a = value;
+}
++ (id) next
+{
+  return b;
+}
++ (void) setNext: (id)value
+{
+  b = value;
+}
+@end
+
+int main (void)
+{
+  MyRootClass *object = [[MyRootClass alloc] init];
+
+  MyRootClass.invalid = 40;      /* { dg-error "could not find setter.getter" } */
+  if (MyRootClass.invalid != 40) /* { dg-error "could not find setter.getter" } */
+    abort ();
+
+  MyRootClass.;           /* { dg-error "expected identifier" } */
+  if (MyRootClass.)       /* { dg-error "expected identifier" } */
+    abort ();
+
+  MyRootClass.int;        /* { dg-error "expected identifier" } */
+  if (MyRootClass.int)    /* { dg-error "expected identifier" } */
+    abort ();
+
+  return 0;
+}