OSDN Git Service

(find_reloads_address_1, case POST_INC): Don't use
[pf3gnuchains/gcc-fork.git] / gcc / c-parse.in
index 11db40f..2a40c5a 100644 (file)
@@ -28,10 +28,10 @@ Boston, MA 02111-1307, USA.  */
    written by AT&T, but I have never seen it.  */
 
 ifobjc
-%expect 52
+%expect 66
 end ifobjc
 ifc
-%expect 34
+%expect 46
 
 /* These are the 23 conflicts you should get in parse.output;
    the state numbers may vary if minor changes in the grammar are made.
@@ -185,6 +185,8 @@ void yyerror ();
 %type <ttype> typed_declspecs reserved_declspecs
 %type <ttype> typed_typespecs reserved_typespecquals
 %type <ttype> declmods typespec typespecqual_reserved
+%type <ttype> typed_declspecs_no_prefix_attr reserved_declspecs_no_prefix_attr
+%type <ttype> declmods_no_prefix_attr
 %type <ttype> SCSPEC TYPESPEC TYPE_QUAL nonempty_type_quals maybe_type_qual
 %type <ttype> initdecls notype_initdecls initdcl notype_initdcl
 %type <ttype> init maybeasm
@@ -239,7 +241,7 @@ static char *if_stmt_file;
 static int if_stmt_line;
 
 /* List of types and structure classes of the current declaration.  */
-static tree current_declspecs;
+static tree current_declspecs = NULL_TREE;
 static tree prefix_attributes = NULL_TREE;
 
 /* Stack of saved values of current_declspecs and prefix_attributes.  */
@@ -307,6 +309,8 @@ end ifobjc
                    assemble_asm ($3);
                  else
                    error ("argument of `asm' is not a constant string"); }
+       | extension extdef
+               { pedantic = $<itype>1; }
        ;
 
 datadef:
@@ -343,11 +347,11 @@ datadef:
 \f
 fndef:
          typed_declspecs setspecs declarator
-               { if (! start_function ($1, $3, prefix_attributes,
-                                       NULL_TREE, 0))
+               { if (! start_function (current_declspecs, $3,
+                                       prefix_attributes, NULL_TREE, 0))
                    YYERROR1;
                  reinit_parse_for_function (); }
-         xdecls
+         old_style_parm_decls
                { store_parm_decls (); }
          compstmt_or_error
                { finish_function (0); 
@@ -361,11 +365,11 @@ fndef:
                  declspec_stack = TREE_CHAIN (declspec_stack);
                  resume_momentary ($2); }
        | declmods setspecs notype_declarator
-               { if (! start_function ($1, $3, prefix_attributes,
-                                       NULL_TREE, 0))
+               { if (! start_function (current_declspecs, $3,
+                                       prefix_attributes, NULL_TREE, 0))
                    YYERROR1;
                  reinit_parse_for_function (); }
-         xdecls
+         old_style_parm_decls
                { store_parm_decls (); }
          compstmt_or_error
                { finish_function (0); 
@@ -383,7 +387,7 @@ fndef:
                                        prefix_attributes, NULL_TREE, 0))
                    YYERROR1;
                  reinit_parse_for_function (); }
-         xdecls
+         old_style_parm_decls
                { store_parm_decls (); }
          compstmt_or_error
                { finish_function (0); 
@@ -445,11 +449,8 @@ unary_expr:
        | '*' cast_expr   %prec UNARY
                { $$ = build_indirect_ref ($2, "unary *"); }
        /* __extension__ turns off -pedantic for following primary.  */
-       | EXTENSION
-               { $<itype>1 = pedantic;
-                 pedantic = 0; }
-         cast_expr       %prec UNARY
-               { $$ = $3;
+       | extension cast_expr     %prec UNARY
+               { $$ = $2;
                  pedantic = $<itype>1; }
        | unop cast_expr  %prec UNARY
                { $$ = build_unary_op ($1, $2, 0);
@@ -483,23 +484,35 @@ unary_expr:
                      $$ = build_unary_op (ADDR_EXPR, $$, 0);
                    } }
 */
-       | SIZEOF unary_expr  %prec UNARY
-               { if (TREE_CODE ($2) == COMPONENT_REF
+       | sizeof unary_expr  %prec UNARY
+               { skip_evaluation--;
+                 if (TREE_CODE ($2) == COMPONENT_REF
                      && DECL_BIT_FIELD (TREE_OPERAND ($2, 1)))
                    error ("`sizeof' applied to a bit-field");
                  $$ = c_sizeof (TREE_TYPE ($2)); }
-       | SIZEOF '(' typename ')'  %prec HYPERUNARY
-               { $$ = c_sizeof (groktypename ($3)); }
-       | ALIGNOF unary_expr  %prec UNARY
-               { $$ = c_alignof_expr ($2); }
-       | ALIGNOF '(' typename ')'  %prec HYPERUNARY
-               { $$ = c_alignof (groktypename ($3)); }
+       | sizeof '(' typename ')'  %prec HYPERUNARY
+               { skip_evaluation--;
+                 $$ = c_sizeof (groktypename ($3)); }
+       | alignof unary_expr  %prec UNARY
+               { skip_evaluation--;
+                 $$ = c_alignof_expr ($2); }
+       | alignof '(' typename ')'  %prec HYPERUNARY
+               { skip_evaluation--;
+                 $$ = c_alignof (groktypename ($3)); }
        | REALPART cast_expr %prec UNARY
                { $$ = build_unary_op (REALPART_EXPR, $2, 0); }
        | IMAGPART cast_expr %prec UNARY
                { $$ = build_unary_op (IMAGPART_EXPR, $2, 0); }
        ;
 
+sizeof:
+       SIZEOF { skip_evaluation++; }
+       ;
+
+alignof:
+       ALIGNOF { skip_evaluation++; }
+       ;
+
 cast_expr:
        unary_expr
        | '(' typename ')' cast_expr  %prec UNARY
@@ -562,12 +575,41 @@ expr_no_commas:
                { $$ = parser_build_binary_op ($2, $1, $3); }
        | expr_no_commas '^' expr_no_commas
                { $$ = parser_build_binary_op ($2, $1, $3); }
-       | expr_no_commas ANDAND expr_no_commas
-               { $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
-       | expr_no_commas OROR expr_no_commas
-               { $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
-       | expr_no_commas '?' xexpr ':' expr_no_commas
-               { $$ = build_conditional_expr ($1, $3, $5); }
+       | expr_no_commas ANDAND
+               { $1 = truthvalue_conversion (default_conversion ($1));
+                 $<itype>2 = $1 == boolean_false_node;
+                 skip_evaluation += $<itype>2; }
+         expr_no_commas
+               { skip_evaluation -= $<itype>2;
+                 $$ = parser_build_binary_op (TRUTH_ANDIF_EXPR, $1, $4); }
+       | expr_no_commas OROR
+               { $1 = truthvalue_conversion (default_conversion ($1));
+                 $<itype>3 = $1 == boolean_true_node;
+                 skip_evaluation += $<itype>3; }
+         expr_no_commas
+               { skip_evaluation -= $<itype>3;
+                 $$ = parser_build_binary_op (TRUTH_ORIF_EXPR, $1, $4); }
+       | expr_no_commas '?'
+               { $1 = truthvalue_conversion (default_conversion ($1));
+                 $<itype>3 = $1 == boolean_true_node;
+                 $<itype>2 = $1 == boolean_false_node;
+                 skip_evaluation += $<itype>2; }
+          expr ':'
+               { skip_evaluation += $<itype>3 - $<itype>2; }
+         expr_no_commas
+               { skip_evaluation -= $<itype>3;
+                 $$ = build_conditional_expr ($1, $4, $7); }
+       | expr_no_commas '?'
+               { if (pedantic)
+                   pedwarn ("ANSI C forbids omitting the middle term of a ?: expression");
+                 /* Make sure first operand is calculated only once.  */
+                 $<ttype>2 = save_expr ($1);
+                 $1 = truthvalue_conversion (default_conversion ($<ttype>2));
+                 $<itype>3 = $1 == boolean_true_node;
+                 skip_evaluation += $<itype>3; }
+         ':' expr_no_commas
+               { skip_evaluation -= $<itype>3;
+                 $$ = build_conditional_expr ($1, $<ttype>2, $5); }
        | expr_no_commas '=' expr_no_commas
                { $$ = build_modify_expr ($1, NOP_EXPR, $3);
                  C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); }
@@ -862,7 +904,7 @@ objc_string:
        ;
 end ifobjc
 
-xdecls:
+old_style_parm_decls:
        /* empty */
        | datadecls
        | datadecls ELLIPSIS
@@ -887,21 +929,25 @@ datadecls:
        | lineno_datadecl errstmt
        ;
 
+/* We don't allow prefix attributes here because they cause reduce/reduce
+   conflicts: we can't know whether we're parsing a function decl with
+   attribute suffix, or function defn with attribute prefix on first old
+   style parm.  */
 datadecl:
-       typed_declspecs setspecs initdecls ';'
+       typed_declspecs_no_prefix_attr setspecs initdecls ';'
                { current_declspecs = TREE_VALUE (declspec_stack);
                  prefix_attributes = TREE_PURPOSE (declspec_stack);
                  declspec_stack = TREE_CHAIN (declspec_stack);
                  resume_momentary ($2); }
-       | declmods setspecs notype_initdecls ';'
+       | declmods_no_prefix_attr 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 ';'
+       | typed_declspecs_no_prefix_attr ';'
                { shadow_tag_warned ($1, 1);
                  pedwarn ("empty declaration"); }
-       | declmods ';'
+       | declmods_no_prefix_attr ';'
                { pedwarn ("empty declaration"); }
        ;
 
@@ -931,10 +977,11 @@ setspecs: /* empty */
                  declspec_stack = tree_cons (prefix_attributes,
                                              current_declspecs,
                                              declspec_stack);
-                 current_declspecs = $<ttype>0; 
-                 prefix_attributes = NULL_TREE; }
+                 split_specs_attrs ($<ttype>0,
+                                    &current_declspecs, &prefix_attributes); }
        ;
 
+/* ??? Yuck.  See after_type_declarator.  */
 setattrs: /* empty */
                { prefix_attributes = chainon (prefix_attributes, $<ttype>0); }
        ;
@@ -964,11 +1011,14 @@ decl:
                { shadow_tag ($1); }
        | declmods ';'
                { pedwarn ("empty declaration"); }
+       | extension decl
+               { pedantic = $<itype>1; }
        ;
 
 /* Declspecs which contain at least one type specifier or typedef name.
    (Just `const' or `volatile' is not enough.)
-   A typedef'd name following these is taken as a name to be declared.  */
+   A typedef'd name following these is taken as a name to be declared.
+   Declspecs have a non-NULL TREE_VALUE, attributes do not.  */
 
 typed_declspecs:
          typespec reserved_declspecs
@@ -986,22 +1036,55 @@ reserved_declspecs:  /* empty */
                    warning ("`%s' is not at beginning of declaration",
                             IDENTIFIER_POINTER ($2));
                  $$ = tree_cons (NULL_TREE, $2, $1); }
+       | reserved_declspecs attributes
+               { $$ = tree_cons ($2, NULL_TREE, $1); }
        ;
 
-/* List of just storage classes and type modifiers.
+typed_declspecs_no_prefix_attr:
+         typespec reserved_declspecs_no_prefix_attr
+               { $$ = tree_cons (NULL_TREE, $1, $2); }
+       | declmods_no_prefix_attr typespec reserved_declspecs_no_prefix_attr
+               { $$ = chainon ($3, tree_cons (NULL_TREE, $2, $1)); }
+       ;
+
+reserved_declspecs_no_prefix_attr:
+         /* empty */
+               { $$ = NULL_TREE; }
+       | reserved_declspecs_no_prefix_attr typespecqual_reserved
+               { $$ = tree_cons (NULL_TREE, $2, $1); }
+       | reserved_declspecs_no_prefix_attr SCSPEC
+               { if (extra_warnings)
+                   warning ("`%s' is not at beginning of declaration",
+                            IDENTIFIER_POINTER ($2));
+                 $$ = tree_cons (NULL_TREE, $2, $1); }
+       ;
+
+/* List of just storage classes, type modifiers, and prefix attributes.
    A declaration can start with just this, but then it cannot be used
-   to redeclare a typedef-name.  */
+   to redeclare a typedef-name.
+   Declspecs have a non-NULL TREE_VALUE, attributes do not.  */
 
 declmods:
+         declmods_no_prefix_attr
+               { $$ = $1; }
+       | attributes
+               { $$ = tree_cons ($1, NULL_TREE, NULL_TREE); }
+       | declmods declmods_no_prefix_attr
+               { $$ = chainon ($2, $1); }
+       | declmods attributes
+               { $$ = tree_cons ($2, NULL_TREE, $1); }
+       ;
+
+declmods_no_prefix_attr:
          TYPE_QUAL
                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);
                  TREE_STATIC ($$) = 1; }
        | SCSPEC
                { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
-       | declmods TYPE_QUAL
+       | declmods_no_prefix_attr TYPE_QUAL
                { $$ = tree_cons (NULL_TREE, $2, $1);
                  TREE_STATIC ($$) = 1; }
-       | declmods SCSPEC
+       | declmods_no_prefix_attr SCSPEC
                { if (extra_warnings && TREE_STATIC ($1))
                    warning ("`%s' is not at beginning of declaration",
                             IDENTIFIER_POINTER ($2));
@@ -1238,7 +1321,7 @@ nested_function:
                      YYERROR1;
                    }
                  reinit_parse_for_function (); }
-          xdecls
+          old_style_parm_decls
                { store_parm_decls (); }
 /* This used to use compstmt_or_error.
    That caused a bug with input `f(g) int g {}',
@@ -1261,7 +1344,7 @@ notype_nested_function:
                      YYERROR1;
                    }
                  reinit_parse_for_function (); }
-         xdecls
+         old_style_parm_decls
                { store_parm_decls (); }
 /* This used to use compstmt_or_error.
    That caused a bug with input `f(g) int g {}',
@@ -1298,6 +1381,11 @@ after_type_declarator:
                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
        | '*' type_quals after_type_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
+       /* ??? Yuck.  setattrs is a quick hack.  We can't use
+          prefix_attributes because $1 only applies to this
+          declarator.  We assume setspecs has already been done.
+          setattrs also avoids 5 reduce/reduce conflicts (otherwise multiple
+          attributes could be recognized here or in `attributes').  */
        | attributes setattrs after_type_declarator
                { $$ = $3; }
        | TYPENAME
@@ -1323,6 +1411,11 @@ parm_declarator:
                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
        | '*' type_quals parm_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
+       /* ??? Yuck.  setattrs is a quick hack.  We can't use
+          prefix_attributes because $1 only applies to this
+          declarator.  We assume setspecs has already been done.
+          setattrs also avoids 5 reduce/reduce conflicts (otherwise multiple
+          attributes could be recognized here or in `attributes').  */
        | attributes setattrs parm_declarator
                { $$ = $3; }
        | TYPENAME
@@ -1345,6 +1438,11 @@ notype_declarator:
                { $$ = build_nt (ARRAY_REF, $1, $3); }
        | notype_declarator '[' ']'  %prec '.'
                { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+       /* ??? Yuck.  setattrs is a quick hack.  We can't use
+          prefix_attributes because $1 only applies to this
+          declarator.  We assume setspecs has already been done.
+          setattrs also avoids 5 reduce/reduce conflicts (otherwise multiple
+          attributes could be recognized here or in `attributes').  */
        | attributes setattrs notype_declarator
                { $$ = $3; }
        | IDENTIFIER
@@ -1467,6 +1565,9 @@ component_decl:
                  $$ = NULL_TREE; }
        | error
                { $$ = NULL_TREE; }
+       | extension component_decl
+               { $$ = $2;
+                 pedantic = $<itype>1; }
        ;
 
 components:
@@ -1559,8 +1660,8 @@ absdcl1:  /* a nonempty absolute declarator */
                { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
        | '[' ']'  %prec '.'
                { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
-       | attributes setattrs absdcl1
-               { $$ = $3; }
+       /* ??? It appears we have to support attributes here, however
+          using prefix_attributes is wrong.  */
        ;
 
 /* at least one statement, the first of which parses without error.  */
@@ -2260,6 +2361,12 @@ identifiers_or_typenames:
        | identifiers_or_typenames ',' identifier
                { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
        ;
+
+extension:
+       EXTENSION
+               { $<itype>$ = pedantic;
+                 pedantic = 0; }
+       ;
 \f
 ifobjc
 /* Objective-C productions.  */