/* Like YYERROR but do call yyerror. */
#define YYERROR1 { yyerror ("syntax error"); YYERROR; }
-/* Cause the `yydebug' variable to be defined. */
+/* Cause the "yydebug" variable to be defined. */
#define YYDEBUG 1
+
+/* Rename the "yyparse" function so that we can override it elsewhere. */
+#define yyparse yyparse_1
%}
%start program
%union {long itype; tree ttype; enum tree_code code;
- const char *filename; int lineno; int ends_in_label; }
+ const char *filename; int lineno; }
/* All identifiers that are not reserved words
and are not declared typedefs in the current block */
%type <ttype> compstmt compstmt_start compstmt_nostart compstmt_primary_start
%type <ttype> do_stmt_start poplevel
+%type <ttype> c99_block_start c99_block_end
%type <ttype> declarator
%type <ttype> notype_declarator after_type_declarator
%type <ttype> parm_declarator
%type <itype> setspecs
-%type <ends_in_label> lineno_stmt_or_label lineno_stmt_or_labels stmt_or_label
-
%type <filename> save_filename
%type <lineno> save_lineno
\f
{ $$ = build_unary_op (REALPART_EXPR, $2, 0); }
| IMAGPART cast_expr %prec UNARY
{ $$ = build_unary_op (IMAGPART_EXPR, $2, 0); }
- | VA_ARG '(' expr_no_commas ',' typename ')'
- { $$ = build_va_arg ($3, groktypename ($5)); }
;
sizeof:
}
| primary '(' exprlist ')' %prec '.'
{ $$ = build_function_call ($1, $3); }
+ | VA_ARG '(' expr_no_commas ',' typename ')'
+ { $$ = build_va_arg ($3, groktypename ($5)); }
| primary '[' expr ']' %prec '.'
{ $$ = build_array_ref ($1, $3); }
| primary '.' identifier
{ }
;
-decls:
- lineno_decl
- | errstmt
- | decls lineno_decl
- | lineno_decl errstmt
- ;
-
/* records the type and storage class specs to use for processing
the declarators that follow.
Maintains a stack of outer-level values of current_declspecs,
It may use braces. */
initelt:
designator_list '=' initval
+ { if (pedantic && ! flag_isoc99)
+ pedwarn ("ISO C89 forbids specifying subobject to initialize"); }
| designator initval
+ { if (pedantic)
+ pedwarn ("obsolete use of designated initializer without `='"); }
| identifier ':'
- { set_init_label ($1); }
+ { set_init_label ($1);
+ if (pedantic)
+ pedwarn ("obsolete use of designated initializer with `:'"); }
initval
| initval
;
so don't include these productions in the Objective-C grammar. */
ifc
| '[' expr_no_commas ELLIPSIS expr_no_commas ']'
- { set_init_index ($2, $4); }
+ { set_init_index ($2, $4);
+ if (pedantic)
+ pedwarn ("ISO C forbids specifying range of elements to initialize"); }
| '[' expr_no_commas ']'
{ set_init_index ($2, NULL_TREE); }
end ifc
{ $$ = $3; }
;
-/* at least one statement, the first of which parses without error. */
-/* stmts is used only after decls, so an invalid first statement
- is actually regarded as an invalid decl and part of the decls. */
+/* A nonempty series of declarations and statements (possibly followed by
+ some labels) that can form the body of a compound statement.
+ NOTE: we don't allow labels on declarations; this might seem like a
+ natural extension, but there would be a conflict between attributes
+ on the label and prefix attributes on the declaration. */
-stmts:
- lineno_stmt_or_labels
+stmts_and_decls:
+ lineno_stmt_decl_or_labels_ending_stmt
+ | lineno_stmt_decl_or_labels_ending_decl
+ | lineno_stmt_decl_or_labels_ending_label
{
- if (pedantic && $1)
- pedwarn ("ISO C forbids label at end of compound statement");
+ pedwarn ("deprecated use of label at end of compound statement");
}
+ | lineno_stmt_decl_or_labels_ending_error
;
-lineno_stmt_or_labels:
- lineno_stmt_or_label
- | lineno_stmt_or_labels lineno_stmt_or_label
- { $$ = $2; }
- | lineno_stmt_or_labels errstmt
- { $$ = 0; }
+lineno_stmt_decl_or_labels_ending_stmt:
+ lineno_stmt
+ | lineno_stmt_decl_or_labels_ending_stmt lineno_stmt
+ | lineno_stmt_decl_or_labels_ending_decl lineno_stmt
+ | lineno_stmt_decl_or_labels_ending_label lineno_stmt
+ | lineno_stmt_decl_or_labels_ending_error lineno_stmt
;
-xstmts:
- /* empty */
- | stmts
+lineno_stmt_decl_or_labels_ending_decl:
+ lineno_decl
+ | lineno_stmt_decl_or_labels_ending_stmt lineno_decl
+ { if (pedantic && !flag_isoc99)
+ pedwarn ("ISO C89 forbids mixed declarations and code"); }
+ | lineno_stmt_decl_or_labels_ending_decl lineno_decl
+ | lineno_stmt_decl_or_labels_ending_error lineno_decl
+ ;
+
+lineno_stmt_decl_or_labels_ending_label:
+ lineno_label
+ | lineno_stmt_decl_or_labels_ending_stmt lineno_label
+ | lineno_stmt_decl_or_labels_ending_decl lineno_label
+ | lineno_stmt_decl_or_labels_ending_label lineno_label
+ | lineno_stmt_decl_or_labels_ending_error lineno_label
+ ;
+
+lineno_stmt_decl_or_labels_ending_error:
+ errstmt
+ | lineno_stmt_decl_or_labels errstmt
+ ;
+
+lineno_stmt_decl_or_labels:
+ lineno_stmt_decl_or_labels_ending_stmt
+ | lineno_stmt_decl_or_labels_ending_decl
+ | lineno_stmt_decl_or_labels_ending_label
+ | lineno_stmt_decl_or_labels_ending_error
;
errstmt: error ';'
poplevel: /* empty */
{ $$ = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); }
+/* Start and end blocks created for the new scopes of C99. */
+c99_block_start: /* empty */
+ { if (flag_isoc99)
+ {
+ $$ = c_begin_compound_stmt ();
+ pushlevel (0);
+ clear_last_expr ();
+ add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
+ifobjc
+ if (objc_method_context)
+ add_objc_decls ();
+end ifobjc
+ }
+ else
+ $$ = NULL_TREE;
+ }
+ ;
+
+/* Productions using c99_block_start and c99_block_end will need to do what's
+ in compstmt: RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); $$ = $2; where
+ $1 is the value of c99_block_start and $2 of c99_block_end. */
+c99_block_end: /* empty */
+ { if (flag_isoc99)
+ {
+ tree scope_stmt = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
+ $$ = poplevel (kept_level_p (), 0, 0);
+ SCOPE_STMT_BLOCK (TREE_PURPOSE (scope_stmt))
+ = SCOPE_STMT_BLOCK (TREE_VALUE (scope_stmt))
+ = $$;
+ }
+ else
+ $$ = NULL_TREE; }
+ ;
+
/* Read zero or more forward-declarations for labels
that nested functions can jump to. */
maybe_label_decls:
compstmt_nostart: '}'
{ $$ = convert (void_type_node, integer_zero_node); }
- | pushlevel maybe_label_decls decls xstmts '}' poplevel
- { $$ = poplevel (1, 1, 0);
- SCOPE_STMT_BLOCK (TREE_PURPOSE ($6))
- = SCOPE_STMT_BLOCK (TREE_VALUE ($6))
- = $$; }
- | pushlevel maybe_label_decls error '}' poplevel
- { $$ = poplevel (kept_level_p (), 0, 0);
- SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
- = SCOPE_STMT_BLOCK (TREE_VALUE ($5))
- = $$; }
- | pushlevel maybe_label_decls stmts '}' poplevel
- { $$ = poplevel (kept_level_p (), 0, 0);
+ | pushlevel maybe_label_decls compstmt_contents_nonempty '}' poplevel
+ { $$ = poplevel (kept_level_p (), 1, 0);
SCOPE_STMT_BLOCK (TREE_PURPOSE ($5))
= SCOPE_STMT_BLOCK (TREE_VALUE ($5))
= $$; }
;
+compstmt_contents_nonempty:
+ stmts_and_decls
+ | error
+ ;
+
compstmt_primary_start:
'(' '{'
{ if (current_function_decl == 0)
/* Value is number of statements counted as of the closeparen. */
simple_if:
- if_prefix lineno_labeled_stmt
+ 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.
{ c_expand_start_cond (truthvalue_conversion ($3),
compstmt_count);
$<itype>$ = stmt_count;
- if_stmt_file = $<filename>-1;
- if_stmt_line = $<lineno>0; }
+ if_stmt_file = $<filename>-2;
+ if_stmt_line = $<lineno>-1; }
;
/* This is a subroutine of stmt.
condition now. Otherwise, we can get crashes at
RTL-generation time. */
DO_COND ($<ttype>$) = error_mark_node; }
- lineno_labeled_stmt WHILE
+ c99_block_lineno_labeled_stmt WHILE
{ $$ = $<ttype>2;
RECHAIN_STMTS ($$, DO_BODY ($$)); }
;
{ }
;
-lineno_stmt_or_label:
- save_filename save_lineno stmt_or_label
- { $$ = $3; }
+/* Like lineno_labeled_stmt, but a block in C99. */
+c99_block_lineno_labeled_stmt:
+ c99_block_start lineno_labeled_stmt c99_block_end
+ { if (flag_isoc99)
+ RECHAIN_STMTS ($1, COMPOUND_BODY ($1)); }
;
-stmt_or_label:
- stmt
- { $$ = 0; }
- | label
- { $$ = 1; }
+lineno_stmt:
+ save_filename save_lineno stmt
+ { }
;
-/* Parse a single real statement, not including any labels. */
-stmt:
- compstmt
- { stmt_count++; }
- | expr ';'
- { stmt_count++;
- c_expand_expr_stmt ($1); }
- | simple_if ELSE
+lineno_label:
+ save_filename save_lineno label
+ { }
+ ;
+
+select_or_iter_stmt:
+ simple_if ELSE
{ c_expand_start_else ();
$<itype>1 = stmt_count; }
- lineno_labeled_stmt
+ c99_block_lineno_labeled_stmt
{ c_finish_else ();
c_expand_end_cond ();
if (extra_warnings && stmt_count == $<itype>1)
{ $4 = truthvalue_conversion ($4);
$<ttype>$
= add_stmt (build_stmt (WHILE_STMT, $4, NULL_TREE)); }
- lineno_labeled_stmt
+ c99_block_lineno_labeled_stmt
{ RECHAIN_STMTS ($<ttype>6, WHILE_BODY ($<ttype>6)); }
| do_stmt_start
'(' expr ')' ';'
| do_stmt_start error
{ }
| FOR
- '(' xexpr ';'
- { stmt_count++;
- $3 = build_stmt (EXPR_STMT, $3);
- $<ttype>$ = build_stmt (FOR_STMT, $3, NULL_TREE,
+ { $<ttype>$ = build_stmt (FOR_STMT, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE);
- add_stmt ($<ttype>$);
- }
+ add_stmt ($<ttype>$); }
+ '(' for_init_stmt
+ { stmt_count++;
+ RECHAIN_STMTS ($<ttype>2, FOR_INIT_STMT ($<ttype>2)); }
xexpr ';'
- { FOR_COND ($<ttype>5) = $6; }
+ { FOR_COND ($<ttype>2) = $6; }
xexpr ')'
- { FOR_EXPR ($<ttype>5) = $9; }
- lineno_labeled_stmt
- { RECHAIN_STMTS ($<ttype>5, FOR_BODY ($<ttype>5)); }
+ { FOR_EXPR ($<ttype>2) = $9; }
+ c99_block_lineno_labeled_stmt
+ { RECHAIN_STMTS ($<ttype>2, FOR_BODY ($<ttype>2)); }
| SWITCH '(' expr ')'
{ stmt_count++;
$<ttype>$ = c_start_case ($3); }
- lineno_labeled_stmt
+ c99_block_lineno_labeled_stmt
{ c_finish_case (); }
+ ;
+
+for_init_stmt:
+ xexpr ';'
+ { add_stmt (build_stmt (EXPR_STMT, $1)); }
+ | decl
+ { check_for_loop_decls (); }
+ ;
+
+/* Parse a single real statement, not including any labels. */
+stmt:
+ compstmt
+ { stmt_count++; }
+ | 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)); }
| BREAK ';'
{ stmt_count++;
add_stmt (build_break_stmt ()); }
cpplib.h's token codes into yacc's token codes. */
static enum cpp_ttype last_token;
-#if USE_CPPLIB
-extern cpp_reader parse_in;
-#endif
/* The reserved keyword table. */
struct resword
static const struct resword reswords[] =
{
+ { "_Bool", RID_BOOL, 0 },
{ "_Complex", RID_COMPLEX, 0 },
{ "__alignof", RID_ALIGNOF, 0 },
{ "__alignof__", RID_ALIGNOF, 0 },
/* RID_PTRVALUE */ PTR_VALUE,
/* C++ */
- /* RID_BOOL */ 0,
+ /* RID_BOOL */ TYPESPEC,
/* RID_WCHAR */ 0,
/* RID_CLASS */ 0,
/* RID_PUBLIC */ 0,
void
finish_parse ()
{
-#if USE_CPPLIB
- cpp_finish (&parse_in);
- errorcount += parse_in.errors;
-#else
- fclose (finput);
-#endif
+ cpp_finish (parse_in);
+ errorcount += parse_in->errors;
}
-#if USE_CPPLIB
#define NAME(type) cpp_type2name (type)
-#else
-/* Bleah */
-#include "symcat.h"
-#define OP(e, s) s,
-#define TK(e, s) STRINGX(e),
-
-static const char *type2name[N_TTYPES] = { TTYPE_TABLE };
-#define NAME(type) type2name[type]
-#endif
static void
yyerror (msgid)
case CPP_DOT: return '.';
case CPP_EOF:
-#if USE_CPPLIB
- cpp_pop_buffer (&parse_in);
- if (! CPP_BUFFER (&parse_in))
-#endif
+ cpp_pop_buffer (parse_in);
+ if (! CPP_BUFFER (parse_in))
return 0;
goto retry;