diff options
author | iains <iains@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-28 20:08:38 +0000 |
---|---|---|
committer | iains <iains@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-28 20:08:38 +0000 |
commit | a336eb4b5042c9ebc2d044d29202649fd9fa2759 (patch) | |
tree | e9f050f6c9de15c20adf243711859bc55a85c841 /gcc/c-parser.c | |
parent | e3d1ab2bdf7b9008475deb5432108db2f0c672be (diff) | |
download | gcc-a336eb4b5042c9ebc2d044d29202649fd9fa2759.tar.gz |
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
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164700 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-parser.c')
-rw-r--r-- | gcc/c-parser.c | 95 |
1 files changed, 82 insertions, 13 deletions
diff --git a/gcc/c-parser.c b/gcc/c-parser.c index b1e6eb2ee08..2743f3020e4 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -977,11 +977,11 @@ static bool c_parser_pragma (c_parser *, enum pragma_context); /* These Objective-C parser functions are only ever called when compiling Objective-C. */ -static void c_parser_objc_class_definition (c_parser *); +static void c_parser_objc_class_definition (c_parser *, tree); static void c_parser_objc_class_instance_variables (c_parser *); static void c_parser_objc_class_declaration (c_parser *); static void c_parser_objc_alias_declaration (c_parser *); -static void c_parser_objc_protocol_definition (c_parser *); +static void c_parser_objc_protocol_definition (c_parser *, tree); static enum tree_code c_parser_objc_method_type (c_parser *); static void c_parser_objc_method_definition (c_parser *); static void c_parser_objc_methodprotolist (c_parser *); @@ -996,6 +996,8 @@ 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 bool c_parser_objc_diagnose_bad_element_prefix + (c_parser *, struct c_declspecs *); /* Parse a translation unit (C90 6.7, C99 6.9). @@ -1079,7 +1081,7 @@ c_parser_external_declaration (c_parser *parser) case RID_AT_INTERFACE: case RID_AT_IMPLEMENTATION: gcc_assert (c_dialect_objc ()); - c_parser_objc_class_definition (parser); + c_parser_objc_class_definition (parser, NULL_TREE); break; case RID_CLASS: gcc_assert (c_dialect_objc ()); @@ -1091,7 +1093,7 @@ c_parser_external_declaration (c_parser *parser) break; case RID_AT_PROTOCOL: gcc_assert (c_dialect_objc ()); - c_parser_objc_protocol_definition (parser); + c_parser_objc_protocol_definition (parser, NULL_TREE); break; case RID_AT_END: gcc_assert (c_dialect_objc ()); @@ -1123,15 +1125,15 @@ c_parser_external_declaration (c_parser *parser) as a declaration or function definition. */ default: decl_or_fndef: - /* A declaration or a function definition. We can only tell - which after parsing the declaration specifiers, if any, and - the first declarator. */ + /* A declaration or a function definition (or, in Objective-C, + an @interface or @protocol with prefix attributes). We can + only tell which after parsing the declaration specifiers, if + any, and the first declarator. */ c_parser_declaration_or_fndef (parser, true, true, true, false, true); break; } } - /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 6.7, 6.9.1). If FNDEF_OK is true, a function definition is accepted; otherwise (old-style parameter declarations) only other @@ -1173,6 +1175,11 @@ c_parser_external_declaration (c_parser *parser) declaration-specifiers declarator declaration-list[opt] compound-statement + Objective-C: + attributes objc-class-definition + attributes objc-category-definition + attributes objc-protocol-definition + The simple-asm-expr and attributes are GNU extensions. This function does not handle __extension__; that is handled in its @@ -1235,6 +1242,51 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, c_parser_consume_token (parser); return; } + else if (c_dialect_objc ()) + { + /* This is where we parse 'attributes @interface ...', + 'attributes @implementation ...', 'attributes @protocol ...' + (where attributes could be, for example, __attribute__ + ((deprecated)). + */ + switch (c_parser_peek_token (parser)->keyword) + { + case RID_AT_INTERFACE: + { + if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) + return; + c_parser_objc_class_definition (parser, specs->attrs); + return; + } + break; + case RID_AT_IMPLEMENTATION: + { + if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) + return; + if (specs->attrs) + { + warning_at (c_parser_peek_token (parser)->location, + OPT_Wattributes, + "prefix attributes are ignored for implementations"); + specs->attrs = NULL_TREE; + } + c_parser_objc_class_definition (parser, NULL_TREE); + return; + } + break; + case RID_AT_PROTOCOL: + { + if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) + return; + c_parser_objc_protocol_definition (parser, specs->attrs); + return; + } + break; + default: + break; + } + } + pending_xref_error (); prefix_attrs = specs->attrs; all_prefix_attrs = prefix_attrs; @@ -6254,7 +6306,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, objc-protocol-refs and objc-class-instance-variables are omitted. */ static void -c_parser_objc_class_definition (c_parser *parser) +c_parser_objc_class_definition (c_parser *parser, tree attributes) { bool iface_p; tree id1; @@ -6265,6 +6317,7 @@ c_parser_objc_class_definition (c_parser *parser) iface_p = false; else gcc_unreachable (); + c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_NAME)) { @@ -6294,7 +6347,7 @@ c_parser_objc_class_definition (c_parser *parser) } if (c_parser_next_token_is (parser, CPP_LESS)) proto = c_parser_objc_protocol_refs (parser); - objc_start_category_interface (id1, id2, proto); + objc_start_category_interface (id1, id2, proto, attributes); c_parser_objc_methodprotolist (parser); c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); objc_finish_interface (); @@ -6318,7 +6371,7 @@ c_parser_objc_class_definition (c_parser *parser) tree proto = NULL_TREE; if (c_parser_next_token_is (parser, CPP_LESS)) proto = c_parser_objc_protocol_refs (parser); - objc_start_class_interface (id1, superclass, proto); + objc_start_class_interface (id1, superclass, proto, attributes); } else objc_start_class_implementation (id1, superclass); @@ -6498,9 +6551,10 @@ c_parser_objc_alias_declaration (c_parser *parser) omitted. */ static void -c_parser_objc_protocol_definition (c_parser *parser) +c_parser_objc_protocol_definition (c_parser *parser, tree attributes) { gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL)); + c_parser_consume_token (parser); if (c_parser_next_token_is_not (parser, CPP_NAME)) { @@ -6540,7 +6594,7 @@ c_parser_objc_protocol_definition (c_parser *parser) if (c_parser_next_token_is (parser, CPP_LESS)) proto = c_parser_objc_protocol_refs (parser); parser->objc_pq_context = true; - objc_start_protocol (id, proto); + objc_start_protocol (id, proto, attributes); c_parser_objc_methodprotolist (parser); c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); parser->objc_pq_context = false; @@ -7129,6 +7183,21 @@ c_parser_objc_keywordexpr (c_parser *parser) return ret; } +/* A check, needed in several places, that ObjC interface, implementation or + method definitions are not prefixed by incorrect items. */ +static bool +c_parser_objc_diagnose_bad_element_prefix (c_parser *parser, + struct c_declspecs *specs) +{ + if (!specs->declspecs_seen_p || specs->type_seen_p || specs->non_sc_seen_p) + { + c_parser_error (parser, + "no type or storage class may be specified here,"); + c_parser_skip_to_end_of_block_or_statement (parser); + return true; + } + return false; +} /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore should be considered, statements. ALLOW_STMT is true if we're within |