X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fc-parse.in;h=7542c3959fbffa306d0f001ae2597635ccdd388b;hp=f2ffed0ba1703ffe34236ea06fc9f0f128e54836;hb=19702c1d34daddd799073407407ff47a44d0084c;hpb=805e22b2051e9c6a75377ea6599654d7415da483 diff --git a/gcc/c-parse.in b/gcc/c-parse.in index f2ffed0ba17..7542c3959fb 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 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, + 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GCC. @@ -20,20 +20,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This file defines the grammar of C and that of Objective C. - ifobjc ... end ifobjc conditionals contain code for Objective C only. - ifc ... end ifc conditionals contain code for C only. + @@ifobjc ... @@end_ifobjc conditionals contain code for Objective C only. + @@ifc ... @@end_ifc conditionals contain code for C only. Sed commands in Makefile.in are used to convert this file into c-parse.y and into objc-parse.y. */ /* To whomever it may concern: I have heard that such a thing was once written by AT&T, but I have never seen it. */ -ifobjc -%expect 32 /* shift/reduce conflicts, and 1 reduce/reduce conflict. */ -end ifobjc -ifc -%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */ -end ifc +@@ifc +%expect 13 /* shift/reduce conflicts, and no reduce/reduce conflicts. */ +@@end_ifc %{ #include "config.h" @@ -41,6 +38,7 @@ end ifc #include "coretypes.h" #include "tm.h" #include "tree.h" +#include "langhooks.h" #include "input.h" #include "cpplib.h" #include "intl.h" @@ -48,19 +46,12 @@ end ifc #include "c-pragma.h" /* For YYDEBUG definition, and parse_in. */ #include "c-tree.h" #include "flags.h" +#include "varray.h" #include "output.h" #include "toplev.h" #include "ggc.h" +#include "c-common.h" -#ifdef MULTIBYTE_CHARS -#include -#endif - -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, @@ -81,15 +72,13 @@ do { \ newsize = *(YYSSZ) *= 2; \ if (malloced_yyss) \ { \ - newss = (short *) \ - really_call_realloc (*(SS), newsize * sizeof (short)); \ - newvs = (YYSTYPE *) \ - really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \ + newss = really_call_realloc (*(SS), newsize * sizeof (short)); \ + newvs = really_call_realloc (*(VS), newsize * sizeof (YYSTYPE)); \ } \ else \ { \ - newss = (short *) really_call_malloc (newsize * sizeof (short)); \ - newvs = (YYSTYPE *) really_call_malloc (newsize * sizeof (YYSTYPE)); \ + newss = really_call_malloc (newsize * sizeof (short)); \ + newvs = really_call_malloc (newsize * sizeof (YYSTYPE)); \ if (newss) \ memcpy (newss, *(SS), (SSSIZE)); \ if (newvs) \ @@ -109,8 +98,11 @@ do { \ %start program -%union {long itype; tree ttype; enum tree_code code; - const char *filename; int lineno; } +%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 */ @@ -134,12 +126,17 @@ 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 /* String constants in raw form. yylval is a STRING_CST node. */ + %token STRING /* "...", used for functions with variable arglists. */ @@ -152,9 +149,7 @@ do { \ %token ATTRIBUTE EXTENSION LABEL %token REALPART IMAGPART VA_ARG CHOOSE_EXPR TYPES_COMPATIBLE_P %token PTR_VALUE PTR_BASE PTR_EXTENT - -/* function name can be a string const or a var decl. */ -%token STRING_FUNC_NAME VAR_FUNC_NAME +%token FUNC_NAME OFFSETOF /* Add precedence rules to solve dangling else s/r conflict */ %nonassoc IF @@ -182,93 +177,98 @@ 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 INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE -%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS +%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 AT_THROW AT_TRY AT_CATCH AT_FINALLY AT_SYNCHRONIZED +%token OBJC_STRING %type unop %type ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT %type BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF -%type identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist -%type expr_no_commas cast_expr unary_expr primary STRING -%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 scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_type_qual +%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 +%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 maybeasm +%type init +%type simple_asm_expr maybeasm asm_stmt asm_argument %type asm_operands nonnull_asm_operands asm_operand asm_clobbers %type maybe_attribute attributes attribute attribute_list attrib -%type any_word extension +%type any_word -%type compstmt compstmt_start compstmt_nostart compstmt_primary_start -%type do_stmt_start poplevel stmt label +%type compstmt compstmt_start compstmt_primary_start +%type stmt label stmt_nocomp start_break start_continue -%type c99_block_start c99_block_end -%type declarator -%type notype_declarator after_type_declarator -%type parm_declarator -%type parm_declarator_starttypename parm_declarator_nostarttypename -%type array_declarator +%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 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 xexpr parms parm firstparm identifiers - -%type parmlist parmlist_1 parmlist_2 -%type parmlist_or_identifiers parmlist_or_identifiers_1 +%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 parm firstparm +%type identifiers + +%type parms parmlist parmlist_1 parmlist_2 +%type parmlist_or_identifiers parmlist_or_identifiers_1 %type identifiers_or_typenames -%type setspecs setspecs_fp +%type setspecs setspecs_fp extension + +%type save_location -%type save_filename -%type save_lineno +%type save_obstack_position -ifobjc +@@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 objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr +%type non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr + +%type CLASSNAME OBJECTNAME OBJC_STRING OBJC_TYPE_QUAL -%type CLASSNAME OBJECTNAME -end ifobjc +%type superclass objc_quals objc_qual objc_typename +%type objc_try_catch_stmt optellipsis +@@end_ifobjc %{ -/* Number of statements (loosely speaking) and compound statements - seen so far. */ -static int stmt_count; -static int compstmt_count; - -/* Input file and line number of the end of the body of last simple_if; - used by the stmt-rule immediately after simple_if returns. */ -static const char *if_stmt_file; -static int if_stmt_line; - -/* 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 @@ -276,50 +276,66 @@ 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 controlled by __extension__. */ -#define SAVE_EXT_FLAGS() \ - size_int (pedantic \ - | (warn_pointer_arith << 1) \ - | (warn_traditional << 2) \ - | (flag_iso << 3)) +#define SAVE_EXT_FLAGS() \ + (pedantic \ + | (warn_pointer_arith << 1) \ + | (warn_traditional << 2) \ + | (flag_iso << 3)) -#define RESTORE_EXT_FLAGS(tval) \ +#define RESTORE_EXT_FLAGS(val) \ do { \ - int val = tree_low_cst (tval, 0); \ pedantic = val & 1; \ warn_pointer_arith = (val >> 1) & 1; \ warn_traditional = (val >> 2) & 1; \ flag_iso = (val >> 3) & 1; \ } while (0) -ifobjc +@@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 @@ -327,29 +343,26 @@ static int objc_pq_context = 0, objc_public_flag = 0; exists. */ static int objc_need_raw_identifier; #define OBJC_NEED_RAW_IDENTIFIER(VAL) objc_need_raw_identifier = VAL -end ifobjc +@@end_ifobjc -ifc +@@ifc #define OBJC_NEED_RAW_IDENTIFIER(VAL) /* nothing */ -end ifc - -static bool parsing_iso_function_signature; +@@end_ifc /* Tell yyparse how to print a token's value, if yydebug is set. */ #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -static void yyprint PARAMS ((FILE *, int, YYSTYPE)); -static void yyerror PARAMS ((const char *)); -static int yylexname PARAMS ((void)); -static int yylexstring PARAMS ((void)); -static inline int _yylex PARAMS ((void)); -static int yylex PARAMS ((void)); -static void init_reswords PARAMS ((void)); +static void yyprint (FILE *, int, YYSTYPE); +static void yyerror (const char *); +static int yylexname (void); +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 () +c_parse_init (void) { init_reswords (); } @@ -360,52 +373,37 @@ c_parse_init () program: /* empty */ { if (pedantic) pedwarn ("ISO C forbids an empty source file"); - finish_file (); } | extdefs - { - /* In case there were missing closebraces, - get us back to the global binding level. */ - while (! global_bindings_p ()) - poplevel (0, 0, 0); - /* __FUNCTION__ is defined at file scope (""). This - call may not be necessary as my tests indicate it - still works without it. */ - finish_fname_decls (); - finish_file (); - } ; /* 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: - extdef_1 - { parsing_iso_function_signature = false; } /* Reset after any external definition. */ - ; - -extdef_1: fndef | datadef -ifobjc - | objcdef -end ifobjc - | ASM_KEYWORD '(' expr ')' ';' - { STRIP_NOPS ($3); - if ((TREE_CODE ($3) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST) - || TREE_CODE ($3) == STRING_CST) - assemble_asm ($3); - else - error ("argument of `asm' is not a constant string"); } + | asmdef | extension extdef { RESTORE_EXT_FLAGS ($1); } +@@ifobjc + | objcdef +@@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: @@ -421,54 +419,51 @@ datadef: | 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 - { store_parm_decls (); } - save_filename save_lineno compstmt_or_error - { DECL_SOURCE_FILE (current_function_decl) = $7; - DECL_SOURCE_LINE (current_function_decl) = $8; - finish_function (0, 1); + old_style_parm_decls save_location + { DECL_SOURCE_LOCATION (current_function_decl) = $6; + store_parm_decls (); } + compstmt_or_error + { finish_function (); POP_DECLSPEC_STACK; } | 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 - { store_parm_decls (); } - save_filename save_lineno compstmt_or_error - { DECL_SOURCE_FILE (current_function_decl) = $7; - DECL_SOURCE_LINE (current_function_decl) = $8; - finish_function (0, 1); + old_style_parm_decls save_location + { DECL_SOURCE_LOCATION (current_function_decl) = $6; + store_parm_decls (); } + compstmt_or_error + { finish_function (); POP_DECLSPEC_STACK; } | 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 - { store_parm_decls (); } - save_filename save_lineno compstmt_or_error - { DECL_SOURCE_FILE (current_function_decl) = $6; - DECL_SOURCE_LINE (current_function_decl) = $7; - finish_function (0, 1); + old_style_parm_decls save_location + { DECL_SOURCE_LOCATION (current_function_decl) = $5; + store_parm_decls (); } + compstmt_or_error + { finish_function (); POP_DECLSPEC_STACK; } | setspecs notype_declarator error { POP_DECLSPEC_STACK; } @@ -477,10 +472,10 @@ fndef: identifier: IDENTIFIER | TYPENAME -ifobjc +@@ifobjc | OBJECTNAME | CLASSNAME -end ifobjc +@@end_ifobjc ; unop: '&' @@ -489,10 +484,10 @@ unop: '&' { $$ = NEGATE_EXPR; } | '+' { $$ = CONVERT_EXPR; -ifc +@@ifc if (warn_traditional && !in_system_header) warning ("traditional C rejects the unary plus operator"); -end ifc +@@end_ifc } | PLUSPLUS { $$ = PREINCREMENT_EXPR; } @@ -504,8 +499,10 @@ end ifc { $$ = TRUTH_NOT_EXPR; } ; -expr: nonnull_exprlist - { $$ = build_compound_expr ($1); } +expr: expr_no_commas + | expr ',' expr_no_commas + { $$.value = build_compound_expr ($1.value, $3.value); + $$.original_code = COMPOUND_EXPR; } ; exprlist: @@ -516,62 +513,74 @@ exprlist: nonnull_exprlist: expr_no_commas - { $$ = build_tree_list (NULL_TREE, $1); } + { $$ = build_tree_list (NULL_TREE, $1.value); } | nonnull_exprlist ',' expr_no_commas - { chainon ($1, build_tree_list (NULL_TREE, $3)); } + { chainon ($1, build_tree_list (NULL_TREE, $3.value)); } ; unary_expr: primary | '*' cast_expr %prec UNARY - { $$ = build_indirect_ref ($2, "unary *"); } + { $$.value = build_indirect_ref ($2.value, "unary *"); + $$.original_code = ERROR_MARK; } /* __extension__ turns off -pedantic for following primary. */ | extension cast_expr %prec UNARY { $$ = $2; RESTORE_EXT_FLAGS ($1); } | unop cast_expr %prec UNARY - { $$ = build_unary_op ($1, $2, 0); - overflow_warning ($$); } + { $$.value = build_unary_op ($1, $2.value, 0); + overflow_warning ($$.value); + $$.original_code = ERROR_MARK; } /* Refer to the address of a label as a pointer. */ | ANDAND identifier - { $$ = finish_label_address_expr ($2); } + { $$.value = finish_label_address_expr ($2); + $$.original_code = ERROR_MARK; } | sizeof unary_expr %prec UNARY { skip_evaluation--; - if (TREE_CODE ($2) == COMPONENT_REF - && DECL_C_BIT_FIELD (TREE_OPERAND ($2, 1))) - error ("`sizeof' applied to a bit-field"); - $$ = c_sizeof (TREE_TYPE ($2)); } + in_sizeof--; + if (TREE_CODE ($2.value) == COMPONENT_REF + && DECL_C_BIT_FIELD (TREE_OPERAND ($2.value, 1))) + error ("% applied to a bit-field"); + $$ = c_expr_sizeof_expr ($2); } | sizeof '(' typename ')' %prec HYPERUNARY { skip_evaluation--; - $$ = c_sizeof (groktypename ($3)); } + in_sizeof--; + $$ = c_expr_sizeof_type ($3); } | alignof unary_expr %prec UNARY { skip_evaluation--; - $$ = c_alignof_expr ($2); } + in_alignof--; + $$.value = c_alignof_expr ($2.value); + $$.original_code = ERROR_MARK; } | alignof '(' typename ')' %prec HYPERUNARY { skip_evaluation--; - $$ = c_alignof (groktypename ($3)); } + in_alignof--; + $$.value = c_alignof (groktypename ($3)); + $$.original_code = ERROR_MARK; } | REALPART cast_expr %prec UNARY - { $$ = build_unary_op (REALPART_EXPR, $2, 0); } + { $$.value = build_unary_op (REALPART_EXPR, $2.value, 0); + $$.original_code = ERROR_MARK; } | IMAGPART cast_expr %prec UNARY - { $$ = build_unary_op (IMAGPART_EXPR, $2, 0); } + { $$.value = build_unary_op (IMAGPART_EXPR, $2.value, 0); + $$.original_code = ERROR_MARK; } ; 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: unary_expr | '(' typename ')' cast_expr %prec UNARY - { $$ = c_cast_expr ($2, $4); } + { $$.value = c_cast_expr ($2, $4.value); + $$.original_code = ERROR_MARK; } ; expr_no_commas: @@ -601,55 +610,51 @@ expr_no_commas: | expr_no_commas '^' expr_no_commas { $$ = parser_build_binary_op ($2, $1, $3); } | expr_no_commas ANDAND - { $1 = c_common_truthvalue_conversion - (default_conversion ($1)); - skip_evaluation += $1 == boolean_false_node; } + { $1.value = lang_hooks.truthvalue_conversion + (default_conversion ($1.value)); + skip_evaluation += $1.value == truthvalue_false_node; } expr_no_commas - { skip_evaluation -= $1 == boolean_false_node; + { skip_evaluation -= $1.value == truthvalue_false_node; $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); } | expr_no_commas OROR - { $1 = c_common_truthvalue_conversion - (default_conversion ($1)); - skip_evaluation += $1 == boolean_true_node; } + { $1.value = lang_hooks.truthvalue_conversion + (default_conversion ($1.value)); + skip_evaluation += $1.value == truthvalue_true_node; } expr_no_commas - { skip_evaluation -= $1 == boolean_true_node; + { skip_evaluation -= $1.value == truthvalue_true_node; $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); } | expr_no_commas '?' - { $1 = c_common_truthvalue_conversion - (default_conversion ($1)); - skip_evaluation += $1 == boolean_false_node; } + { $1.value = lang_hooks.truthvalue_conversion + (default_conversion ($1.value)); + skip_evaluation += $1.value == truthvalue_false_node; } expr ':' - { skip_evaluation += (($1 == boolean_true_node) - - ($1 == boolean_false_node)); } + { skip_evaluation += (($1.value == truthvalue_true_node) + - ($1.value == truthvalue_false_node)); } expr_no_commas - { skip_evaluation -= $1 == boolean_true_node; - $$ = build_conditional_expr ($1, $4, $7); } + { skip_evaluation -= $1.value == truthvalue_true_node; + $$.value = build_conditional_expr ($1.value, $4.value, + $7.value); + $$.original_code = ERROR_MARK; } | expr_no_commas '?' { if (pedantic) pedwarn ("ISO C forbids omitting the middle term of a ?: expression"); /* Make sure first operand is calculated only once. */ - $2 = save_expr ($1); - $1 = c_common_truthvalue_conversion - (default_conversion ($2)); - skip_evaluation += $1 == boolean_true_node; } + $2 = save_expr (default_conversion ($1.value)); + $1.value = lang_hooks.truthvalue_conversion ($2); + skip_evaluation += $1.value == truthvalue_true_node; } ':' expr_no_commas - { skip_evaluation -= $1 == boolean_true_node; - $$ = build_conditional_expr ($1, $2, $5); } + { skip_evaluation -= $1.value == truthvalue_true_node; + $$.value = build_conditional_expr ($1.value, $2, + $5.value); + $$.original_code = ERROR_MARK; } | expr_no_commas '=' expr_no_commas - { char class; - $$ = build_modify_expr ($1, NOP_EXPR, $3); - class = TREE_CODE_CLASS (TREE_CODE ($$)); - if (IS_EXPR_CODE_CLASS (class)) - C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); + { $$.value = build_modify_expr ($1.value, NOP_EXPR, $3.value); + $$.original_code = MODIFY_EXPR; } | expr_no_commas ASSIGN expr_no_commas - { char class; - $$ = build_modify_expr ($1, $2, $3); - /* This inhibits warnings in - c_common_truthvalue_conversion. */ - class = TREE_CODE_CLASS (TREE_CODE ($$)); - if (IS_EXPR_CODE_CLASS (class)) - C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); + { $$.value = build_modify_expr ($1.value, $2, $3.value); + TREE_NO_WARNING ($$.value) = 1; + $$.original_code = ERROR_MARK; } ; @@ -658,147 +663,154 @@ primary: { if (yychar == YYEMPTY) yychar = YYLEX; - $$ = build_external_ref ($1, yychar == '('); + $$.value = build_external_ref ($1, yychar == '('); + $$.original_code = ERROR_MARK; } | CONSTANT + { $$.value = $1; $$.original_code = ERROR_MARK; } | STRING - { $$ = fix_string_type ($$); } - | VAR_FUNC_NAME - { $$ = fname_decl (C_RID_CODE ($$), $$); } + { $$.value = $1; $$.original_code = STRING_CST; } + | FUNC_NAME + { $$.value = fname_decl (C_RID_CODE ($1), $1); + $$.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 - { tree constructor = pop_init_level (0); - tree type = $2; + { struct c_expr init = pop_init_level (0); + tree constructor = init.value; + tree type = $5; finish_init (); + maybe_warn_string_init (type, init); - if (pedantic && ! flag_isoc99) - pedwarn ("ISO C89 forbids compound literals"); - $$ = build_compound_literal (type, constructor); + if (pedantic && !flag_isoc99) + pedwarn ("ISO C90 forbids compound literals"); + $$.value = build_compound_literal (type, constructor); + $$.original_code = ERROR_MARK; } | '(' expr ')' - { char class = TREE_CODE_CLASS (TREE_CODE ($2)); - if (IS_EXPR_CODE_CLASS (class)) - C_SET_EXP_ORIGINAL_CODE ($2, ERROR_MARK); - $$ = $2; } + { $$.value = $2.value; + if (TREE_CODE ($$.value) == MODIFY_EXPR) + TREE_NO_WARNING ($$.value) = 1; + $$.original_code = ERROR_MARK; } | '(' error ')' - { $$ = error_mark_node; } + { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } | compstmt_primary_start compstmt_nostart ')' - { tree saved_last_tree; - - if (pedantic) - pedwarn ("ISO C forbids braced-groups within expressions"); - pop_label_level (); - - saved_last_tree = COMPOUND_BODY ($1); - RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); - last_tree = saved_last_tree; - TREE_CHAIN (last_tree) = NULL_TREE; - if (!last_expr_type) - last_expr_type = void_type_node; - $$ = build1 (STMT_EXPR, last_expr_type, $1); - TREE_SIDE_EFFECTS ($$) = 1; + { if (pedantic) + pedwarn ("ISO C forbids braced-groups within expressions"); + $$.value = c_finish_stmt_expr ($1); + $$.original_code = ERROR_MARK; } | compstmt_primary_start error ')' - { - pop_label_level (); - last_tree = COMPOUND_BODY ($1); - TREE_CHAIN (last_tree) = NULL_TREE; - $$ = error_mark_node; + { c_finish_stmt_expr ($1); + $$.value = error_mark_node; + $$.original_code = ERROR_MARK; } | primary '(' exprlist ')' %prec '.' - { $$ = build_function_call ($1, $3); } + { $$.value = build_function_call ($1.value, $3); + $$.original_code = ERROR_MARK; } | VA_ARG '(' expr_no_commas ',' typename ')' - { $$ = build_va_arg ($3, groktypename ($5)); } + { $$.value = build_va_arg ($3.value, groktypename ($5)); + $$.original_code = ERROR_MARK; } - | CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ',' expr_no_commas ')' + | 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; } + | CHOOSE_EXPR '(' expr_no_commas ',' expr_no_commas ',' + expr_no_commas ')' { tree c; - c = fold ($3); + c = fold ($3.value); STRIP_NOPS (c); if (TREE_CODE (c) != INTEGER_CST) - error ("first argument to __builtin_choose_expr not a constant"); + error ("first argument to __builtin_choose_expr not" + " a constant"); $$ = integer_zerop (c) ? $7 : $5; } - | TYPES_COMPATIBLE_P '(' typename ',' typename ')' + | CHOOSE_EXPR '(' error ')' + { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } + | TYPES_COMPATIBLE_P '(' typename ',' typename ')' { tree e1, e2; e1 = TYPE_MAIN_VARIANT (groktypename ($3)); e2 = TYPE_MAIN_VARIANT (groktypename ($5)); - $$ = comptypes (e1, e2) - ? build_int_2 (1, 0) : build_int_2 (0, 0); + $$.value = comptypes (e1, e2) + ? build_int_cst (NULL_TREE, 1) + : build_int_cst (NULL_TREE, 0); + $$.original_code = ERROR_MARK; } + | TYPES_COMPATIBLE_P '(' error ')' + { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } | primary '[' expr ']' %prec '.' - { $$ = build_array_ref ($1, $3); } + { $$.value = build_array_ref ($1.value, $3.value); + $$.original_code = ERROR_MARK; } | primary '.' identifier - { -ifobjc - if (!is_public ($1, $3)) - $$ = error_mark_node; - else -end ifobjc - $$ = build_component_ref ($1, $3); - } + { $$.value = build_component_ref ($1.value, $3); + $$.original_code = ERROR_MARK; } | primary POINTSAT identifier { - tree expr = build_indirect_ref ($1, "->"); - -ifobjc - if (!is_public (expr, $3)) - $$ = error_mark_node; - else -end ifobjc - $$ = build_component_ref (expr, $3); + tree expr = build_indirect_ref ($1.value, "->"); + $$.value = build_component_ref (expr, $3); + $$.original_code = ERROR_MARK; } | primary PLUSPLUS - { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); } + { $$.value = build_unary_op (POSTINCREMENT_EXPR, $1.value, 0); + $$.original_code = ERROR_MARK; } | primary MINUSMINUS - { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); } -ifobjc + { $$.value = build_unary_op (POSTDECREMENT_EXPR, $1.value, 0); + $$.original_code = ERROR_MARK; } +@@ifobjc | objcmessageexpr - { $$ = build_message_expr ($1); } + { $$.value = objc_build_message_expr ($1); + $$.original_code = ERROR_MARK; } | objcselectorexpr - { $$ = build_selector_expr ($1); } + { $$.value = objc_build_selector_expr ($1); + $$.original_code = ERROR_MARK; } | objcprotocolexpr - { $$ = build_protocol_expr ($1); } + { $$.value = objc_build_protocol_expr ($1); + $$.original_code = ERROR_MARK; } | objcencodeexpr - { $$ = build_encode_expr ($1); } - | objc_string - { $$ = build_objc_string_object ($1); } -end ifobjc + { $$.value = objc_build_encode_expr ($1); + $$.original_code = ERROR_MARK; } + | OBJC_STRING + { $$.value = objc_build_string_object ($1); + $$.original_code = ERROR_MARK; } +@@end_ifobjc ; -ifobjc -/* Produces an STRING_CST with perhaps more STRING_CSTs chained - onto it, which is to be read as an ObjC string object. */ -objc_string: - '@' STRING - { $$ = $2; } - | objc_string '@' STRING - { $$ = chainon ($1, $3); } - ; -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. */ -old_style_parm_decls: - old_style_parm_decls_1 - { - parsing_iso_function_signature = false; /* Reset after decls. */ - } +offsetof_member_designator: + identifier + { $$ = build_component_ref (offsetof_base, $1); } + | offsetof_member_designator '.' identifier + { $$ = build_component_ref ($1, $3); } + | offsetof_member_designator '[' expr ']' + { $$ = build_array_ref ($1, $3.value); } ; -old_style_parm_decls_1: +old_style_parm_decls: /* empty */ - { - if (warn_traditional && !in_system_header - && parsing_iso_function_signature) - warning ("traditional C rejects ISO C style function definitions"); - parsing_iso_function_signature = false; /* Reset after warning. */ - } | datadecls ; @@ -806,7 +818,7 @@ old_style_parm_decls_1: except that they do not allow nested functions. They are used for old-style parm decls. */ lineno_datadecl: - save_filename save_lineno datadecl + save_location datadecl { } ; @@ -827,7 +839,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"); } @@ -838,7 +850,7 @@ datadecl: This is to avoid shift/reduce conflicts in contexts where statement labels are allowed. */ lineno_decl: - save_filename save_lineno decl + save_location decl { } ; @@ -849,8 +861,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; } ; @@ -871,7 +893,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); } ; @@ -887,16 +909,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 @@ -925,334 +937,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. */ @@ -1339,7 +1225,7 @@ declspecs: /* A (possibly empty) sequence of type qualifiers and attributes. */ maybe_type_quals_attrs: /* empty */ - { $$ = NULL_TREE; } + { $$ = NULL; } | declspecs_nosc_nots { $$ = $1; } ; @@ -1363,7 +1249,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 @@ -1376,7 +1262,9 @@ typespec_attr: typespec_reserved_nonattr: TYPESPEC - { OBJC_NEED_RAW_IDENTIFIER (1); } + { OBJC_NEED_RAW_IDENTIFIER (1); + $$.kind = ctsk_resword; + $$.spec = $1; } | structsp_nonattr ; @@ -1388,22 +1276,39 @@ typespec_nonreserved_nonattr: TYPENAME { /* For a typedef name, record the meaning, not the name. In case of `foo foo, bar;'. */ - $$ = lookup_name ($1); } -ifobjc + $$.kind = ctsk_typedef; + $$.spec = lookup_name ($1); } +@@ifobjc | CLASSNAME protocolrefs - { $$ = get_static_reference ($1, $2); } + { $$.kind = ctsk_objc; + $$.spec = objc_get_protocol_qualified_type ($1, $2); } | OBJECTNAME protocolrefs - { $$ = get_object_reference ($2); } + { $$.kind = ctsk_objc; + $$.spec = objc_get_protocol_qualified_type ($1, $2); } /* Make "" equivalent to "id " - nisse@lysator.liu.se */ | non_empty_protocolrefs - { $$ = get_object_reference ($1); } -end ifobjc + { $$.kind = ctsk_objc; + $$.spec = objc_get_protocol_qualified_type (NULL_TREE, $1); } +@@end_ifobjc | typeof '(' expr ')' - { skip_evaluation--; $$ = TREE_TYPE ($3); } + { skip_evaluation--; + in_typeof--; + if (TREE_CODE ($3.value) == COMPONENT_REF + && DECL_C_BIT_FIELD (TREE_OPERAND ($3.value, 1))) + 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. */ @@ -1418,24 +1323,18 @@ notype_initdecls: | notype_initdecls ',' maybe_resetattrs notype_initdcl ; -maybeasm: - /* empty */ - { $$ = NULL_TREE; } - | ASM_KEYWORD '(' STRING ')' - { $$ = $3; } - ; - initdcl: declarator maybeasm maybe_attribute '=' - { $$ = start_decl ($1, current_declspecs, 1, + { $$ = start_decl ($1, current_declspecs, true, chainon ($3, all_prefix_attributes)); start_init ($$, $2, global_bindings_p ()); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_init (); - finish_decl ($5, $6, $2); } + 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); } @@ -1443,15 +1342,16 @@ initdcl: notype_initdcl: notype_declarator maybeasm maybe_attribute '=' - { $$ = start_decl ($1, current_declspecs, 1, + { $$ = start_decl ($1, current_declspecs, true, chainon ($3, all_prefix_attributes)); start_init ($$, $2, global_bindings_p ()); } init /* Note how the declaration of the variable is in effect while its init is parsed! */ { finish_init (); - finish_decl ($5, $6, $2); } + 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); } ; @@ -1459,7 +1359,7 @@ notype_initdcl: so that the header files compile. */ maybe_attribute: /* empty */ - { $$ = NULL_TREE; } + { $$ = NULL_TREE; } | attributes { $$ = $1; } ; @@ -1472,8 +1372,11 @@ attributes: ; attribute: - ATTRIBUTE '(' '(' attribute_list ')' ')' - { $$ = $4; } + ATTRIBUTE stop_string_translation + '(' '(' attribute_list ')' ')' start_string_translation + { $$ = $5; } + | ATTRIBUTE error start_string_translation + { $$ = NULL_TREE; } ; attribute_list: @@ -1515,12 +1418,13 @@ scspec: init: expr_no_commas + { $$ = $1; } | '{' { really_start_incremental_init (NULL_TREE); } initlist_maybe_comma '}' { $$ = pop_init_level (0); } | error - { $$ = error_mark_node; } + { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } ; /* `initlist_maybe_comma' is the guts of an initializer in braces. */ @@ -1540,15 +1444,15 @@ initlist1: It may use braces. */ initelt: designator_list '=' initval - { if (pedantic && ! flag_isoc99) - pedwarn ("ISO C89 forbids specifying subobject to initialize"); } + { if (pedantic && !flag_isoc99) + pedwarn ("ISO C90 forbids specifying subobject to initialize"); } | 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 @@ -1573,73 +1477,71 @@ designator: '.' identifier { set_init_label ($2); } | '[' expr_no_commas ELLIPSIS expr_no_commas ']' - { set_init_index ($2, $4); + { set_init_index ($2.value, $4.value); if (pedantic) pedwarn ("ISO C forbids specifying range of elements to initialize"); } | '[' expr_no_commas ']' - { set_init_index ($2, NULL_TREE); } + { set_init_index ($2.value, NULL_TREE); } ; nested_function: - declarator + declarator { if (pedantic) 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; } - parsing_iso_function_signature = false; /* Don't warn about nested functions. */ - } - old_style_parm_decls - { store_parm_decls (); } -/* This used to use compstmt_or_error. - That caused a bug with input `f(g) int g {}', - where the use of YYERROR1 above caused an error - which then was handled by compstmt_or_error. - There followed a repeated execution of that same rule, - which called YYERROR1 again, and so on. */ - save_filename save_lineno compstmt + } + old_style_parm_decls save_location { tree decl = current_function_decl; - DECL_SOURCE_FILE (decl) = $5; - DECL_SOURCE_LINE (decl) = $6; - finish_function (1, 1); + DECL_SOURCE_LOCATION (decl) = $4; + store_parm_decls (); } + /* This used to use compstmt_or_error. That caused a bug with + input `f(g) int g {}', where the use of YYERROR1 above caused + an error which then was handled by compstmt_or_error. There + followed a repeated execution of that same rule, which called + YYERROR1 again, and so on. */ + compstmt + { tree decl = current_function_decl; + add_stmt ($6); + finish_function (); pop_function_context (); - add_decl_stmt (decl); } + add_stmt (build_stmt (DECL_EXPR, decl)); } ; notype_nested_function: - notype_declarator + notype_declarator { if (pedantic) 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; } - parsing_iso_function_signature = false; /* Don't warn about nested functions. */ - } - old_style_parm_decls - { store_parm_decls (); } -/* This used to use compstmt_or_error. - That caused a bug with input `f(g) int g {}', - where the use of YYERROR1 above caused an error - which then was handled by compstmt_or_error. - There followed a repeated execution of that same rule, - which called YYERROR1 again, and so on. */ - save_filename save_lineno compstmt + } + old_style_parm_decls save_location + { tree decl = current_function_decl; + DECL_SOURCE_LOCATION (decl) = $4; + store_parm_decls (); } + /* This used to use compstmt_or_error. That caused a bug with + input `f(g) int g {}', where the use of YYERROR1 above caused + an error which then was handled by compstmt_or_error. There + followed a repeated execution of that same rule, which called + YYERROR1 again, and so on. */ + compstmt { tree decl = current_function_decl; - DECL_SOURCE_FILE (decl) = $5; - DECL_SOURCE_LINE (decl) = $6; - finish_function (1, 1); + add_stmt ($6); + finish_function (); pop_function_context (); - add_decl_stmt (decl); } + add_stmt (build_stmt (DECL_EXPR, decl)); } ; /* Any kind of declarator (thus, all declarators allowed @@ -1654,20 +1556,19 @@ 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); } -/* | after_type_declarator '(' error ')' %prec '.' - { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); - poplevel (0, 0, 0); } */ + { $$ = 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 + { $$ = build_id_declarator ($1); } +@@ifobjc | OBJECTNAME -end ifobjc + { $$ = build_id_declarator ($1); } +@@end_ifobjc ; /* Kinds of declarator that can appear in a parameter list @@ -1681,32 +1582,28 @@ parm_declarator: parm_declarator_starttypename: parm_declarator_starttypename '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } -/* | parm_declarator_starttypename '(' error ')' %prec '.' - { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); - poplevel (0, 0, 0); } */ + { $$ = 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 + { $$ = build_id_declarator ($1); } +@@ifobjc | OBJECTNAME -end ifobjc + { $$ = build_id_declarator ($1); } +@@end_ifobjc ; parm_declarator_nostarttypename: parm_declarator_nostarttypename '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } -/* | parm_declarator_nostarttypename '(' error ')' %prec '.' - { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); - poplevel (0, 0, 0); } */ + { $$ = 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 @@ -1714,17 +1611,15 @@ parm_declarator_nostarttypename: notype_declarator: notype_declarator '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } -/* | notype_declarator '(' error ')' %prec '.' - { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); - poplevel (0, 0, 0); } */ + { $$ = 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: @@ -1756,46 +1651,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, $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), - $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, $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), - $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: @@ -1806,56 +1711,55 @@ maybecomma: maybecomma_warn: /* empty */ | ',' - { if (pedantic && ! flag_isoc99) + { if (pedantic && !flag_isoc99) pedwarn ("comma at end of enumerator list"); } ; +/* We chain the components in reverse order. They are put in forward + order in structsp_attr. + + Note that component_declarator returns single decls, so components + and components_notype can use TREE_CHAIN directly, wheras components + and components_notype return lists (of comma separated decls), so + component_decl_list and component_decl_list2 must use chainon. + + The theory behind all this is that there will be more semicolon + separated fields than comma separated fields, and so we'll be + minimizing the number of node traversals required by chainon. */ + component_decl_list: component_decl_list2 { $$ = $1; } | component_decl_list2 component_decl - { $$ = chainon ($1, $2); + { $$ = chainon ($2, $1); pedwarn ("no semicolon at end of struct or union"); } ; component_decl_list2: /* empty */ { $$ = NULL_TREE; } | component_decl_list2 component_decl ';' - { $$ = chainon ($1, $2); } + { $$ = chainon ($2, $1); } | component_decl_list2 ';' { if (pedantic) pedwarn ("extra semicolon in struct or union specified"); } -ifobjc +@@ifobjc /* foo(sizeof(struct{ @defs(ClassName)})); */ - | DEFS '(' CLASSNAME ')' - { - tree interface = lookup_interface ($3); - - if (interface) - $$ = get_class_ivars (interface); - else - { - error ("cannot find interface declaration for `%s'", - IDENTIFIER_POINTER ($3)); - $$ = NULL_TREE; - } - } -end ifobjc + | AT_DEFS '(' CLASSNAME ')' + { $$ = nreverse (objc_get_class_ivars ($3)); } +@@end_ifobjc ; component_decl: declspecs_nosc_ts setspecs components { $$ = $3; POP_DECLSPEC_STACK; } - | declspecs_nosc_ts setspecs save_filename save_lineno + | declspecs_nosc_ts setspecs { /* 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($3, $4, 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; @@ -1863,7 +1767,7 @@ component_decl: | declspecs_nosc_nots { if (pedantic) pedwarn ("ISO C forbids member declarations with no members"); - shadow_tag($1); + shadow_tag_warned (finish_declspecs ($1), pedantic); $$ = NULL_TREE; } | error { $$ = NULL_TREE; } @@ -1875,45 +1779,49 @@ component_decl: components: component_declarator | components ',' maybe_resetattrs component_declarator - { $$ = chainon ($1, $4); } + { TREE_CHAIN ($4) = $1; $$ = $4; } ; components_notype: component_notype_declarator | components_notype ',' maybe_resetattrs component_notype_declarator - { $$ = chainon ($1, $4); } + { TREE_CHAIN ($4) = $1; $$ = $4; } ; component_declarator: - save_filename save_lineno declarator maybe_attribute - { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE); - decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); } - | save_filename save_lineno - declarator ':' expr_no_commas maybe_attribute - { $$ = grokfield ($1, $2, $3, current_declspecs, $5); - decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); } - | save_filename save_lineno ':' expr_no_commas maybe_attribute - { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4); - decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); } + declarator maybe_attribute + { $$ = grokfield ($1, current_declspecs, NULL_TREE); + decl_attributes (&$$, + chainon ($2, all_prefix_attributes), 0); } + | declarator ':' expr_no_commas maybe_attribute + { $$ = grokfield ($1, current_declspecs, $3.value); + decl_attributes (&$$, + chainon ($4, all_prefix_attributes), 0); } + | ':' expr_no_commas maybe_attribute + { $$ = grokfield (build_id_declarator (NULL_TREE), + current_declspecs, $2.value); + decl_attributes (&$$, + chainon ($3, all_prefix_attributes), 0); } ; component_notype_declarator: - save_filename save_lineno notype_declarator maybe_attribute - { $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE); - decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); } - | save_filename save_lineno - notype_declarator ':' expr_no_commas maybe_attribute - { $$ = grokfield ($1, $2, $3, current_declspecs, $5); - decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); } - | save_filename save_lineno ':' expr_no_commas maybe_attribute - { $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4); - decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); } + notype_declarator maybe_attribute + { $$ = grokfield ($1, current_declspecs, NULL_TREE); + decl_attributes (&$$, + chainon ($2, all_prefix_attributes), 0); } + | notype_declarator ':' expr_no_commas maybe_attribute + { $$ = grokfield ($1, current_declspecs, $3.value); + decl_attributes (&$$, + chainon ($4, all_prefix_attributes), 0); } + | ':' expr_no_commas maybe_attribute + { $$ = grokfield (build_id_declarator (NULL_TREE), + current_declspecs, $2.value); + decl_attributes (&$$, + chainon ($3, all_prefix_attributes), 0); } ; /* We chain the enumerators in reverse order. - They are put in forward order where enumlist is used. - (The order used to be significant, but no longer is so. - However, we still maintain the order, just to be clean.) */ + They are put in forward order in structsp_attr. */ enumlist: enumerator @@ -1921,7 +1829,7 @@ enumlist: { if ($1 == error_mark_node) $$ = $1; else - $$ = chainon ($3, $1); } + TREE_CHAIN ($3) = $1, $$ = $3; } | error { $$ = error_mark_node; } ; @@ -1931,36 +1839,36 @@ enumerator: identifier { $$ = build_enumerator ($1, NULL_TREE); } | identifier '=' expr_no_commas - { $$ = build_enumerator ($1, $3); } + { $$ = build_enumerator ($1, $3.value); } ; 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 */ @@ -1976,38 +1884,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 ']' - { $$ = build_array_declarator ($3, $2, 0, 0); } + '[' maybe_type_quals_attrs expr_no_commas ']' + { $$ = 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); } - | '[' STATIC maybe_type_quals_attrs expr ']' - { $$ = build_array_declarator ($4, $3, 1, 0); } + { $$ = build_array_declarator (NULL_TREE, $2, false, true); } + | '[' STATIC maybe_type_quals_attrs expr_no_commas ']' + { $$ = build_array_declarator ($4.value, $3, true, false); } /* declspecs_nosc_nots is a synonym for type_quals_attrs. */ - | '[' declspecs_nosc_nots STATIC expr ']' - { $$ = build_array_declarator ($4, $2, 1, 0); } + | '[' declspecs_nosc_nots STATIC expr_no_commas ']' + { $$ = build_array_declarator ($4.value, $2, true, false); } ; /* A nonempty series of declarations and statements (possibly followed by @@ -2021,7 +1932,7 @@ stmts_and_decls: | lineno_stmt_decl_or_labels_ending_decl | lineno_stmt_decl_or_labels_ending_label { - pedwarn ("deprecated use of label at end of compound statement"); + error ("label at end of compound statement"); } | lineno_stmt_decl_or_labels_ending_error ; @@ -2037,8 +1948,11 @@ lineno_stmt_decl_or_labels_ending_stmt: lineno_stmt_decl_or_labels_ending_decl: lineno_decl | lineno_stmt_decl_or_labels_ending_stmt lineno_decl - { if (pedantic && !flag_isoc99) - pedwarn ("ISO C89 forbids mixed declarations and code"); } + { + if ((pedantic && !flag_isoc99) + || warn_declaration_after_statement) + pedwarn_c90 ("ISO C90 forbids mixed declarations and code"); + } | lineno_stmt_decl_or_labels_ending_decl lineno_decl | lineno_stmt_decl_or_labels_ending_error lineno_decl ; @@ -2066,53 +1980,9 @@ lineno_stmt_decl_or_labels: errstmt: error ';' ; -pushlevel: /* empty */ - { pushlevel (0); - clear_last_expr (); - add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); -ifobjc - if (objc_method_context) - add_objc_decls (); -end ifobjc - } - ; - -poplevel: /* empty */ - { $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); } - ; - /* Start and end blocks created for the new scopes of C99. */ c99_block_start: /* empty */ - { if (flag_isoc99) - { - $$ = c_begin_compound_stmt (); - pushlevel (0); - clear_last_expr (); - add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); -ifobjc - if (objc_method_context) - add_objc_decls (); -end ifobjc - } - else - $$ = NULL_TREE; - } - ; - -/* Productions using c99_block_start and c99_block_end will need to do what's - in compstmt: RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); $$ = $2; where - $1 is the value of c99_block_start and $2 of c99_block_end. */ -c99_block_end: /* empty */ - { if (flag_isoc99) - { - tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); - $$ = poplevel (kept_level_p (), 0, 0); - SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt)) - = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt)) - = $$; - } - else - $$ = NULL_TREE; } + { $$ = c_begin_compound_stmt (flag_isoc99); } ; /* Read zero or more forward-declarations for labels @@ -2134,9 +2004,9 @@ label_decl: { tree link; for (link = $2; link; link = TREE_CHAIN (link)) { - tree label = shadow_label (TREE_VALUE (link)); + tree label = declare_label (TREE_VALUE (link)); C_DECLARED_LABEL_FLAG (label) = 1; - add_decl_stmt (label); + add_stmt (build_stmt (DECL_EXPR, label)); } } ; @@ -2145,21 +2015,15 @@ label_decl: It causes syntax errors to ignore to the next openbrace. */ compstmt_or_error: compstmt - {} + { add_stmt ($1); } | error compstmt ; -compstmt_start: '{' { compstmt_count++; - $$ = c_begin_compound_stmt (); } +compstmt_start: '{' { $$ = c_begin_compound_stmt (true); } ; compstmt_nostart: '}' - { $$ = convert (void_type_node, integer_zero_node); } - | pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel - { $$ = poplevel (kept_level_p (), 1, 0); - SCOPE_STMT_BLOCK (TREE_PURPOSE ($5)) - = SCOPE_STMT_BLOCK (TREE_VALUE ($5)) - = $$; } + | maybe_label_decls compstmt_contents_nonempty '}' ; compstmt_contents_nonempty: @@ -2171,260 +2035,267 @@ compstmt_primary_start: '(' '{' { if (current_function_decl == 0) { - error ("braced-group within expression allowed only inside a function"); + error ("braced-group within expression allowed " + "only inside a function"); YYERROR; } - /* We must force a BLOCK for this level - so that, if it is not expanded later, - there is a way to turn off the entire subtree of blocks - that are contained in it. */ - keep_next_level (); - push_label_level (); - compstmt_count++; - $$ = add_stmt (build_stmt (COMPOUND_STMT, last_tree)); + $$ = c_begin_stmt_expr (); } ; compstmt: compstmt_start compstmt_nostart - { RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); - last_expr_type = NULL_TREE; - $$ = $1; } - ; - -/* Value is number of statements counted as of the closeparen. */ -simple_if: - if_prefix c99_block_lineno_labeled_stmt - { c_finish_then (); } -/* Make sure c_expand_end_cond is run once - for each call to c_expand_start_cond. - Otherwise a crash is likely. */ - | if_prefix error - ; - -if_prefix: - /* We must build the IF_STMT node before parsing its - condition so that STMT_LINENO refers to the line - containing the "if", and not the line containing - the close-parenthesis. - - c_begin_if_stmt returns the IF_STMT node, which - we later pass to c_expand_start_cond to fill - in the condition and other tidbits. */ - IF - { $$ = c_begin_if_stmt (); } - '(' expr ')' - { c_expand_start_cond (c_common_truthvalue_conversion ($4), - compstmt_count,$2); - $$ = stmt_count; - if_stmt_file = $-2; - if_stmt_line = $-1; } - ; - -/* This is a subroutine of stmt. - It is used twice, once for valid DO statements - and once for catching errors in parsing the end test. */ -do_stmt_start: - DO - { stmt_count++; - compstmt_count++; - $$ - = add_stmt (build_stmt (DO_STMT, NULL_TREE, - NULL_TREE)); - /* In the event that a parse error prevents - parsing the complete do-statement, set the - condition now. Otherwise, we can get crashes at - RTL-generation time. */ - DO_COND ($$) = error_mark_node; } - c99_block_lineno_labeled_stmt WHILE - { $$ = $2; - RECHAIN_STMTS ($$, DO_BODY ($$)); } + { $$ = c_end_compound_stmt ($1, true); } ; /* The forced readahead in here is because we might be at the end of a line, and the line and file won't be bumped until yylex absorbs the first token on the next line. */ -save_filename: - { if (yychar == YYEMPTY) - yychar = YYLEX; - $$ = input_filename; } - ; -save_lineno: +save_location: { if (yychar == YYEMPTY) yychar = YYLEX; - $$ = lineno; } + $$ = input_location; } ; -lineno_labeled_stmt: - lineno_stmt - | lineno_label lineno_labeled_stmt +lineno_labels: + /* empty */ + | lineno_labels lineno_label ; -/* Like lineno_labeled_stmt, but a block in C99. */ +/* A labeled statement. In C99 it also generates an implicit block. */ c99_block_lineno_labeled_stmt: - c99_block_start lineno_labeled_stmt c99_block_end - { if (flag_isoc99) - RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); } + c99_block_start lineno_labels lineno_stmt + { $$ = c_end_compound_stmt ($1, flag_isoc99); } ; lineno_stmt: - save_filename save_lineno stmt - { if ($3) - { - STMT_LINENO ($3) = $2; - /* ??? We currently have no way of recording - the filename for a statement. This probably - matters little in practice at the moment, - but I suspect that problems will occur when - doing inlining at the tree level. */ - } + save_location stmt + { + /* Two cases cannot and do not have line numbers associated: + 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, + or discarded. If stmt was compound, but without new + variables, we will have skipped the creation of a BIND + and will have a bare STATEMENT_LIST. But that's ok + because (recursively) all of the component statments + should already have line numbers assigned. */ + if ($2 && EXPR_P ($2)) + SET_EXPR_LOCATION ($2, $1); } ; lineno_label: - save_filename save_lineno label - { if ($3) - { - STMT_LINENO ($3) = $2; - } - } + save_location label + { if ($2) SET_EXPR_LOCATION ($2, $1); } ; -select_or_iter_stmt: - simple_if ELSE - { c_expand_start_else (); - $1 = stmt_count; } - c99_block_lineno_labeled_stmt - { c_finish_else (); - c_expand_end_cond (); - if (extra_warnings && stmt_count == $1) - warning ("empty body in an else-statement"); } - | simple_if %prec IF - { c_expand_end_cond (); - /* This warning is here instead of in simple_if, because we - do not want a warning if an empty if is followed by an - else statement. Increment stmt_count so we don't - give a second error if this is a nested `if'. */ - if (extra_warnings && stmt_count++ == $1) - warning_with_file_and_line (if_stmt_file, if_stmt_line, - "empty body in an if-statement"); } -/* Make sure c_expand_end_cond is run once - for each call to c_expand_start_cond. - Otherwise a crash is likely. */ - | simple_if ELSE error - { c_expand_end_cond (); } - /* We must build the WHILE_STMT node before parsing its - condition so that STMT_LINENO refers to the line - containing the "while", and not the line containing - the close-parenthesis. - - c_begin_while_stmt returns the WHILE_STMT node, which - we later pass to c_finish_while_stmt_cond to fill - in the condition and other tidbits. */ - | WHILE - { stmt_count++; - $$ = c_begin_while_stmt (); } - '(' expr ')' - { $4 = c_common_truthvalue_conversion ($4); - c_finish_while_stmt_cond - (c_common_truthvalue_conversion ($4), $2); - $$ = add_stmt ($2); } - c99_block_lineno_labeled_stmt - { RECHAIN_STMTS ($6, WHILE_BODY ($6)); } - | do_stmt_start - '(' expr ')' ';' - { DO_COND ($1) = c_common_truthvalue_conversion ($3); } - | do_stmt_start error - { } - | FOR - { $$ = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE, - NULL_TREE, NULL_TREE); - add_stmt ($$); } - '(' for_init_stmt - { stmt_count++; - RECHAIN_STMTS ($2, FOR_INIT_STMT ($2)); } - xexpr ';' - { if ($6) - FOR_COND ($2) - = c_common_truthvalue_conversion ($6); } - xexpr ')' - { FOR_EXPR ($2) = $9; } - c99_block_lineno_labeled_stmt - { RECHAIN_STMTS ($2, FOR_BODY ($2)); } - | SWITCH '(' expr ')' - { stmt_count++; - $$ = c_start_case ($3); } - c99_block_lineno_labeled_stmt - { c_finish_case (); } +condition: save_location expr + { $$ = lang_hooks.truthvalue_conversion ($2.value); + if (EXPR_P ($$)) + SET_EXPR_LOCATION ($$, $1); } + ; + +/* Implement -Wparenthesis by special casing IF statement directly nested + within IF statement. This requires some amount of duplication of the + productions under c99_block_lineno_labeled_stmt in order to work out. + But it's still likely more maintainable than lots of state outside the + parser... */ + +if_statement_1: + c99_block_start lineno_labels if_statement + { $$ = c_end_compound_stmt ($1, flag_isoc99); } + ; + +if_statement_2: + c99_block_start lineno_labels ';' + { if (extra_warnings) + add_stmt (build (NOP_EXPR, NULL_TREE, NULL_TREE)); + $$ = c_end_compound_stmt ($1, flag_isoc99); } + | c99_block_lineno_labeled_stmt + ; + +if_statement: + IF c99_block_start save_location '(' condition ')' + if_statement_1 ELSE if_statement_2 + { c_finish_if_stmt ($3, $5, $7, $9, true); + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } + | IF c99_block_start save_location '(' condition ')' + if_statement_2 ELSE if_statement_2 + { c_finish_if_stmt ($3, $5, $7, $9, false); + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } + | IF c99_block_start save_location '(' condition ')' + if_statement_1 %prec IF + { c_finish_if_stmt ($3, $5, $7, NULL, true); + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } + | IF c99_block_start save_location '(' condition ')' + if_statement_2 %prec IF + { c_finish_if_stmt ($3, $5, $7, NULL, false); + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } + ; + +start_break: /* empty */ + { $$ = c_break_label; c_break_label = NULL; } + ; + +start_continue: /* empty */ + { $$ = c_cont_label; c_cont_label = NULL; } + ; + +while_statement: + WHILE c99_block_start save_location '(' condition ')' + start_break start_continue c99_block_lineno_labeled_stmt + { c_finish_loop ($3, $5, NULL, $9, c_break_label, + c_cont_label, true); + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); + c_break_label = $7; c_cont_label = $8; } + ; + +do_statement: + DO c99_block_start save_location start_break start_continue + c99_block_lineno_labeled_stmt WHILE + { $$ = c_break_label; c_break_label = $4; } + { $$ = c_cont_label; c_cont_label = $5; } + '(' condition ')' ';' + { c_finish_loop ($3, $11, NULL, $6, $8, + $9, false); + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } + ; + +xexpr: + /* empty */ + { $$ = NULL_TREE; } + | expr + { $$ = $1.value; } ; for_init_stmt: xexpr ';' - { add_stmt (build_stmt (EXPR_STMT, $1)); } + { c_finish_expr_stmt ($1); } | decl { check_for_loop_decls (); } ; -/* Parse a single real statement, not including any labels. */ -stmt: - compstmt - { stmt_count++; $$ = $1; } - | expr ';' - { stmt_count++; - $$ = c_expand_expr_stmt ($1); } - | c99_block_start select_or_iter_stmt c99_block_end - { if (flag_isoc99) - RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); - $$ = NULL_TREE; } +for_cond_expr: save_location xexpr + { if ($2) + { + $$ = lang_hooks.truthvalue_conversion ($2); + if (EXPR_P ($$)) + SET_EXPR_LOCATION ($$, $1); + } + else + $$ = NULL; + } + ; + +for_incr_expr: xexpr + { $$ = c_process_expr_stmt ($1); } + ; + +for_statement: + FOR c99_block_start '(' for_init_stmt + save_location for_cond_expr ';' for_incr_expr ')' + start_break start_continue c99_block_lineno_labeled_stmt + { c_finish_loop ($5, $6, $8, $12, c_break_label, + c_cont_label, true); + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); + c_break_label = $10; c_cont_label = $11; } + ; + +switch_statement: + SWITCH c99_block_start '(' expr ')' + { $$ = c_start_case ($4.value); } + start_break c99_block_lineno_labeled_stmt + { c_finish_case ($8); + if (c_break_label) + add_stmt (build (LABEL_EXPR, void_type_node, + c_break_label)); + c_break_label = $7; + add_stmt (c_end_compound_stmt ($2, flag_isoc99)); } + ; + +/* Parse a single real statement, not including any labels or compounds. */ +stmt_nocomp: + expr ';' + { $$ = c_finish_expr_stmt ($1.value); } + | if_statement + { $$ = NULL_TREE; } + | while_statement + { $$ = NULL_TREE; } + | do_statement + { $$ = NULL_TREE; } + | for_statement + { $$ = NULL_TREE; } + | switch_statement + { $$ = NULL_TREE; } | BREAK ';' - { stmt_count++; - $$ = add_stmt (build_break_stmt ()); } + { $$ = c_finish_bc_stmt (&c_break_label, true); } | CONTINUE ';' - { stmt_count++; - $$ = add_stmt (build_continue_stmt ()); } + { $$ = c_finish_bc_stmt (&c_cont_label, false); } | RETURN ';' - { stmt_count++; - $$ = c_expand_return (NULL_TREE); } + { $$ = c_finish_return (NULL_TREE); } | RETURN expr ';' - { stmt_count++; - $$ = c_expand_return ($2); } - | ASM_KEYWORD maybe_type_qual '(' expr ')' ';' - { stmt_count++; - $$ = simple_asm_stmt ($4); } - /* This is the case with just output operands. */ - | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';' - { stmt_count++; - $$ = build_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); } - /* This is the case with input operands as well. */ - | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' - asm_operands ')' ';' - { stmt_count++; - $$ = build_asm_stmt ($2, $4, $6, $8, NULL_TREE); } - /* This is the case with clobbered registers as well. */ - | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':' - asm_operands ':' asm_clobbers ')' ';' - { stmt_count++; - $$ = build_asm_stmt ($2, $4, $6, $8, $10); } + { $$ = c_finish_return ($2.value); } + | asm_stmt | GOTO identifier ';' - { tree decl; - stmt_count++; - decl = lookup_label ($2); - if (decl != 0) - { - TREE_USED (decl) = 1; - $$ = add_stmt (build_stmt (GOTO_STMT, decl)); - } - else - $$ = NULL_TREE; - } + { $$ = c_finish_goto_label ($2); } | GOTO '*' expr ';' - { if (pedantic) - pedwarn ("ISO C forbids `goto *expr;'"); - stmt_count++; - $3 = convert (ptr_type_node, $3); - $$ = add_stmt (build_stmt (GOTO_STMT, $3)); } + { $$ = c_finish_goto_ptr ($3.value); } | ';' { $$ = NULL_TREE; } +@@ifobjc + | AT_THROW expr ';' + { $$ = objc_build_throw_stmt ($2.value); } + | AT_THROW ';' + { $$ = objc_build_throw_stmt (NULL_TREE); } + | objc_try_catch_stmt + { $$ = NULL_TREE; } + | AT_SYNCHRONIZED save_location '(' expr ')' compstmt + { objc_build_synchronized ($2, $4.value, $6); $$ = NULL_TREE; } + ; + +objc_catch_prefix: + AT_CATCH '(' parm ')' + { objc_begin_catch_clause (grokparm ($3)); } + ; + +objc_catch_clause: + objc_catch_prefix '{' compstmt_nostart + { objc_finish_catch_clause (); } + | objc_catch_prefix '{' error '}' + { objc_finish_catch_clause (); } + ; + +objc_opt_catch_list: + /* empty */ + | objc_opt_catch_list objc_catch_clause + ; + +objc_try_catch_clause: + AT_TRY save_location compstmt + { objc_begin_try_stmt ($2, $3); } + objc_opt_catch_list + ; + +objc_finally_clause: + AT_FINALLY save_location compstmt + { objc_build_finally_clause ($2, $3); } + ; + +objc_try_catch_stmt: + objc_try_catch_clause + { objc_finish_try_stmt (); } + | objc_try_catch_clause objc_finally_clause + { objc_finish_try_stmt (); } +@@end_ifobjc + ; + +/* Parse a single or compound real statement, not including any labels. */ +stmt: + compstmt + { add_stmt ($1); $$ = NULL_TREE; } + | stmt_nocomp ; /* Any kind of label, including jump labels and case labels. @@ -2432,41 +2303,85 @@ stmt: also at the end of a compound statement. */ label: CASE expr_no_commas ':' - { stmt_count++; - $$ = do_case ($2, NULL_TREE); } + { $$ = do_case ($2.value, NULL_TREE); } | CASE expr_no_commas ELLIPSIS expr_no_commas ':' - { stmt_count++; - $$ = do_case ($2, $4); } + { $$ = do_case ($2.value, $4.value); } | DEFAULT ':' - { stmt_count++; - $$ = do_case (NULL_TREE, NULL_TREE); } - | identifier save_filename save_lineno ':' maybe_attribute - { tree label = define_label ($2, $3, $1); - stmt_count++; + { $$ = do_case (NULL_TREE, NULL_TREE); } + | identifier save_location ':' maybe_attribute + { tree label = define_label ($2, $1); if (label) { - decl_attributes (&label, $5, 0); - $$ = add_stmt (build_stmt (LABEL_STMT, label)); + decl_attributes (&label, $4, 0); + $$ = add_stmt (build_stmt (LABEL_EXPR, label)); } else $$ = NULL_TREE; } ; -/* Either a type-qualifier or nothing. First thing in an `asm' statement. */ +/* Asm expressions and statements */ -maybe_type_qual: - /* empty */ - { emit_line_note (input_filename, lineno); - $$ = NULL_TREE; } - | TYPE_QUAL - { emit_line_note (input_filename, lineno); } +/* simple_asm_expr is used in restricted contexts, where a full + expression with inputs and outputs does not make sense. */ +simple_asm_expr: + ASM_KEYWORD stop_string_translation + '(' STRING ')' start_string_translation + { $$ = $4; } ; -xexpr: - /* empty */ +/* maybeasm: used for assembly names for declarations */ +maybeasm: + /* empty */ { $$ = NULL_TREE; } - | expr + | simple_asm_expr + ; + +/* asmdef: asm() outside a function body. */ +asmdef: + simple_asm_expr ';' + { assemble_asm ($1); } + | ASM_KEYWORD error start_string_translation ';' + {} + ; + +/* Full-blown asm statement with inputs, outputs, clobbers, and + volatile tag allowed. */ +asm_stmt: + ASM_KEYWORD maybe_volatile stop_string_translation + '(' asm_argument ')' start_string_translation ';' + { $$ = build_asm_stmt ($2, $5); } + ; + +asm_argument: + /* no operands */ + STRING + { $$ = build_asm_expr ($1, 0, 0, 0, true); } + /* output operands */ + | STRING ':' asm_operands + { $$ = build_asm_expr ($1, $3, 0, 0, false); } + /* output and input operands */ + | 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 + { $$ = build_asm_expr ($1, $3, $5, $7, false); } + ; + +/* Either 'volatile' or nothing. First thing in an `asm' statement. */ + +maybe_volatile: + /* empty */ + { $$ = 0; } + | TYPE_QUAL + { if ($1 != ridpointers[RID_VOLATILE]) + { + warning ("%E qualifier ignored on asm", $1); + $$ = 0; + } + else + $$ = $1; + } ; /* These are the operands other than the first string and colon @@ -2483,12 +2398,14 @@ nonnull_asm_operands: ; asm_operand: - STRING '(' expr ')' - { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $3); } - | '[' identifier ']' STRING '(' expr ')' + STRING start_string_translation '(' expr ')' stop_string_translation + { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), + $4.value); } + | '[' identifier ']' STRING start_string_translation + '(' expr ')' stop_string_translation { $2 = build_string (IDENTIFIER_LENGTH ($2), IDENTIFIER_POINTER ($2)); - $$ = build_tree_list (build_tree_list ($2, $4), $6); } + $$ = build_tree_list (build_tree_list ($2, $4), $7.value); } ; asm_clobbers: @@ -2497,6 +2414,15 @@ asm_clobbers: | asm_clobbers ',' STRING { $$ = tree_cons (NULL_TREE, $3, $1); } ; + +stop_string_translation: + { c_lex_string_translate = 0; } + ; + +start_string_translation: + { c_lex_string_translate = 1; } + ; + /* This is what appears inside the parens in a function declarator. Its value is a list of ..._TYPE nodes. Attributes must appear here @@ -2505,54 +2431,51 @@ asm_clobbers: "void bar (int (__attribute__((__mode__(SI))) int foo));". */ parmlist: maybe_attribute - { pushlevel (0); - clear_parm_order (); - declare_parm_level (0); } + { push_scope (); + declare_parm_level (); } parmlist_1 { $$ = $3; - parmlist_tags_warning (); - poplevel (0, 0, 0); } + pop_scope (); } ; parmlist_1: parmlist_2 ')' | parms ';' - { tree parm; - if (pedantic) - pedwarn ("ISO C forbids forward parameter declarations"); - /* Mark the forward decls as such. */ - for (parm = getdecls (); parm; parm = TREE_CHAIN (parm)) - TREE_ASM_WRITTEN (parm) = 1; - clear_parm_order (); } + { mark_forward_parm_decls (); } maybe_attribute { /* Dummy action so attributes are in known place on parser stack. */ } parmlist_1 { $$ = $6; } | error ')' - { $$ = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE); } + { $$ = 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 */ - { $$ = get_parm_info (0); } + { $$ = XOBNEW (&parser_obstack, struct c_arg_info); + $$->parms = 0; + $$->tags = 0; + $$->types = 0; + $$->others = 0; } | ELLIPSIS - { $$ = get_parm_info (0); - /* Gcc used to allow this as an extension. However, it does - not work for all targets, and thus has been disabled. - Also, since func (...) and func () are indistinguishable, - it caused problems with the code in expand_builtin which - tries to verify that BUILT_IN_NEXT_ARG is being used - correctly. */ - error ("ISO C requires a named argument before `...'"); + { $$ = XOBNEW (&parser_obstack, struct c_arg_info); + $$->parms = 0; + $$->tags = 0; + $$->others = 0; + /* Suppress -Wold-style-definition for this case. */ + $$->types = error_mark_node; + error ("ISO C requires a named argument before %<...%>"); } | parms - { $$ = get_parm_info (1); - parsing_iso_function_signature = true; - } + { $$ = get_parm_info (/*ellipsis=*/false); } | parms ',' ELLIPSIS - { $$ = get_parm_info (0); } + { $$ = get_parm_info (/*ellipsis=*/true); } ; parms: @@ -2566,22 +2489,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 @@ -2593,22 +2513,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 @@ -2627,29 +2544,24 @@ setspecs_fp: Its value is a list of ..._TYPE nodes or a list of identifiers. */ parmlist_or_identifiers: maybe_attribute - { pushlevel (0); - clear_parm_order (); - declare_parm_level (1); } + { push_scope (); + declare_parm_level (); } parmlist_or_identifiers_1 { $$ = $3; - parmlist_tags_warning (); - poplevel (0, 0, 0); } + pop_scope (); } ; 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; } ; @@ -2672,14 +2584,14 @@ identifiers_or_typenames: extension: EXTENSION - { $$ = SAVE_EXT_FLAGS(); + { $$ = SAVE_EXT_FLAGS (); pedantic = 0; warn_pointer_arith = 0; warn_traditional = 0; flag_iso = 0; } ; -ifobjc +@@ifobjc /* Objective-C productions. */ objcdef: @@ -2688,16 +2600,9 @@ objcdef: | aliasdecl | protocoldef | methoddef - | END + | 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 (); } ; @@ -2710,159 +2615,82 @@ identifier_list: ; classdecl: - CLASS identifier_list ';' + AT_CLASS identifier_list ';' { objc_declare_class ($2); } ; aliasdecl: - ALIAS identifier identifier ';' + AT_ALIAS identifier identifier ';' { objc_declare_alias ($2, $3); } ; -classdef: - INTERFACE identifier protocolrefs '{' - { - objc_interface_context = objc_ivar_context - = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3); - objc_public_flag = 0; - } - ivar_decl_list '}' - { - continue_class (objc_interface_context); - } - methodprotolist - END - { - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - } - - | INTERFACE identifier protocolrefs - { - objc_interface_context - = start_class (CLASS_INTERFACE_TYPE, $2, NULL_TREE, $3); - continue_class (objc_interface_context); - } - methodprotolist - END - { - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - } - - | INTERFACE identifier ':' identifier protocolrefs '{' - { - objc_interface_context = objc_ivar_context - = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5); - objc_public_flag = 0; - } - ivar_decl_list '}' - { - continue_class (objc_interface_context); - } - methodprotolist - END - { - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - } +superclass: + ':' identifier { $$ = $2; } + | /* NULL */ %prec HYPERUNARY { $$ = NULL_TREE; } + ; - | INTERFACE identifier ':' identifier protocolrefs - { - objc_interface_context - = start_class (CLASS_INTERFACE_TYPE, $2, $4, $5); - continue_class (objc_interface_context); - } - methodprotolist - END - { - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; - } +class_ivars: + '{' ivar_decl_list '}' + | /* NULL */ + ; - | IMPLEMENTATION identifier '{' +classdef: + AT_INTERFACE identifier superclass protocolrefs { - objc_implementation_context = objc_ivar_context - = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE); - objc_public_flag = 0; + objc_start_class_interface ($2, $3, $4); } - ivar_decl_list '}' + class_ivars { - objc_ivar_chain - = continue_class (objc_implementation_context); + objc_continue_interface (); } - - | IMPLEMENTATION identifier + methodprotolist AT_END { - objc_implementation_context - = start_class (CLASS_IMPLEMENTATION_TYPE, $2, NULL_TREE, NULL_TREE); - objc_ivar_chain - = continue_class (objc_implementation_context); + objc_finish_interface (); } - | IMPLEMENTATION identifier ':' identifier '{' + | AT_IMPLEMENTATION identifier superclass { - objc_implementation_context = objc_ivar_context - = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); - objc_public_flag = 0; + objc_start_class_implementation ($2, $3); } - ivar_decl_list '}' + class_ivars { - objc_ivar_chain - = continue_class (objc_implementation_context); + objc_continue_implementation (); } - | IMPLEMENTATION identifier ':' identifier + | AT_INTERFACE identifier '(' identifier ')' protocolrefs { - objc_implementation_context - = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); - objc_ivar_chain - = continue_class (objc_implementation_context); + objc_start_category_interface ($2, $4, $6); } - - | INTERFACE identifier '(' identifier ')' protocolrefs - { - objc_interface_context - = start_class (CATEGORY_INTERFACE_TYPE, $2, $4, $6); - continue_class (objc_interface_context); - } - methodprotolist - END + methodprotolist AT_END { - finish_class (objc_interface_context); - objc_interface_context = NULL_TREE; + objc_finish_interface (); } - | IMPLEMENTATION identifier '(' identifier ')' + | 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); } ; protocoldef: - PROTOCOL identifier protocolrefs + AT_PROTOCOL identifier protocolrefs { objc_pq_context = 1; - objc_interface_context - = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3); + objc_start_protocol ($2, $3); } - methodprotolist END + 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 favor of the production 'identifier_list -> identifier'. */ - | PROTOCOL identifier_list ';' + | AT_PROTOCOL identifier_list ';' { objc_declare_protocols ($2); } @@ -2887,110 +2715,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: - PRIVATE { objc_public_flag = 2; } - | PROTECTED { objc_public_flag = 0; } - | 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); - } - | ':' expr_no_commas +opt_semi: + /* NULL */ + | ';' { - $$ = add_instance_variable (objc_ivar_context, - objc_public_flag, - NULL_TREE, - current_declspecs, $2); - } + 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; - if (objc_inherit_code == CLASS_METHOD_DECL) - add_class_method (objc_implementation_context, $3); - else - add_instance_method (objc_implementation_context, $3); - 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); } ; @@ -3000,14 +2785,8 @@ methoddef: methodprotolist: /* empty */ - | {$$ = NULL_TREE; } methodprotolist2 - ; - -methodprotolist2: /* eliminates a shift/reduce conflict */ - methodproto - | datadef - | methodprotolist2 methodproto - | methodprotolist2 {$$ = NULL_TREE; } datadef + | methodprotolist methodproto + | methodprotolist { $$ = NULL_TREE; } datadef ; semi_or_error: @@ -3018,6 +2797,7 @@ semi_or_error: methodproto: methodtype { + objc_set_method_type ($1); /* Remember protocol qualifiers in prototypes. */ objc_pq_context = 1; } @@ -3025,110 +2805,63 @@ methodproto: { /* Forget protocol qualifiers here. */ objc_pq_context = 0; - if (objc_inherit_code == CLASS_METHOD_DECL) - add_class_method (objc_interface_context, $3); - else - add_instance_method (objc_interface_context, $3); + 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 */ { - pushlevel (0); + $$ = 0; } - parmlist_2 + | ',' ELLIPSIS { - /* returns a tree list node generated by get_parm_info */ - $$ = $3; - poplevel (0, 0, 0); + $$ = 1; } ; @@ -3154,31 +2887,57 @@ selector: ; 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 ; +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); } ; @@ -3221,9 +2980,14 @@ keywordarg: receiver: expr + { $$ = $1.value; } | CLASSNAME { - $$ = get_class_reference ($1); + $$ = objc_get_class_reference ($1); + } + | TYPENAME + { + $$ = objc_get_class_reference ($1); } ; @@ -3257,14 +3021,14 @@ keywordname: ; objcselectorexpr: - SELECTOR '(' selectorarg ')' + AT_SELECTOR '(' selectorarg ')' { $$ = $3; } ; objcprotocolexpr: - PROTOCOL '(' identifier ')' + AT_PROTOCOL '(' identifier ')' { $$ = $3; } @@ -3273,13 +3037,13 @@ objcprotocolexpr: /* extension to support C-structures in the archiver */ objcencodeexpr: - ENCODE '(' typename ')' + AT_ENCODE '(' typename ')' { $$ = groktypename ($3); } ; -end ifobjc +@@end_ifobjc %% /* yylex() is a thin wrapper around c_lex(), all it does is translate @@ -3314,9 +3078,8 @@ static const struct resword reswords[] = { "__asm__", RID_ASM, 0 }, { "__attribute", RID_ATTRIBUTE, 0 }, { "__attribute__", RID_ATTRIBUTE, 0 }, - { "__bounded", RID_BOUNDED, 0 }, - { "__bounded__", RID_BOUNDED, 0 }, { "__builtin_choose_expr", RID_CHOOSE_EXPR, 0 }, + { "__builtin_offsetof", RID_OFFSETOF, 0 }, { "__builtin_types_compatible_p", RID_TYPES_COMPATIBLE_P, 0 }, { "__builtin_va_arg", RID_VA_ARG, 0 }, { "__complex", RID_COMPLEX, 0 }, @@ -3345,8 +3108,6 @@ static const struct resword reswords[] = { "__thread", RID_THREAD, 0 }, { "__typeof", RID_TYPEOF, 0 }, { "__typeof__", RID_TYPEOF, 0 }, - { "__unbounded", RID_UNBOUNDED, 0 }, - { "__unbounded__", RID_UNBOUNDED, 0 }, { "__volatile", RID_VOLATILE, 0 }, { "__volatile__", RID_VOLATILE, 0 }, { "asm", RID_ASM, D_EXT }, @@ -3385,7 +3146,8 @@ static const struct resword reswords[] = { "void", RID_VOID, 0 }, { "volatile", RID_VOLATILE, 0 }, { "while", RID_WHILE, 0 }, -ifobjc + +@@ifobjc { "id", RID_ID, D_OBJC }, /* These objc keywords are recognized only immediately after @@ -3402,7 +3164,11 @@ ifobjc { "protocol", RID_AT_PROTOCOL, D_OBJC }, { "public", RID_AT_PUBLIC, D_OBJC }, { "selector", RID_AT_SELECTOR, D_OBJC }, - + { "throw", RID_AT_THROW, D_OBJC }, + { "try", RID_AT_TRY, D_OBJC }, + { "catch", RID_AT_CATCH, D_OBJC }, + { "finally", RID_AT_FINALLY, D_OBJC }, + { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC }, /* These are recognized only in protocol-qualifier context (see above) */ { "bycopy", RID_BYCOPY, D_OBJC }, @@ -3411,7 +3177,7 @@ ifobjc { "inout", RID_INOUT, D_OBJC }, { "oneway", RID_ONEWAY, D_OBJC }, { "out", RID_OUT, D_OBJC }, -end ifobjc +@@end_ifobjc }; #define N_reswords (sizeof reswords / sizeof (struct resword)) @@ -3435,8 +3201,6 @@ static const short rid_to_yy[RID_MAX] = /* RID_RESTRICT */ TYPE_QUAL, /* C extensions */ - /* RID_BOUNDED */ TYPE_QUAL, - /* RID_UNBOUNDED */ TYPE_QUAL, /* RID_COMPLEX */ TYPESPEC, /* RID_THREAD */ SCSPEC, @@ -3448,12 +3212,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, @@ -3495,9 +3259,9 @@ static const short rid_to_yy[RID_MAX] = /* RID_CHOOSE_EXPR */ CHOOSE_EXPR, /* RID_TYPES_COMPATIBLE_P */ TYPES_COMPATIBLE_P, - /* RID_FUNCTION_NAME */ STRING_FUNC_NAME, - /* RID_PRETTY_FUNCTION_NAME */ STRING_FUNC_NAME, - /* RID_C99_FUNCTION_NAME */ VAR_FUNC_NAME, + /* RID_FUNCTION_NAME */ FUNC_NAME, + /* RID_PRETTY_FUNCTION_NAME */ FUNC_NAME, + /* RID_C99_FUNCTION_NAME */ FUNC_NAME, /* C++ */ /* RID_BOOL */ TYPESPEC, @@ -3513,6 +3277,7 @@ static const short rid_to_yy[RID_MAX] = /* RID_FALSE */ 0, /* RID_NAMESPACE */ 0, /* RID_NEW */ 0, + /* RID_OFFSETOF */ OFFSETOF, /* RID_OPERATOR */ 0, /* RID_THIS */ 0, /* RID_THROW */ 0, @@ -3530,35 +3295,37 @@ static const short rid_to_yy[RID_MAX] = /* Objective C */ /* RID_ID */ OBJECTNAME, - /* RID_AT_ENCODE */ ENCODE, - /* RID_AT_END */ END, - /* RID_AT_CLASS */ CLASS, - /* RID_AT_ALIAS */ ALIAS, - /* RID_AT_DEFS */ DEFS, - /* RID_AT_PRIVATE */ PRIVATE, - /* RID_AT_PROTECTED */ PROTECTED, - /* RID_AT_PUBLIC */ PUBLIC, - /* RID_AT_PROTOCOL */ PROTOCOL, - /* RID_AT_SELECTOR */ SELECTOR, - /* RID_AT_INTERFACE */ INTERFACE, - /* RID_AT_IMPLEMENTATION */ IMPLEMENTATION + /* RID_AT_ENCODE */ AT_ENCODE, + /* RID_AT_END */ AT_END, + /* RID_AT_CLASS */ AT_CLASS, + /* RID_AT_ALIAS */ AT_ALIAS, + /* RID_AT_DEFS */ AT_DEFS, + /* RID_AT_PRIVATE */ AT_PRIVATE, + /* RID_AT_PROTECTED */ AT_PROTECTED, + /* RID_AT_PUBLIC */ AT_PUBLIC, + /* RID_AT_PROTOCOL */ AT_PROTOCOL, + /* RID_AT_SELECTOR */ AT_SELECTOR, + /* RID_AT_THROW */ AT_THROW, + /* RID_AT_TRY */ AT_TRY, + /* RID_AT_CATCH */ AT_CATCH, + /* RID_AT_FINALLY */ AT_FINALLY, + /* RID_AT_SYNCHRONIZED */ AT_SYNCHRONIZED, + /* RID_AT_INTERFACE */ AT_INTERFACE, + /* RID_AT_IMPLEMENTATION */ AT_IMPLEMENTATION }; static void -init_reswords () +init_reswords (void) { unsigned int i; tree id; int mask = (flag_isoc99 ? 0 : D_C89) | (flag_no_asm ? (flag_isoc99 ? D_EXT : D_EXT|D_EXT89) : 0); - if (!flag_objc) + if (!c_dialect_objc ()) mask |= D_OBJC; - /* It is not necessary to register ridpointers as a GC root, because - all the trees it points to are permanently interned in the - get_identifier hash anyway. */ - ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree)); + ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX); for (i = 0; i < N_reswords; i++) { /* If a keyword is disabled, do not enter it into the table @@ -3576,48 +3343,26 @@ init_reswords () #define NAME(type) cpp_type2name (type) static void -yyerror (msgid) - const char *msgid; +yyerror (const char *msgid) { - const char *string = _(msgid); - - if (last_token == CPP_EOF) - error ("%s at end of input", string); - else if (last_token == CPP_CHAR || last_token == CPP_WCHAR) - { - unsigned int val = TREE_INT_CST_LOW (yylval.ttype); - const char *const ell = (last_token == CPP_CHAR) ? "" : "L"; - if (val <= UCHAR_MAX && ISGRAPH (val)) - error ("%s before %s'%c'", string, ell, val); - else - error ("%s before %s'\\x%x'", string, ell, val); - } - else if (last_token == CPP_STRING - || last_token == CPP_WSTRING) - error ("%s before string constant", string); - else if (last_token == CPP_NUMBER) - error ("%s before numeric constant", string); - else if (last_token == CPP_NAME) - error ("%s before \"%s\"", string, IDENTIFIER_POINTER (yylval.ttype)); - else - error ("%s before '%s' token", string, NAME(last_token)); + c_parse_error (msgid, last_token, yylval.ttype); } static int -yylexname () +yylexname (void) { tree decl; -ifobjc +@@ifobjc int objc_force_identifier = objc_need_raw_identifier; OBJC_NEED_RAW_IDENTIFIER (0); -end ifobjc +@@end_ifobjc if (C_IS_RESERVED_WORD (yylval.ttype)) { enum rid rid_code = C_RID_CODE (yylval.ttype); -ifobjc +@@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) @@ -3629,24 +3374,11 @@ ifobjc if (!OBJC_IS_AT_KEYWORD (rid_code) && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context)) -end ifobjc +@@end_ifobjc { - int yycode = rid_to_yy[(int) rid_code]; - if (yycode == STRING_FUNC_NAME) - { - /* __FUNCTION__ and __PRETTY_FUNCTION__ get converted - to string constants. */ - const char *name = fname_string (rid_code); - - yylval.ttype = build_string (strlen (name) + 1, name); - C_ARTIFICIAL_STRING_P (yylval.ttype) = 1; - last_token = CPP_STRING; /* so yyerror won't choke */ - return STRING; - } - /* Return the canonical spelling for this keyword. */ yylval.ttype = ridpointers[(int) rid_code]; - return yycode; + return rid_to_yy[(int) rid_code]; } } @@ -3656,10 +3388,10 @@ end ifobjc if (TREE_CODE (decl) == TYPE_DECL) return TYPENAME; } -ifobjc +@@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 @@ -3670,65 +3402,13 @@ ifobjc return CLASSNAME; } } -end ifobjc +@@end_ifobjc return IDENTIFIER; } -/* Concatenate strings before returning them to the parser. This isn't quite - as good as having it done in the lexer, but it's better than nothing. */ - -static int -yylexstring () -{ - enum cpp_ttype next_type; - tree orig = yylval.ttype; - - next_type = c_lex (&yylval.ttype); - if (next_type == CPP_STRING - || next_type == CPP_WSTRING - || (next_type == CPP_NAME && yylexname () == STRING)) - { - varray_type strings; - -ifc - static int last_lineno = 0; - static const char *last_input_filename = 0; - if (warn_traditional && !in_system_header - && (lineno != last_lineno || !last_input_filename || - strcmp (last_input_filename, input_filename))) - { - warning ("traditional C rejects string concatenation"); - last_lineno = lineno; - last_input_filename = input_filename; - } -end ifc - - VARRAY_TREE_INIT (strings, 32, "strings"); - VARRAY_PUSH_TREE (strings, orig); - - do - { - VARRAY_PUSH_TREE (strings, yylval.ttype); - next_type = c_lex (&yylval.ttype); - } - while (next_type == CPP_STRING - || next_type == CPP_WSTRING - || (next_type == CPP_NAME && yylexname () == STRING)); - - yylval.ttype = combine_strings (strings); - } - else - yylval.ttype = orig; - - /* We will have always read one token too many. */ - _cpp_backup_tokens (parse_in, 1); - - return STRING; -} - static inline int -_yylex () +_yylex (void) { get_next: last_token = c_lex (&yylval.ttype); @@ -3792,13 +3472,11 @@ _yylex () return 0; case CPP_NAME: - { - int ret = yylexname (); - if (ret == STRING) - return yylexstring (); - else - return ret; - } + return yylexname (); + + case CPP_AT_NAME: + /* This only happens in Objective-C; it must be a keyword. */ + return rid_to_yy [(int) C_RID_CODE (yylval.ttype)]; case CPP_NUMBER: case CPP_CHAR: @@ -3807,30 +3485,10 @@ _yylex () case CPP_STRING: case CPP_WSTRING: - return yylexstring (); + return STRING; - /* This token is Objective-C specific. It gives the next token - special significance. */ - case CPP_ATSIGN: -ifobjc - { - tree after_at; - enum cpp_ttype after_at_type; - - after_at_type = c_lex (&after_at); - - if (after_at_type == CPP_NAME - && C_IS_RESERVED_WORD (after_at) - && OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at))) - { - yylval.ttype = after_at; - last_token = after_at_type; - return rid_to_yy [(int) C_RID_CODE (after_at)]; - } - _cpp_backup_tokens (parse_in, 1); - return '@'; - } -end ifobjc + case CPP_OBJC_STRING: + return OBJC_STRING; /* These tokens are C++ specific (and will not be generated in C mode, but let's be cautious). */ @@ -3844,7 +3502,7 @@ end ifobjc /* 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: @@ -3854,7 +3512,7 @@ end ifobjc } static int -yylex() +yylex (void) { int r; timevar_push (TV_LEX); @@ -3866,10 +3524,7 @@ yylex() /* Function used when yydebug is set, to print a token in more detail. */ static void -yyprint (file, yychar, yyl) - FILE *file; - int yychar; - YYSTYPE yyl; +yyprint (FILE *file, int yychar, YYSTYPE yyl) { tree t = yyl.ttype; @@ -3885,48 +3540,53 @@ yyprint (file, yychar, yyl) case SCSPEC: case STATIC: if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); + fprintf (file, " '%s'", IDENTIFIER_POINTER (t)); break; case CONSTANT: fprintf (file, " %s", GET_MODE_NAME (TYPE_MODE (TREE_TYPE (t)))); if (TREE_CODE (t) == INTEGER_CST) - fprintf (file, -#if HOST_BITS_PER_WIDE_INT == 64 -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT - " 0x%x%016x", -#else -#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG - " 0x%lx%016lx", -#else - " 0x%llx%016llx", -#endif -#endif -#else -#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT - " 0x%lx%08lx", -#else - " 0x%x%08x", -#endif -#endif - TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t)); + { + fputs (" ", file); + fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX, + TREE_INT_CST_HIGH (t), TREE_INT_CST_LOW (t)); + } break; } } -/* This is not the ideal place to put these, but we have to get them out - of c-lex.c because cp/lex.c has its own versions. */ - -/* Free malloced parser stacks if necessary. */ +/* This is not the ideal place to put this, but we have to get it out + of c-lex.c because cp/lex.c has its own version. */ +/* Parse the file. */ void -free_parser_stacks () +c_parse_file (void) { + yyparse (); + if (malloced_yyss) { free (malloced_yyss); free (malloced_yyvs); + malloced_yyss = 0; } } +#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"