+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
+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
{ "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 },
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,
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++. */
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))
{
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 *);
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);
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));
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);
+}
+
\f
/* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
should be considered, statements. ALLOW_STMT is true if we're within
+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.
(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 *) ;
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;
}
}
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,
/* ... 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);
+}
+
\f
/* OpenMP 2.5 parsing routines. */
+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.
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);
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
+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.
--- /dev/null
+/* 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 .;." } */
--- /dev/null
+/* { 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
--- /dev/null
+/* { 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
--- /dev/null
+/* 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 .;." } */
--- /dev/null
+/* { 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
--- /dev/null
+/* { 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