X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fc-parse.in;h=16cbd228908cd7e3b928e060ee0a5d674f22b021;hp=08badedb0022c97a6e01ede2d9e08856792cf1f3;hb=7016c6128fa54ae4f68077da816fe0744cb8a852;hpb=3ed275a69c65d1f323feab80baf7f4f4e961783d diff --git a/gcc/c-parse.in b/gcc/c-parse.in index 08badedb002..16cbd228908 100644 --- a/gcc/c-parse.in +++ b/gcc/c-parse.in @@ -29,7 +29,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA written by AT&T, but I have never seen it. */ @@ifc -%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */ +%expect 13 /* shift/reduce conflicts, and no reduce/reduce conflicts. */ @@end_ifc %{ @@ -102,7 +102,7 @@ do { \ %start program -%union {long itype; tree ttype; enum tree_code code; +%union {long itype; tree ttype; struct c_expr exprtype; enum tree_code code; location_t location; } /* All identifiers that are not reserved words @@ -174,8 +174,9 @@ 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 @@ -183,8 +184,9 @@ do { \ %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 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 @@ -202,16 +204,18 @@ do { \ %type offsetof_member_designator %type scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile -%type initdecls notype_initdecls initdcl notype_initdcl init +%type initdecls notype_initdecls initdcl notype_initdcl +%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 -%type compstmt compstmt_start compstmt_nostart compstmt_primary_start -%type do_stmt_start pop_scope 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 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 @@ -226,7 +230,8 @@ do { \ %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 condition xexpr for_cond_expr for_incr_expr +%type parms parm firstparm identifiers %type parmlist parmlist_1 parmlist_2 %type parmlist_or_identifiers parmlist_or_identifiers_1 @@ -250,20 +255,9 @@ do { \ %type CLASSNAME OBJECTNAME OBJC_STRING %type superclass -%type objc_try_catch_stmt objc_finally_block @@end_ifobjc %{ -/* Number of statements (loosely speaking) and compound statements - seen so far. */ -static int stmt_count; -static int compstmt_count; - -/* Input location of the end of the body of last simple_if; - used by the stmt-rule immediately after simple_if returns. */ -static location_t if_stmt_locus; - - /* List of types and structure classes of the current declaration. */ static GTY(()) tree current_declspecs; static GTY(()) tree prefix_attributes; @@ -470,8 +464,10 @@ unop: '&' { $$ = 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: @@ -482,44 +478,53 @@ 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))) + if (TREE_CODE ($2.value) == COMPONENT_REF + && DECL_C_BIT_FIELD (TREE_OPERAND ($2.value, 1))) error ("`sizeof' applied to a bit-field"); - $$ = c_sizeof (TREE_TYPE ($2)); } + $$.value = c_sizeof (TREE_TYPE ($2.value)); + $$.original_code = ERROR_MARK; } | sizeof '(' typename ')' %prec HYPERUNARY { skip_evaluation--; - $$ = c_sizeof (groktypename ($3)); } + $$.value = c_sizeof (groktypename ($3)); + $$.original_code = ERROR_MARK; } | alignof unary_expr %prec UNARY { skip_evaluation--; - $$ = c_alignof_expr ($2); } + $$.value = c_alignof_expr ($2.value); + $$.original_code = ERROR_MARK; } | alignof '(' typename ')' %prec HYPERUNARY { skip_evaluation--; - $$ = c_alignof (groktypename ($3)); } + $$.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: @@ -537,7 +542,8 @@ 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: @@ -567,54 +573,51 @@ expr_no_commas: | expr_no_commas '^' expr_no_commas { $$ = parser_build_binary_op ($2, $1, $3); } | expr_no_commas ANDAND - { $1 = lang_hooks.truthvalue_conversion - (default_conversion ($1)); - skip_evaluation += $1 == truthvalue_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 == truthvalue_false_node; + { skip_evaluation -= $1.value == truthvalue_false_node; $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); } | expr_no_commas OROR - { $1 = lang_hooks.truthvalue_conversion - (default_conversion ($1)); - skip_evaluation += $1 == truthvalue_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 == truthvalue_true_node; + { skip_evaluation -= $1.value == truthvalue_true_node; $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); } | expr_no_commas '?' - { $1 = lang_hooks.truthvalue_conversion - (default_conversion ($1)); - skip_evaluation += $1 == truthvalue_false_node; } + { $1.value = lang_hooks.truthvalue_conversion + (default_conversion ($1.value)); + skip_evaluation += $1.value == truthvalue_false_node; } expr ':' - { skip_evaluation += (($1 == truthvalue_true_node) - - ($1 == truthvalue_false_node)); } + { skip_evaluation += (($1.value == truthvalue_true_node) + - ($1.value == truthvalue_false_node)); } expr_no_commas - { skip_evaluation -= $1 == truthvalue_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 (default_conversion ($1)); - $1 = lang_hooks.truthvalue_conversion ($2); - skip_evaluation += $1 == truthvalue_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 == truthvalue_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; } ; @@ -623,68 +626,68 @@ 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 + { $$.value = $1; $$.original_code = STRING_CST; } | FUNC_NAME - { $$ = fname_decl (C_RID_CODE ($$), $$); } + { $$.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); } initlist_maybe_comma '}' %prec UNARY - { tree constructor = pop_init_level (0); + { struct c_expr init = pop_init_level (0); + tree constructor = init.value; tree type = $2; finish_init (); + maybe_warn_string_init (type, init); if (pedantic && ! flag_isoc99) pedwarn ("ISO C90 forbids compound literals"); - $$ = build_compound_literal (type, constructor); + $$.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"); - 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; - annotate_with_locus ($$, input_location); + { if (pedantic) + pedwarn ("ISO C forbids braced-groups within expressions"); + $$.value = c_finish_stmt_expr ($1); + $$.original_code = ERROR_MARK; } | compstmt_primary_start error ')' - { - 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; } | OFFSETOF '(' typename ',' offsetof_member_designator ')' - { $$ = build_offsetof (groktypename ($3), $5); } + { $$.value = build_offsetof (groktypename ($3), $5); + $$.original_code = ERROR_MARK; } | OFFSETOF '(' error ')' - { $$ = error_mark_node; } + { $$.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" @@ -692,7 +695,7 @@ primary: $$ = integer_zerop (c) ? $7 : $5; } | CHOOSE_EXPR '(' error ')' - { $$ = error_mark_node; } + { $$.value = error_mark_node; $$.original_code = ERROR_MARK; } | TYPES_COMPATIBLE_P '(' typename ',' typename ')' { tree e1, e2; @@ -700,35 +703,47 @@ primary: 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 ')' - { $$ = error_mark_node; } + { $$.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 - { $$ = 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, "->"); - $$ = 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); } + { $$.value = build_unary_op (POSTDECREMENT_EXPR, $1.value, 0); + $$.original_code = ERROR_MARK; } @@ifobjc | objcmessageexpr - { $$ = build_message_expr ($1); } + { $$.value = build_message_expr ($1); + $$.original_code = ERROR_MARK; } | objcselectorexpr - { $$ = build_selector_expr ($1); } + { $$.value = build_selector_expr ($1); + $$.original_code = ERROR_MARK; } | objcprotocolexpr - { $$ = build_protocol_expr ($1); } + { $$.value = build_protocol_expr ($1); + $$.original_code = ERROR_MARK; } | objcencodeexpr - { $$ = build_encode_expr ($1); } + { $$.value = build_encode_expr ($1); + $$.original_code = ERROR_MARK; } | OBJC_STRING - { $$ = build_objc_string_object ($1); } + { $$.value = build_objc_string_object ($1); + $$.original_code = ERROR_MARK; } @@end_ifobjc ; @@ -744,7 +759,7 @@ offsetof_member_designator: | offsetof_member_designator '.' identifier { $$ = tree_cons ($3, NULL_TREE, $1); } | offsetof_member_designator '[' expr ']' - { $$ = tree_cons (NULL_TREE, $3, $1); } + { $$ = tree_cons (NULL_TREE, $3.value, $1); } ; old_style_parm_decls: @@ -1343,19 +1358,19 @@ typespec_nonreserved_nonattr: | CLASSNAME protocolrefs { $$ = get_static_reference ($1, $2); } | OBJECTNAME protocolrefs - { $$ = get_object_reference ($2); } + { $$ = get_protocol_reference ($2); } /* Make "" equivalent to "id " - nisse@lysator.liu.se */ | non_empty_protocolrefs - { $$ = get_object_reference ($1); } + { $$ = get_protocol_reference ($1); } @@end_ifobjc | typeof '(' expr ')' { skip_evaluation--; - if (TREE_CODE ($3) == COMPONENT_REF - && DECL_C_BIT_FIELD (TREE_OPERAND ($3, 1))) + if (TREE_CODE ($3.value) == COMPONENT_REF + && DECL_C_BIT_FIELD (TREE_OPERAND ($3.value, 1))) error ("`typeof' applied to a bit-field"); - $$ = TREE_TYPE ($3); } + $$ = TREE_TYPE ($3.value); } | typeof '(' typename ')' { skip_evaluation--; $$ = groktypename ($3); } ; @@ -1374,15 +1389,16 @@ notype_initdecls: 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); } @@ -1390,15 +1406,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); } ; @@ -1465,12 +1482,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. */ @@ -1523,15 +1541,15 @@ 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"); @@ -1543,25 +1561,25 @@ nested_function: YYERROR1; } } - old_style_parm_decls save_location + 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 + /* 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"); @@ -1573,21 +1591,21 @@ notype_nested_function: YYERROR1; } } - old_style_parm_decls save_location + 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 + /* 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)); } ; /* Any kind of declarator (thus, all declarators allowed @@ -1602,11 +1620,11 @@ declarator: after_type_declarator: '(' maybe_attribute after_type_declarator ')' - { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; } + { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } | after_type_declarator '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | after_type_declarator array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | '*' maybe_type_quals_attrs after_type_declarator %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | TYPENAME @@ -1626,9 +1644,9 @@ parm_declarator: parm_declarator_starttypename: parm_declarator_starttypename '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | parm_declarator_starttypename array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | TYPENAME @@ifobjc | OBJECTNAME @@ -1637,15 +1655,15 @@ parm_declarator_starttypename: parm_declarator_nostarttypename: parm_declarator_nostarttypename '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | parm_declarator_nostarttypename array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | '*' maybe_type_quals_attrs parm_declarator_starttypename %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | '*' maybe_type_quals_attrs parm_declarator_nostarttypename %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | '(' maybe_attribute parm_declarator_nostarttypename ')' - { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; } + { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } ; /* A declarator allowed whether or not there has been @@ -1653,13 +1671,13 @@ parm_declarator_nostarttypename: notype_declarator: notype_declarator '(' parmlist_or_identifiers %prec '.' - { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); } + { $$ = build_function_declarator ($3, $1); } | '(' maybe_attribute notype_declarator ')' - { $$ = $2 ? tree_cons ($2, $3, NULL_TREE) : $3; } + { $$ = $2 ? build_attrs_declarator ($2, $3) : $3; } | '*' maybe_type_quals_attrs notype_declarator %prec UNARY { $$ = make_pointer_declarator ($2, $3); } | notype_declarator array_declarator %prec '.' - { $$ = set_array_declarator_type ($2, $1, 0); } + { $$ = set_array_declarator_inner ($2, $1, false); } | IDENTIFIER ; @@ -1777,7 +1795,7 @@ component_decl_list2: /* empty */ pedwarn ("extra semicolon in struct or union specified"); } @@ifobjc /* foo(sizeof(struct{ @defs(ClassName)})); */ - | DEFS '(' CLASSNAME ')' + | AT_DEFS '(' CLASSNAME ')' { $$ = nreverse (get_class_ivars_from_name ($3)); } @@end_ifobjc ; @@ -1829,11 +1847,11 @@ component_declarator: decl_attributes (&$$, chainon ($2, all_prefix_attributes), 0); } | declarator ':' expr_no_commas maybe_attribute - { $$ = grokfield ($1, current_declspecs, $3); + { $$ = grokfield ($1, current_declspecs, $3.value); decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); } | ':' expr_no_commas maybe_attribute - { $$ = grokfield (NULL_TREE, current_declspecs, $2); + { $$ = grokfield (NULL_TREE, current_declspecs, $2.value); decl_attributes (&$$, chainon ($3, all_prefix_attributes), 0); } ; @@ -1844,11 +1862,11 @@ component_notype_declarator: decl_attributes (&$$, chainon ($2, all_prefix_attributes), 0); } | notype_declarator ':' expr_no_commas maybe_attribute - { $$ = grokfield ($1, current_declspecs, $3); + { $$ = grokfield ($1, current_declspecs, $3.value); decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); } | ':' expr_no_commas maybe_attribute - { $$ = grokfield (NULL_TREE, current_declspecs, $2); + { $$ = grokfield (NULL_TREE, current_declspecs, $2.value); decl_attributes (&$$, chainon ($3, all_prefix_attributes), 0); } ; @@ -1872,7 +1890,7 @@ enumerator: identifier { $$ = build_enumerator ($1, NULL_TREE); } | identifier '=' expr_no_commas - { $$ = build_enumerator ($1, $3); } + { $$ = build_enumerator ($1, $3.value); } ; typename: @@ -1891,17 +1909,15 @@ absdcl: /* an absolute declarator */ 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, + 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 */ @@ -1924,31 +1940,31 @@ absdcl1_ea: 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, NULL_TREE); } | array_declarator - { $$ = set_array_declarator_type ($1, NULL_TREE, 1); } + { $$ = set_array_declarator_inner ($1, NULL_TREE, true); } ; /* The [...] part of a declarator for an array type. */ array_declarator: '[' maybe_type_quals_attrs expr_no_commas ']' - { $$ = build_array_declarator ($3, $2, 0, 0); } + { $$ = build_array_declarator ($3.value, $2, false, false); } | '[' maybe_type_quals_attrs ']' - { $$ = build_array_declarator (NULL_TREE, $2, 0, 0); } + { $$ = build_array_declarator (NULL_TREE, $2, false, false); } | '[' maybe_type_quals_attrs '*' ']' - { $$ = build_array_declarator (NULL_TREE, $2, 0, 1); } + { $$ = build_array_declarator (NULL_TREE, $2, false, true); } | '[' STATIC maybe_type_quals_attrs expr_no_commas ']' - { $$ = build_array_declarator ($4, $3, 1, 0); } + { $$ = build_array_declarator ($4.value, $3, true, false); } /* declspecs_nosc_nots is a synonym for type_quals_attrs. */ | '[' declspecs_nosc_nots STATIC expr_no_commas ']' - { $$ = build_array_declarator ($4, $2, 1, 0); } + { $$ = build_array_declarator ($4.value, $2, true, false); } ; /* A nonempty series of declarations and statements (possibly followed by @@ -2010,51 +2026,9 @@ lineno_stmt_decl_or_labels: errstmt: error ';' ; -push_scope: /* empty */ - { push_scope (); - clear_last_expr (); - add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); - } - ; - -pop_scope: /* empty */ - { -@@ifobjc - if (c_dialect_objc ()) - objc_clear_super_receiver (); -@@end_ifobjc - $$ = 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 (); - push_scope (); - clear_last_expr (); - add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); - } - 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); - $$ = pop_scope (); - 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 @@ -2078,7 +2052,7 @@ label_decl: { tree label = declare_label (TREE_VALUE (link)); C_DECLARED_LABEL_FLAG (label) = 1; - add_decl_stmt (label); + add_stmt (build_stmt (DECL_EXPR, label)); } } ; @@ -2087,21 +2061,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); } - | push_scope maybe_label_decls compstmt_contents_nonempty '}' pop_scope - { $$ = pop_scope (); - SCOPE_STMT_BLOCK (TREE_PURPOSE ($5)) - = SCOPE_STMT_BLOCK (TREE_VALUE ($5)) - = $$; } + | maybe_label_decls compstmt_contents_nonempty '}' ; compstmt_contents_nonempty: @@ -2113,74 +2081,16 @@ 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 (); - compstmt_count++; - $$ = add_stmt (build_stmt (COMPOUND_STMT, last_tree)); - last_expr_type = NULL_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 EXPR_LOCUS 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 (lang_hooks.truthvalue_conversion ($4), - compstmt_count,$2); - $$ = stmt_count; - if_stmt_locus = $-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++; - c_in_iteration_stmt++; - $$ - = 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_in_iteration_stmt--; } + { $$ = c_end_compound_stmt ($1, true); } ; /* The forced readahead in here is because we might be at the end of a @@ -2193,256 +2103,263 @@ save_location: $$ = 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_location stmt - { if ($2) - { - SET_EXPR_LOCUS ($2, NULL); - annotate_with_locus ($2, $1); - } + { + /* 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_location label - { if ($2) - { - SET_EXPR_LOCUS ($2, NULL); - annotate_with_locus ($2, $1); - } - } + { 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 ("%Hempty body in an if-statement", - &if_stmt_locus); } -/* 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 EXPR_LOCUS 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 ')' - { c_in_iteration_stmt++; - $4 = lang_hooks.truthvalue_conversion ($4); - c_finish_while_stmt_cond - (lang_hooks.truthvalue_conversion ($4), $2); - $$ = add_stmt ($2); } - c99_block_lineno_labeled_stmt - { c_in_iteration_stmt--; - RECHAIN_STMTS ($6, WHILE_BODY ($6)); } - | do_stmt_start - '(' expr ')' ';' - { DO_COND ($1) = lang_hooks.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) - = lang_hooks.truthvalue_conversion ($6); } - xexpr ')' - { c_in_iteration_stmt++; - FOR_EXPR ($2) = $9; } - c99_block_lineno_labeled_stmt - { RECHAIN_STMTS ($2, FOR_BODY ($2)); - c_in_iteration_stmt--;} - | SWITCH '(' expr ')' - { stmt_count++; - $$ = c_start_case ($3); - c_in_case_stmt++; } - c99_block_lineno_labeled_stmt - { c_finish_case (); - c_in_case_stmt--; } +condition: save_location expr + { $$ = lang_hooks.truthvalue_conversion ($2.value); + if (EXPR_P ($$)) + SET_EXPR_LOCATION ($$, $1); } ; -for_init_stmt: - xexpr ';' - { add_stmt (build_stmt (EXPR_STMT, $1)); } - | decl - { check_for_loop_decls (); } +/* 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; } ; -/* 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_init_stmt: + xexpr ';' + { c_finish_expr_stmt ($1); } + | decl + { check_for_loop_decls (); } + ; + +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++; - if (!(c_in_iteration_stmt || c_in_case_stmt)) - { - error ("break statement not within loop or switch"); - $$ = NULL_TREE; - } - else - $$ = add_stmt (build_break_stmt ()); } + { $$ = c_finish_bc_stmt (&c_break_label, true); } | CONTINUE ';' - { stmt_count++; - if (!c_in_iteration_stmt) - { - error ("continue statement not within a loop"); - $$ = NULL_TREE; - } - else - $$ = 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); } + { $$ = 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 ';' - { stmt_count++; - $$ = objc_build_throw_stmt ($2); - } + { $$ = objc_build_throw_stmt ($2.value); } | AT_THROW ';' - { stmt_count++; - $$ = objc_build_throw_stmt (NULL_TREE); - } + { $$ = objc_build_throw_stmt (NULL_TREE); } | objc_try_catch_stmt - { objc_build_finally_prologue (); } - objc_finally_block - { $$ = objc_build_try_catch_finally_stmt ($1, $3); } - | AT_SYNCHRONIZED '(' expr ')' - { objc_build_synchronized_prologue ($3); } - compstmt - { $$ = objc_build_synchronized_epilogue (); } + { $$ = NULL_TREE; } + | AT_SYNCHRONIZED save_location '(' expr ')' compstmt + { objc_build_synchronized ($2, $4.value, $6); $$ = NULL_TREE; } ; -objc_try_catch_stmt: - objc_try_stmt - { objc_build_try_epilogue (1); } - objc_catch_list - { objc_build_catch_epilogue (); $$ = 1; } - | objc_try_stmt - { objc_build_try_epilogue (0); $$ = 0; } +objc_catch_prefix: + AT_CATCH '(' parm ')' + { objc_begin_catch_clause ($3); } ; +objc_catch_clause: + objc_catch_prefix '{' compstmt_nostart + { objc_finish_catch_clause (); } + | objc_catch_prefix '{' error '}' + { objc_finish_catch_clause (); } + ; -objc_try_stmt: - AT_TRY - { objc_build_try_prologue (); } - compstmt +objc_opt_catch_list: + /* empty */ + | objc_opt_catch_list objc_catch_clause ; -objc_catch_list: - objc_catch_list objc_catch_block - | objc_catch_block +objc_try_catch_clause: + AT_TRY save_location compstmt + { objc_begin_try_stmt ($2, $3); } + objc_opt_catch_list ; -objc_catch_block: - AT_CATCH '(' parm ')' - { objc_build_catch_stmt ($3); } - compstmt - { stmt_count++; } +objc_finally_clause: + AT_FINALLY save_location compstmt + { objc_build_finally_clause ($2, $3); } ; -objc_finally_block: - AT_FINALLY compstmt - { $$ = 1; } - | /* NULL */ - { $$ = 0; } +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. ANSI C accepts labels only before statements, but we allow them 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); } + { $$ = do_case (NULL_TREE, NULL_TREE); } | identifier save_location ':' maybe_attribute { tree label = define_label ($2, $1); - stmt_count++; if (label) { decl_attributes (&label, $4, 0); - $$ = add_stmt (build_stmt (LABEL_STMT, label)); + $$ = add_stmt (build_stmt (LABEL_EXPR, label)); } else $$ = NULL_TREE; @@ -2479,8 +2396,7 @@ asmdef: asm_stmt: ASM_KEYWORD maybe_volatile stop_string_translation '(' asm_argument ')' start_string_translation ';' - { stmt_count++; - $$ = build_asm_stmt ($2, $5); } + { $$ = build_asm_stmt ($2, $5); } ; asm_argument: @@ -2529,12 +2445,13 @@ nonnull_asm_operands: asm_operand: STRING start_string_translation '(' expr ')' stop_string_translation - { $$ = build_tree_list (build_tree_list (NULL_TREE, $1), $4); } + { $$ = 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), $7); } + $$ = build_tree_list (build_tree_list ($2, $4), $7.value); } ; asm_clobbers: @@ -2545,11 +2462,11 @@ asm_clobbers: ; stop_string_translation: - { c_lex_string_translate = false; } + { c_lex_string_translate = 0; } ; start_string_translation: - { c_lex_string_translate = true; } + { c_lex_string_translate = 1; } ; @@ -2607,22 +2524,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 @@ -2634,22 +2548,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 @@ -2727,7 +2638,7 @@ objcdef: | aliasdecl | protocoldef | methoddef - | END + | AT_END { if (objc_implementation_context) { @@ -2749,14 +2660,14 @@ 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); } @@ -2773,7 +2684,7 @@ class_ivars: ; classdef: - INTERFACE identifier superclass protocolrefs + AT_INTERFACE identifier superclass protocolrefs { objc_interface_context = objc_ivar_context = start_class (CLASS_INTERFACE_TYPE, $2, $3, $4); @@ -2783,13 +2694,13 @@ classdef: { continue_class (objc_interface_context); } - methodprotolist END + methodprotolist AT_END { finish_class (objc_interface_context); objc_interface_context = NULL_TREE; } - | IMPLEMENTATION identifier superclass + | AT_IMPLEMENTATION identifier superclass { objc_implementation_context = objc_ivar_context = start_class (CLASS_IMPLEMENTATION_TYPE, $2, $3, NULL_TREE); @@ -2801,19 +2712,19 @@ classdef: = continue_class (objc_implementation_context); } - | INTERFACE identifier '(' identifier ')' protocolrefs + | AT_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; } - | IMPLEMENTATION identifier '(' identifier ')' + | AT_IMPLEMENTATION identifier '(' identifier ')' { objc_implementation_context = start_class (CATEGORY_IMPLEMENTATION_TYPE, $2, $4, NULL_TREE); @@ -2823,13 +2734,13 @@ classdef: ; protocoldef: - PROTOCOL identifier protocolrefs + AT_PROTOCOL identifier protocolrefs { objc_pq_context = 1; objc_interface_context = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3); } - methodprotolist END + methodprotolist AT_END { objc_pq_context = 0; finish_protocol(objc_interface_context); @@ -2838,7 +2749,7 @@ protocoldef: /* 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); } @@ -2868,9 +2779,9 @@ ivar_decl_list: ; visibility_spec: - PRIVATE { objc_public_flag = 2; } - | PROTECTED { objc_public_flag = 0; } - | PUBLIC { objc_public_flag = 1; } + AT_PRIVATE { objc_public_flag = 2; } + | AT_PROTECTED { objc_public_flag = 0; } + | AT_PUBLIC { objc_public_flag = 1; } ; ivar_decls: @@ -2926,14 +2837,14 @@ ivar_declarator: { $$ = add_instance_variable (objc_ivar_context, objc_public_flag, - $1, current_declspecs, $3); + $1, current_declspecs, $3.value); } | ':' expr_no_commas { $$ = add_instance_variable (objc_ivar_context, objc_public_flag, NULL_TREE, - current_declspecs, $2); + current_declspecs, $2.value); } ; @@ -3189,6 +3100,7 @@ keywordarg: receiver: expr + { $$ = $1.value; } | CLASSNAME { $$ = get_class_reference ($1); @@ -3229,14 +3141,14 @@ keywordname: ; objcselectorexpr: - SELECTOR '(' selectorarg ')' + AT_SELECTOR '(' selectorarg ')' { $$ = $3; } ; objcprotocolexpr: - PROTOCOL '(' identifier ')' + AT_PROTOCOL '(' identifier ')' { $$ = $3; } @@ -3245,7 +3157,7 @@ objcprotocolexpr: /* extension to support C-structures in the archiver */ objcencodeexpr: - ENCODE '(' typename ')' + AT_ENCODE '(' typename ')' { $$ = groktypename ($3); } @@ -3502,23 +3414,23 @@ 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_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 */ INTERFACE, - /* RID_AT_IMPLEMENTATION */ IMPLEMENTATION + /* RID_AT_INTERFACE */ AT_INTERFACE, + /* RID_AT_IMPLEMENTATION */ AT_IMPLEMENTATION }; static void @@ -3532,7 +3444,7 @@ init_reswords (void) if (!c_dialect_objc ()) mask |= D_OBJC; - ridpointers = ggc_calloc ((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