Commit c165dca7 by Iain Sandoe

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
parent 41804a5b
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* 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.
2010-09-28 Tobias Burnus <burnus@net-b.de> 2010-09-28 Tobias Burnus <burnus@net-b.de>
PR fortran/40569 PR fortran/40569
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* 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.
2010-09-27 Ian Lance Taylor <iant@google.com> 2010-09-27 Ian Lance Taylor <iant@google.com>
* c-common.c (c_common_attribute_table): Add no_split_stack. * c-common.c (c_common_attribute_table): Add no_split_stack.
......
...@@ -965,9 +965,9 @@ extern tree objc_get_protocol_qualified_type (tree, tree); ...@@ -965,9 +965,9 @@ extern tree objc_get_protocol_qualified_type (tree, tree);
extern tree objc_get_class_reference (tree); extern tree objc_get_class_reference (tree);
extern tree objc_get_class_ivars (tree); extern tree objc_get_class_ivars (tree);
extern tree objc_get_interface_ivars (tree); extern tree objc_get_interface_ivars (tree);
extern void objc_start_class_interface (tree, tree, tree); extern void objc_start_class_interface (tree, tree, tree, tree);
extern void objc_start_category_interface (tree, tree, tree); extern void objc_start_category_interface (tree, tree, tree, tree);
extern void objc_start_protocol (tree, tree); extern void objc_start_protocol (tree, tree, tree);
extern void objc_continue_interface (void); extern void objc_continue_interface (void);
extern void objc_finish_interface (void); extern void objc_finish_interface (void);
extern void objc_start_class_implementation (tree, tree); extern void objc_start_class_implementation (tree, tree);
......
...@@ -122,21 +122,24 @@ objc_declare_protocols (tree ARG_UNUSED (list)) ...@@ -122,21 +122,24 @@ objc_declare_protocols (tree ARG_UNUSED (list))
void void
objc_start_protocol (tree ARG_UNUSED (proto), objc_start_protocol (tree ARG_UNUSED (proto),
tree ARG_UNUSED (protorefs)) tree ARG_UNUSED (protorefs),
tree ARG_UNUSED (attribs))
{ {
} }
void void
objc_start_class_interface (tree ARG_UNUSED (name), objc_start_class_interface (tree ARG_UNUSED (name),
tree ARG_UNUSED (super), tree ARG_UNUSED (super),
tree ARG_UNUSED (protos)) tree ARG_UNUSED (protos),
tree ARG_UNUSED (attribs))
{ {
} }
void void
objc_start_category_interface (tree ARG_UNUSED (name), objc_start_category_interface (tree ARG_UNUSED (name),
tree ARG_UNUSED (categ), tree ARG_UNUSED (categ),
tree ARG_UNUSED (protos)) tree ARG_UNUSED (protos),
tree ARG_UNUSED (attribs))
{ {
} }
......
...@@ -977,11 +977,11 @@ static bool c_parser_pragma (c_parser *, enum pragma_context); ...@@ -977,11 +977,11 @@ static bool c_parser_pragma (c_parser *, enum pragma_context);
/* These Objective-C parser functions are only ever called when /* These Objective-C parser functions are only ever called when
compiling Objective-C. */ 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_instance_variables (c_parser *);
static void c_parser_objc_class_declaration (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_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 enum tree_code c_parser_objc_method_type (c_parser *);
static void c_parser_objc_method_definition (c_parser *); static void c_parser_objc_method_definition (c_parser *);
static void c_parser_objc_methodprotolist (c_parser *); static void c_parser_objc_methodprotolist (c_parser *);
...@@ -996,6 +996,8 @@ static tree c_parser_objc_selector_arg (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_receiver (c_parser *);
static tree c_parser_objc_message_args (c_parser *); static tree c_parser_objc_message_args (c_parser *);
static tree c_parser_objc_keywordexpr (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). /* Parse a translation unit (C90 6.7, C99 6.9).
...@@ -1079,7 +1081,7 @@ c_parser_external_declaration (c_parser *parser) ...@@ -1079,7 +1081,7 @@ c_parser_external_declaration (c_parser *parser)
case RID_AT_INTERFACE: case RID_AT_INTERFACE:
case RID_AT_IMPLEMENTATION: case RID_AT_IMPLEMENTATION:
gcc_assert (c_dialect_objc ()); gcc_assert (c_dialect_objc ());
c_parser_objc_class_definition (parser); c_parser_objc_class_definition (parser, NULL_TREE);
break; break;
case RID_CLASS: case RID_CLASS:
gcc_assert (c_dialect_objc ()); gcc_assert (c_dialect_objc ());
...@@ -1091,7 +1093,7 @@ c_parser_external_declaration (c_parser *parser) ...@@ -1091,7 +1093,7 @@ c_parser_external_declaration (c_parser *parser)
break; break;
case RID_AT_PROTOCOL: case RID_AT_PROTOCOL:
gcc_assert (c_dialect_objc ()); gcc_assert (c_dialect_objc ());
c_parser_objc_protocol_definition (parser); c_parser_objc_protocol_definition (parser, NULL_TREE);
break; break;
case RID_AT_END: case RID_AT_END:
gcc_assert (c_dialect_objc ()); gcc_assert (c_dialect_objc ());
...@@ -1123,15 +1125,15 @@ c_parser_external_declaration (c_parser *parser) ...@@ -1123,15 +1125,15 @@ c_parser_external_declaration (c_parser *parser)
as a declaration or function definition. */ as a declaration or function definition. */
default: default:
decl_or_fndef: decl_or_fndef:
/* A declaration or a function definition. We can only tell /* A declaration or a function definition (or, in Objective-C,
which after parsing the declaration specifiers, if any, and an @interface or @protocol with prefix attributes). We can
the first declarator. */ 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); c_parser_declaration_or_fndef (parser, true, true, true, false, true);
break; break;
} }
} }
/* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 /* 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 6.7, 6.9.1). If FNDEF_OK is true, a function definition is
accepted; otherwise (old-style parameter declarations) only other accepted; otherwise (old-style parameter declarations) only other
...@@ -1173,6 +1175,11 @@ c_parser_external_declaration (c_parser *parser) ...@@ -1173,6 +1175,11 @@ c_parser_external_declaration (c_parser *parser)
declaration-specifiers declarator declaration-list[opt] declaration-specifiers declarator declaration-list[opt]
compound-statement 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. The simple-asm-expr and attributes are GNU extensions.
This function does not handle __extension__; that is handled in its 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, ...@@ -1235,6 +1242,51 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
c_parser_consume_token (parser); c_parser_consume_token (parser);
return; 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 (); pending_xref_error ();
prefix_attrs = specs->attrs; prefix_attrs = specs->attrs;
all_prefix_attrs = prefix_attrs; all_prefix_attrs = prefix_attrs;
...@@ -6254,7 +6306,7 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, ...@@ -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. */ objc-protocol-refs and objc-class-instance-variables are omitted. */
static void static void
c_parser_objc_class_definition (c_parser *parser) c_parser_objc_class_definition (c_parser *parser, tree attributes)
{ {
bool iface_p; bool iface_p;
tree id1; tree id1;
...@@ -6265,6 +6317,7 @@ c_parser_objc_class_definition (c_parser *parser) ...@@ -6265,6 +6317,7 @@ c_parser_objc_class_definition (c_parser *parser)
iface_p = false; iface_p = false;
else else
gcc_unreachable (); gcc_unreachable ();
c_parser_consume_token (parser); c_parser_consume_token (parser);
if (c_parser_next_token_is_not (parser, CPP_NAME)) if (c_parser_next_token_is_not (parser, CPP_NAME))
{ {
...@@ -6294,7 +6347,7 @@ c_parser_objc_class_definition (c_parser *parser) ...@@ -6294,7 +6347,7 @@ c_parser_objc_class_definition (c_parser *parser)
} }
if (c_parser_next_token_is (parser, CPP_LESS)) if (c_parser_next_token_is (parser, CPP_LESS))
proto = c_parser_objc_protocol_refs (parser); 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_objc_methodprotolist (parser);
c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
objc_finish_interface (); objc_finish_interface ();
...@@ -6318,7 +6371,7 @@ c_parser_objc_class_definition (c_parser *parser) ...@@ -6318,7 +6371,7 @@ c_parser_objc_class_definition (c_parser *parser)
tree proto = NULL_TREE; tree proto = NULL_TREE;
if (c_parser_next_token_is (parser, CPP_LESS)) if (c_parser_next_token_is (parser, CPP_LESS))
proto = c_parser_objc_protocol_refs (parser); proto = c_parser_objc_protocol_refs (parser);
objc_start_class_interface (id1, superclass, proto); objc_start_class_interface (id1, superclass, proto, attributes);
} }
else else
objc_start_class_implementation (id1, superclass); objc_start_class_implementation (id1, superclass);
...@@ -6498,9 +6551,10 @@ c_parser_objc_alias_declaration (c_parser *parser) ...@@ -6498,9 +6551,10 @@ c_parser_objc_alias_declaration (c_parser *parser)
omitted. */ omitted. */
static void 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)); gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
c_parser_consume_token (parser); c_parser_consume_token (parser);
if (c_parser_next_token_is_not (parser, CPP_NAME)) if (c_parser_next_token_is_not (parser, CPP_NAME))
{ {
...@@ -6540,7 +6594,7 @@ c_parser_objc_protocol_definition (c_parser *parser) ...@@ -6540,7 +6594,7 @@ c_parser_objc_protocol_definition (c_parser *parser)
if (c_parser_next_token_is (parser, CPP_LESS)) if (c_parser_next_token_is (parser, CPP_LESS))
proto = c_parser_objc_protocol_refs (parser); proto = c_parser_objc_protocol_refs (parser);
parser->objc_pq_context = true; parser->objc_pq_context = true;
objc_start_protocol (id, proto); objc_start_protocol (id, proto, attributes);
c_parser_objc_methodprotolist (parser); c_parser_objc_methodprotolist (parser);
c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
parser->objc_pq_context = false; parser->objc_pq_context = false;
...@@ -7129,6 +7183,21 @@ c_parser_objc_keywordexpr (c_parser *parser) ...@@ -7129,6 +7183,21 @@ c_parser_objc_keywordexpr (c_parser *parser)
return ret; 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 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore
should be considered, statements. ALLOW_STMT is true if we're within should be considered, statements. ALLOW_STMT is true if we're within
......
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* 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.
2010-09-27 Jason Merrill <jason@redhat.com> 2010-09-27 Jason Merrill <jason@redhat.com>
Require lvalues as specified by the standard. Require lvalues as specified by the standard.
......
...@@ -2086,9 +2086,11 @@ static tree cp_parser_objc_selector ...@@ -2086,9 +2086,11 @@ static tree cp_parser_objc_selector
static tree cp_parser_objc_protocol_refs_opt static tree cp_parser_objc_protocol_refs_opt
(cp_parser *); (cp_parser *);
static void cp_parser_objc_declaration static void cp_parser_objc_declaration
(cp_parser *); (cp_parser *, tree);
static tree cp_parser_objc_statement static tree cp_parser_objc_statement
(cp_parser *); (cp_parser *);
static bool cp_parser_objc_valid_prefix_attributes
(cp_parser* parser, tree *attrib);
/* Utility Routines */ /* Utility Routines */
...@@ -9285,6 +9287,7 @@ cp_parser_declaration (cp_parser* parser) ...@@ -9285,6 +9287,7 @@ cp_parser_declaration (cp_parser* parser)
cp_token token2; cp_token token2;
int saved_pedantic; int saved_pedantic;
void *p; void *p;
tree attributes = NULL_TREE;
/* Check for the `__extension__' keyword. */ /* Check for the `__extension__' keyword. */
if (cp_parser_extension_opt (parser, &saved_pedantic)) if (cp_parser_extension_opt (parser, &saved_pedantic))
...@@ -9362,7 +9365,11 @@ cp_parser_declaration (cp_parser* parser) ...@@ -9362,7 +9365,11 @@ cp_parser_declaration (cp_parser* parser)
cp_parser_namespace_definition (parser); cp_parser_namespace_definition (parser);
/* Objective-C++ declaration/definition. */ /* Objective-C++ declaration/definition. */
else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1.keyword)) 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 /* We must have either a block declaration or a function
definition. */ definition. */
else else
...@@ -21739,7 +21746,7 @@ cp_parser_objc_class_ivars (cp_parser* parser) ...@@ -21739,7 +21746,7 @@ cp_parser_objc_class_ivars (cp_parser* parser)
/* Parse an Objective-C protocol declaration. */ /* Parse an Objective-C protocol declaration. */
static void static void
cp_parser_objc_protocol_declaration (cp_parser* parser) cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
{ {
tree proto, protorefs; tree proto, protorefs;
cp_token *tok; cp_token *tok;
...@@ -21768,7 +21775,7 @@ cp_parser_objc_protocol_declaration (cp_parser* parser) ...@@ -21768,7 +21775,7 @@ cp_parser_objc_protocol_declaration (cp_parser* parser)
{ {
proto = cp_parser_identifier (parser); proto = cp_parser_identifier (parser);
protorefs = cp_parser_objc_protocol_refs_opt (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); cp_parser_objc_method_prototype_list (parser);
} }
} }
...@@ -21798,7 +21805,7 @@ cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super, ...@@ -21798,7 +21805,7 @@ cp_parser_objc_superclass_or_category (cp_parser *parser, tree *super,
/* Parse an Objective-C class interface. */ /* Parse an Objective-C class interface. */
static void 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; tree name, super, categ, protos;
...@@ -21809,10 +21816,10 @@ cp_parser_objc_class_interface (cp_parser* parser) ...@@ -21809,10 +21816,10 @@ cp_parser_objc_class_interface (cp_parser* parser)
/* We have either a class or a category on our hands. */ /* We have either a class or a category on our hands. */
if (categ) if (categ)
objc_start_category_interface (name, categ, protos); objc_start_category_interface (name, categ, protos, attributes);
else else
{ {
objc_start_class_interface (name, super, protos); objc_start_class_interface (name, super, protos, attributes);
/* Handle instance variable declarations, if any. */ /* Handle instance variable declarations, if any. */
cp_parser_objc_class_ivars (parser); cp_parser_objc_class_ivars (parser);
objc_continue_interface (); objc_continue_interface ();
...@@ -21858,11 +21865,31 @@ cp_parser_objc_end_implementation (cp_parser* parser) ...@@ -21858,11 +21865,31 @@ cp_parser_objc_end_implementation (cp_parser* parser)
/* Parse an Objective-C declaration. */ /* Parse an Objective-C declaration. */
static void 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. */ /* Try to figure out what kind of declaration is present. */
cp_token *kwd = cp_lexer_peek_token (parser->lexer); 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) switch (kwd->keyword)
{ {
case RID_AT_ALIAS: case RID_AT_ALIAS:
...@@ -21872,10 +21899,10 @@ cp_parser_objc_declaration (cp_parser* parser) ...@@ -21872,10 +21899,10 @@ cp_parser_objc_declaration (cp_parser* parser)
cp_parser_objc_class_declaration (parser); cp_parser_objc_class_declaration (parser);
break; break;
case RID_AT_PROTOCOL: case RID_AT_PROTOCOL:
cp_parser_objc_protocol_declaration (parser); cp_parser_objc_protocol_declaration (parser, attributes);
break; break;
case RID_AT_INTERFACE: case RID_AT_INTERFACE:
cp_parser_objc_class_interface (parser); cp_parser_objc_class_interface (parser, attributes);
break; break;
case RID_AT_IMPLEMENTATION: case RID_AT_IMPLEMENTATION:
cp_parser_objc_class_implementation (parser); cp_parser_objc_class_implementation (parser);
...@@ -22024,6 +22051,26 @@ cp_parser_objc_statement (cp_parser * parser) { ...@@ -22024,6 +22051,26 @@ cp_parser_objc_statement (cp_parser * parser) {
return error_mark_node; 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. */ /* OpenMP 2.5 parsing routines. */
......
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* objc-act.c (objc_start_class_interface): Handle and ignore attributes.
(objc_start_category_interface): Likewise.
(objc_start_protocol): Likewise.
2010-09-28 Nicola Pero <nicola.pero@meta-innovation.com> 2010-09-28 Nicola Pero <nicola.pero@meta-innovation.com>
Merge from 'apple/trunk' branch on FSF servers. Merge from 'apple/trunk' branch on FSF servers.
......
...@@ -651,8 +651,13 @@ lookup_protocol_in_reflist (tree rproto_list, tree lproto) ...@@ -651,8 +651,13 @@ lookup_protocol_in_reflist (tree rproto_list, tree lproto)
} }
void void
objc_start_class_interface (tree klass, tree super_class, tree protos) objc_start_class_interface (tree klass, tree super_class,
tree protos, tree attributes)
{ {
if (attributes)
warning_at (input_location, OPT_Wattributes,
"class attributes are not available in this version"
" of the compiler, (ignored)");
objc_interface_context objc_interface_context
= objc_ivar_context = objc_ivar_context
= start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos); = start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
...@@ -660,8 +665,13 @@ objc_start_class_interface (tree klass, tree super_class, tree protos) ...@@ -660,8 +665,13 @@ objc_start_class_interface (tree klass, tree super_class, tree protos)
} }
void void
objc_start_category_interface (tree klass, tree categ, tree protos) objc_start_category_interface (tree klass, tree categ,
tree protos, tree attributes)
{ {
if (attributes)
warning_at (input_location, OPT_Wattributes,
"category attributes are not available in this version"
" of the compiler, (ignored)");
objc_interface_context objc_interface_context
= start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos); = start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
objc_ivar_chain objc_ivar_chain
...@@ -669,8 +679,12 @@ objc_start_category_interface (tree klass, tree categ, tree protos) ...@@ -669,8 +679,12 @@ objc_start_category_interface (tree klass, tree categ, tree protos)
} }
void void
objc_start_protocol (tree name, tree protos) objc_start_protocol (tree name, tree protos, tree attributes)
{ {
if (attributes)
warning_at (input_location, OPT_Wattributes,
"protocol attributes are not available in this version"
" of the compiler, (ignored)");
objc_interface_context objc_interface_context
= start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos); = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
} }
......
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* 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
2010-09-28 Nicola Pero <nicola.pero@meta-innovation.com> 2010-09-28 Nicola Pero <nicola.pero@meta-innovation.com>
Merge from 'apple/trunk' branch on FSF servers (test method-20.m Merge from 'apple/trunk' branch on FSF servers (test method-20.m
......
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
# Load support procs.
load_lib obj-c++-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_OBJCXXFLAGS
if ![info exists DEFAULT_OBJCXXFLAGS] then {
set DEFAULT_OBJCXXFLAGS " -ansi -pedantic-errors -Wno-long-long"
}
# Initialize `dg'.
dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.mm]]
# Main loop.
dg-runtest $tests "-fgnu-runtime" $DEFAULT_OBJCXXFLAGS
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
dg-runtest $tests "-fnext-runtime" $DEFAULT_OBJCXXFLAGS
}
# All done.
dg-finish
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
@interface obj : Object {
@public
int var;
}
- (int) mth;
@end
@implementation obj
- (int) mth { return var; }
@end
__attribute ((deprecated))
@interface obj (dep_categ) /* { dg-warning "category attributes are not available in this version" } */
- (int) depmth;
@end
@implementation obj (dep_categ)
- (int) depmth { return var + 1; }
@end
int foo (void)
{
obj *p = [obj new];
int q = [p depmth];
return [p mth];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
@interface obj : Object {
@public
int var;
}
- (int) mth;
@end
@implementation obj
- (int) mth { return var; }
@end
__attribute__ ((deprecated("no dep_categ")))
@interface obj (dep_categ) /* { dg-warning "category attributes are not available in this version" } */
- (int) depmth;
@end
__attribute__ ((deprecated))
@implementation obj (dep_categ) /* { dg-error "prefix attributes are ignored before" } */
- (int) depmth { return var + 1; }
@end
int foo (void)
{
obj *p = [obj new];
int q = [p depmth];
return [p mth];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
/* Normal deprecated func. */
__attribute ((deprecated)) void f1();
__attribute__ ((deprecated("use some new func"))) void f2();
__attribute__ ((deprecated))
@interface depobj : Object { /* { dg-warning "class attributes are not available in this version" } */
@public
int var;
}
- (int) mth;
@end
@implementation depobj
-(int) mth { return var; }
@end
@interface depobj (ok_categ)
@end
@interface NS : depobj
@end
depobj * deprecated;
int foo (depobj *dep_obj) /* dg - warning "deprecated" */
{
depobj *p = [depobj new]; /* dg - warning "deprecated" */
f1(); /* { dg-warning "'void f1..' is deprecated .declared at" } */
f2(); /* { dg-warning "'void f2..' is deprecated .declared at \[^\\)\]*.: use some new func" } */
int q = p->var;
return [p mth];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
__attribute ((deprecated))
@interface depobj : Object { /* { dg-warning "class attributes are not available in this version" } */
@public
int ivar;
}
- (int) mth;
@end
__attribute ((deprecated))
@implementation depobj /* { dg-error "prefix attributes are ignored before" } */
-(int) mth { return ivar; }
@end
int foo (void)
{
depobj *p = [depobj new]; /* dg - warning "deprecated" */
int q = p->ivar;
return [p mth];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
__attribute ((deprecated))
@protocol dep_proto /* { dg-warning "protocol attributes are not available in this version" } */
- (int) depprotomth;
@end
@interface obj : Object <dep_proto>
{
@public
int var;
}
- (int) mth;
@end
@implementation obj
- (int) mth { return var; }
- (int) depprotomth { return var + 1; }
@end
int foo (void)
{
obj *p = [obj new];
int q = [p depprotomth];
return [p mth];
}
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
# Load support procs.
load_lib objc-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
set DEFAULT_CFLAGS ""
}
# Initialize `dg'.
dg-init
# Gather a list of all tests.
set tests [lsort [glob -nocomplain $srcdir/$subdir/*.m]]
# Main loop.
dg-runtest $tests "-fgnu-runtime" $DEFAULT_CFLAGS
# darwin targets can also run code with the NeXT runtime.
if [istarget "*-*-darwin*" ] {
dg-runtest $tests "-fnext-runtime" $DEFAULT_CFLAGS
}
# All done.
dg-finish
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
@interface obj : Object {
@public
int var;
}
- (int) mth;
@end
@implementation obj
- (int) mth { return var; }
@end
__attribute ((deprecated))
@interface obj (dep_categ)
- (int) depmth;/* { dg-warning "category attributes are not available in this version" } */
@end
@implementation obj (dep_categ)
- (int) depmth { return var + 1; }
@end
int foo (void)
{
obj *p = [obj new];
int q = [p depmth];
return [p mth];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
@interface obj : Object {
@public
int var;
}
- (int) mth;
@end
@implementation obj
- (int) mth { return var; }
@end
__attribute__ ((deprecated("no dep_categ")))
@interface obj (dep_categ)
- (int) depmth;/* { dg-warning "category attributes are not available in this version" } */
@end
__attribute__ ((deprecated))
@implementation obj (dep_categ) /* { dg-warning "prefix attributes are ignored for implementations" } */
- (int) depmth { return var + 1; }
@end
int foo (void)
{
obj *p = [obj new];
int q = [p depmth];
return [p mth];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
/* Normal deprecated func. */
__attribute ((deprecated)) void f1();
__attribute__ ((deprecated("use some new func"))) void f2();
__attribute__ ((deprecated))
@interface DEPRECATED : Object
{ @public int ivar; } /* { dg-warning "class attributes are not available in this version" } */
- (int) instancemethod;
@end
@implementation DEPRECATED
-(int) instancemethod { return ivar; }
@end
@interface DEPRECATED (Category)
@end /* dg - warning "deprecated" */
@interface NS : DEPRECATED
@end /* dg - warning "deprecated" */
DEPRECATED * deprecated_obj; /* dg - warning "deprecated" */
int foo (DEPRECATED *unavailable_obj) /* dg - warning "deprecated" */
{
DEPRECATED *p = [DEPRECATED new]; /* dg - warning "deprecated" */
f1(); /* { dg-warning "'f1' is deprecated" } */
f2(); /* { dg-warning "'f2' is deprecated .declared at \[^\\)\]*.: use some new func" } */
int q = p->ivar;
return [p instancemethod];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
__attribute ((deprecated))
@interface depobj : Object { /* { dg-warning "class attributes are not available in this version" } */
@public
int ivar;
}
- (int) mth;
@end
__attribute ((deprecated))
@implementation depobj /* { dg-warning "prefix attributes are ignored for implementations" } */
-(int) mth { return ivar; }
@end
int foo (void)
{
depobj *p = [depobj new]; /* dg - warning "deprecated" */
int q = p->ivar;
return [p mth];
}
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
__attribute ((deprecated))
@protocol dep_proto
- (int) depprotomth; /* { dg-warning "protocol attributes are not available in this version" } */
@end
@interface obj : Object <dep_proto>
{
@public
int var;
}
- (int) mth;
@end
@implementation obj
- (int) mth { return var; }
- (int) depprotomth { return var + 1; }
@end
int foo (void)
{
obj *p = [obj new];
int q = [p depprotomth];
return [p mth];
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment