aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-parser.c
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-10-27 04:37:47 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-10-27 04:37:47 +0000
commitf614132bc795c4773957e0d7fec7ee9dfd127274 (patch)
tree6ea8370f843d34af7151be0a948bae894059845f /gcc/c-parser.c
parent3e1484c9ee7d218f9e07f13916cbeb0ada3164c2 (diff)
downloadgcc-f614132bc795c4773957e0d7fec7ee9dfd127274.zip
gcc-f614132bc795c4773957e0d7fec7ee9dfd127274.tar.gz
gcc-f614132bc795c4773957e0d7fec7ee9dfd127274.tar.bz2
In gcc/: 2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/: 2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com> * c-parser.c (c_parser_objc_at_property): Renamed to c_parser_objc_at_property_declaration. Updated calls to objc_add_property_variable, now objc_add_property_declaration. Code rewritten to be much more robust in recovering from syntax errors. Added comments. (c_parser_objc_property_attrlist): Removed. (c_parser_external_declaration): Updated calls to c_parser_objc_at_property, now c_parser_objc_at_property_declaration. (c_parser_objc_methodprotolist): Same change. In gcc/c-family/: 2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com> * c-common.h (objc_add_property_variable): Renamed to objc_add_property_declaration. Added location argument. * stub-objc.c (objc_add_property_variable): Same change. In gcc/cp/: 2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com> * parser.c (cp_parser_objc_property_decl): Renamed to cp_parser_objc_struct_declaration. Return the parsed trees instead of calling objc_add_property_variable directly. Detect missing or invalid declspecs. Implemented attributes. Do not eat the ';' at the end. Exit loop whenever a non-comma is parsed, not just EOF. (cp_parser_objc_at_property): Renamed to cp_parser_objc_at_property_declaration. Updated calls to objc_add_property_variable, now objc_add_property_declaration, and to cp_parser_objc_property_decl, now cp_parser_objc_struct_declaration. Rewritten all code to be more robust in dealing with syntax errors, and almost identical to the one in c_parser_objc_at_property_declaration. (cp_parser_objc_property_attrlist): Removed. (cp_parser_objc_method_prototype_list): Updated call to cp_parser_objc_at_property. (cp_parser_objc_method_definition_list): Same change. (cp_parser_objc_class_ivars): Detect a number of invalid declarations of instance variables and produce errors when they are found. In gcc/objc/: 2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (objc_add_property_variable): Renamed to objc_add_property_declaration. Added location argument. Updated warnings and errors to use it. Use error, not fatal_error, if a property declaration is found outside an interface or implementation context. In gcc/testsuite/: 2010-10-27 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/property/at-property-1.m: New. * objc.dg/property/at-property-2.m: New. * objc.dg/property/at-property-3.m: New. * objc.dg/ivar-invalid-type-1.m: New. * obj-c++.dg/property/at-property-1.mm: New. * obj-c++.dg/property/at-property-2.mm: New. * obj-c++.dg/property/at-property-3.mm: New. * obj-c++.dg/ivar-invalid-type-1.mm: New. * objc.dg/property/property-neg-6.m: Updated testcase for updates in error reporting. From-SVN: r165996
Diffstat (limited to 'gcc/c-parser.c')
-rw-r--r--gcc/c-parser.c272
1 files changed, 159 insertions, 113 deletions
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index e4efd38..c885c8a9 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -1081,7 +1081,7 @@ static tree c_parser_objc_selector_arg (c_parser *);
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_property_declaration (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
@@ -1185,7 +1185,7 @@ c_parser_external_declaration (c_parser *parser)
break;
case RID_AT_PROPERTY:
gcc_assert (c_dialect_objc ());
- c_parser_objc_at_property (parser);
+ c_parser_objc_at_property_declaration (parser);
break;
case RID_AT_SYNTHESIZE:
gcc_assert (c_dialect_objc ());
@@ -6997,7 +6997,7 @@ c_parser_objc_methodprotolist (c_parser *parser)
if (c_parser_next_token_is_keyword (parser, RID_AT_END))
return;
else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
- c_parser_objc_at_property (parser);
+ c_parser_objc_at_property_declaration (parser);
else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
{
objc_set_method_opt (true);
@@ -7574,132 +7574,178 @@ c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
return false;
}
-/* ObjC @property. */
+/* Parse an Objective-C @property declaration. The syntax is:
-/* Parse a comma-separated list of property attributes. */
+ objc-property-declaration:
+ '@property' objc-property-attributes[opt] struct-declaration ;
+ objc-property-attributes:
+ '(' objc-property-attribute-list ')'
+
+ objc-property-attribute-list:
+ objc-property-attribute
+ objc-property-attribute-list, objc-property-attribute
+
+ objc-property-attribute
+ 'getter' = identifier
+ 'setter' = identifier
+ 'readonly'
+ 'readwrite'
+ 'assign'
+ 'retain'
+ 'copy'
+ 'nonatomic'
+
+ For example:
+ @property NSString *name;
+ @property (readonly) id object;
+ @property (retain, nonatomic, getter=getTheName) id name;
+ @property int a, b, c;
+
+ PS: This function is identical to cp_parser_objc_at_propery_declaration
+ for C++. Keep them in sync.
+
+ WORK IN PROGRESS: At the moment, the list of attributes that are
+ parsed is different from the above list. It will be updated to use
+ the above list at the same time as @synthesize is implemented. */
static void
-c_parser_objc_property_attrlist (c_parser *parser)
+c_parser_objc_at_property_declaration (c_parser *parser)
{
- bool err = false;
- /* Initialize to an empty list. */
- objc_set_property_attr (c_parser_peek_token (parser)->location,
- OBJC_PATTR_INIT, NULL_TREE);
+ tree properties;
+ location_t loc;
+ loc = c_parser_peek_token (parser)->location;
+ gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
- if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
- return;
+ c_parser_consume_token (parser); /* Eat '@property'. */
- /* Eat the '(' */
- c_parser_consume_token (parser);
-
- /* Property attribute keywords are valid now. */
- parser->objc_property_attr_context = true;
- while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)
- && c_parser_next_token_is_not (parser, CPP_EOF)
- && !err)
+ /* Initialize attributes to an empty list. */
+ objc_set_property_attr (loc, OBJC_PATTR_INIT, NULL_TREE);
+
+ /* Parse the optional attribute list... */
+ if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
- enum rid keywd;
- location_t loc;
- if (c_parser_peek_token (parser)->type != CPP_KEYWORD)
- {
- c_parser_error (parser, "expected a property attribute");
- c_parser_consume_token (parser);
- err = true;
- break;
- }
- keywd = c_parser_peek_token (parser)->keyword;
- /* Initially, make diagnostics point to the attribute. */
- loc = c_parser_peek_token (parser)->location;
- switch (keywd)
+ /* Eat the '(' */
+ c_parser_consume_token (parser);
+
+ /* Property attribute keywords are valid now. */
+ parser->objc_property_attr_context = true;
+
+ while (true)
{
- tree ident;
- objc_property_attribute_kind pkind;
- case RID_READONLY:
- objc_set_property_attr (loc, OBJC_PATTR_READONLY, NULL_TREE);
+ bool syntax_error = false;
+ c_token *token = c_parser_peek_token (parser);
+ enum rid keyword;
+
+ if (token->type != CPP_KEYWORD)
+ {
+ if (token->type == CPP_CLOSE_PAREN)
+ c_parser_error (parser, "expected identifier");
+ else
+ {
+ c_parser_consume_token (parser);
+ c_parser_error (parser, "unknown property attribute");
+ }
+ break;
+ }
+ keyword = token->keyword;
+ switch (keyword)
+ {
+ tree ident;
+ objc_property_attribute_kind pkind;
+ case RID_READONLY:
+ c_parser_consume_token (parser);
+ objc_set_property_attr (loc, OBJC_PATTR_READONLY, NULL_TREE);
+ break;
+ case RID_GETTER:
+ case RID_SETTER:
+ case RID_IVAR:
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is_not (parser, CPP_EQ))
+ {
+ c_parser_error (parser,
+ "getter/setter/ivar attribute must be followed by %<=%>");
+ syntax_error = true;
+ break;
+ }
+ c_parser_consume_token (parser); /* eat the = */
+ if (c_parser_next_token_is_not (parser, CPP_NAME))
+ {
+ c_parser_error (parser, "expected identifier");
+ syntax_error = true;
+ break;
+ }
+ ident = c_parser_peek_token (parser)->value;
+ c_parser_consume_token (parser);
+ if (keyword == RID_SETTER)
+ {
+ pkind = OBJC_PATTR_SETTER;
+ /* Eat the identifier, and look for the following : */
+ if (c_parser_next_token_is_not (parser, CPP_COLON))
+ {
+ c_parser_error (parser,
+ "setter name must be followed by %<:%>");
+ syntax_error = true;
+ break;
+ }
+ c_parser_consume_token (parser);
+ }
+ else if (keyword == RID_GETTER)
+ pkind = OBJC_PATTR_GETTER;
+ else
+ pkind = OBJC_PATTR_IVAR;
+ objc_set_property_attr (loc, pkind, ident);
+ break;
+ case RID_COPIES:
+ c_parser_consume_token (parser);
+ objc_set_property_attr (loc, OBJC_PATTR_COPIES, NULL_TREE);
+ break;
+ default:
+ if (token->type == CPP_CLOSE_PAREN)
+ c_parser_error (parser, "expected identifier");
+ else
+ {
+ c_parser_consume_token (parser);
+ c_parser_error (parser, "unknown property attribute");
+ }
+ syntax_error = true;
+ break;
+ }
+
+ if (syntax_error)
break;
- case RID_GETTER:
- case RID_SETTER:
- case RID_IVAR:
+
+ if (c_parser_next_token_is (parser, CPP_COMMA))
c_parser_consume_token (parser);
- if (c_parser_next_token_is_not (parser, CPP_EQ))
- {
- c_parser_error (parser,
- "getter/setter/ivar attribute must be followed by %<=%>");
- err = true;
- break;
- }
- c_parser_consume_token (parser); /* eat the = */
- if (c_parser_next_token_is_not (parser, CPP_NAME))
- {
- c_parser_error (parser, "expected an identifier");
- err = true;
- break;
- }
- ident = c_parser_peek_token (parser)->value;
- if (keywd == RID_SETTER)
- {
- pkind = OBJC_PATTR_SETTER;
- /* Eat the identifier, and look for the following : */
- c_parser_consume_token (parser);
- if (c_parser_next_token_is_not (parser, CPP_COLON))
- {
- c_parser_error (parser,
- "setter name must be followed by %<:%>");
- err = true;
- }
- }
- else if (keywd == RID_GETTER)
- pkind = OBJC_PATTR_GETTER;
- else
- pkind = OBJC_PATTR_IVAR;
-
- objc_set_property_attr (loc, pkind, ident);
- break;
- case RID_COPIES:
- objc_set_property_attr (loc, OBJC_PATTR_COPIES, NULL_TREE);
- break;
- default:
- c_parser_error (parser, "unknown property attribute");
- err = true;
+ else
break;
}
- /* Eat the attribute,identifier or colon that's been used. */
- c_parser_consume_token (parser);
- if (err)
- break;
-
- if (c_parser_next_token_is (parser, CPP_COMMA))
- c_parser_consume_token (parser);
- else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
- warning_at (c_parser_peek_token (parser)->location, 0,
- "property attributes should be separated by a %<,%>");
- }
- parser->objc_property_attr_context = false;
- c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
-}
-
-/* Parse property attributes and then the definition. */
-
-static void
-c_parser_objc_at_property (c_parser *parser)
-{
- tree props;
- /* We should only arrive here with the property keyword. */
- c_parser_require_keyword (parser, RID_AT_PROPERTY, "expected %<@property%>");
-
- /* Process the optional attribute list... */
- c_parser_objc_property_attrlist (parser) ;
- /* ... and the property var decls. */
- props = c_parser_struct_declaration (parser);
+ parser->objc_property_attr_context = false;
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+ }
+ /* ... and the property declaration(s). */
+ properties = c_parser_struct_declaration (parser);
- /* Comma-separated properties are chained together in
- reverse order; add them one by one. */
- props = nreverse (props);
+ if (properties == error_mark_node)
+ {
+ c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
+ parser->error = false;
+ return;
+ }
- for (; props; props = TREE_CHAIN (props))
- objc_add_property_variable (copy_node (props));
+ if (properties == NULL_TREE)
+ c_parser_error (parser, "expected identifier");
+ else
+ {
+ /* Comma-separated properties are chained together in
+ reverse order; add them one by one. */
+ properties = nreverse (properties);
+
+ for (; properties; properties = TREE_CHAIN (properties))
+ objc_add_property_declaration (loc, copy_node (properties));
+ }
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+ parser->error = false;
}
/* Parse an Objective-C @synthesize declaration. The syntax is: