diff options
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]; +} |