summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriains <iains@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-28 20:08:38 +0000
committeriains <iains@138bc75d-0d04-0410-961f-82ee72b054a4>2010-09-28 20:08:38 +0000
commita336eb4b5042c9ebc2d044d29202649fd9fa2759 (patch)
treee9f050f6c9de15c20adf243711859bc55a85c841
parente3d1ab2bdf7b9008475deb5432108db2f0c672be (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-family/ChangeLog9
-rw-r--r--gcc/c-family/c-common.h6
-rw-r--r--gcc/c-family/stub-objc.c9
-rw-r--r--gcc/c-parser.c95
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/parser.c67
-rw-r--r--gcc/objc/ChangeLog6
-rw-r--r--gcc/objc/objc-act.c20
-rw-r--r--gcc/testsuite/ChangeLog18
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/attributes.exp43
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/categ-attribute-1.mm31
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/categ-attribute-2.mm32
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm38
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm25
-rw-r--r--gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm29
-rw-r--r--gcc/testsuite/objc.dg/attributes/attributes.exp44
-rw-r--r--gcc/testsuite/objc.dg/attributes/categ-attribute-1.m31
-rw-r--r--gcc/testsuite/objc.dg/attributes/categ-attribute-2.m32
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-1.m36
-rw-r--r--gcc/testsuite/objc.dg/attributes/class-attribute-2.m25
-rw-r--r--gcc/testsuite/objc.dg/attributes/proto-attribute-1.m29
22 files changed, 610 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 440c257943d..780d46a3804 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+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>
PR fortran/40569
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index e16c8718b88..b3687d8c71c 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,12 @@
+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>
* c-common.c (c_common_attribute_table): Add no_split_stack.
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 296f69058e9..99efe84906d 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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_ivars (tree);
extern tree objc_get_interface_ivars (tree);
-extern void objc_start_class_interface (tree, tree, tree);
-extern void objc_start_category_interface (tree, tree, tree);
-extern void objc_start_protocol (tree, tree);
+extern void objc_start_class_interface (tree, tree, tree, tree);
+extern void objc_start_category_interface (tree, tree, tree, tree);
+extern void objc_start_protocol (tree, tree, tree);
extern void objc_continue_interface (void);
extern void objc_finish_interface (void);
extern void objc_start_class_implementation (tree, tree);
diff --git a/gcc/c-family/stub-objc.c b/gcc/c-family/stub-objc.c
index 0384b486fce..83472bef1d1 100644
--- a/gcc/c-family/stub-objc.c
+++ b/gcc/c-family/stub-objc.c
@@ -122,21 +122,24 @@ objc_declare_protocols (tree ARG_UNUSED (list))
void
objc_start_protocol (tree ARG_UNUSED (proto),
- tree ARG_UNUSED (protorefs))
+ tree ARG_UNUSED (protorefs),
+ tree ARG_UNUSED (attribs))
{
}
void
objc_start_class_interface (tree ARG_UNUSED (name),
tree ARG_UNUSED (super),
- tree ARG_UNUSED (protos))
+ tree ARG_UNUSED (protos),
+ tree ARG_UNUSED (attribs))
{
}
void
objc_start_category_interface (tree ARG_UNUSED (name),
tree ARG_UNUSED (categ),
- tree ARG_UNUSED (protos))
+ tree ARG_UNUSED (protos),
+ tree ARG_UNUSED (attribs))
{
}
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
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 42d8b1729b0..a1806fcff7e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+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>
Require lvalues as specified by the standard.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 938534450fe..8f6ea256ea7 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. */
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index 65d61b1d0e1..d797283e51f 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -1,3 +1,9 @@
+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>
Merge from 'apple/trunk' branch on FSF servers.
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 8e6c6838edf..9401769b7d6 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -651,8 +651,13 @@ lookup_protocol_in_reflist (tree rproto_list, tree lproto)
}
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_ivar_context
= start_class (CLASS_INTERFACE_TYPE, klass, super_class, protos);
@@ -660,8 +665,13 @@ objc_start_class_interface (tree klass, tree super_class, tree protos)
}
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
= start_class (CATEGORY_INTERFACE_TYPE, klass, categ, protos);
objc_ivar_chain
@@ -669,8 +679,12 @@ objc_start_category_interface (tree klass, tree categ, tree protos)
}
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
= start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6e54f4e78ee..22cb056a0d2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,21 @@
+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>
Merge from 'apple/trunk' branch on FSF servers (test method-20.m
diff --git a/gcc/testsuite/obj-c++.dg/attributes/attributes.exp b/gcc/testsuite/obj-c++.dg/attributes/attributes.exp
new file mode 100644
index 00000000000..1d4cae4ef2e
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/attributes.exp
@@ -0,0 +1,43 @@
+# 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
diff --git a/gcc/testsuite/obj-c++.dg/attributes/categ-attribute-1.mm b/gcc/testsuite/obj-c++.dg/attributes/categ-attribute-1.mm
new file mode 100644
index 00000000000..6c48e0ad1bc
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/categ-attribute-1.mm
@@ -0,0 +1,31 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/obj-c++.dg/attributes/categ-attribute-2.mm b/gcc/testsuite/obj-c++.dg/attributes/categ-attribute-2.mm
new file mode 100644
index 00000000000..631607a0147
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/categ-attribute-2.mm
@@ -0,0 +1,32 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm
new file mode 100644
index 00000000000..5cd5ea05712
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-1.mm
@@ -0,0 +1,38 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm
new file mode 100644
index 00000000000..ae94e2f7ad0
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/class-attribute-2.mm
@@ -0,0 +1,25 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm
new file mode 100644
index 00000000000..c21caad3be6
--- /dev/null
+++ b/gcc/testsuite/obj-c++.dg/attributes/proto-attribute-1.mm
@@ -0,0 +1,29 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/attributes.exp b/gcc/testsuite/objc.dg/attributes/attributes.exp
new file mode 100644
index 00000000000..cb11216c5be
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/attributes.exp
@@ -0,0 +1,44 @@
+# 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
diff --git a/gcc/testsuite/objc.dg/attributes/categ-attribute-1.m b/gcc/testsuite/objc.dg/attributes/categ-attribute-1.m
new file mode 100644
index 00000000000..e9fe9c986cd
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/categ-attribute-1.m
@@ -0,0 +1,31 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/categ-attribute-2.m b/gcc/testsuite/objc.dg/attributes/categ-attribute-2.m
new file mode 100644
index 00000000000..4a98de13099
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/categ-attribute-2.m
@@ -0,0 +1,32 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-1.m b/gcc/testsuite/objc.dg/attributes/class-attribute-1.m
new file mode 100644
index 00000000000..802c211ff36
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-1.m
@@ -0,0 +1,36 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/class-attribute-2.m b/gcc/testsuite/objc.dg/attributes/class-attribute-2.m
new file mode 100644
index 00000000000..3ab93ccdfc2
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/class-attribute-2.m
@@ -0,0 +1,25 @@
+/* { 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];
+}
diff --git a/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m b/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m
new file mode 100644
index 00000000000..c9dc8786f76
--- /dev/null
+++ b/gcc/testsuite/objc.dg/attributes/proto-attribute-1.m
@@ -0,0 +1,29 @@
+/* { 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];
+}