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
%{
%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
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
/* 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 <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
%type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF
-%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
-%type <ttype> expr_no_commas cast_expr unary_expr primary STRING
+%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT STRING FUNC_NAME
+%type <ttype> nonnull_exprlist exprlist
+%type <exprtype> expr expr_no_commas cast_expr unary_expr primary
%type <ttype> declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea
%type <ttype> declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea
%type <ttype> declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea
%type <ttype> offsetof_member_designator
%type <ttype> scspec SCSPEC STATIC TYPESPEC TYPE_QUAL maybe_volatile
-%type <ttype> initdecls notype_initdecls initdcl notype_initdcl init
+%type <ttype> initdecls notype_initdecls initdcl notype_initdcl
+%type <exprtype> init
%type <ttype> simple_asm_expr maybeasm asm_stmt asm_argument
%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers
%type <ttype> maybe_attribute attributes attribute attribute_list attrib
%type <ttype> any_word
%type <ttype> compstmt compstmt_start compstmt_primary_start
-%type <ttype> do_stmt_start stmt label
+%type <ttype> stmt label stmt_nocomp start_break start_continue
%type <ttype> c99_block_start c99_block_lineno_labeled_stmt
+%type <ttype> if_statement_1 if_statement_2
%type <ttype> declarator
%type <ttype> notype_declarator after_type_declarator
%type <ttype> parm_declarator
%type <ttype> struct_head union_head enum_head
%type <ttype> typename absdcl absdcl1 absdcl1_ea absdcl1_noea
%type <ttype> direct_absdcl1 absdcl_maybe_attribute
-%type <ttype> xexpr parms parm firstparm identifiers
+%type <ttype> condition xexpr for_cond_expr for_incr_expr
+%type <ttype> parms parm firstparm identifiers
%type <ttype> parmlist parmlist_1 parmlist_2
%type <ttype> parmlist_or_identifiers parmlist_or_identifiers_1
%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
%type <ttype> superclass
-%type <itype> objc_try_catch_stmt objc_finally_block
@@end_ifobjc
\f
%{
-/* 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;
all_prefix_attributes. */
static GTY(()) tree 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 \
{ $$ = 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:
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:
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:
| 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. */
- $<ttype>2 = save_expr (default_conversion ($1));
- $1 = lang_hooks.truthvalue_conversion ($<ttype>2);
- skip_evaluation += $1 == truthvalue_true_node; }
+ $<ttype>2 = save_expr (default_conversion ($1.value));
+ $1.value = lang_hooks.truthvalue_conversion ($<ttype>2);
+ skip_evaluation += $1.value == truthvalue_true_node; }
':' expr_no_commas
- { skip_evaluation -= $1 == truthvalue_true_node;
- $$ = build_conditional_expr ($1, $<ttype>2, $5); }
+ { skip_evaluation -= $1.value == truthvalue_true_node;
+ $$.value = build_conditional_expr ($1.value, $<ttype>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;
}
;
{
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 ')'
{ if (pedantic)
pedwarn ("ISO C forbids braced-groups within expressions");
- $$ = c_finish_stmt_expr ($1);
+ $$.value = c_finish_stmt_expr ($1);
+ $$.original_code = ERROR_MARK;
}
| compstmt_primary_start error ')'
{ c_finish_stmt_expr ($1);
- $$ = error_mark_node;
+ $$.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); }
+ | 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 ')'
- { $$ = 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"
$$ = 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;
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 = 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); }
+ { $$.value = objc_build_encode_expr ($1);
+ $$.original_code = ERROR_MARK; }
| OBJC_STRING
- { $$ = build_objc_string_object ($1); }
+ { $$.value = objc_build_string_object ($1);
+ $$.original_code = ERROR_MARK; }
@@end_ifobjc
;
/* This is the second argument to __builtin_offsetof. We must have one
identifier, and beyond that we want to accept sub structure and sub
- array references. We return tree list where each element has
- PURPOSE set for component refs or VALUE set for array refs. We'll
- turn this into something real inside build_offsetof. */
+ array references. */
offsetof_member_designator:
identifier
- { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); }
+ { $$ = build_component_ref (offsetof_base, $1); }
| offsetof_member_designator '.' identifier
- { $$ = tree_cons ($3, NULL_TREE, $1); }
+ { $$ = build_component_ref ($1, $3); }
| offsetof_member_designator '[' expr ']'
- { $$ = tree_cons (NULL_TREE, $3, $1); }
+ { $$ = build_array_ref ($1, $3.value); }
;
old_style_parm_decls:
| CLASSNAME protocolrefs
{ $$ = get_static_reference ($1, $2); }
| OBJECTNAME protocolrefs
- { $$ = get_object_reference ($2); }
+ { $$ = get_protocol_reference ($2); }
/* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>"
- 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); }
;
initdcl:
declarator maybeasm maybe_attribute '='
- { $<ttype>$ = start_decl ($1, current_declspecs, 1,
+ { $<ttype>$ = start_decl ($1, current_declspecs, true,
chainon ($3, all_prefix_attributes));
start_init ($<ttype>$, $2, global_bindings_p ()); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_init ();
- finish_decl ($<ttype>5, $6, $2); }
+ maybe_warn_string_init (TREE_TYPE ($<ttype>5), $6);
+ finish_decl ($<ttype>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);
}
notype_initdcl:
notype_declarator maybeasm maybe_attribute '='
- { $<ttype>$ = start_decl ($1, current_declspecs, 1,
+ { $<ttype>$ = start_decl ($1, current_declspecs, true,
chainon ($3, all_prefix_attributes));
start_init ($<ttype>$, $2, global_bindings_p ()); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
{ finish_init ();
- finish_decl ($<ttype>5, $6, $2); }
+ maybe_warn_string_init (TREE_TYPE ($<ttype>5), $6);
+ finish_decl ($<ttype>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); }
;
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. */
'.' 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); }
;
\f
nested_function:
- declarator
+ declarator
{ if (pedantic)
pedwarn ("ISO C forbids nested functions");
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");
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
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
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
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
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
;
pedwarn ("extra semicolon in struct or union specified"); }
@@ifobjc
/* foo(sizeof(struct{ @defs(ClassName)})); */
- | DEFS '(' CLASSNAME ')'
- { $$ = nreverse (get_class_ivars_from_name ($3)); }
+ | AT_DEFS '(' CLASSNAME ')'
+ { $$ = nreverse (objc_get_class_ivars ($3)); }
@@end_ifobjc
;
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); }
;
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); }
;
identifier
{ $$ = build_enumerator ($1, NULL_TREE); }
| identifier '=' expr_no_commas
- { $$ = build_enumerator ($1, $3); }
+ { $$ = build_enumerator ($1, $3.value); }
;
typename:
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 */
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
{
tree label = declare_label (TREE_VALUE (link));
C_DECLARED_LABEL_FLAG (label) = 1;
- add_decl_stmt (label);
+ add_stmt (build_stmt (DECL_EXPR, label));
}
}
;
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 (true); }
+compstmt_start: '{' { $$ = c_begin_compound_stmt (true); }
;
compstmt_nostart: '}'
"only inside a function");
YYERROR;
}
- compstmt_count++;
$$ = c_begin_stmt_expr ();
}
;
compstmt: compstmt_start compstmt_nostart
- { add_stmt (c_end_compound_stmt ($1, true));
- $$ = NULL_TREE; }
- ;
-
-/* Value is number of statements counted as of the closeparen. */
-simple_if:
- if_prefix c99_block_lineno_labeled_stmt
- { c_finish_then ($2); }
-/* 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
- { $<ttype>$ = c_begin_if_stmt (); }
- '(' expr ')'
- { c_expand_start_cond (lang_hooks.truthvalue_conversion ($4),
- compstmt_count,$<ttype>2);
- $<itype>$ = stmt_count;
- if_stmt_locus = $<location>-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++;
- $<ttype>$
- = 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 ($<ttype>$) = error_mark_node; }
- c99_block_lineno_labeled_stmt WHILE
- { $$ = $<ttype>2;
- DO_BODY ($$) = $3;
- 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
$$ = 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_start lineno_labels lineno_stmt
{ $$ = c_end_compound_stmt ($1, flag_isoc99); }
;
because (recursively) all of the component statments
should already have line numbers assigned. */
if ($2 && EXPR_P ($2))
- {
- SET_EXPR_LOCUS ($2, NULL);
- annotate_with_locus ($2, $1);
- }
+ 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 ();
- $<itype>1 = stmt_count; }
- c99_block_lineno_labeled_stmt
- { c_finish_else ($4);
- c_expand_end_cond ();
- if (extra_warnings && stmt_count == $<itype>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++ == $<itype>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++;
- $<ttype>$ = c_begin_while_stmt (); }
- '(' expr ')'
- { c_in_iteration_stmt++;
- c_finish_while_stmt_cond ($4, $<ttype>2); }
- c99_block_lineno_labeled_stmt
- { c_in_iteration_stmt--;
- c_finish_while_stmt ($7, $<ttype>2); }
- | do_stmt_start
- '(' expr ')' ';'
- { DO_COND ($1) = lang_hooks.truthvalue_conversion ($3); }
- | do_stmt_start error
- { }
- | FOR
- { $<ttype>$ = c_begin_for_stmt (); }
- '(' for_init_stmt
- { stmt_count++;
- c_finish_for_stmt_init ($<ttype>2); }
- xexpr ';'
- { c_finish_for_stmt_cond ($6, $<ttype>2); }
- xexpr ')'
- { c_in_iteration_stmt++;
- c_finish_for_stmt_incr ($9, $<ttype>2); }
- c99_block_lineno_labeled_stmt
- { c_finish_for_stmt ($12, $<ttype>2);
- c_in_iteration_stmt--; }
- | SWITCH '(' expr ')'
- { stmt_count++;
- $<ttype>$ = c_start_case ($3);
- c_in_case_stmt++; }
- c99_block_lineno_labeled_stmt
- { c_finish_case ($6);
- 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
+ { $<ttype>$ = c_break_label; c_break_label = $4; }
+ { $<ttype>$ = c_cont_label; c_cont_label = $5; }
+ '(' condition ')' ';'
+ { c_finish_loop ($3, $11, NULL, $6, $<ttype>8,
+ $<ttype>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
- { add_stmt (c_end_compound_stmt ($1, flag_isoc99));
- $$ = NULL_TREE; }
- | BREAK ';'
- { stmt_count++;
- if (!(c_in_iteration_stmt || c_in_case_stmt))
+for_init_stmt:
+ xexpr ';'
+ { c_finish_expr_stmt ($1); }
+ | decl
+ { check_for_loop_decls (); }
+ ;
+
+for_cond_expr: save_location xexpr
+ { if ($2)
{
- error ("break statement not within loop or switch");
- $$ = NULL_TREE;
+ $$ = lang_hooks.truthvalue_conversion ($2);
+ if (EXPR_P ($$))
+ SET_EXPR_LOCATION ($$, $1);
}
else
- $$ = add_stmt (build_break_stmt ()); }
+ $$ = 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 ')'
+ { $<ttype>$ = 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 ';'
+ { $$ = 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_EXPR, 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_EXPR, $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);
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:
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:
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
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
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);
+ { $$ = tree_cons (NULL_TREE, NULL_TREE, $1);
/* Make sure we have a parmlist after attributes. */
- if ($<ttype>-1 != 0
- && (TREE_CODE ($$) != TREE_LIST
- || TREE_PURPOSE ($$) == 0
- || TREE_CODE (TREE_PURPOSE ($$)) != PARM_DECL))
+ if ($<ttype>-1 != 0)
YYERROR1;
}
;
| aliasdecl
| protocoldef
| methoddef
- | END
+ | AT_END
{
if (objc_implementation_context)
{
;
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 superclass protocolrefs
+ AT_INTERFACE identifier superclass protocolrefs
{
objc_interface_context = objc_ivar_context
= start_class (CLASS_INTERFACE_TYPE, $2, $3, $4);
{
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);
= 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);
;
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);
/* 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);
}
;
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:
{
$$ = 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);
}
;
keyworddecl:
selector ':' '(' 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
{
- $$ = 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);
}
;
receiver:
expr
+ { $$ = $1.value; }
| CLASSNAME
{
- $$ = get_class_reference ($1);
+ $$ = objc_get_class_reference ($1);
}
| TYPENAME
{
- $$ = get_class_reference ($1);
+ $$ = objc_get_class_reference ($1);
}
;
;
objcselectorexpr:
- SELECTOR '(' selectorarg ')'
+ AT_SELECTOR '(' selectorarg ')'
{
$$ = $3;
}
;
objcprotocolexpr:
- PROTOCOL '(' identifier ')'
+ AT_PROTOCOL '(' identifier ')'
{
$$ = $3;
}
/* extension to support C-structures in the archiver */
objcencodeexpr:
- ENCODE '(' typename ')'
+ AT_ENCODE '(' typename ')'
{
$$ = groktypename ($3);
}
{ "void", RID_VOID, 0 },
{ "volatile", RID_VOLATILE, 0 },
{ "while", RID_WHILE, 0 },
+
@@ifobjc
{ "id", RID_ID, D_OBJC },
/* 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
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
@@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