aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorNicola Pero <nicola.pero@meta-innovation.com>2010-12-10 09:38:52 +0000
committerNicola Pero <nicola@gcc.gnu.org>2010-12-10 09:38:52 +0000
commitec3e9f826773a7aa4cfc135b4cc9e2de222bc137 (patch)
tree1455b598d50eb7e482cbb74cb6884dc439905ab7 /gcc/cp/parser.c
parentaff7f4c416f03bcadf563a3f73896ddabd8da844 (diff)
downloadgcc-ec3e9f826773a7aa4cfc135b4cc9e2de222bc137.zip
gcc-ec3e9f826773a7aa4cfc135b4cc9e2de222bc137.tar.gz
gcc-ec3e9f826773a7aa4cfc135b4cc9e2de222bc137.tar.bz2
In gcc/: 2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com>
In gcc/: 2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com> * c-parser.c (c_parser_objc_class_definition): Recognize Objective-C 2.0 class extensions. In gcc/cp/: 2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com> * parser.c (cp_parser_objc_superclass_or_category): Recognize Objective-C 2.0 class extensions. Added iface_p and is_class_extension arguments. (cp_parser_objc_class_interface): Updated call to cp_parser_objc_superclass_or_category. (cp_parser_objc_class_implementation): Same change. In gcc/objc/: 2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com> * objc-act.c (objc_in_class_extension): New. (objc_start_category_interface): If -fobjc-std=objc1 was specified, produce an error if a class extension is used. (objc_finish_interface): Reset objc_in_class_extension to false. (objc_add_property_declaration): Allow a class extension to extend readonly properties in the main @interface to be readwrite. (start_class): Added code to deal with class extensions. In that case, return the existing interface after adding any additional protocols to it and setting objc_in_class_extension to true. (continue_class): If in a class extension, do not generate the instance variable template. In gcc/testsuite/: 2010-12-10 Nicola Pero <nicola.pero@meta-innovation.com> * objc.dg/class-extension-1.m: New. * objc.dg/class-extension-2.m: New. * objc.dg/class-extension-3.m: New. * objc.dg/property/at-property-26.m: New. * objc.dg/property/at-property-27.m: New. * objc.dg/property/at-property-28.m: New. * obj-c++.dg/class-extension-1.mm: New. * obj-c++.dg/class-extension-2.mm: New. * obj-c++.dg/class-extension-3.mm: New. * obj-c++.dg/property/at-property-26.mm: New. * obj-c++.dg/property/at-property-27.mm: New. * obj-c++.dg/property/at-property-28.mm: New. From-SVN: r167680
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ab533f4..4c8ca72 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -22435,12 +22435,15 @@ cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
/* Parse an Objective-C superclass or category. */
static void
-cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super,
- tree *categ)
+cp_parser_objc_superclass_or_category (cp_parser *parser,
+ bool iface_p,
+ tree *super,
+ tree *categ, bool *is_class_extension)
{
cp_token *next = cp_lexer_peek_token (parser->lexer);
*super = *categ = NULL_TREE;
+ *is_class_extension = false;
if (next->type == CPP_COLON)
{
cp_lexer_consume_token (parser->lexer); /* Eat ':'. */
@@ -22449,7 +22452,17 @@ cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super,
else if (next->type == CPP_OPEN_PAREN)
{
cp_lexer_consume_token (parser->lexer); /* Eat '('. */
- *categ = cp_parser_identifier (parser);
+
+ /* If there is no category name, and this is an @interface, we
+ have a class extension. */
+ if (iface_p && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
+ {
+ *categ = NULL_TREE;
+ *is_class_extension = true;
+ }
+ else
+ *categ = cp_parser_identifier (parser);
+
cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN);
}
}
@@ -22460,6 +22473,7 @@ static void
cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
{
tree name, super, categ, protos;
+ bool is_class_extension;
cp_lexer_consume_token (parser->lexer); /* Eat '@interface'. */
name = cp_parser_identifier (parser);
@@ -22472,11 +22486,12 @@ cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
*/
return;
}
- cp_parser_objc_superclass_or_category (parser, &super, &categ);
+ cp_parser_objc_superclass_or_category (parser, true, &super, &categ,
+ &is_class_extension);
protos = cp_parser_objc_protocol_refs_opt (parser);
/* We have either a class or a category on our hands. */
- if (categ)
+ if (categ || is_class_extension)
objc_start_category_interface (name, categ, protos, attributes);
else
{
@@ -22495,6 +22510,7 @@ static void
cp_parser_objc_class_implementation (cp_parser* parser)
{
tree name, super, categ;
+ bool is_class_extension;
cp_lexer_consume_token (parser->lexer); /* Eat '@implementation'. */
name = cp_parser_identifier (parser);
@@ -22508,7 +22524,8 @@ cp_parser_objc_class_implementation (cp_parser* parser)
*/
return;
}
- cp_parser_objc_superclass_or_category (parser, &super, &categ);
+ cp_parser_objc_superclass_or_category (parser, false, &super, &categ,
+ &is_class_extension);
/* We have either a class or a category on our hands. */
if (categ)