From: Nicola Pero Date: Thu, 4 Nov 2010 20:59:47 +0000 (+0000) Subject: In gcc/: 2010-11-04 Nicola Pero X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bede2adc26d83608df2c21d82d1ff0246baf1456;p=gcc.git In gcc/: 2010-11-04 Nicola Pero In gcc/: 2010-11-04 Nicola Pero 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 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 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 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 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ec1c157732..d89ecd1dbe2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-11-04 Nicola Pero + + 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 * final.c (compute_alignments): Compute/free loop info all the time. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index fc3a8956404..c613ab36b8b 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2010-11-04 Nicola Pero + + 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 * c.opt (Wproperty-assign-default): New option. diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 7a04d10e897..13d9227ddca 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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); diff --git a/gcc/c-family/stub-objc.c b/gcc/c-family/stub-objc.c index 52ecc990250..1f3b854f0c0 100644 --- a/gcc/c-family/stub-objc.c +++ b/gcc/c-family/stub-objc.c @@ -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)) { diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 0e56b1898ca..78ccdd4ebfc 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -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 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7167992ae16..b1c9e01e7b0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2010-11-04 Nicola Pero + + 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 PR c++/46298 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 864ec9b2806..6302864fd97 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -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) diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index bc9aebc8563..dc4cffd1e53 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,8 @@ +2010-11-04 Nicola Pero + + 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 * objc-act.c (objc_add_dynamic_declaration): Allow @dynamic in a diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 40ecc4cb580..aa4c2e392b8 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 766163452ac..3b1dcab0405 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,15 @@ +2010-11-04 Nicola Pero + + 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 * gcc.target/powerpc/loop_align.c: New. diff --git a/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm b/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm index b8234ee0ccd..b6ae044df3d 100644 --- a/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm +++ b/gcc/testsuite/obj-c++.dg/fobjc-std-1.mm @@ -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 index 00000000000..5991962b921 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-3.mm @@ -0,0 +1,63 @@ +/* Contributed by Nicola Pero , November 2010. */ +/* { dg-do run } */ + +/* Test the 'dot syntax' without a declarated property. This tests the case where + the object is a Class. */ + + +#include +#include +#include + +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 index 00000000000..af410185526 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dotsyntax-4.mm @@ -0,0 +1,69 @@ +/* Contributed by Nicola Pero , 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 +#include +#include + +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; +} diff --git a/gcc/testsuite/objc.dg/fobjc-std-1.m b/gcc/testsuite/objc.dg/fobjc-std-1.m index 3ef4857b2e5..4f0a7e6e63e 100644 --- a/gcc/testsuite/objc.dg/fobjc-std-1.m +++ b/gcc/testsuite/objc.dg/fobjc-std-1.m @@ -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 index 00000000000..5991962b921 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-3.m @@ -0,0 +1,63 @@ +/* Contributed by Nicola Pero , November 2010. */ +/* { dg-do run } */ + +/* Test the 'dot syntax' without a declarated property. This tests the case where + the object is a Class. */ + + +#include +#include +#include + +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 index 00000000000..d890f3bfc0d --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dotsyntax-4.m @@ -0,0 +1,67 @@ +/* Contributed by Nicola Pero , 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 +#include +#include + +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; +}