You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* This file defines the grammar of C and that of Objective C.
ifobjc ... end ifobjc conditionals contain code for Objective C only.
written by AT&T, but I have never seen it. */
ifobjc
-%expect 42
+%expect 48
end ifobjc
ifc
-%expect 30
+%expect 34
/* These are the 23 conflicts you should get in parse.output;
the state numbers may vary if minor changes in the grammar are made.
%start program
%union {long itype; tree ttype; enum tree_code code;
- char *filename; int lineno; }
+ char *filename; int lineno; int ends_in_label; }
/* All identifiers that are not reserved words
and are not declared typedefs in the current block */
%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
{ if (pedantic)
error ("ANSI C forbids data definition with no type or storage class");
else if (!flag_traditional)
- warning ("data definition has no type or storage class"); }
+ warning ("data definition has no type or storage class");
+
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($1); }
| declmods setspecs notype_initdecls ';'
- {}
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| typed_declspecs setspecs initdecls ';'
- {}
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| declmods ';'
{ pedwarn ("empty declaration"); }
| typed_declspecs ';'
\f
fndef:
typed_declspecs setspecs declarator
- { if (! start_function ($1, $3, prefix_attributes, 0))
+ { if (! start_function ($1, $3, prefix_attributes,
+ NULL_TREE, 0))
YYERROR1;
reinit_parse_for_function (); }
xdecls
{ store_parm_decls (); }
compstmt_or_error
- { finish_function (0); }
+ { finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| typed_declspecs setspecs declarator error
- { }
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| declmods setspecs notype_declarator
- { if (! start_function ($1, $3, prefix_attributes, 0))
+ { if (! start_function ($1, $3, prefix_attributes,
+ NULL_TREE, 0))
YYERROR1;
reinit_parse_for_function (); }
xdecls
{ store_parm_decls (); }
compstmt_or_error
- { finish_function (0); }
+ { finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| declmods setspecs notype_declarator error
- { }
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| setspecs notype_declarator
- { if (! start_function (NULL_TREE, $2, prefix_attributes, 0))
+ { if (! start_function (NULL_TREE, $2,
+ prefix_attributes, NULL_TREE, 0))
YYERROR1;
reinit_parse_for_function (); }
xdecls
{ store_parm_decls (); }
compstmt_or_error
- { finish_function (0); }
+ { finish_function (0);
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($1); }
| setspecs notype_declarator error
- { }
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($1); }
;
identifier:
;
ifobjc
-/* Produces an OBJC_STRING_CST with prehaps more OBJC_STRING_CSTs chained
+/* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained
onto it. */
objc_string:
OBJC_STRING
| error
/* These are for labeled elements. The syntax for an array element
initializer conflicts with the syntax for an Objective-C message,
- so don't include these productions in the Objective-C grammer. */
+ so don't include these productions in the Objective-C grammar. */
ifc
| '[' expr_no_commas ELLIPSIS expr_no_commas ']' '='
{ set_init_index ($2, $4); }
declarator
{ push_c_function_context ();
if (! start_function (current_declspecs, $1,
- prefix_attributes, 1))
+ prefix_attributes, NULL_TREE, 1))
{
pop_c_function_context ();
YYERROR1;
notype_declarator
{ push_c_function_context ();
if (! start_function (current_declspecs, $1,
- prefix_attributes, 1))
+ prefix_attributes, NULL_TREE, 1))
{
pop_c_function_context ();
YYERROR1;
enumlist:
enumerator
| enumlist ',' enumerator
- { $$ = chainon ($3, $1); }
+ { if ($1 == error_mark_node)
+ $$ = $1;
+ else
+ $$ = chainon ($3, $1); }
| error
{ $$ = error_mark_node; }
;
is actually regarded as an invalid decl and part of the decls. */
stmts:
+ lineno_stmt_or_labels
+ {
+ if (pedantic && $1)
+ pedwarn ("ANSI C forbids label at end of compound statement");
+ }
+ ;
+
+lineno_stmt_or_labels:
lineno_stmt_or_label
- | stmts lineno_stmt_or_label
- | stmts errstmt
+ | lineno_stmt_or_labels lineno_stmt_or_label
+ { $$ = $2; }
+ | lineno_stmt_or_labels errstmt
+ { $$ = 0; }
;
xstmts:
lineno_stmt_or_label:
save_filename save_lineno stmt_or_label
- { }
+ { $$ = $3; }
;
stmt_or_label:
stmt
+ { $$ = 0; }
| label
- { int next;
- position_after_white_space ();
- next = getc (finput);
- ungetc (next, finput);
- if (pedantic && next == '}')
- pedwarn ("ANSI C forbids label at end of compound statement");
- }
+ { $$ = 1; }
;
/* Parse a single real statement, not including any labels. */
/* A single parameter declaration or parameter type name,
as found in a parmlist. */
parm:
- typed_declspecs parm_declarator
- { $$ = build_tree_list ($1, $2) ; }
- | typed_declspecs notype_declarator
- { $$ = build_tree_list ($1, $2) ; }
- | typed_declspecs absdcl
- { $$ = build_tree_list ($1, $2); }
- | declmods notype_declarator
- { $$ = build_tree_list ($1, $2) ; }
- | declmods absdcl
- { $$ = build_tree_list ($1, $2); }
+ typed_declspecs setspecs parm_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs setspecs notype_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | typed_declspecs setspecs absdcl maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+ | declmods setspecs notype_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
+
+ | declmods setspecs absdcl maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $3),
+ build_tree_list (prefix_attributes,
+ $4));
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
;
/* This is used in a function definition
ivar_decl:
typed_typespecs setspecs ivars
- {
- $$ = $3;
- resume_momentary ($2);
- }
+ { $$ = $3;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| nonempty_type_quals setspecs ivars
- {
- $$ = $3;
- resume_momentary ($2);
- }
+ { $$ = $3;
+ current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| error
{ $$ = NULL_TREE; }
;
mydecl:
typed_declspecs setspecs myparms ';'
- { resume_momentary ($2); }
+ { current_declspecs = TREE_VALUE (declspec_stack);
+ prefix_attributes = TREE_PURPOSE (declspec_stack);
+ declspec_stack = TREE_CHAIN (declspec_stack);
+ resume_momentary ($2); }
| typed_declspecs ';'
{ shadow_tag ($1); }
| declmods ';'
as found in a parmlist. DOES NOT ALLOW AN INITIALIZER OR ASMSPEC */
myparm:
- parm_declarator
- { $$ = build_tree_list (current_declspecs, $1) ; }
- | notype_declarator
- { $$ = build_tree_list (current_declspecs, $1) ; }
- | absdcl
- { $$ = build_tree_list (current_declspecs, $1) ; }
+ parm_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $1),
+ build_tree_list (prefix_attributes,
+ $2)); }
+ | notype_declarator maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $1),
+ build_tree_list (prefix_attributes,
+ $2)); }
+ | absdcl maybe_attribute
+ { $$ = build_tree_list (build_tree_list (current_declspecs,
+ $1),
+ build_tree_list (prefix_attributes,
+ $2)); }
;
optparmlist: