add parsing for ObjC* method & method parm attributes

gcc/cp:
	
	Partially merged from apple/trunk branch on FSF servers:
	2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
	Radar 3803157 (method attributes)

	* parser.c (cp_parser_objc_method_keyword_params): Handle attributes.
	(cp_parser_objc_method_tail_params_opt): Likewise.
	(cp_parser_objc_method_signature): Likewise.
	(cp_parser_objc_method_maybe_bad_prefix_attributes): New.
	(cp_parser_objc_method_prototype_list): Handle attributes.
	(cp_parser_objc_method_definition_list): Likewise.

gcc/objc:
	
	* objc-act.c (objc_add_method_declaration): Handle attributes.
	(objc_start_method_definition): Likewise.
	(objc_generate_cxx_ctor_or_dtor): Pass NULL attributes to ctor/dtor.
	(objc_build_keyword_decl): Handle attributes.

gcc:

	* c-parser.c (c_parser_declaration_or_fndef): Diagnose incorrect prefix
	attributes on methods.
	 (c_parser_objc_method_definition): Handle attributes.
	(c_parser_objc_methodproto): Likewise.
	(c_parser_objc_maybe_method_attributes): New.
	(c_parser_objc_method_decl): Handle attributes, add a similar diagnostic
	to ObjC++ for a missing definition.

gcc/c-family:
	
	* c-common.h: Update declarations to include attributes.
	* stub-objc.c: Likewise.

testsuite:

	* objc.dg/attributes/method-attribute-1.m: New.
	* objc.dg/attributes/method-attribute-2.m: New.

	* obj-c++.dg/attributes/method-attribute-1.m: New.
	* obj-c++.dg/attributes/method-attribute-2.m: New.

From-SVN: r164702
This commit is contained in:
Iain Sandoe 2010-09-28 21:02:38 +00:00
parent f0a0390e69
commit f7e71da52f
14 changed files with 455 additions and 41 deletions

View File

@ -1,3 +1,13 @@
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* c-parser.c (c_parser_declaration_or_fndef): Diagnose incorrect prefix
attributes on methods.
(c_parser_objc_method_definition): Handle attributes.
(c_parser_objc_methodproto): Likewise.
(c_parser_objc_maybe_method_attributes): New.
(c_parser_objc_method_decl): Handle attributes, add a diagnostic for a
missing definition, similar to that in ObjC++.
2010-09-28 Richard Henderson <rth@redhat.com>
* defaults.h (DWARF2_UNWIND_INFO): Don't depend on TARGET_UNWIND_INFO.
@ -62,7 +72,7 @@
(TARGET_UNWIND_INFO): Remove.
* config/pa/pa.c (pa_option_override): Use targetm.except_unwind_info.
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* c-parser.c (c_parser_objc_class_definition): Adjust prototype.

View File

@ -1,3 +1,13 @@
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* c-common.h (objc_add_method_declaration): Adjust prototype to
include attributes.
(objc_start_method_definition): Likewise.
(objc_build_keyword_decl): Likewise.
* stub-objc.c:(objc_add_method_declaration): Handle attributes.
(objc_start_method_definition): Likewise.
(objc_build_keyword_decl): Likewise.
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* c-common.h (objc_start_class_interface): Adjust prototype.

View File

@ -977,11 +977,11 @@ extern void objc_finish_implementation (void);
extern void objc_set_visibility (int);
extern void objc_set_method_type (enum tree_code);
extern tree objc_build_method_signature (tree, tree, tree, bool);
extern void objc_add_method_declaration (tree);
extern bool objc_start_method_definition (tree);
extern void objc_add_method_declaration (tree, tree);
extern bool objc_start_method_definition (tree, tree);
extern void objc_finish_method_definition (tree);
extern void objc_add_instance_variable (tree);
extern tree objc_build_keyword_decl (tree, tree, tree);
extern tree objc_build_keyword_decl (tree, tree, tree, tree);
extern tree objc_build_throw_stmt (location_t, tree);
extern void objc_begin_try_stmt (location_t, tree);
extern tree objc_finish_try_stmt (void);

View File

@ -196,12 +196,14 @@ objc_finish_implementation (void)
}
void
objc_add_method_declaration (tree ARG_UNUSED (signature))
objc_add_method_declaration (tree ARG_UNUSED (signature),
tree ARG_UNUSED (attributes))
{
}
bool
objc_start_method_definition (tree ARG_UNUSED (signature))
objc_start_method_definition (tree ARG_UNUSED (signature),
tree ARG_UNUSED (attributes))
{
return true;
}
@ -214,7 +216,8 @@ objc_finish_method_definition (tree ARG_UNUSED (fndecl))
tree
objc_build_keyword_decl (tree ARG_UNUSED (selector),
tree ARG_UNUSED (type),
tree ARG_UNUSED (identifier))
tree ARG_UNUSED (identifier),
tree ARG_UNUSED (attributes))
{
return 0;
}

View File

@ -986,7 +986,7 @@ 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 *);
static void c_parser_objc_methodproto (c_parser *);
static tree c_parser_objc_method_decl (c_parser *);
static tree c_parser_objc_method_decl (c_parser *, tree *);
static tree c_parser_objc_type_name (c_parser *);
static tree c_parser_objc_protocol_refs (c_parser *);
static void c_parser_objc_try_catch_statement (c_parser *);
@ -1244,6 +1244,29 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
}
else if (c_dialect_objc ())
{
/* Prefix attributes are an error on method decls. */
switch (c_parser_peek_token (parser)->type)
{
case CPP_PLUS:
case CPP_MINUS:
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 methods");
specs->attrs = NULL_TREE;
}
if (fndef_ok)
c_parser_objc_method_definition (parser);
else
c_parser_objc_methodproto (parser);
return;
break;
default:
break;
}
/* This is where we parse 'attributes @interface ...',
'attributes @implementation ...', 'attributes @protocol ...'
(where attributes could be, for example, __attribute__
@ -6635,23 +6658,28 @@ static void
c_parser_objc_method_definition (c_parser *parser)
{
enum tree_code type = c_parser_objc_method_type (parser);
tree decl;
tree decl, attributes = NULL_TREE;
objc_set_method_type (type);
parser->objc_pq_context = true;
decl = c_parser_objc_method_decl (parser);
decl = c_parser_objc_method_decl (parser, &attributes);
if (decl == error_mark_node)
return; /* Bail here. */
if (c_parser_next_token_is (parser, CPP_SEMICOLON))
{
c_parser_consume_token (parser);
pedwarn (c_parser_peek_token (parser)->location, OPT_pedantic,
"extra semicolon in method definition specified");
}
if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
{
c_parser_error (parser, "expected %<{%>");
return;
}
parser->objc_pq_context = false;
if (objc_start_method_definition (decl))
if (objc_start_method_definition (decl, attributes))
{
add_stmt (c_parser_compound_statement (parser));
objc_finish_method_definition (current_function_decl);
@ -6722,17 +6750,64 @@ static void
c_parser_objc_methodproto (c_parser *parser)
{
enum tree_code type = c_parser_objc_method_type (parser);
tree decl;
tree decl, attributes = NULL_TREE;
objc_set_method_type (type);
/* Remember protocol qualifiers in prototypes. */
parser->objc_pq_context = true;
decl = c_parser_objc_method_decl (parser);
/* Forget protocol qualifiers here. */
decl = c_parser_objc_method_decl (parser, &attributes);
/* Forget protocol qualifiers now. */
parser->objc_pq_context = false;
objc_add_method_declaration (decl);
/* Do not allow the presence of attributes to hide an erroneous
method implementation in the interface section. */
if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
{
c_parser_error (parser, "expected %<;%>");
return;
}
if (decl != error_mark_node)
objc_add_method_declaration (decl, attributes);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
}
/* If we are at a position that method attributes may be present, check that
there are not any parsed already (a syntax error) and then collect any
specified at the current location. Finally, if new attributes were present,
check that the next token is legal ( ';' for decls and '{' for defs). */
static bool
c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
{
bool bad = false;
if (*attributes)
{
c_parser_error (parser,
"method attributes must be specified at the end only");
*attributes = NULL_TREE;
bad = true;
}
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
*attributes = c_parser_attributes (parser);
/* If there were no attributes here, just report any earlier error. */
if (*attributes == NULL_TREE || bad)
return bad;
/* If the attributes are followed by a ; or {, then just report any earlier
error. */
if (c_parser_next_token_is (parser, CPP_SEMICOLON)
|| c_parser_next_token_is (parser, CPP_OPEN_BRACE))
return bad;
/* We've got attributes, but not at the end. */
c_parser_error (parser,
"expected %<;%> or %<{%> after method attribute definition");
return true;
}
/* Parse an objc-method-decl.
objc-method-decl:
@ -6740,6 +6815,7 @@ c_parser_objc_methodproto (c_parser *parser)
objc-selector
( objc-type-name ) objc-keyword-selector objc-optparmlist
objc-keyword-selector objc-optparmlist
attributes
objc-keyword-selector:
objc-keyword-decl
@ -6764,13 +6840,15 @@ c_parser_objc_methodproto (c_parser *parser)
*/
static tree
c_parser_objc_method_decl (c_parser *parser)
c_parser_objc_method_decl (c_parser *parser, tree *attributes)
{
tree type = NULL_TREE;
tree sel;
tree parms = NULL_TREE;
bool ellipsis = false;
bool attr_err = false;
*attributes = NULL_TREE;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
{
c_parser_consume_token (parser);
@ -6788,6 +6866,7 @@ c_parser_objc_method_decl (c_parser *parser)
while (true)
{
tree atype = NULL_TREE, id, keyworddecl;
tree param_attr = NULL_TREE;
if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
break;
if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
@ -6797,6 +6876,9 @@ c_parser_objc_method_decl (c_parser *parser)
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<)%>");
}
/* New ObjC allows attributes on method parameters. */
if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
param_attr = c_parser_attributes (parser);
if (c_parser_next_token_is_not (parser, CPP_NAME))
{
c_parser_error (parser, "expected identifier");
@ -6804,12 +6886,15 @@ c_parser_objc_method_decl (c_parser *parser)
}
id = c_parser_peek_token (parser)->value;
c_parser_consume_token (parser);
keyworddecl = objc_build_keyword_decl (tsel, atype, id);
keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
list = chainon (list, keyworddecl);
tsel = c_parser_objc_selector (parser);
if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
break;
}
attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
/* Parse the optional parameter list. Optional Objective-C
method parameters follow the C syntax, and may include '...'
to denote a variable number of arguments. */
@ -6822,6 +6907,8 @@ c_parser_objc_method_decl (c_parser *parser)
{
ellipsis = true;
c_parser_consume_token (parser);
attr_err |= c_parser_objc_maybe_method_attributes
(parser, attributes) ;
break;
}
parm = c_parser_parameter_declaration (parser, NULL_TREE);
@ -6832,6 +6919,18 @@ c_parser_objc_method_decl (c_parser *parser)
}
sel = list;
}
else
attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
if (sel == NULL)
{
c_parser_error (parser, "objective-c method declaration is expected");
return error_mark_node;
}
if (attr_err)
return error_mark_node;
return objc_build_method_signature (type, sel, parms, ellipsis);
}

View File

@ -1,3 +1,16 @@
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
Partially merged from apple/trunk branch on FSF servers:
2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
Radar 3803157 (method attributes)
* parser.c (cp_parser_objc_method_keyword_params): Handle attributes.
(cp_parser_objc_method_tail_params_opt): Likewise.
(cp_parser_objc_method_signature): Likewise.
(cp_parser_objc_method_maybe_bad_prefix_attributes): New.
(cp_parser_objc_method_prototype_list): Handle attributes.
(cp_parser_objc_method_definition_list): Likewise.
2010-09-28 Richard Henderson <rth@redhat.com>
* cp-lang.c: Include "target.h".

View File

@ -21449,7 +21449,7 @@ cp_parser_objc_selector (cp_parser* parser)
/* Parse an Objective-C params list. */
static tree
cp_parser_objc_method_keyword_params (cp_parser* parser)
cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
{
tree params = NULL_TREE;
bool maybe_unary_selector_p = true;
@ -21458,6 +21458,10 @@ cp_parser_objc_method_keyword_params (cp_parser* parser)
while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
{
tree selector = NULL_TREE, type_name, identifier;
tree parm_attr = NULL_TREE;
if (token->keyword == RID_ATTRIBUTE)
break;
if (token->type != CPP_COLON)
selector = cp_parser_objc_selector (parser);
@ -21465,29 +21469,55 @@ cp_parser_objc_method_keyword_params (cp_parser* parser)
/* Detect if we have a unary selector. */
if (maybe_unary_selector_p
&& cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
return selector;
{
params = selector; /* Might be followed by attributes. */
break;
}
maybe_unary_selector_p = false;
cp_parser_require (parser, CPP_COLON, RT_COLON);
type_name = cp_parser_objc_typename (parser);
/* New ObjC allows attributes on parameters too. */
if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
parm_attr = cp_parser_attributes_opt (parser);
identifier = cp_parser_identifier (parser);
params
= chainon (params,
objc_build_keyword_decl (selector,
type_name,
identifier));
identifier,
parm_attr));
token = cp_lexer_peek_token (parser->lexer);
}
if (params == NULL_TREE)
{
cp_parser_error (parser, "objective-c++ method declaration is expected");
return error_mark_node;
}
/* We allow tail attributes for the method. */
if (token->keyword == RID_ATTRIBUTE)
{
*attributes = cp_parser_attributes_opt (parser);
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
|| cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
return params;
cp_parser_error (parser,
"method attributes must be specified at the end");
return error_mark_node;
}
return params;
}
/* Parse the non-keyword Objective-C params. */
static tree
cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp)
cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp,
tree* attributes)
{
tree params = make_node (TREE_LIST);
cp_token *token = cp_lexer_peek_token (parser->lexer);
@ -21508,6 +21538,7 @@ cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp)
break;
}
/* TODO: parse attributes for tail parameters. */
parmdecl = cp_parser_parameter_declaration (parser, false, NULL);
parm = grokdeclarator (parmdecl->declarator,
&parmdecl->decl_specifiers,
@ -21518,6 +21549,26 @@ cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp)
token = cp_lexer_peek_token (parser->lexer);
}
/* We allow tail attributes for the method. */
if (token->keyword == RID_ATTRIBUTE)
{
if (*attributes == NULL_TREE)
{
*attributes = cp_parser_attributes_opt (parser);
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
|| cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
return params;
}
else
/* We have an error, but parse the attributes, so that we can
carry on. */
*attributes = cp_parser_attributes_opt (parser);
cp_parser_error (parser,
"method attributes must be specified at the end");
return error_mark_node;
}
return params;
}
@ -21547,34 +21598,70 @@ cp_parser_objc_interstitial_code (cp_parser* parser)
/* Parse a method signature. */
static tree
cp_parser_objc_method_signature (cp_parser* parser)
cp_parser_objc_method_signature (cp_parser* parser, tree* attributes)
{
tree rettype, kwdparms, optparms;
bool ellipsis = false;
cp_parser_objc_method_type (parser);
rettype = cp_parser_objc_typename (parser);
kwdparms = cp_parser_objc_method_keyword_params (parser);
optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis);
*attributes = NULL_TREE;
kwdparms = cp_parser_objc_method_keyword_params (parser, attributes);
if (kwdparms == error_mark_node)
return error_mark_node;
optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis, attributes);
if (optparms == error_mark_node)
return error_mark_node;
return objc_build_method_signature (rettype, kwdparms, optparms, ellipsis);
}
/* Pars an Objective-C method prototype list. */
static bool
cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
{
tree tattr;
cp_lexer_save_tokens (parser->lexer);
tattr = cp_parser_attributes_opt (parser);
gcc_assert (tattr) ;
/* If the attributes are followed by a method introducer, this is not allowed.
Dump the attributes and flag the situation. */
if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS)
|| cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
return true;
/* Otherwise, the attributes introduce some interstitial code, possibly so
rewind to allow that check. */
cp_lexer_rollback_tokens (parser->lexer);
return false;
}
/* Parse an Objective-C method prototype list. */
static void
cp_parser_objc_method_prototype_list (cp_parser* parser)
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
while (token->keyword != RID_AT_END)
while (token->keyword != RID_AT_END && token->type != CPP_EOF)
{
if (token->type == CPP_PLUS || token->type == CPP_MINUS)
{
objc_add_method_declaration
(cp_parser_objc_method_signature (parser));
tree attributes, sig;
sig = cp_parser_objc_method_signature (parser, &attributes);
if (sig == error_mark_node)
{
cp_parser_skip_to_end_of_block_or_statement (parser);
continue;
}
objc_add_method_declaration (sig, attributes);
cp_parser_consume_semicolon_at_end_of_statement (parser);
}
else if (token->keyword == RID_ATTRIBUTE
&& cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
warning_at (cp_lexer_peek_token (parser->lexer)->location,
OPT_Wattributes,
"prefix attributes are ignored for methods");
else
/* Allow for interspersed non-ObjC++ code. */
cp_parser_objc_interstitial_code (parser);
@ -21593,27 +21680,43 @@ cp_parser_objc_method_definition_list (cp_parser* parser)
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
while (token->keyword != RID_AT_END)
while (token->keyword != RID_AT_END && token->type != CPP_EOF)
{
tree meth;
if (token->type == CPP_PLUS || token->type == CPP_MINUS)
{
cp_token *ptk;
tree sig, attribute;
push_deferring_access_checks (dk_deferred);
objc_start_method_definition
(cp_parser_objc_method_signature (parser));
sig = cp_parser_objc_method_signature (parser, &attribute);
if (sig == error_mark_node)
{
cp_parser_skip_to_end_of_block_or_statement (parser);
continue;
}
objc_start_method_definition (sig, attribute);
/* For historical reasons, we accept an optional semicolon. */
if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
cp_lexer_consume_token (parser->lexer);
perform_deferred_access_checks ();
stop_deferring_access_checks ();
meth = cp_parser_function_definition_after_declarator (parser,
ptk = cp_lexer_peek_token (parser->lexer);
if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS
|| ptk->type == CPP_EOF || ptk->keyword == RID_AT_END))
{
perform_deferred_access_checks ();
stop_deferring_access_checks ();
meth = cp_parser_function_definition_after_declarator (parser,
false);
pop_deferring_access_checks ();
objc_finish_method_definition (meth);
pop_deferring_access_checks ();
objc_finish_method_definition (meth);
}
}
else if (token->keyword == RID_ATTRIBUTE
&& cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
warning_at (token->location, OPT_Wattributes,
"prefix attributes are ignored for methods");
else
/* Allow for interspersed non-ObjC++ code. */
cp_parser_objc_interstitial_code (parser);

View File

@ -1,3 +1,11 @@
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* objc-act.c (objc_add_method_declaration): Handle and ignore
attributes.
(objc_start_method_definition): Likewise.
(objc_generate_cxx_ctor_or_dtor): Pass NULL attributes to ctor/dtor.
(objc_build_keyword_decl): Handle and ignore attributes.
2010-09-28 Richard Henderson <rth@redhat.com>
* objc-act.c (objc_eh_personality): Use targetm.except_unwind_info.

View File

@ -769,7 +769,7 @@ objc_build_method_signature (tree rettype, tree selector,
}
void
objc_add_method_declaration (tree decl)
objc_add_method_declaration (tree decl, tree attributes)
{
if (!objc_interface_context)
{
@ -780,6 +780,11 @@ objc_add_method_declaration (tree decl)
fatal_error ("method declaration not in @interface context");
}
if (attributes)
warning_at (input_location, OPT_Wattributes,
"method attributes are not available in this version"
" of the compiler, (ignored)");
objc_add_method (objc_interface_context,
decl,
objc_inherit_code == CLASS_METHOD_DECL);
@ -789,7 +794,7 @@ objc_add_method_declaration (tree decl)
'false' if not (because we are outside an @implementation context).
*/
bool
objc_start_method_definition (tree decl)
objc_start_method_definition (tree decl, tree attributes)
{
if (!objc_implementation_context)
{
@ -797,6 +802,11 @@ objc_start_method_definition (tree decl)
return false;
}
if (attributes)
warning_at (input_location, OPT_Wattributes,
"method attributes are not available in this version"
" of the compiler, (ignored)");
#ifndef OBJCPLUS
/* Indicate no valid break/continue context by setting these variables
to some non-null, non-label value. We'll notice and emit the proper
@ -4644,7 +4654,7 @@ objc_generate_cxx_ctor_or_dtor (bool dtor)
? TAG_CXX_DESTRUCT
: TAG_CXX_CONSTRUCT),
make_node (TREE_LIST),
false));
false), NULL);
body = begin_function_body ();
compound_stmt = begin_compound_stmt (0);
@ -5976,6 +5986,7 @@ adjust_type_for_id_default (tree type)
In: key_name, an "identifier_node" (optional).
arg_type, a "tree_list" (optional).
arg_name, an "identifier_node".
attributes, a optional tree containing param attributes.
Note: It would be really nice to strongly type the preceding
arguments in the function prototype; however, then I
@ -5984,10 +5995,16 @@ adjust_type_for_id_default (tree type)
Out: an instance of "keyword_decl". */
tree
objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
objc_build_keyword_decl (tree key_name, tree arg_type,
tree arg_name, tree attributes)
{
tree keyword_decl;
if (attributes)
warning_at (input_location, OPT_Wattributes,
"method parameter attributes are not available in this "
"version of the compiler, (ignored)");
/* If no type is specified, default to "id". */
arg_type = adjust_type_for_id_default (arg_type);
@ -8128,7 +8145,7 @@ encode_array (tree type, int curtype, int format)
tree an_int_cst = TYPE_SIZE (type);
tree array_of = TREE_TYPE (type);
char buffer[40];
if (an_int_cst == NULL)
{
/* We are trying to encode an incomplete array. An incomplete

View File

@ -1,3 +1,11 @@
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* objc.dg/attributes/method-attribute-1.m: New.
* objc.dg/attributes/method-attribute-2.m: New.
* obj-c++.dg/attributes/method-attribute-1.m: New.
* obj-c++.dg/attributes/method-attribute-2.m: New.
2010-09-28 Iain Sandoe <iains@gcc.gnu.org>
* objc.dg/attributes: New.

View File

@ -0,0 +1,41 @@
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
@interface obj : Object {
@public
int var;
}
- (int) mth;
+ (id) dep_cls_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */
- (int) dep_ins_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */
- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */
- (int) dep_ins_mtharg1: (int) i __attribute__((deprecated)) add: (int) j;/* { dg-error "method attributes must be specified at the end " } */
- (int) nodef __attribute__((deprecated)) { return var-2; } ; /* { dg-error "expected ';' before '\{' token" } */
/* { dg-warning "method attributes are not available in this version" "" { target *-*-* } 15 } */
__attribute__((deprecated))
- (int) bad_pref_mth; /* { dg-warning "prefix attributes are ignored for methods" } */
@end
@implementation obj
- (int) mth { return var; }
+ (id) dep_cls_mth { return self; }
- (int) dep_ins_mth { return var ; }
- (int) dep_ins_mtharg: (int) i { return var + i ; }
- (int) dep_ins_mtharg1: (int) i add: (int) j { return var + i + j ; }
- (int) bad_pref_mth { return var; };
- (int) nodef { return var-2; } ;
@end
int foo (void)
{
obj *p = [obj new];
id n = [obj dep_cls_mth];
[p dep_ins_mth];
[p dep_ins_mtharg:2];
[p dep_ins_mtharg1:3 add:3];
return [p mth];
}

View File

@ -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) depmtharg:(int) iarg __attribute__((deprecated)); /* { dg-warning "method attributes are not available in this version" } */
- (int) unusedarg:(int) __attribute__((unused)) uarg ; /* { dg-warning "method parameter attributes are not available in this version" } */
- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ; /* { dg-warning "method attributes are not available in this version" } */
/* { dg-warning "method parameter attributes are not available in this version" "" { target *-*-* } 12 } */
@end
@implementation obj
- (int) depmtharg:(int) iarg { return var + iarg ; };
- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; } ; /* { dg-warning "method parameter attributes are not available in this version" } */
- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; }; /* { dg-warning "method parameter attributes are not available in this version" } */
@end
int foo (void)
{
obj *p = [obj new];
[p depmtharg:1];
[p unusedarg:2];
[p depunusedarg:3 ];
return [p depmtharg:0];
}

View File

@ -0,0 +1,40 @@
/* { dg-do compile } */
#include <objc/objc.h>
#include "../../objc-obj-c++-shared/Object1.h"
@interface obj : Object {
@public
int var;
}
- (int) mth;
+ (id) dep_cls_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */
- (int) dep_ins_mth __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */
- (int) dep_ins_mtharg: (int) i __attribute__((deprecated)) ;/* { dg-warning "method attributes are not available in this version" } */
- (int) dep_ins_mtharg1: (int) i __attribute__((deprecated)) add: (int) j;/* { dg-error "expected ';' or '\{' after method attribute definition" } */
- (int) nodef __attribute__((deprecated)) { return var-2; } ; /* { dg-error "expected ';' before '\{' token" } */
__attribute__((deprecated))
- (int) bad_pref_mth; /* { dg-warning "prefix attributes are ignored for methods" } */
@end
@implementation obj
- (int) mth { return var; }
+ (id) dep_cls_mth { return self; }
- (int) dep_ins_mth { return var ; }
- (int) dep_ins_mtharg: (int) i { return var + i ; }
- (int) dep_ins_mtharg1: (int) i add: (int) j { return var + i + j ; }
- (int) bad_pref_mth { return var; };
- (int) nodef { return var-2; } ;
@end
int foo (void)
{
obj *p = [obj new];
id n = [obj dep_cls_mth];
[p dep_ins_mth];
[p dep_ins_mtharg:2];
[p dep_ins_mtharg1:3 add:3];
return [p mth];
}

View File

@ -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) depmtharg:(int) iarg __attribute__((deprecated)); /* { dg-warning "method attributes are not available in this version" } */
- (int) unusedarg:(int) __attribute__((unused)) uarg ; /* { dg-warning "method parameter attributes are not available in this version" } */
- (int) depunusedarg:(int) __attribute__((unused)) uarg __attribute__((deprecated)) ; /* { dg-warning "method attributes are not available in this version" } */
/* { dg-warning "method parameter attributes are not available in this version" "" { target *-*-* } 12 } */
@end
@implementation obj
- (int) depmtharg:(int) iarg { return var + iarg ; };
- (int) unusedarg:(int) __attribute__((unused)) uarg { return var; } ; /* { dg-warning "method parameter attributes are not available in this version" } */
- (int) depunusedarg:(int) __attribute__((unused)) uarg { return var; }; /* { dg-warning "method parameter attributes are not available in this version" } */
@end
int foo (void)
{
obj *p = [obj new];
[p depmtharg:1];
[p unusedarg:2];
[p depunusedarg:3 ];
return [p depmtharg:0];
}