aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-10-18 23:28:20 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-10-18 23:28:20 +0000
commitda57d1b98f8ca9d1304fe66ff14315f12ce2a14f (patch)
tree59330bf1f36ce8580abaac8db170b72523706080
parent0069111f9c747028548f8c5dd7b91c4e5358039d (diff)
downloadgcc-da57d1b98f8ca9d1304fe66ff14315f12ce2a14f.zip
gcc-da57d1b98f8ca9d1304fe66ff14315f12ce2a14f.tar.gz
gcc-da57d1b98f8ca9d1304fe66ff14315f12ce2a14f.tar.bz2
In gcc/: 2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/: 2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com> 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 <nicola.pero@meta-innovation.com> * 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 <nicola.pero@meta-innovation.com> 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 <nicola.pero@meta-innovation.com> * 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 <nicola.pero@meta-innovation.com> 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 <nicola.pero@meta-innovation.com> * objc-act.c (lookup_and_install_protocols): Return NULL if passed error_mark_node. In gcc/testsuite/: 2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com> 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 <nicola.pero@meta-innovation.com> * objc.dg/at-class-1.m: New. * objc.dg/at-class-1.mm: New. From-SVN: r165667
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/c-family/ChangeLog11
-rw-r--r--gcc/c-family/c-common.c2
-rw-r--r--gcc/c-family/c-common.h3
-rw-r--r--gcc/c-family/stub-objc.c12
-rw-r--r--gcc/c-parser.c127
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/parser.c130
-rw-r--r--gcc/objc/ChangeLog12
-rw-r--r--gcc/objc/objc-act.c52
-rw-r--r--gcc/testsuite/ChangeLog14
-rw-r--r--gcc/testsuite/obj-c++.dg/at-class-1.mm11
-rw-r--r--gcc/testsuite/obj-c++.dg/property/dynamic-1.mm30
-rw-r--r--gcc/testsuite/obj-c++.dg/property/synthesize-1.mm31
-rw-r--r--gcc/testsuite/objc.dg/at-class-1.m11
-rw-r--r--gcc/testsuite/objc.dg/property/dynamic-1.m30
-rw-r--r--gcc/testsuite/objc.dg/property/synthesize-1.m31
17 files changed, 526 insertions, 7 deletions
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 <nicola.pero@meta-innovation.com>
+
+ 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 <nicola.pero@meta-innovation.com>
+
+ * 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 <meissner@linux.vnet.ibm.com>
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 <nicola.pero@meta-innovation.com>
+
+ 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 <meissner@linux.vnet.ibm.com>
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 <nicola.pero@meta-innovation.com>
+
+ 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 <nicola.pero@meta-innovation.com>
+
+ * 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 <nicola.pero@meta-innovation.com>
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 <nicola.pero@meta-innovation.com>
+ 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 <nicola.pero@meta-innovation.com>
+
+ * objc-act.c (lookup_and_install_protocols): Return NULL if passed
+ error_mark_node.
+
+2010-10-18 Nicola Pero <nicola.pero@meta-innovation.com>
+
Merge from 'apple/trunk' branch on FSF servers.
2006-03-10 Fariborz Jahanian <fjahanian@apple.com>
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 <nicola.pero@meta-innovation.com>
+
+ 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 <nicola.pero@meta-innovation.com>
+
+ * objc.dg/at-class-1.m: New.
+ * objc.dg/at-class-1.mm: New.
+
2010-10-18 Steve Ellcey <sje@cup.hp.com>
* 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 <objc/objc.h>
+
+@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 <objc/objc.h>
+
+@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 <objc/objc.h>
+
+@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 <objc/objc.h>
+
+@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