diff options
author | Iain Sandoe <iains@gcc.gnu.org> | 2010-09-28 20:08:38 +0000 |
---|---|---|
committer | Iain Sandoe <iains@gcc.gnu.org> | 2010-09-28 20:08:38 +0000 |
commit | c165dca7efdb3f4bdae82c01b409a6b9cf4dbd65 (patch) | |
tree | e9f050f6c9de15c20adf243711859bc55a85c841 /gcc/cp/parser.c | |
parent | 41804a5be02d8d811e5189a9cca9060f41cea765 (diff) | |
download | gcc-c165dca7efdb3f4bdae82c01b409a6b9cf4dbd65.zip gcc-c165dca7efdb3f4bdae82c01b409a6b9cf4dbd65.tar.gz gcc-c165dca7efdb3f4bdae82c01b409a6b9cf4dbd65.tar.bz2 |
add ObjC* class, category and protocol attribute parsers
gcc/c-family:
* c-common.h (objc_start_class_interface): Adjust prototype.
(objc_start_category_interface): Likewise.
(objc_start_protocol): Likewise.
* stub-objc.c (objc_start_protocol): Adjust for extra argument.
(objc_start_class_interface): Likewise.
(objc_start_category_interface): Likewise.
gcc/objc:
* objc-act.c (objc_start_class_interface): Handle and ignore attributes.
(objc_start_category_interface): Likewise.
(objc_start_protocol): Likewise.
gcc/cp:
* parser.c (cp_parser_objc_valid_prefix_attributes): New.
(cp_parser_declaration): Parse prefix attributes for ObjC++.
(cp_parser_objc_protocol_declaration): Handle attributes.
(cp_parser_objc_class_interface): Likewise.
(cp_parser_objc_declaration): Likewise.
gcc:
* c-parser.c (c_parser_objc_class_definition): Adjust prototype.
(c_parser_objc_protocol_definition): Likewise.
(c_parser_external_declaration): Provide dummy attribute arguments.
(c_parser_declaration_or_fndef): Parse prefix attributes for ObjC.
(c_parser_objc_class_definition): Handle attributes.
(c_parser_objc_protocol_definition): Likewise.
gcc/testsuite:
* objc.dg/attributes: New.
* objc.dg/attributes/attributes.exp: New.
* objc.dg/attributes/class-attribute-1.m: New.
* objc.dg/attributes/class-attribute-2.m: New
* objc.dg/attributes/categ-attribute-1.m: New
* objc.dg/attributes/categ-attribute-2.m: New
* objc.dg/attributes/proto-attribute-1.m: New
* obj-c++.dg/attributes: New.
* obj-c++.dg/attributes/attributes.exp: New
* obj-c++.dg/attributes/class-attribute-1.mm: New
* obj-c++.dg/attributes/class-attribute-2.mm: New
* obj-c++.dg/attributes/categ-attribute-1.mm: New
* obj-c++.dg/attributes/categ-attribute-2.mm: New
* obj-c++.dg/attributes/proto-attribute-1.mm: New
From-SVN: r164700
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r-- | gcc/cp/parser.c | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9385344..8f6ea25 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2086,9 +2086,11 @@ static tree cp_parser_objc_selector static tree cp_parser_objc_protocol_refs_opt (cp_parser *); static void cp_parser_objc_declaration - (cp_parser *); + (cp_parser *, tree); static tree cp_parser_objc_statement (cp_parser *); +static bool cp_parser_objc_valid_prefix_attributes + (cp_parser* parser, tree *attrib); /* Utility Routines */ @@ -9285,6 +9287,7 @@ cp_parser_declaration (cp_parser* parser) cp_token token2; int saved_pedantic; void *p; + tree attributes = NULL_TREE; /* Check for the `__extension__' keyword. */ if (cp_parser_extension_opt (parser, &saved_pedantic)) @@ -9362,7 +9365,11 @@ cp_parser_declaration (cp_parser* parser) cp_parser_namespace_definition (parser); /* Objective-C++ declaration/definition. */ else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword)) - cp_parser_objc_declaration (parser); + cp_parser_objc_declaration (parser, NULL_TREE); + else if (c_dialect_objc () + && token1.keyword == RID_ATTRIBUTE + && cp_parser_objc_valid_prefix_attributes (parser, &attributes)) + cp_parser_objc_declaration (parser, attributes); /* We must have either a block declaration or a function definition. */ else @@ -21739,7 +21746,7 @@ cp_parser_objc_class_ivars (cp_parser* parser) /* Parse an Objective-C protocol declaration. */ static void -cp_parser_objc_protocol_declaration (cp_parser* parser) +cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes) { tree proto, protorefs; cp_token *tok; @@ -21768,7 +21775,7 @@ cp_parser_objc_protocol_declaration (cp_parser* parser) { proto = cp_parser_identifier (parser); protorefs = cp_parser_objc_protocol_refs_opt (parser); - objc_start_protocol (proto, protorefs); + objc_start_protocol (proto, protorefs, attributes); cp_parser_objc_method_prototype_list (parser); } } @@ -21798,7 +21805,7 @@ cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super, /* Parse an Objective-C class interface. */ static void -cp_parser_objc_class_interface (cp_parser* parser) +cp_parser_objc_class_interface (cp_parser* parser, tree attributes) { tree name, super, categ, protos; @@ -21809,10 +21816,10 @@ cp_parser_objc_class_interface (cp_parser* parser) /* We have either a class or a category on our hands. */ if (categ) - objc_start_category_interface (name, categ, protos); + objc_start_category_interface (name, categ, protos, attributes); else { - objc_start_class_interface (name, super, protos); + objc_start_class_interface (name, super, protos, attributes); /* Handle instance variable declarations, if any. */ cp_parser_objc_class_ivars (parser); objc_continue_interface (); @@ -21858,11 +21865,31 @@ cp_parser_objc_end_implementation (cp_parser* parser) /* Parse an Objective-C declaration. */ static void -cp_parser_objc_declaration (cp_parser* parser) +cp_parser_objc_declaration (cp_parser* parser, tree attributes) { /* Try to figure out what kind of declaration is present. */ cp_token *kwd = cp_lexer_peek_token (parser->lexer); + if (attributes) + switch (kwd->keyword) + { + case RID_AT_ALIAS: + case RID_AT_CLASS: + case RID_AT_END: + error_at (kwd->location, "attributes may not be specified before" + " the %<@%D%> Objective-C++ keyword", + kwd->u.value); + attributes = NULL; + break; + case RID_AT_IMPLEMENTATION: + warning_at (kwd->location, OPT_Wattributes, + "prefix attributes are ignored before %<@%D%>", + kwd->u.value); + attributes = NULL; + default: + break; + } + switch (kwd->keyword) { case RID_AT_ALIAS: @@ -21872,10 +21899,10 @@ cp_parser_objc_declaration (cp_parser* parser) cp_parser_objc_class_declaration (parser); break; case RID_AT_PROTOCOL: - cp_parser_objc_protocol_declaration (parser); + cp_parser_objc_protocol_declaration (parser, attributes); break; case RID_AT_INTERFACE: - cp_parser_objc_class_interface (parser); + cp_parser_objc_class_interface (parser, attributes); break; case RID_AT_IMPLEMENTATION: cp_parser_objc_class_implementation (parser); @@ -22024,6 +22051,26 @@ cp_parser_objc_statement (cp_parser * parser) { return error_mark_node; } + +/* If we are compiling ObjC++ and we see an __attribute__ we neeed to + look ahead to see if an objc keyword follows the attributes. This + is to detect the use of prefix attributes on ObjC @interface and + @protocol. */ + +static bool +cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib) +{ + cp_lexer_save_tokens (parser->lexer); + *attrib = cp_parser_attributes_opt (parser); + gcc_assert (*attrib); + if (OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword)) + { + cp_lexer_commit_tokens (parser->lexer); + return true; + } + cp_lexer_rollback_tokens (parser->lexer); + return false; +} /* OpenMP 2.5 parsing routines. */ |