X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fc-parse.in;h=413593e5f9709d0f027fa9f4b5045b5669e66cb4;hp=f1597302627da27fa89209a0e851d36dee6e0e6b;hb=e7783f3ed60338810e05489e103908224dfe2158;hpb=7c446c951a941facd5f225bba9916ff669420c34 diff --git a/gcc/c-parse.in b/gcc/c-parse.in index f1597302627..413593e5f97 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -1,6 +1,6 @@ /* YACC parser for C syntax and for Objective C. -*-c-*- - Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GCC. @@ -50,12 +50,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "output.h" #include "toplev.h" #include "ggc.h" +#include "c-common.h" -@@ifobjc -#include "objc-act.h" -@@end_ifobjc - -/* Like YYERROR but do call yyerror. */ #define YYERROR1 { yyerror ("syntax error"); YYERROR; } /* Like the default stack expander, except (1) use realloc when possible, @@ -102,8 +98,11 @@ do { \ %start program -%union {long itype; tree ttype; struct c_expr exprtype; enum tree_code code; - location_t location; } +%union {long itype; tree ttype; void *otype; struct c_expr exprtype; + struct c_arg_info *arginfotype; struct c_declarator *dtrtype; + struct c_type_name *typenametype; struct c_parm *parmtype; + struct c_declspecs *dsptype; struct c_typespec tstype; + enum tree_code code; location_t location; } /* All identifiers that are not reserved words and are not declared typedefs in the current block */ @@ -127,6 +126,10 @@ do { \ yylval contains an IDENTIFIER_NODE which indicates which one. */ %token TYPE_QUAL +/* Objective-C protocol qualifiers. These acquire their magic powers + only in certain contexts. */ +%token OBJC_TYPE_QUAL + /* Character or numeric constants. yylval is the node for the constant. */ %token CONSTANT @@ -145,7 +148,6 @@ do { \ %token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF %token ATTRIBUTE EXTENSION LABEL %token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P -%token PTR_VALUE PTR_BASE PTR_EXTENT %token FUNC_NAME OFFSETOF /* Add precedence rules to solve dangling else s/r conflict */ @@ -175,8 +177,8 @@ do { \ /* The Objective-C keywords. These are included in C and in Objective C, so that the token codes are the same in both. */ %token AT_INTERFACE AT_IMPLEMENTATION AT_END AT_SELECTOR AT_DEFS AT_ENCODE -%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL -%token OBJECTNAME AT_CLASS AT_ALIAS +%token CLASSNAME AT_PUBLIC AT_PRIVATE AT_PROTECTED AT_PROTOCOL +%token AT_CLASS AT_ALIAS %token AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED %token OBJC_STRING @@ -187,26 +189,27 @@ do { \ %type identifier IDENTIFIER TYPENAME CONSTANT STRING FUNC_NAME %type nonnull_exprlist exprlist %type expr expr_no_commas cast_expr unary_expr primary -%type declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea -%type declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea -%type declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea -%type declspecs_nosc_ts_sa_noea declspecs_nosc_ts_sa_ea -%type declspecs_sc_nots_nosa_noea declspecs_sc_nots_nosa_ea -%type declspecs_sc_nots_sa_noea declspecs_sc_nots_sa_ea -%type declspecs_sc_ts_nosa_noea declspecs_sc_ts_nosa_ea -%type declspecs_sc_ts_sa_noea declspecs_sc_ts_sa_ea -%type declspecs_ts declspecs_nots -%type declspecs_ts_nosa declspecs_nots_nosa -%type declspecs_nosc_ts declspecs_nosc_nots declspecs_nosc declspecs -%type maybe_type_quals_attrs typespec_nonattr typespec_attr -%type typespec_reserved_nonattr typespec_reserved_attr -%type typespec_nonreserved_nonattr +%type declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea +%type declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea +%type declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea +%type declspecs_nosc_ts_sa_noea declspecs_nosc_ts_sa_ea +%type declspecs_sc_nots_nosa_noea declspecs_sc_nots_nosa_ea +%type declspecs_sc_nots_sa_noea declspecs_sc_nots_sa_ea +%type declspecs_sc_ts_nosa_noea declspecs_sc_ts_nosa_ea +%type declspecs_sc_ts_sa_noea declspecs_sc_ts_sa_ea +%type declspecs_ts declspecs_nots +%type declspecs_ts_nosa declspecs_nots_nosa +%type declspecs_nosc_ts declspecs_nosc_nots declspecs_nosc declspecs +%type maybe_type_quals_attrs +%type typespec_nonattr typespec_attr +%type typespec_reserved_nonattr typespec_reserved_attr +%type typespec_nonreserved_nonattr %type offsetof_member_designator %type scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile %type initdecls notype_initdecls initdcl notype_initdcl %type init -%type simple_asm_expr maybeasm asm_stmt asm_argument +%type simple_asm_expr maybeasm asm_stmt asm_argument asm_string %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type maybe_attribute attributes attribute attribute_list attrib %type any_word @@ -216,50 +219,55 @@ do { \ %type c99_block_start c99_block_lineno_labeled_stmt %type if_statement_1 if_statement_2 -%type declarator -%type notype_declarator after_type_declarator -%type parm_declarator -%type parm_declarator_starttypename parm_declarator_nostarttypename -%type array_declarator +%type declarator +%type notype_declarator after_type_declarator +%type parm_declarator +%type parm_declarator_starttypename parm_declarator_nostarttypename +%type array_declarator -%type structsp_attr structsp_nonattr +%type structsp_attr structsp_nonattr %type component_decl_list component_decl_list2 %type component_decl components components_notype component_declarator %type component_notype_declarator %type enumlist enumerator %type struct_head union_head enum_head -%type typename absdcl absdcl1 absdcl1_ea absdcl1_noea -%type direct_absdcl1 absdcl_maybe_attribute +%type typename +%type absdcl absdcl1 absdcl1_ea absdcl1_noea direct_absdcl1 +%type absdcl_maybe_attribute %type condition xexpr for_cond_expr for_incr_expr -%type parms parm firstparm identifiers +%type parm firstparm +%type identifiers -%type parmlist parmlist_1 parmlist_2 -%type parmlist_or_identifiers parmlist_or_identifiers_1 +%type parms parmlist parmlist_1 parmlist_2 +%type parmlist_or_identifiers parmlist_or_identifiers_1 %type identifiers_or_typenames %type setspecs setspecs_fp extension %type save_location + +%type save_obstack_position @@ifobjc /* the Objective-C nonterminals */ -%type ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator %type methoddecl unaryselector keywordselector selector +%type methodtype %type keyworddecl receiver objcmessageexpr messageargs %type keywordexpr keywordarglist keywordarg -%type myparms myparm optparmlist reservedwords objcselectorexpr +%type optparmlist optparms reservedwords objcselectorexpr %type selectorarg keywordnamelist keywordname objcencodeexpr %type non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr -%type CLASSNAME OBJECTNAME OBJC_STRING +%type CLASSNAME OBJC_STRING OBJC_TYPE_QUAL -%type superclass +%type superclass objc_quals objc_qual objc_typename +%type objc_try_catch_stmt optellipsis @@end_ifobjc %{ -/* List of types and structure classes of the current declaration. */ -static GTY(()) tree current_declspecs; +/* Declaration specifiers of the current declaration. */ +static struct c_declspecs *current_declspecs; static GTY(()) tree prefix_attributes; /* List of all the attributes applying to the identifier currently being @@ -267,26 +275,44 @@ static GTY(()) tree prefix_attributes; just after a comma. */ static GTY(()) tree all_prefix_attributes; +/* Structure to save declaration specifiers. */ +struct c_declspec_stack { + /* Saved value of current_declspecs. */ + struct c_declspecs *current_declspecs; + /* Saved value of prefix_attributes. */ + tree prefix_attributes; + /* Saved value of all_prefix_attributes. */ + tree all_prefix_attributes; + /* Next level of stack. */ + struct c_declspec_stack *next; +}; + /* Stack of saved values of current_declspecs, prefix_attributes and all_prefix_attributes. */ -static GTY(()) tree declspec_stack; +static struct c_declspec_stack *declspec_stack; + +/* INDIRECT_REF with a TREE_TYPE of the type being queried for offsetof. */ +static tree offsetof_base; /* PUSH_DECLSPEC_STACK is called from setspecs; POP_DECLSPEC_STACK should be called from the productions making use of setspecs. */ -#define PUSH_DECLSPEC_STACK \ - do { \ - declspec_stack = tree_cons (build_tree_list (prefix_attributes, \ - all_prefix_attributes), \ - current_declspecs, \ - declspec_stack); \ +#define PUSH_DECLSPEC_STACK \ + do { \ + struct c_declspec_stack *t = XOBNEW (&parser_obstack, \ + struct c_declspec_stack); \ + t->current_declspecs = current_declspecs; \ + t->prefix_attributes = prefix_attributes; \ + t->all_prefix_attributes = all_prefix_attributes; \ + t->next = declspec_stack; \ + declspec_stack = t; \ } while (0) #define POP_DECLSPEC_STACK \ do { \ - current_declspecs = TREE_VALUE (declspec_stack); \ - prefix_attributes = TREE_PURPOSE (TREE_PURPOSE (declspec_stack)); \ - all_prefix_attributes = TREE_VALUE (TREE_PURPOSE (declspec_stack)); \ - declspec_stack = TREE_CHAIN (declspec_stack); \ + current_declspecs = declspec_stack->current_declspecs; \ + prefix_attributes = declspec_stack->prefix_attributes; \ + all_prefix_attributes = declspec_stack->all_prefix_attributes; \ + declspec_stack = declspec_stack->next; \ } while (0) /* For __extension__, save/restore the warning flags which are @@ -308,8 +334,7 @@ static GTY(()) tree declspec_stack; @@ifobjc /* Objective-C specific parser/lexer information */ -static enum tree_code objc_inherit_code; -static int objc_pq_context = 0, objc_public_flag = 0; +static int objc_pq_context = 0; /* The following flag is needed to contextualize ObjC lexical analysis. In some cases (e.g., 'int NSObject;'), it is undesirable to bind @@ -334,7 +359,7 @@ static inline int _yylex (void); static int yylex (void); static void init_reswords (void); - /* Initialisation routine for this file. */ + /* Initialization routine for this file. */ void c_parse_init (void) { @@ -353,11 +378,14 @@ program: /* empty */ /* the reason for the strange actions in this rule is so that notype_initdecls when reached via datadef - can find a valid list of type and sc specs in $0. */ + can find valid declaration specifiers in $0. */ extdefs: - {$$ = NULL_TREE; } extdef - | extdefs {$$ = NULL_TREE; ggc_collect(); } extdef + save_obstack_position { $$ = NULL; } extdef + { obstack_free (&parser_obstack, $1); } + | extdefs save_obstack_position + { $$ = NULL; ggc_collect (); } extdef + { obstack_free (&parser_obstack, $2); } ; extdef: @@ -371,31 +399,33 @@ extdef: @@end_ifobjc ; +/* Record the current position of parser_obstack before a + declaration to restore it afterwards. */ +save_obstack_position: + { $$ = obstack_alloc (&parser_obstack, 0); } + ; + datadef: setspecs notype_initdecls ';' - { if (pedantic) - error ("ISO C forbids data definition with no type or storage class"); - else - warning ("data definition has no type or storage class"); - + { pedwarn ("data definition has no type or storage class"); POP_DECLSPEC_STACK; } | declspecs_nots setspecs notype_initdecls ';' { POP_DECLSPEC_STACK; } | declspecs_ts setspecs initdecls ';' { POP_DECLSPEC_STACK; } | declspecs ';' - { shadow_tag ($1); } + { shadow_tag (finish_declspecs ($1)); } | error ';' | error '}' | ';' { if (pedantic) - pedwarn ("ISO C does not allow extra `;' outside of a function"); } + pedwarn ("ISO C does not allow extra %<;%> outside of a function"); } ; fndef: declspecs_ts setspecs declarator - { if (! start_function (current_declspecs, $3, - all_prefix_attributes)) + { if (!start_function (current_declspecs, $3, + all_prefix_attributes)) YYERROR1; } old_style_parm_decls save_location @@ -407,8 +437,8 @@ fndef: | declspecs_ts setspecs declarator error { POP_DECLSPEC_STACK; } | declspecs_nots setspecs notype_declarator - { if (! start_function (current_declspecs, $3, - all_prefix_attributes)) + { if (!start_function (current_declspecs, $3, + all_prefix_attributes)) YYERROR1; } old_style_parm_decls save_location @@ -420,8 +450,8 @@ fndef: | declspecs_nots setspecs notype_declarator error { POP_DECLSPEC_STACK; } | setspecs notype_declarator - { if (! start_function (NULL_TREE, $2, - all_prefix_attributes)) + { if (!start_function (current_declspecs, $2, + all_prefix_attributes)) YYERROR1; } old_style_parm_decls save_location @@ -438,7 +468,6 @@ identifier: IDENTIFIER | TYPENAME @@ifobjc - | OBJECTNAME | CLASSNAME @@end_ifobjc ; @@ -502,21 +531,23 @@ unary_expr: $$.original_code = ERROR_MARK; } | sizeof unary_expr %prec UNARY { skip_evaluation--; + in_sizeof--; if (TREE_CODE ($2.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND ($2.value, 1))) - error ("`sizeof' applied to a bit-field"); - $$.value = c_sizeof (TREE_TYPE ($2.value)); - $$.original_code = ERROR_MARK; } + error ("% applied to a bit-field"); + $$ = c_expr_sizeof_expr ($2); } | sizeof '(' typename ')' %prec HYPERUNARY { skip_evaluation--; - $$.value = c_sizeof (groktypename ($3)); - $$.original_code = ERROR_MARK; } + in_sizeof--; + $$ = c_expr_sizeof_type ($3); } | alignof unary_expr %prec UNARY { skip_evaluation--; + in_alignof--; $$.value = c_alignof_expr ($2.value); $$.original_code = ERROR_MARK; } | alignof '(' typename ')' %prec HYPERUNARY { skip_evaluation--; + in_alignof--; $$.value = c_alignof (groktypename ($3)); $$.original_code = ERROR_MARK; } | REALPART cast_expr %prec UNARY @@ -528,15 +559,15 @@ unary_expr: ; sizeof: - SIZEOF { skip_evaluation++; } + SIZEOF { skip_evaluation++; in_sizeof++; } ; alignof: - ALIGNOF { skip_evaluation++; } + ALIGNOF { skip_evaluation++; in_alignof++; } ; typeof: - TYPEOF { skip_evaluation++; } + TYPEOF { skip_evaluation++; in_typeof++; } ; cast_expr: @@ -638,16 +669,21 @@ primary: $$.original_code = ERROR_MARK; } | '(' typename ')' '{' { start_init (NULL_TREE, NULL, 0); - $2 = groktypename ($2); - really_start_incremental_init ($2); } + $$ = groktypename ($2); + if (C_TYPE_VARIABLE_SIZE ($$)) + { + error ("compound literal has variable size"); + $$ = error_mark_node; + } + really_start_incremental_init ($$); } initlist_maybe_comma '}' %prec UNARY { struct c_expr init = pop_init_level (0); tree constructor = init.value; - tree type = $2; + tree type = $5; finish_init (); maybe_warn_string_init (type, init); - if (pedantic && ! flag_isoc99) + if (pedantic && !flag_isoc99) pedwarn ("ISO C90 forbids compound literals"); $$.value = build_compound_literal (type, constructor); $$.original_code = ERROR_MARK; @@ -677,8 +713,15 @@ primary: { $$.value = build_va_arg ($3.value, groktypename ($5)); $$.original_code = ERROR_MARK; } - | OFFSETOF '(' typename ',' offsetof_member_designator ')' - { $$.value = build_offsetof (groktypename ($3), $5); + | OFFSETOF '(' typename ',' + { tree type = groktypename ($3); + if (type == error_mark_node) + offsetof_base = error_mark_node; + else + offsetof_base = build1 (INDIRECT_REF, type, NULL); + } + offsetof_member_designator ')' + { $$.value = fold_offsetof ($6); $$.original_code = ERROR_MARK; } | OFFSETOF '(' error ')' { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } @@ -690,7 +733,7 @@ primary: c = fold ($3.value); STRIP_NOPS (c); if (TREE_CODE (c) != INTEGER_CST) - error ("first argument to __builtin_choose_expr not" + error ("first argument to %<__builtin_choose_expr%> not" " a constant"); $$ = integer_zerop (c) ? $7 : $5; } @@ -704,8 +747,8 @@ primary: e2 = TYPE_MAIN_VARIANT (groktypename ($5)); $$.value = comptypes (e1, e2) - ? build_int_cst (NULL_TREE, 1, 0) - : build_int_cst (NULL_TREE, 0, 0); + ? build_int_cst (NULL_TREE, 1) + : build_int_cst (NULL_TREE, 0); $$.original_code = ERROR_MARK; } | TYPES_COMPATIBLE_P '(' error ')' @@ -730,36 +773,34 @@ primary: $$.original_code = ERROR_MARK; } @@ifobjc | objcmessageexpr - { $$.value = build_message_expr ($1); + { $$.value = objc_build_message_expr ($1); $$.original_code = ERROR_MARK; } | objcselectorexpr - { $$.value = build_selector_expr ($1); + { $$.value = objc_build_selector_expr ($1); $$.original_code = ERROR_MARK; } | objcprotocolexpr - { $$.value = build_protocol_expr ($1); + { $$.value = objc_build_protocol_expr ($1); $$.original_code = ERROR_MARK; } | objcencodeexpr - { $$.value = build_encode_expr ($1); + { $$.value = objc_build_encode_expr ($1); $$.original_code = ERROR_MARK; } | OBJC_STRING - { $$.value = build_objc_string_object ($1); + { $$.value = objc_build_string_object ($1); $$.original_code = ERROR_MARK; } @@end_ifobjc ; /* This is the second argument to __builtin_offsetof. We must have one identifier, and beyond that we want to accept sub structure and sub - array references. We return tree list where each element has - PURPOSE set for component refs or VALUE set for array refs. We'll - turn this into something real inside build_offsetof. */ + array references. */ offsetof_member_designator: identifier - { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); } + { $$ = build_component_ref (offsetof_base, $1); } | offsetof_member_designator '.' identifier - { $$ = tree_cons ($3, NULL_TREE, $1); } + { $$ = build_component_ref ($1, $3); } | offsetof_member_designator '[' expr ']' - { $$ = tree_cons (NULL_TREE, $3.value, $1); } + { $$ = build_array_ref ($1, $3.value); } ; old_style_parm_decls: @@ -792,7 +833,7 @@ datadecl: | declspecs_nots_nosa setspecs notype_initdecls ';' { POP_DECLSPEC_STACK; } | declspecs_ts_nosa ';' - { shadow_tag_warned ($1, 1); + { shadow_tag_warned (finish_declspecs ($1), 1); pedwarn ("empty declaration"); } | declspecs_nots_nosa ';' { pedwarn ("empty declaration"); } @@ -814,8 +855,18 @@ lineno_decl: setspecs: /* empty */ { pending_xref_error (); PUSH_DECLSPEC_STACK; - split_specs_attrs ($0, - ¤t_declspecs, &prefix_attributes); + if ($0) + { + prefix_attributes = $0->attrs; + $0->attrs = NULL_TREE; + current_declspecs = $0; + } + else + { + prefix_attributes = NULL_TREE; + current_declspecs = build_null_declspecs (); + } + current_declspecs = finish_declspecs (current_declspecs); all_prefix_attributes = prefix_attributes; } ; @@ -836,7 +887,7 @@ decl: | declspecs_nots setspecs notype_nested_function { POP_DECLSPEC_STACK; } | declspecs ';' - { shadow_tag ($1); } + { shadow_tag (finish_declspecs ($1)); } | extension decl { RESTORE_EXT_FLAGS ($1); } ; @@ -852,16 +903,6 @@ decl: - Attribute specifier lists (attributes). - These are stored as a TREE_LIST; the head of the list is the last - item in the specifier list. Each entry in the list has either a - TREE_PURPOSE that is an attribute specifier list, or a TREE_VALUE that - is a single other specifier or qualifier; and a TREE_CHAIN that is the - rest of the list. TREE_STATIC is set on the list if something other - than a storage class specifier or attribute has been seen; this is used - to warn for the obsolescent usage of storage class specifiers other than - at the start of the list. (Doing this properly would require function - specifiers to be handled separately from storage class specifiers.) - The various cases below are classified according to: (a) Whether a storage class specifier is included or not; some @@ -890,334 +931,208 @@ decl: /* Declspecs which contain at least one type specifier or typedef name. (Just `const' or `volatile' is not enough.) - A typedef'd name following these is taken as a name to be declared. - Declspecs have a non-NULL TREE_VALUE, attributes do not. */ + A typedef'd name following these is taken as a name to be declared. */ declspecs_nosc_nots_nosa_noea: TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual (build_null_declspecs (), $1); } | declspecs_nosc_nots_nosa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_nots_nosa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } ; declspecs_nosc_nots_nosa_ea: declspecs_nosc_nots_nosa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } ; declspecs_nosc_nots_sa_noea: declspecs_nosc_nots_sa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_nots_sa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } ; declspecs_nosc_nots_sa_ea: attributes - { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); - TREE_STATIC ($$) = 0; } + { $$ = declspecs_add_attrs (build_null_declspecs (), $1); } | declspecs_nosc_nots_sa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } ; declspecs_nosc_ts_nosa_noea: typespec_nonattr - { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type (build_null_declspecs (), $1); } | declspecs_nosc_ts_nosa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_ts_nosa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_ts_nosa_noea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_ts_nosa_ea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_nosa_noea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_nosa_ea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } ; declspecs_nosc_ts_nosa_ea: typespec_attr - { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type (build_null_declspecs (), $1); } | declspecs_nosc_ts_nosa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } | declspecs_nosc_ts_nosa_noea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_ts_nosa_ea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_nosa_noea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_nosa_ea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } ; declspecs_nosc_ts_sa_noea: declspecs_nosc_ts_sa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_ts_sa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_ts_sa_noea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_ts_sa_ea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_sa_noea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_sa_ea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } ; declspecs_nosc_ts_sa_ea: declspecs_nosc_ts_sa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } | declspecs_nosc_ts_sa_noea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_ts_sa_ea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_sa_noea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_nots_sa_ea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } ; declspecs_sc_nots_nosa_noea: scspec - { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); - TREE_STATIC ($$) = 0; } + { $$ = declspecs_add_scspec (build_null_declspecs (), $1); } | declspecs_sc_nots_nosa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_sc_nots_nosa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_nots_nosa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_nosc_nots_nosa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_nots_nosa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_nots_nosa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } ; declspecs_sc_nots_nosa_ea: declspecs_sc_nots_nosa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } ; declspecs_sc_nots_sa_noea: declspecs_sc_nots_sa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_sc_nots_sa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_nosc_nots_sa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_nosc_nots_sa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_nots_sa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_nots_sa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } ; declspecs_sc_nots_sa_ea: declspecs_sc_nots_sa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } ; declspecs_sc_ts_nosa_noea: declspecs_sc_ts_nosa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_sc_ts_nosa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_sc_ts_nosa_noea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_ts_nosa_ea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_nosa_noea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_nosa_ea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_ts_nosa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_nosc_ts_nosa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_ts_nosa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_ts_nosa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } ; declspecs_sc_ts_nosa_ea: declspecs_sc_ts_nosa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } | declspecs_sc_ts_nosa_noea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_ts_nosa_ea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_nosa_noea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_nosa_ea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } ; declspecs_sc_ts_sa_noea: declspecs_sc_ts_sa_noea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_sc_ts_sa_ea TYPE_QUAL - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_qual ($1, $2); } | declspecs_sc_ts_sa_noea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_ts_sa_ea typespec_reserved_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_sa_noea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_sa_ea typespec_nonattr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_nosc_ts_sa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_nosc_ts_sa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_ts_sa_noea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } | declspecs_sc_ts_sa_ea scspec - { if (extra_warnings && TREE_STATIC ($1)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_scspec ($1, $2); } ; declspecs_sc_ts_sa_ea: declspecs_sc_ts_sa_noea attributes - { $$ = tree_cons ($2, NULL_TREE, $1); - TREE_STATIC ($$) = TREE_STATIC ($1); } + { $$ = declspecs_add_attrs ($1, $2); } | declspecs_sc_ts_sa_noea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_ts_sa_ea typespec_reserved_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_sa_noea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } | declspecs_sc_nots_sa_ea typespec_attr - { $$ = tree_cons (NULL_TREE, $2, $1); - TREE_STATIC ($$) = 1; } + { $$ = declspecs_add_type ($1, $2); } ; /* Particular useful classes of declspecs. */ @@ -1304,7 +1219,7 @@ declspecs: /* A (possibly empty) sequence of type qualifiers and attributes. */ maybe_type_quals_attrs: /* empty */ - { $$ = NULL_TREE; } + { $$ = NULL; } | declspecs_nosc_nots { $$ = $1; } ; @@ -1328,7 +1243,7 @@ maybe_type_quals_attrs: or are such that any following attributes would be parsed as part of the specifier. - _nonattr: specifiers. */ + _nonattr: other specifiers not ending with attributes. */ typespec_nonattr: typespec_reserved_nonattr @@ -1341,7 +1256,9 @@ typespec_attr: typespec_reserved_nonattr: TYPESPEC - { OBJC_NEED_RAW_IDENTIFIER (1); } + { OBJC_NEED_RAW_IDENTIFIER (1); + $$.kind = ctsk_resword; + $$.spec = $1; } | structsp_nonattr ; @@ -1353,26 +1270,39 @@ typespec_nonreserved_nonattr: TYPENAME { /* For a typedef name, record the meaning, not the name. In case of `foo foo, bar;'. */ - $$ = lookup_name ($1); } + $$.kind = ctsk_typedef; + $$.spec = lookup_name ($1); } @@ifobjc | CLASSNAME protocolrefs - { $$ = get_static_reference ($1, $2); } - | OBJECTNAME protocolrefs - { $$ = get_protocol_reference ($2); } + { $$.kind = ctsk_objc; + $$.spec = objc_get_protocol_qualified_type ($1, $2); } + | TYPENAME non_empty_protocolrefs + { $$.kind = ctsk_objc; + $$.spec = objc_get_protocol_qualified_type ($1, $2); } /* Make "" equivalent to "id " - nisse@lysator.liu.se */ | non_empty_protocolrefs - { $$ = get_protocol_reference ($1); } + { $$.kind = ctsk_objc; + $$.spec = objc_get_protocol_qualified_type (NULL_TREE, $1); } @@end_ifobjc | typeof '(' expr ')' { skip_evaluation--; + in_typeof--; if (TREE_CODE ($3.value) == COMPONENT_REF && DECL_C_BIT_FIELD (TREE_OPERAND ($3.value, 1))) - error ("`typeof' applied to a bit-field"); - $$ = TREE_TYPE ($3.value); } + error ("% applied to a bit-field"); + $$.kind = ctsk_typeof; + $$.spec = TREE_TYPE ($3.value); + pop_maybe_used (variably_modified_type_p ($$.spec, + NULL_TREE)); } | typeof '(' typename ')' - { skip_evaluation--; $$ = groktypename ($3); } + { skip_evaluation--; + in_typeof--; + $$.kind = ctsk_typeof; + $$.spec = groktypename ($3); + pop_maybe_used (variably_modified_type_p ($$.spec, + NULL_TREE)); } ; /* typespec_nonreserved_attr does not exist. */ @@ -1389,35 +1319,49 @@ notype_initdecls: initdcl: declarator maybeasm maybe_attribute '=' - { $$ = start_decl ($1, current_declspecs, 1, + { $$ = start_decl ($1, current_declspecs, true, chainon ($3, all_prefix_attributes)); + if (!$$) + $$ = error_mark_node; start_init ($$, $2, global_bindings_p ()); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_init (); - maybe_warn_string_init (TREE_TYPE ($5), $6); - finish_decl ($5, $6.value, $2); } + if ($5 != error_mark_node) + { + maybe_warn_string_init (TREE_TYPE ($5), $6); + finish_decl ($5, $6.value, $2); + } + } | declarator maybeasm maybe_attribute - { tree d = start_decl ($1, current_declspecs, 0, + { tree d = start_decl ($1, current_declspecs, false, chainon ($3, all_prefix_attributes)); - finish_decl (d, NULL_TREE, $2); + if (d) + finish_decl (d, NULL_TREE, $2); } ; notype_initdcl: notype_declarator maybeasm maybe_attribute '=' - { $$ = start_decl ($1, current_declspecs, 1, + { $$ = start_decl ($1, current_declspecs, true, chainon ($3, all_prefix_attributes)); + if (!$$) + $$ = error_mark_node; start_init ($$, $2, global_bindings_p ()); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_init (); - maybe_warn_string_init (TREE_TYPE ($5), $6); - finish_decl ($5, $6.value, $2); } + if ($5 != error_mark_node) + { + maybe_warn_string_init (TREE_TYPE ($5), $6); + finish_decl ($5, $6.value, $2); + } + } | notype_declarator maybeasm maybe_attribute - { tree d = start_decl ($1, current_declspecs, 0, + { tree d = start_decl ($1, current_declspecs, false, chainon ($3, all_prefix_attributes)); - finish_decl (d, NULL_TREE, $2); } + if (d) + finish_decl (d, NULL_TREE, $2); } ; /* the * rules are dummies to accept the Apollo extended syntax so that the header files compile. */ @@ -1440,7 +1384,7 @@ attribute: '(' '(' attribute_list ')' ')' start_string_translation { $$ = $5; } | ATTRIBUTE error start_string_translation - {} + { $$ = NULL_TREE; } ; attribute_list: @@ -1508,15 +1452,15 @@ initlist1: It may use braces. */ initelt: designator_list '=' initval - { if (pedantic && ! flag_isoc99) + { if (pedantic && !flag_isoc99) pedwarn ("ISO C90 forbids specifying subobject to initialize"); } - | designator initval + | array_designator initval { if (pedantic) - pedwarn ("obsolete use of designated initializer without `='"); } + pedwarn ("obsolete use of designated initializer without %<=%>"); } | identifier ':' { set_init_label ($1); if (pedantic) - pedwarn ("obsolete use of designated initializer with `:'"); } + pedwarn ("obsolete use of designated initializer with %<:%>"); } initval {} | initval @@ -1540,7 +1484,11 @@ designator_list: designator: '.' identifier { set_init_label ($2); } - | '[' expr_no_commas ELLIPSIS expr_no_commas ']' + | array_designator + ; + +array_designator: + '[' expr_no_commas ELLIPSIS expr_no_commas ']' { set_init_index ($2.value, $4.value); if (pedantic) pedwarn ("ISO C forbids specifying range of elements to initialize"); } @@ -1554,8 +1502,8 @@ nested_function: pedwarn ("ISO C forbids nested functions"); push_function_context (); - if (! start_function (current_declspecs, $1, - all_prefix_attributes)) + if (!start_function (current_declspecs, $1, + all_prefix_attributes)) { pop_function_context (); YYERROR1; @@ -1584,8 +1532,8 @@ notype_nested_function: pedwarn ("ISO C forbids nested functions"); push_function_context (); - if (! start_function (current_declspecs, $1, - all_prefix_attributes)) + if (!start_function (current_declspecs, $1, + all_prefix_attributes)) { pop_function_context (); YYERROR1; @@ -1620,17 +1568,15 @@ declarator: after_type_declarator: '(' maybe_attribute after_type_declarator ')' - { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; } + { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } | after_type_declarator '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | after_type_declarator array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | '*' maybe_type_quals_attrs after_type_declarator %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | TYPENAME -@@ifobjc - | OBJECTNAME -@@end_ifobjc + { $$ = build_id_declarator ($1); } ; /* Kinds of declarator that can appear in a parameter list @@ -1644,26 +1590,24 @@ parm_declarator: parm_declarator_starttypename: parm_declarator_starttypename '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | parm_declarator_starttypename array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | TYPENAME -@@ifobjc - | OBJECTNAME -@@end_ifobjc + { $$ = build_id_declarator ($1); } ; parm_declarator_nostarttypename: parm_declarator_nostarttypename '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | parm_declarator_nostarttypename array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | '*' maybe_type_quals_attrs parm_declarator_starttypename %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | '*' maybe_type_quals_attrs parm_declarator_nostarttypename %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | '(' maybe_attribute parm_declarator_nostarttypename ')' - { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; } + { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } ; /* A declarator allowed whether or not there has been @@ -1671,14 +1615,15 @@ parm_declarator_nostarttypename: notype_declarator: notype_declarator '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | '(' maybe_attribute notype_declarator ')' - { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; } + { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } | '*' maybe_type_quals_attrs notype_declarator %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | notype_declarator array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | IDENTIFIER + { $$ = build_id_declarator ($1); } ; struct_head: @@ -1710,48 +1655,56 @@ enum_head: structsp_attr: struct_head identifier '{' - { $$ = start_struct (RECORD_TYPE, $2); + { $$ = start_struct (RECORD_TYPE, $2); /* Start scope of tag before parsing components. */ } component_decl_list '}' maybe_attribute - { $$ = finish_struct ($4, nreverse ($5), - chainon ($1, $7)); } + { $$.spec = finish_struct ($4, nreverse ($5), + chainon ($1, $7)); + $$.kind = ctsk_tagdef; } | struct_head '{' component_decl_list '}' maybe_attribute - { $$ = finish_struct (start_struct (RECORD_TYPE, NULL_TREE), - nreverse ($3), chainon ($1, $5)); + { $$.spec = finish_struct (start_struct (RECORD_TYPE, + NULL_TREE), + nreverse ($3), chainon ($1, $5)); + $$.kind = ctsk_tagdef; } | union_head identifier '{' - { $$ = start_struct (UNION_TYPE, $2); } + { $$ = start_struct (UNION_TYPE, $2); } component_decl_list '}' maybe_attribute - { $$ = finish_struct ($4, nreverse ($5), - chainon ($1, $7)); } + { $$.spec = finish_struct ($4, nreverse ($5), + chainon ($1, $7)); + $$.kind = ctsk_tagdef; } | union_head '{' component_decl_list '}' maybe_attribute - { $$ = finish_struct (start_struct (UNION_TYPE, NULL_TREE), - nreverse ($3), chainon ($1, $5)); + { $$.spec = finish_struct (start_struct (UNION_TYPE, + NULL_TREE), + nreverse ($3), chainon ($1, $5)); + $$.kind = ctsk_tagdef; } | enum_head identifier '{' - { $$ = start_enum ($2); } + { $$ = start_enum ($2); } enumlist maybecomma_warn '}' maybe_attribute - { $$ = finish_enum ($4, nreverse ($5), - chainon ($1, $8)); } + { $$.spec = finish_enum ($4, nreverse ($5), + chainon ($1, $8)); + $$.kind = ctsk_tagdef; } | enum_head '{' - { $$ = start_enum (NULL_TREE); } + { $$ = start_enum (NULL_TREE); } enumlist maybecomma_warn '}' maybe_attribute - { $$ = finish_enum ($3, nreverse ($4), - chainon ($1, $7)); } + { $$.spec = finish_enum ($3, nreverse ($4), + chainon ($1, $7)); + $$.kind = ctsk_tagdef; } ; structsp_nonattr: struct_head identifier - { $$ = xref_tag (RECORD_TYPE, $2); } + { $$ = parser_xref_tag (RECORD_TYPE, $2); } | union_head identifier - { $$ = xref_tag (UNION_TYPE, $2); } + { $$ = parser_xref_tag (UNION_TYPE, $2); } | enum_head identifier - { $$ = xref_tag (ENUMERAL_TYPE, $2); + { $$ = parser_xref_tag (ENUMERAL_TYPE, $2); /* In ISO C, enumerated types can be referred to only if already defined. */ - if (pedantic && !COMPLETE_TYPE_P ($$)) - pedwarn ("ISO C forbids forward references to `enum' types"); } + if (pedantic && !COMPLETE_TYPE_P ($$.spec)) + pedwarn ("ISO C forbids forward references to % types"); } ; maybecomma: @@ -1762,7 +1715,7 @@ maybecomma: maybecomma_warn: /* empty */ | ',' - { if (pedantic && ! flag_isoc99) + { if (pedantic && !flag_isoc99) pedwarn ("comma at end of enumerator list"); } ; @@ -1796,7 +1749,7 @@ component_decl_list2: /* empty */ @@ifobjc /* foo(sizeof(struct{ @defs(ClassName)})); */ | AT_DEFS '(' CLASSNAME ')' - { $$ = nreverse (get_class_ivars_from_name ($3)); } + { $$ = nreverse (objc_get_class_ivars ($3)); } @@end_ifobjc ; @@ -1809,10 +1762,8 @@ component_decl: /* Support for unnamed structs or unions as members of structs or unions (which is [a] useful and [b] supports MS P-SDK). */ - if (pedantic) - pedwarn ("ISO C doesn't support unnamed structs/unions"); - - $$ = grokfield(NULL, current_declspecs, NULL_TREE); + $$ = grokfield (build_id_declarator (NULL_TREE), + current_declspecs, NULL_TREE); POP_DECLSPEC_STACK; } | declspecs_nosc_nots setspecs components_notype { $$ = $3; @@ -1820,7 +1771,7 @@ component_decl: | declspecs_nosc_nots { if (pedantic) pedwarn ("ISO C forbids member declarations with no members"); - shadow_tag_warned ($1, pedantic); + shadow_tag_warned (finish_declspecs ($1), pedantic); $$ = NULL_TREE; } | error { $$ = NULL_TREE; } @@ -1851,7 +1802,8 @@ component_declarator: decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); } | ':' expr_no_commas maybe_attribute - { $$ = grokfield (NULL_TREE, current_declspecs, $2.value); + { $$ = grokfield (build_id_declarator (NULL_TREE), + current_declspecs, $2.value); decl_attributes (&$$, chainon ($3, all_prefix_attributes), 0); } ; @@ -1866,7 +1818,8 @@ component_notype_declarator: decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); } | ':' expr_no_commas maybe_attribute - { $$ = grokfield (NULL_TREE, current_declspecs, $2.value); + { $$ = grokfield (build_id_declarator (NULL_TREE), + current_declspecs, $2.value); decl_attributes (&$$, chainon ($3, all_prefix_attributes), 0); } ; @@ -1896,30 +1849,30 @@ enumerator: typename: declspecs_nosc { pending_xref_error (); - $$ = $1; } + $$ = finish_declspecs ($1); } absdcl - { $$ = build_tree_list ($2, $3); } + { $$ = XOBNEW (&parser_obstack, struct c_type_name); + $$->specs = $2; + $$->declarator = $3; } ; absdcl: /* an absolute declarator */ /* empty */ - { $$ = NULL_TREE; } + { $$ = build_id_declarator (NULL_TREE); } | absdcl1 ; absdcl_maybe_attribute: /* absdcl maybe_attribute, but not just attributes */ /* empty */ - { $$ = build_tree_list (build_tree_list (current_declspecs, - NULL_TREE), - all_prefix_attributes); } + { $$ = build_c_parm (current_declspecs, all_prefix_attributes, + build_id_declarator (NULL_TREE)); } | absdcl1 - { $$ = build_tree_list (build_tree_list (current_declspecs, - $1), - all_prefix_attributes); } + { $$ = build_c_parm (current_declspecs, all_prefix_attributes, + $1); } | absdcl1_noea attributes - { $$ = build_tree_list (build_tree_list (current_declspecs, - $1), - chainon ($2, all_prefix_attributes)); } + { $$ = build_c_parm (current_declspecs, + chainon ($2, all_prefix_attributes), + $1); } ; absdcl1: /* a nonempty absolute declarator */ @@ -1935,38 +1888,41 @@ absdcl1_noea: absdcl1_ea: '*' maybe_type_quals_attrs - { $$ = make_pointer_declarator ($2, NULL_TREE); } + { $$ = make_pointer_declarator + ($2, build_id_declarator (NULL_TREE)); } | '*' maybe_type_quals_attrs absdcl1_ea { $$ = make_pointer_declarator ($2, $3); } ; direct_absdcl1: '(' maybe_attribute absdcl1 ')' - { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; } + { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } | direct_absdcl1 '(' parmlist - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | direct_absdcl1 array_declarator - { $$ = set_array_declarator_type ($2, $1, 1); } + { $$ = set_array_declarator_inner ($2, $1, true); } | '(' parmlist - { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); } + { $$ = build_function_declarator + ($2, build_id_declarator (NULL_TREE)); } | array_declarator - { $$ = set_array_declarator_type ($1, NULL_TREE, 1); } + { $$ = set_array_declarator_inner + ($1, build_id_declarator (NULL_TREE), true); } ; /* The [...] part of a declarator for an array type. */ array_declarator: '[' maybe_type_quals_attrs expr_no_commas ']' - { $$ = build_array_declarator ($3.value, $2, 0, 0); } + { $$ = build_array_declarator ($3.value, $2, false, false); } | '[' maybe_type_quals_attrs ']' - { $$ = build_array_declarator (NULL_TREE, $2, 0, 0); } + { $$ = build_array_declarator (NULL_TREE, $2, false, false); } | '[' maybe_type_quals_attrs '*' ']' - { $$ = build_array_declarator (NULL_TREE, $2, 0, 1); } + { $$ = build_array_declarator (NULL_TREE, $2, false, true); } | '[' STATIC maybe_type_quals_attrs expr_no_commas ']' - { $$ = build_array_declarator ($4.value, $3, 1, 0); } + { $$ = build_array_declarator ($4.value, $3, true, false); } /* declspecs_nosc_nots is a synonym for type_quals_attrs. */ | '[' declspecs_nosc_nots STATIC expr_no_commas ']' - { $$ = build_array_declarator ($4.value, $2, 1, 0); } + { $$ = build_array_declarator ($4.value, $2, true, false); } ; /* A nonempty series of declarations and statements (possibly followed by @@ -2081,7 +2037,7 @@ compstmt_contents_nonempty: compstmt_primary_start: '(' '{' - { if (current_function_decl == 0) + { if (cur_stmt_list == NULL) { error ("braced-group within expression allowed " "only inside a function"); @@ -2118,9 +2074,9 @@ c99_block_lineno_labeled_stmt: lineno_stmt: save_location stmt - { + { /* Two cases cannot and do not have line numbers associated: - If stmt is degenerate, such as "2;", then stmt is an + If stmt is degenerate, such as "2;", then stmt is an INTEGER_CST, which cannot hold line numbers. But that's ok because the statement will either be changed to a MODIFY_EXPR during gimplification of the statement expr, @@ -2305,7 +2261,7 @@ stmt_nocomp: objc_catch_prefix: AT_CATCH '(' parm ')' - { objc_begin_catch_clause ($3); } + { objc_begin_catch_clause (grokparm ($3)); } ; objc_catch_clause: @@ -2374,7 +2330,7 @@ label: CASE expr_no_commas ':' expression with inputs and outputs does not make sense. */ simple_asm_expr: ASM_KEYWORD stop_string_translation - '(' STRING ')' start_string_translation + '(' asm_string ')' start_string_translation { $$ = $4; } ; @@ -2403,16 +2359,16 @@ asm_stmt: asm_argument: /* no operands */ - STRING + asm_string { $$ = build_asm_expr ($1, 0, 0, 0, true); } /* output operands */ - | STRING ':' asm_operands + | asm_string ':' asm_operands { $$ = build_asm_expr ($1, $3, 0, 0, false); } /* output and input operands */ - | STRING ':' asm_operands ':' asm_operands + | asm_string ':' asm_operands ':' asm_operands { $$ = build_asm_expr ($1, $3, $5, 0, false); } /* output and input operands and clobbers */ - | STRING ':' asm_operands ':' asm_operands ':' asm_clobbers + | asm_string ':' asm_operands ':' asm_operands ':' asm_clobbers { $$ = build_asm_expr ($1, $3, $5, $7, false); } ; @@ -2446,10 +2402,11 @@ nonnull_asm_operands: ; asm_operand: - STRING start_string_translation '(' expr ')' stop_string_translation + asm_string start_string_translation '(' expr ')' + stop_string_translation { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $4.value); } - | '[' identifier ']' STRING start_string_translation + | '[' identifier ']' asm_string start_string_translation '(' expr ')' stop_string_translation { $2 = build_string (IDENTIFIER_LENGTH ($2), IDENTIFIER_POINTER ($2)); @@ -2457,12 +2414,24 @@ asm_operand: ; asm_clobbers: - STRING + asm_string { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); } - | asm_clobbers ',' STRING + | asm_clobbers ',' asm_string { $$ = tree_cons (NULL_TREE, $3, $1); } ; +/* Strings in 'asm' must be narrow strings. */ +asm_string: + STRING + { if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE ($1))) + != char_type_node) + { + error ("wide string literal in %"); + $$ = build_string (1, ""); + } + else + $$ = $1; } + stop_string_translation: { c_lex_string_translate = 0; } ; @@ -2496,18 +2465,29 @@ parmlist_1: parmlist_1 { $$ = $6; } | error ')' - { $$ = make_node (TREE_LIST); } + { $$ = XOBNEW (&parser_obstack, struct c_arg_info); + $$->parms = 0; + $$->tags = 0; + $$->types = 0; + $$->others = 0; } ; /* This is what appears inside the parens in a function declarator. - Is value is represented in the format that grokdeclarator expects. */ + Its value is represented in the format that grokdeclarator expects. */ parmlist_2: /* empty */ - { $$ = make_node (TREE_LIST); } + { $$ = XOBNEW (&parser_obstack, struct c_arg_info); + $$->parms = 0; + $$->tags = 0; + $$->types = 0; + $$->others = 0; } | ELLIPSIS - { $$ = make_node (TREE_LIST); + { $$ = XOBNEW (&parser_obstack, struct c_arg_info); + $$->parms = 0; + $$->tags = 0; + $$->others = 0; /* Suppress -Wold-style-definition for this case. */ - TREE_CHAIN ($$) = error_mark_node; - error ("ISO C requires a named argument before `...'"); + $$->types = error_mark_node; + error ("ISO C requires a named argument before %<...%>"); } | parms { $$ = get_parm_info (/*ellipsis=*/false); } @@ -2526,22 +2506,19 @@ parms: as found in a parmlist. */ parm: declspecs_ts setspecs parm_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - chainon ($4, all_prefix_attributes)); + { $$ = build_c_parm (current_declspecs, + chainon ($4, all_prefix_attributes), $3); POP_DECLSPEC_STACK; } | declspecs_ts setspecs notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - chainon ($4, all_prefix_attributes)); + { $$ = build_c_parm (current_declspecs, + chainon ($4, all_prefix_attributes), $3); POP_DECLSPEC_STACK; } | declspecs_ts setspecs absdcl_maybe_attribute { $$ = $3; POP_DECLSPEC_STACK; } | declspecs_nots setspecs notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - chainon ($4, all_prefix_attributes)); + { $$ = build_c_parm (current_declspecs, + chainon ($4, all_prefix_attributes), $3); POP_DECLSPEC_STACK; } | declspecs_nots setspecs absdcl_maybe_attribute @@ -2553,22 +2530,19 @@ parm: stack. */ firstparm: declspecs_ts_nosa setspecs_fp parm_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - chainon ($4, all_prefix_attributes)); + { $$ = build_c_parm (current_declspecs, + chainon ($4, all_prefix_attributes), $3); POP_DECLSPEC_STACK; } | declspecs_ts_nosa setspecs_fp notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - chainon ($4, all_prefix_attributes)); + { $$ = build_c_parm (current_declspecs, + chainon ($4, all_prefix_attributes), $3); POP_DECLSPEC_STACK; } | declspecs_ts_nosa setspecs_fp absdcl_maybe_attribute { $$ = $3; POP_DECLSPEC_STACK; } | declspecs_nots_nosa setspecs_fp notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $3), - chainon ($4, all_prefix_attributes)); + { $$ = build_c_parm (current_declspecs, + chainon ($4, all_prefix_attributes), $3); POP_DECLSPEC_STACK; } | declspecs_nots_nosa setspecs_fp absdcl_maybe_attribute @@ -2597,17 +2571,14 @@ parmlist_or_identifiers: parmlist_or_identifiers_1: parmlist_1 | identifiers ')' - { tree t; - for (t = $1; t; t = TREE_CHAIN (t)) - if (TREE_VALUE (t) == NULL_TREE) - error ("`...' in old-style identifier list"); - $$ = tree_cons (NULL_TREE, NULL_TREE, $1); + { $$ = XOBNEW (&parser_obstack, struct c_arg_info); + $$->parms = 0; + $$->tags = 0; + $$->types = $1; + $$->others = 0; /* Make sure we have a parmlist after attributes. */ - if ($-1 != 0 - && (TREE_CODE ($$) != TREE_LIST - || TREE_PURPOSE ($$) == 0 - || TREE_CODE (TREE_PURPOSE ($$)) != PARM_DECL)) + if ($-1 != 0) YYERROR1; } ; @@ -2630,7 +2601,7 @@ identifiers_or_typenames: extension: EXTENSION - { $$ = SAVE_EXT_FLAGS(); + { $$ = SAVE_EXT_FLAGS (); pedantic = 0; warn_pointer_arith = 0; warn_traditional = 0; @@ -2648,14 +2619,7 @@ objcdef: | methoddef | AT_END { - if (objc_implementation_context) - { - finish_class (objc_implementation_context); - objc_ivar_chain = NULL_TREE; - objc_implementation_context = NULL_TREE; - } - else - warning ("`@end' must appear in an implementation context"); + objc_finish_implementation (); } ; @@ -2694,50 +2658,38 @@ class_ivars: classdef: AT_INTERFACE identifier superclass protocolrefs { - objc_interface_context = objc_ivar_context - = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4); - objc_public_flag = 0; + objc_start_class_interface ($2, $3, $4); } class_ivars { - continue_class (objc_interface_context); + objc_continue_interface (); } methodprotolist AT_END { - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; + objc_finish_interface (); } | AT_IMPLEMENTATION identifier superclass { - objc_implementation_context = objc_ivar_context - = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE); - objc_public_flag = 0; + objc_start_class_implementation ($2, $3); } class_ivars { - objc_ivar_chain - = continue_class (objc_implementation_context); + objc_continue_implementation (); } | AT_INTERFACE identifier '(' identifier ')' protocolrefs { - objc_interface_context - = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6); - continue_class (objc_interface_context); + objc_start_category_interface ($2, $4, $6); } methodprotolist AT_END { - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; + objc_finish_interface (); } | AT_IMPLEMENTATION identifier '(' identifier ')' { - objc_implementation_context - = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); - objc_ivar_chain - = continue_class (objc_implementation_context); + objc_start_category_implementation ($2, $4); } ; @@ -2745,14 +2697,12 @@ protocoldef: AT_PROTOCOL identifier protocolrefs { objc_pq_context = 1; - objc_interface_context - = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3); + objc_start_protocol ($2, $3); } methodprotolist AT_END { objc_pq_context = 0; - finish_protocol(objc_interface_context); - objc_interface_context = NULL_TREE; + objc_finish_interface (); } /* The @protocol forward-declaration production introduces a reduce/reduce conflict on ';', which should be resolved in @@ -2782,109 +2732,67 @@ non_empty_protocolrefs: ; ivar_decl_list: - ivar_decl_list visibility_spec ivar_decls - | ivar_decls + /* empty */ + | ivar_decl_list visibility_spec ivar_decls ; visibility_spec: - AT_PRIVATE { objc_public_flag = 2; } - | AT_PROTECTED { objc_public_flag = 0; } - | AT_PUBLIC { objc_public_flag = 1; } + /* empty */ + | AT_PRIVATE { objc_set_visibility (2); } + | AT_PROTECTED { objc_set_visibility (0); } + | AT_PUBLIC { objc_set_visibility (1); } ; ivar_decls: - /* empty */ - { - $$ = NULL_TREE; - } + /* empty */ | ivar_decls ivar_decl ';' | ivar_decls ';' { - if (pedantic) + if (pedantic) pedwarn ("extra semicolon in struct or union specified"); - } + } ; - -/* There is a shift-reduce conflict here, because `components' may - start with a `typename'. It happens that shifting (the default resolution) - does the right thing, because it treats the `typename' as part of - a `typed_typespecs'. - - It is possible that this same technique would allow the distinction - between `notype_initdecls' and `initdecls' to be eliminated. - But I am being cautious and not trying it. */ - ivar_decl: - declspecs_nosc_ts setspecs ivars - { $$ = $3; - POP_DECLSPEC_STACK; } - | declspecs_nosc_nots setspecs ivars - { $$ = $3; - POP_DECLSPEC_STACK; } - | error - { $$ = NULL_TREE; } - ; + component_decl + { + /* Comma-separated ivars are chained together in + reverse order; add them one by one. */ + tree ivar = nreverse ($1); -ivars: - /* empty */ - { $$ = NULL_TREE; } - | ivar_declarator - | ivars ',' maybe_resetattrs ivar_declarator + for (; ivar; ivar = TREE_CHAIN (ivar)) + objc_add_instance_variable (copy_node (ivar)); + } ; -ivar_declarator: - declarator - { - $$ = add_instance_variable (objc_ivar_context, - objc_public_flag, - $1, current_declspecs, - NULL_TREE); - } - | declarator ':' expr_no_commas - { - $$ = add_instance_variable (objc_ivar_context, - objc_public_flag, - $1, current_declspecs, $3.value); - } - | ':' expr_no_commas +opt_semi: + /* NULL */ + | ';' { - $$ = add_instance_variable (objc_ivar_context, - objc_public_flag, - NULL_TREE, - current_declspecs, $2.value); - } + if (pedantic) + pedwarn ("extra semicolon in method definition specified"); + } ; methodtype: '+' - { objc_inherit_code = CLASS_METHOD_DECL; } | '-' - { objc_inherit_code = INSTANCE_METHOD_DECL; } ; methoddef: methodtype { + objc_set_method_type ($1); objc_pq_context = 1; - if (!objc_implementation_context) - fatal_error ("method definition not in class context"); } - methoddecl + methoddecl opt_semi { objc_pq_context = 0; - objc_add_method (objc_implementation_context, - $3, - objc_inherit_code == CLASS_METHOD_DECL); - start_method_def ($3); - } - optarglist - { - continue_method_def (); + objc_start_method_definition ($3); } compstmt_or_error { - finish_method_def (); + objc_finish_method_definition (current_function_decl); } ; @@ -2906,6 +2814,7 @@ semi_or_error: methodproto: methodtype { + objc_set_method_type ($1); /* Remember protocol qualifiers in prototypes. */ objc_pq_context = 1; } @@ -2913,109 +2822,63 @@ methodproto: { /* Forget protocol qualifiers here. */ objc_pq_context = 0; - objc_add_method (objc_interface_context, - $3, - objc_inherit_code == CLASS_METHOD_DECL); + objc_add_method_declaration ($3); } semi_or_error ; methoddecl: - '(' typename ')' unaryselector + '(' objc_typename ')' unaryselector { - $$ = build_method_decl (objc_inherit_code, $2, $4, NULL_TREE); + $$ = objc_build_method_signature ($2, $4, NULL_TREE); } | unaryselector { - $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, NULL_TREE); + $$ = objc_build_method_signature (NULL_TREE, $1, NULL_TREE); } - | '(' typename ')' keywordselector optparmlist + | '(' objc_typename ')' keywordselector optparmlist { - $$ = build_method_decl (objc_inherit_code, $2, $4, $5); + $$ = objc_build_method_signature ($2, $4, $5); } | keywordselector optparmlist { - $$ = build_method_decl (objc_inherit_code, NULL_TREE, $1, $2); + $$ = objc_build_method_signature (NULL_TREE, $1, $2); } ; -/* "optarglist" assumes that start_method_def has already been called... - if it is not, the "xdecls" will not be placed in the proper scope */ - -optarglist: - /* empty */ - | ';' myxdecls - ; - -/* to get around the following situation: "int foo (int a) int b; {}" that - is synthesized when parsing "- a:a b:b; id c; id d; { ... }" */ - -myxdecls: - /* empty */ - | mydecls - ; - -mydecls: - mydecl - | errstmt - | mydecls mydecl - | mydecl errstmt - ; - -mydecl: - declspecs_ts setspecs myparms ';' - { POP_DECLSPEC_STACK; } - | declspecs_ts ';' - { shadow_tag ($1); } - | declspecs_nots ';' - { pedwarn ("empty declaration"); } - ; +/* Optional ObjC method parameters follow the C syntax, and may include '...' + to denote a variable number of arguments. */ -myparms: - myparm - { push_parm_decl ($1); } - | myparms ',' myparm - { push_parm_decl ($3); } - ; - -/* A single parameter declaration or parameter type name, - as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */ - -myparm: - parm_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $1), - chainon ($2, all_prefix_attributes)); } - | notype_declarator maybe_attribute - { $$ = build_tree_list (build_tree_list (current_declspecs, - $1), - chainon ($2, all_prefix_attributes)); } - | absdcl_maybe_attribute - { $$ = $1; } +optparmlist: + optparms optellipsis + { + TREE_OVERFLOW ($$) = $2; + } ; -optparmlist: - /* empty */ +optparms: + /* NULL */ { - $$ = NULL_TREE; + $$ = make_node (TREE_LIST); } - | ',' ELLIPSIS + | optparms ',' parm { - /* oh what a kludge! */ - $$ = objc_ellipsis_node; + $$ = chainon ($1, build_tree_list (NULL_TREE, + grokparm ($3))); } - | ',' + ; + +optellipsis: + /* NULL */ { - push_scope (); + $$ = 0; } - parmlist_2 + | ',' ELLIPSIS { - /* returns a tree list node generated by get_parm_info */ - $$ = $3; - pop_scope (); + $$ = 1; } ; @@ -3036,36 +2899,61 @@ selector: IDENTIFIER | TYPENAME | CLASSNAME - | OBJECTNAME | reservedwords ; reservedwords: - ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR + ENUM | STRUCT | UNION | IF | ELSE | WHILE | DO | FOR | SWITCH | CASE | DEFAULT | BREAK | CONTINUE | RETURN | GOTO | ASM_KEYWORD | SIZEOF | TYPEOF | ALIGNOF - | TYPESPEC | TYPE_QUAL + | TYPESPEC | TYPE_QUAL | OBJC_TYPE_QUAL + ; + +objc_qual: + OBJC_TYPE_QUAL + ; + +objc_quals: + objc_quals objc_qual + { + $$ = chainon ($1, build_tree_list (NULL_TREE, $2)); + } + | /* NULL */ + { + $$ = NULL_TREE; + } + ; + +objc_typename: + objc_quals typename + { + $$ = build_tree_list ($1, groktypename ($2)); + } + | objc_quals + { + $$ = build_tree_list ($1, NULL_TREE); + } ; keyworddecl: - selector ':' '(' typename ')' identifier + selector ':' '(' objc_typename ')' identifier { - $$ = build_keyword_decl ($1, $4, $6); + $$ = objc_build_keyword_decl ($1, $4, $6); } | selector ':' identifier { - $$ = build_keyword_decl ($1, NULL_TREE, $3); + $$ = objc_build_keyword_decl ($1, NULL_TREE, $3); } - | ':' '(' typename ')' identifier + | ':' '(' objc_typename ')' identifier { - $$ = build_keyword_decl (NULL_TREE, $3, $5); + $$ = objc_build_keyword_decl (NULL_TREE, $3, $5); } | ':' identifier { - $$ = build_keyword_decl (NULL_TREE, NULL_TREE, $2); + $$ = objc_build_keyword_decl (NULL_TREE, NULL_TREE, $2); } ; @@ -3111,11 +2999,11 @@ receiver: { $$ = $1.value; } | CLASSNAME { - $$ = get_class_reference ($1); + $$ = objc_get_class_reference ($1); } | TYPENAME { - $$ = get_class_reference ($1); + $$ = objc_get_class_reference ($1); } ; @@ -3221,12 +3109,6 @@ static const struct resword reswords[] = { "__inline", RID_INLINE, 0 }, { "__inline__", RID_INLINE, 0 }, { "__label__", RID_LABEL, 0 }, - { "__ptrbase", RID_PTRBASE, 0 }, - { "__ptrbase__", RID_PTRBASE, 0 }, - { "__ptrextent", RID_PTREXTENT, 0 }, - { "__ptrextent__", RID_PTREXTENT, 0 }, - { "__ptrvalue", RID_PTRVALUE, 0 }, - { "__ptrvalue__", RID_PTRVALUE, 0 }, { "__real", RID_REALPART, 0 }, { "__real__", RID_REALPART, 0 }, { "__restrict", RID_RESTRICT, 0 }, @@ -3274,8 +3156,8 @@ static const struct resword reswords[] = { "void", RID_VOID, 0 }, { "volatile", RID_VOLATILE, 0 }, { "while", RID_WHILE, 0 }, + @@ifobjc - { "id", RID_ID, D_OBJC }, /* These objc keywords are recognized only immediately after an '@'. */ @@ -3339,12 +3221,12 @@ static const short rid_to_yy[RID_MAX] = /* RID_MUTABLE */ 0, /* ObjC */ - /* RID_IN */ TYPE_QUAL, - /* RID_OUT */ TYPE_QUAL, - /* RID_INOUT */ TYPE_QUAL, - /* RID_BYCOPY */ TYPE_QUAL, - /* RID_BYREF */ TYPE_QUAL, - /* RID_ONEWAY */ TYPE_QUAL, + /* RID_IN */ OBJC_TYPE_QUAL, + /* RID_OUT */ OBJC_TYPE_QUAL, + /* RID_INOUT */ OBJC_TYPE_QUAL, + /* RID_BYCOPY */ OBJC_TYPE_QUAL, + /* RID_BYREF */ OBJC_TYPE_QUAL, + /* RID_ONEWAY */ OBJC_TYPE_QUAL, /* C */ /* RID_INT */ TYPESPEC, @@ -3379,9 +3261,6 @@ static const short rid_to_yy[RID_MAX] = /* RID_IMAGPART */ IMAGPART, /* RID_REALPART */ REALPART, /* RID_LABEL */ LABEL, - /* RID_PTRBASE */ PTR_BASE, - /* RID_PTREXTENT */ PTR_EXTENT, - /* RID_PTRVALUE */ PTR_VALUE, /* RID_CHOOSE_EXPR */ CHOOSE_EXPR, /* RID_TYPES_COMPATIBLE_P */ TYPES_COMPATIBLE_P, @@ -3421,7 +3300,6 @@ static const short rid_to_yy[RID_MAX] = /* RID_STATCAST */ 0, /* Objective C */ - /* RID_ID */ OBJECTNAME, /* RID_AT_ENCODE */ AT_ENCODE, /* RID_AT_END */ AT_END, /* RID_AT_CLASS */ AT_CLASS, @@ -3490,15 +3368,6 @@ yylexname (void) enum rid rid_code = C_RID_CODE (yylval.ttype); @@ifobjc - /* Turn non-typedefed refs to "id" into plain identifiers; this - allows constructs like "void foo(id id);" to work. */ - if (rid_code == RID_ID) - { - decl = lookup_name (yylval.ttype); - if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - } - if (!OBJC_IS_AT_KEYWORD (rid_code) && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) @@end_ifobjc @@ -3518,7 +3387,7 @@ yylexname (void) @@ifobjc else { - tree objc_interface_decl = is_class_name (yylval.ttype); + tree objc_interface_decl = objc_is_class_name (yylval.ttype); /* ObjC class names are in the same namespace as variables and typedefs, and hence are shadowed by local declarations. */ if (objc_interface_decl @@ -3629,7 +3498,7 @@ _yylex (void) /* These tokens should not survive translation phase 4. */ case CPP_HASH: case CPP_PASTE: - error ("syntax error at '%s' token", NAME(last_token)); + error ("syntax error at %qs token", NAME(last_token)); goto get_next; default: @@ -3661,13 +3530,12 @@ yyprint (FILE *file, int yychar, YYSTYPE yyl) { case IDENTIFIER: case TYPENAME: - case OBJECTNAME: case TYPESPEC: case TYPE_QUAL: case SCSPEC: case STATIC: if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); + fprintf (file, " '%s'", IDENTIFIER_POINTER (t)); break; case CONSTANT: @@ -3699,4 +3567,21 @@ c_parse_file (void) } } +#ifdef __XGETTEXT__ +/* Depending on the version of Bison used to compile this grammar, + it may issue generic diagnostics spelled "syntax error" or + "parse error". To prevent this from changing the translation + template randomly, we list all the variants of this particular + diagnostic here. Translators: there is no fine distinction + between diagnostics with "syntax error" in them, and diagnostics + with "parse error" in them. It's okay to give them both the same + translation. */ +const char d1[] = N_("syntax error"); +const char d2[] = N_("parse error"); +const char d3[] = N_("syntax error; also virtual memory exhausted"); +const char d4[] = N_("parse error; also virtual memory exhausted"); +const char d5[] = N_("syntax error: cannot back up"); +const char d6[] = N_("parse error: cannot back up"); +#endif + #include "gt-c-parse.h"