From da57d1b98f8ca9d1304fe66ff14315f12ce2a14f Mon Sep 17 00:00:00 2001 From: Nicola Pero Date: Mon, 18 Oct 2010 23:28:20 +0000 Subject: [PATCH] In gcc/: 2010-10-18 Nicola Pero In gcc/: 2010-10-18 Nicola Pero Implemented parsing @synthesize and @dynamic for Objective-C. * c-parser.c (c_parser_external_declaration): Recognize RID_AT_SYNTHESIZE and RID_AT_DYNAMIC. (c_parser_objc_at_synthesize_declaration): New. (c_parser_objc_at_dynamic_declaration): New. 2010-10-18 Nicola Pero * c-parser.c (c_parser_objc_class_declaration): After finding an error, parse the whole declaration then reset parser->error. In gcc/cp/: 2010-10-18 Nicola Pero Implemented parsing @synthesize and @dynamic for Objective-C++. * parser.c (cp_parser_objc_method_definition_list): Recognize RID_AT_SYNTHESIZE and RID_AT_DYNAMIC. (cp_parser_objc_at_dynamic_declaration): New. (cp_parser_objc_at_synthesize_declaration): New. 2010-10-18 Nicola Pero * parser.c (cp_parser_objc_identifier_list): Check the return value of cp_parser_identifier and react if it is error_mark_node. In gcc/objc/: 2010-10-18 Nicola Pero Implemented parsing @synthesize and @dynamic for Objective-C/Objective-C++. * objc-act.c (objc_add_synthesize_declaration): New. (objc_add_dynamic_declaration): New. 2010-10-18 Nicola Pero * objc-act.c (lookup_and_install_protocols): Return NULL if passed error_mark_node. In gcc/testsuite/: 2010-10-18 Nicola Pero Implemented parsing @synthesize and @dynamic for Objective-C/Objective-C++. * objc.dg/property/dynamic-1.m: New. * objc.dg/property/synthesize-1.m: New. * obj-c++.dg/property/dynamic-1.mm: New. * obj-c++.dg/property/synthesize-1.mm: New. 2010-10-18 Nicola Pero * objc.dg/at-class-1.m: New. * objc.dg/at-class-1.mm: New. From-SVN: r165667 --- gcc/ChangeLog | 13 +++ gcc/c-family/ChangeLog | 11 ++ gcc/c-family/c-common.c | 2 + gcc/c-family/c-common.h | 3 + gcc/c-family/stub-objc.c | 12 ++ gcc/c-parser.c | 127 ++++++++++++++++++++- gcc/cp/ChangeLog | 13 +++ gcc/cp/parser.c | 130 +++++++++++++++++++++- gcc/objc/ChangeLog | 12 ++ gcc/objc/objc-act.c | 52 +++++++++ gcc/testsuite/ChangeLog | 14 +++ gcc/testsuite/obj-c++.dg/at-class-1.mm | 11 ++ gcc/testsuite/obj-c++.dg/property/dynamic-1.mm | 30 +++++ gcc/testsuite/obj-c++.dg/property/synthesize-1.mm | 31 ++++++ gcc/testsuite/objc.dg/at-class-1.m | 11 ++ gcc/testsuite/objc.dg/property/dynamic-1.m | 30 +++++ gcc/testsuite/objc.dg/property/synthesize-1.m | 31 ++++++ 17 files changed, 526 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/obj-c++.dg/at-class-1.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/dynamic-1.mm create mode 100644 gcc/testsuite/obj-c++.dg/property/synthesize-1.mm create mode 100644 gcc/testsuite/objc.dg/at-class-1.m create mode 100644 gcc/testsuite/objc.dg/property/dynamic-1.m create mode 100644 gcc/testsuite/objc.dg/property/synthesize-1.m diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b21e191..edbf40a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2010-10-18 Nicola Pero + + Implemented parsing @synthesize and @dynamic for Objective-C. + * c-parser.c (c_parser_external_declaration): Recognize + RID_AT_SYNTHESIZE and RID_AT_DYNAMIC. + (c_parser_objc_at_synthesize_declaration): New. + (c_parser_objc_at_dynamic_declaration): New. + +2010-10-18 Nicola Pero + + * c-parser.c (c_parser_objc_class_declaration): After finding an + error, parse the whole declaration then reset parser->error. + 2010-10-18 Michael Meissner PR target/46041 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7a17df7..1f8726c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,14 @@ +2010-10-18 Nicola Pero + + Implemented parsing @synthesize and @dynamic for + Objective-C/Objective-C++. + * c-common.h (enum rid): Add RID_AT_SYNTHESIZE and RID_AT_DYNAMIC. + (objc_add_synthesize_declaration): New. + (objc_add_dynamic_declaration): New. + * c-common.c (c_common_reswords): Add synthesize and dynamic. + * stub-objc.c (objc_add_synthesize_declaration): New. + (objc_add_dynamic_declaration): New. + 2010-10-18 Michael Meissner PR target/46041 diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 5068c56..3716b5b 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -545,6 +545,8 @@ const struct c_common_resword c_common_reswords[] = { "required", RID_AT_REQUIRED, D_OBJC }, { "property", RID_AT_PROPERTY, D_OBJC }, { "package", RID_AT_PACKAGE, D_OBJC }, + { "synthesize", RID_AT_SYNTHESIZE, D_OBJC }, + { "dynamic", RID_AT_DYNAMIC, D_OBJC }, /* These are recognized only in protocol-qualifier context (see above) */ { "bycopy", RID_BYCOPY, D_OBJC }, diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index a6348ab..6b8a8f4 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -148,6 +148,7 @@ enum rid RID_AT_THROW, RID_AT_TRY, RID_AT_CATCH, RID_AT_FINALLY, RID_AT_SYNCHRONIZED, RID_AT_OPTIONAL, RID_AT_REQUIRED, RID_AT_PROPERTY, + RID_AT_SYNTHESIZE, RID_AT_DYNAMIC, RID_AT_INTERFACE, RID_AT_IMPLEMENTATION, @@ -1045,6 +1046,8 @@ extern bool objc_method_decl (enum tree_code); extern void objc_add_property_variable (tree); extern tree objc_build_getter_call (tree, tree); extern tree objc_build_setter_call (tree, tree); +extern void objc_add_synthesize_declaration (location_t, tree); +extern void objc_add_dynamic_declaration (location_t, tree); /* The following are provided by the C and C++ front-ends, and called by ObjC/ObjC++. */ diff --git a/gcc/c-family/stub-objc.c b/gcc/c-family/stub-objc.c index bcce0ae..a1ea033 100644 --- a/gcc/c-family/stub-objc.c +++ b/gcc/c-family/stub-objc.c @@ -349,6 +349,18 @@ objc_build_setter_call (tree ARG_UNUSED (lhs), tree ARG_UNUSED (rhs)) return 0; } +void +objc_add_synthesize_declaration (location_t ARG_UNUSED (start_locus), + tree ARG_UNUSED (property_and_ivar_list)) +{ +} + +void +objc_add_dynamic_declaration (location_t ARG_UNUSED (start_locus), + tree ARG_UNUSED (property_list)) +{ +} + tree objc_build_throw_stmt (location_t ARG_UNUSED (loc), tree ARG_UNUSED (expr)) { diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 6a7d7c6..d234218 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -1082,6 +1082,8 @@ static tree c_parser_objc_receiver (c_parser *); static tree c_parser_objc_message_args (c_parser *); static tree c_parser_objc_keywordexpr (c_parser *); static void c_parser_objc_at_property (c_parser *) ; +static void c_parser_objc_at_synthesize_declaration (c_parser *); +static void c_parser_objc_at_dynamic_declaration (c_parser *); static bool c_parser_objc_diagnose_bad_element_prefix (c_parser *, struct c_declspecs *); @@ -1185,6 +1187,14 @@ c_parser_external_declaration (c_parser *parser) gcc_assert (c_dialect_objc ()); c_parser_objc_at_property (parser); break; + case RID_AT_SYNTHESIZE: + gcc_assert (c_dialect_objc ()); + c_parser_objc_at_synthesize_declaration (parser); + break; + case RID_AT_DYNAMIC: + gcc_assert (c_dialect_objc ()); + c_parser_objc_at_dynamic_declaration (parser); + break; case RID_AT_END: gcc_assert (c_dialect_objc ()); c_parser_consume_token (parser); @@ -6763,7 +6773,9 @@ c_parser_objc_class_declaration (c_parser *parser) if (c_parser_next_token_is_not (parser, CPP_NAME)) { c_parser_error (parser, "expected identifier"); - break; + c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); + parser->error = false; + return; } id = c_parser_peek_token (parser)->value; list = chainon (list, build_tree_list (NULL_TREE, id)); @@ -7689,6 +7701,119 @@ c_parser_objc_at_property (c_parser *parser) c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); } +/* Parse an Objective-C @synthesize declaration. The syntax is: + + objc-synthesize-declaration: + @synthesize objc-synthesize-identifier-list ; + + objc-synthesize-identifier-list: + objc-synthesize-identifier + objc-synthesize-identifier-list, objc-synthesize-identifier + + objc-synthesize-identifier + identifier + identifier = identifier + + For example: + @synthesize MyProperty; + @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty; + + PS: This function is identical to cp_parser_objc_at_synthesize_declaration + for C++. Keep them in sync. +*/ +static void +c_parser_objc_at_synthesize_declaration (c_parser *parser) +{ + tree list = NULL_TREE; + location_t loc; + gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE)); + loc = c_parser_peek_token (parser)->location; + + c_parser_consume_token (parser); + while (true) + { + tree property, ivar; + if (c_parser_next_token_is_not (parser, CPP_NAME)) + { + c_parser_error (parser, "expected identifier"); + c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); + /* Once we find the semicolon, we can resume normal parsing. + We have to reset parser->error manually because + c_parser_skip_until_found() won't reset it for us if the + next token is precisely a semicolon. */ + parser->error = false; + return; + } + property = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + if (c_parser_next_token_is (parser, CPP_EQ)) + { + c_parser_consume_token (parser); + if (c_parser_next_token_is_not (parser, CPP_NAME)) + { + c_parser_error (parser, "expected identifier"); + c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); + parser->error = false; + return; + } + ivar = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + } + else + ivar = NULL_TREE; + list = chainon (list, build_tree_list (ivar, property)); + if (c_parser_next_token_is (parser, CPP_COMMA)) + c_parser_consume_token (parser); + else + break; + } + c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); + objc_add_synthesize_declaration (loc, list); +} + +/* Parse an Objective-C @dynamic declaration. The syntax is: + + objc-dynamic-declaration: + @dynamic identifier-list ; + + For example: + @dynamic MyProperty; + @dynamic MyProperty, AnotherProperty; + + PS: This function is identical to cp_parser_objc_at_dynamic_declaration + for C++. Keep them in sync. +*/ +static void +c_parser_objc_at_dynamic_declaration (c_parser *parser) +{ + tree list = NULL_TREE; + location_t loc; + gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC)); + loc = c_parser_peek_token (parser)->location; + + c_parser_consume_token (parser); + while (true) + { + tree property; + if (c_parser_next_token_is_not (parser, CPP_NAME)) + { + c_parser_error (parser, "expected identifier"); + c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); + parser->error = false; + return; + } + property = c_parser_peek_token (parser)->value; + list = chainon (list, build_tree_list (NULL_TREE, property)); + c_parser_consume_token (parser); + if (c_parser_next_token_is (parser, CPP_COMMA)) + c_parser_consume_token (parser); + else + break; + } + c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); + objc_add_dynamic_declaration (loc, list); +} + /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore should be considered, statements. ALLOW_STMT is true if we're within diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5d001bb..5447b45 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,4 +1,17 @@ 2010-10-18 Nicola Pero + + Implemented parsing @synthesize and @dynamic for Objective-C++. + * parser.c (cp_parser_objc_method_definition_list): Recognize + RID_AT_SYNTHESIZE and RID_AT_DYNAMIC. + (cp_parser_objc_at_dynamic_declaration): New. + (cp_parser_objc_at_synthesize_declaration): New. + +2010-10-18 Nicola Pero + + * parser.c (cp_parser_objc_identifier_list): Check the return + value of cp_parser_identifier and react if it is error_mark_node. + +2010-10-18 Nicola Pero Merge from apple/trunk branch on FSF servers. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cfc3ddd..4773486 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2100,6 +2100,10 @@ static bool cp_parser_objc_valid_prefix_attributes (cp_parser *, tree *); static void cp_parser_objc_at_property (cp_parser *) ; +static void cp_parser_objc_at_synthesize_declaration + (cp_parser *) ; +static void cp_parser_objc_at_dynamic_declaration + (cp_parser *) ; static void cp_parser_objc_property_decl (cp_parser *) ; @@ -21270,18 +21274,29 @@ cp_parser_objc_selector_expression (cp_parser* parser) static tree cp_parser_objc_identifier_list (cp_parser* parser) { - tree list = build_tree_list (NULL_TREE, cp_parser_identifier (parser)); - cp_token *sep = cp_lexer_peek_token (parser->lexer); + tree identifier; + tree list; + cp_token *sep; + + identifier = cp_parser_identifier (parser); + if (identifier == error_mark_node) + return error_mark_node; + + list = build_tree_list (NULL_TREE, identifier); + sep = cp_lexer_peek_token (parser->lexer); while (sep->type == CPP_COMMA) { cp_lexer_consume_token (parser->lexer); /* Eat ','. */ - list = chainon (list, - build_tree_list (NULL_TREE, - cp_parser_identifier (parser))); + identifier = cp_parser_identifier (parser); + if (identifier == error_mark_node) + return list; + + list = chainon (list, build_tree_list (NULL_TREE, + identifier)); sep = cp_lexer_peek_token (parser->lexer); } - + return list; } @@ -21790,6 +21805,10 @@ cp_parser_objc_method_definition_list (cp_parser* parser) } else if (token->keyword == RID_AT_PROPERTY) cp_parser_objc_at_property (parser); + else if (token->keyword == RID_AT_SYNTHESIZE) + cp_parser_objc_at_synthesize_declaration (parser); + else if (token->keyword == RID_AT_DYNAMIC) + cp_parser_objc_at_dynamic_declaration (parser); else if (token->keyword == RID_ATTRIBUTE && cp_parser_objc_method_maybe_bad_prefix_attributes(parser)) warning_at (token->location, OPT_Wattributes, @@ -22422,6 +22441,105 @@ cp_parser_objc_at_property (cp_parser *parser) /* ... and the property declaration(s). */ cp_parser_objc_property_decl (parser); } + +/* Parse an Objective-C++ @synthesize declaration. The syntax is: + + objc-synthesize-declaration: + @synthesize objc-synthesize-identifier-list ; + + objc-synthesize-identifier-list: + objc-synthesize-identifier + objc-synthesize-identifier-list, objc-synthesize-identifier + + objc-synthesize-identifier + identifier + identifier = identifier + + For example: + @synthesize MyProperty; + @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty; + + PS: This function is identical to c_parser_objc_at_synthesize_declaration + for C. Keep them in sync. +*/ +static void +cp_parser_objc_at_synthesize_declaration (cp_parser *parser) +{ + tree list = NULL_TREE; + location_t loc; + loc = cp_lexer_peek_token (parser->lexer)->location; + + cp_lexer_consume_token (parser->lexer); /* Eat '@synthesize'. */ + while (true) + { + tree property, ivar; + property = cp_parser_identifier (parser); + if (property == error_mark_node) + { + cp_parser_consume_semicolon_at_end_of_statement (parser); + return; + } + if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)) + { + cp_lexer_consume_token (parser->lexer); + ivar = cp_parser_identifier (parser); + if (ivar == error_mark_node) + { + cp_parser_consume_semicolon_at_end_of_statement (parser); + return; + } + } + else + ivar = NULL_TREE; + list = chainon (list, build_tree_list (ivar, property)); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); + else + break; + } + cp_parser_consume_semicolon_at_end_of_statement (parser); + objc_add_synthesize_declaration (loc, list); +} + +/* Parse an Objective-C++ @dynamic declaration. The syntax is: + + objc-dynamic-declaration: + @dynamic identifier-list ; + + For example: + @dynamic MyProperty; + @dynamic MyProperty, AnotherProperty; + + PS: This function is identical to c_parser_objc_at_dynamic_declaration + for C. Keep them in sync. +*/ +static void +cp_parser_objc_at_dynamic_declaration (cp_parser *parser) +{ + tree list = NULL_TREE; + location_t loc; + loc = cp_lexer_peek_token (parser->lexer)->location; + + cp_lexer_consume_token (parser->lexer); /* Eat '@dynamic'. */ + while (true) + { + tree property; + property = cp_parser_identifier (parser); + if (property == error_mark_node) + { + cp_parser_consume_semicolon_at_end_of_statement (parser); + return; + } + list = chainon (list, build_tree_list (NULL, property)); + if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)) + cp_lexer_consume_token (parser->lexer); + else + break; + } + cp_parser_consume_semicolon_at_end_of_statement (parser); + objc_add_dynamic_declaration (loc, list); +} + /* OpenMP 2.5 parsing routines. */ diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index fd8f15d..745b7bb 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,5 +1,17 @@ 2010-10-18 Nicola Pero + Implemented parsing @synthesize and @dynamic for + Objective-C/Objective-C++. + * objc-act.c (objc_add_synthesize_declaration): New. + (objc_add_dynamic_declaration): New. + +2010-10-18 Nicola Pero + + * objc-act.c (lookup_and_install_protocols): Return NULL if passed + error_mark_node. + +2010-10-18 Nicola Pero + Merge from 'apple/trunk' branch on FSF servers. 2006-03-10 Fariborz Jahanian diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 53a29bc..048d2ae 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2114,6 +2114,9 @@ lookup_and_install_protocols (tree protocols) tree proto; tree return_value = NULL_TREE; + if (protocols == error_mark_node) + return NULL; + for (proto = protocols; proto; proto = TREE_CHAIN (proto)) { tree ident = TREE_VALUE (proto); @@ -8701,6 +8704,55 @@ objc_synthesize_setter (tree klass, tree class_method, tree property) objc_finish_method_definition (fn); } +/* This function is called by the parser after a @synthesize + expression is parsed. 'start_locus' is the location of the + @synthesize expression, and 'property_and_ivar_list' is a chained + list of the property and ivar names. + */ +void +objc_add_synthesize_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_and_ivar_list ATTRIBUTE_UNUSED) +{ + if (property_and_ivar_list == error_mark_node) + return; + + if (!objc_implementation_context) + { + /* We can get here only in Objective-C; the Objective-C++ parser + detects the problem while parsing, outputs the error + "misplaced '@synthesize' Objective-C++ construct" and skips + the declaration. */ + error ("%<@synthesize%> not in @implementation context"); + return; + } + + /* TODO */ + error ("%<@synthesize%> is not supported in this version of the compiler"); +} + +/* This function is called by the parser after a @dynamic expression + is parsed. 'start_locus' is the location of the @dynamic + expression, and 'property_list' is a chained list of all the + property names. */ +void +objc_add_dynamic_declaration (location_t start_locus ATTRIBUTE_UNUSED, tree property_list ATTRIBUTE_UNUSED) +{ + if (property_list == error_mark_node) + return; + + if (!objc_implementation_context) + { + /* We can get here only in Objective-C; the Objective-C++ parser + detects the problem while parsing, outputs the error + "misplaced '@dynamic' Objective-C++ construct" and skips the + declaration. */ + error ("%<@dynamic%> not in @implementation context"); + return; + } + + /* TODO */ + error ("%<@dynamic%> is not supported in this version of the compiler"); +} + /* Main routine to generate code/data for all the property information for current implementation (class or category). CLASS is the interface where ivars are declared. CLASS_METHODS is where methods are found which diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 13ef3b0..2c64ae9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2010-10-18 Nicola Pero + + Implemented parsing @synthesize and @dynamic for + Objective-C/Objective-C++. + * objc.dg/property/dynamic-1.m: New. + * objc.dg/property/synthesize-1.m: New. + * obj-c++.dg/property/dynamic-1.mm: New. + * obj-c++.dg/property/synthesize-1.mm: New. + +2010-10-18 Nicola Pero + + * objc.dg/at-class-1.m: New. + * objc.dg/at-class-1.mm: New. + 2010-10-18 Steve Ellcey * gcc.c-torture/compile/920625-1.c: Remove dg-prune-output lines. diff --git a/gcc/testsuite/obj-c++.dg/at-class-1.mm b/gcc/testsuite/obj-c++.dg/at-class-1.mm new file mode 100644 index 0000000..63721aa --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/at-class-1.mm @@ -0,0 +1,11 @@ +/* Test @class. */ +/* { dg-do compile } */ + +@class Object; /* Ok */ + +@class Object, ; /* { dg-error "expected identifier" } */ +@class Object, ; /* { dg-error "expected identifier" } */ +@class Object, AnotherObject, ; /* { dg-error "expected identifier" } */ +@class Object, AnotherObject, TestObject ; /* Ok */ + +@class Object /* { dg-error "expected .;." } */ diff --git a/gcc/testsuite/obj-c++.dg/property/dynamic-1.mm b/gcc/testsuite/obj-c++.dg/property/dynamic-1.mm new file mode 100644 index 0000000..d66ef28 --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/dynamic-1.mm @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +#include + +@interface MyRootClass +{ + Class isa; +} +@end + +@implementation MyRootClass +@end + +@dynamic isa; /* { dg-error "misplaced .@dynamic. Objective-C.. construct" } */ + +@interface Test : MyRootClass +{ + int v1; + int v2; + int v3; + int v4; +} +@end + +@implementation Test +@dynamic; /* { dg-error "expected identifier" } */ +@dynamic v1, ; /* { dg-error "expected identifier" } */ +@dynamic v1, v2, v3; /* { dg-error ".@dynamic. is not supported in this version of the compiler" } */ +@dynamic v4; /* { dg-error ".@dynamic. is not supported in this version of the compiler" } */ +@end diff --git a/gcc/testsuite/obj-c++.dg/property/synthesize-1.mm b/gcc/testsuite/obj-c++.dg/property/synthesize-1.mm new file mode 100644 index 0000000..fb9b38e --- /dev/null +++ b/gcc/testsuite/obj-c++.dg/property/synthesize-1.mm @@ -0,0 +1,31 @@ +/* { dg-do compile } */ + +#include + +@interface MyRootClass +{ + Class isa; +} +@end + +@implementation MyRootClass +@end + +@synthesize isa; /* { dg-error "misplaced .@synthesize. Objective-C.. construct" } */ + +@interface Test : MyRootClass +{ + int v1; + int v2; + int v3; + int v4; +} +@end + +@implementation Test +@synthesize; /* { dg-error "expected identifier" } */ +@synthesize v1, ; /* { dg-error "expected identifier" } */ +@synthesize v1, v2 = ; /* { dg-error "expected identifier" } */ +@synthesize v1, v2=v2, v3 = v3,v4; /* { dg-error ".@synthesize. is not supported in this version of the compiler" } */ +@synthesize v4; /* { dg-error ".@synthesize. is not supported in this version of the compiler" } */ +@end diff --git a/gcc/testsuite/objc.dg/at-class-1.m b/gcc/testsuite/objc.dg/at-class-1.m new file mode 100644 index 0000000..63721aa --- /dev/null +++ b/gcc/testsuite/objc.dg/at-class-1.m @@ -0,0 +1,11 @@ +/* Test @class. */ +/* { dg-do compile } */ + +@class Object; /* Ok */ + +@class Object, ; /* { dg-error "expected identifier" } */ +@class Object, ; /* { dg-error "expected identifier" } */ +@class Object, AnotherObject, ; /* { dg-error "expected identifier" } */ +@class Object, AnotherObject, TestObject ; /* Ok */ + +@class Object /* { dg-error "expected .;." } */ diff --git a/gcc/testsuite/objc.dg/property/dynamic-1.m b/gcc/testsuite/objc.dg/property/dynamic-1.m new file mode 100644 index 0000000..b91a030 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/dynamic-1.m @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +#include + +@interface MyRootClass +{ + Class isa; +} +@end + +@implementation MyRootClass +@end + +@dynamic isa; /* { dg-error ".@dynamic. not in @implementation context" } */ + +@interface Test : MyRootClass +{ + int v1; + int v2; + int v3; + int v4; +} +@end + +@implementation Test +@dynamic; /* { dg-error "expected identifier" } */ +@dynamic v1, ; /* { dg-error "expected identifier" } */ +@dynamic v1, v2, v3; /* { dg-error ".@dynamic. is not supported in this version of the compiler" } */ +@dynamic v4; /* { dg-error ".@dynamic. is not supported in this version of the compiler" } */ +@end diff --git a/gcc/testsuite/objc.dg/property/synthesize-1.m b/gcc/testsuite/objc.dg/property/synthesize-1.m new file mode 100644 index 0000000..09085d8 --- /dev/null +++ b/gcc/testsuite/objc.dg/property/synthesize-1.m @@ -0,0 +1,31 @@ +/* { dg-do compile } */ + +#include + +@interface MyRootClass +{ + Class isa; +} +@end + +@implementation MyRootClass +@end + +@synthesize isa; /* { dg-error ".@synthesize. not in @implementation context" } */ + +@interface Test : MyRootClass +{ + int v1; + int v2; + int v3; + int v4; +} +@end + +@implementation Test +@synthesize; /* { dg-error "expected identifier" } */ +@synthesize v1, ; /* { dg-error "expected identifier" } */ +@synthesize v1, v2 = ; /* { dg-error "expected identifier" } */ +@synthesize v1, v2=v2, v3 = v3,v4; /* { dg-error ".@synthesize. is not supported in this version of the compiler" } */ +@synthesize v4; /* { dg-error ".@synthesize. is not supported in this version of the compiler" } */ +@end -- 2.7.4