OSDN Git Service

(emit_cmp_insn): Likewise for memcmp and bcmp.
[pf3gnuchains/gcc-fork.git] / gcc / c-parse.in
index b4eea8e..044e452 100644 (file)
@@ -15,7 +15,8 @@ GNU General Public License for more details.
 
 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.
@@ -27,10 +28,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
    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.
@@ -102,7 +103,7 @@ void yyerror ();
 %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 */
@@ -209,6 +210,8 @@ void yyerror ();
 
 %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
@@ -310,11 +313,22 @@ datadef:
                { 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 ';'
@@ -328,35 +342,59 @@ datadef:
 \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:
@@ -814,7 +852,7 @@ string:
        ;
 
 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
@@ -1164,7 +1202,7 @@ initelt:
        | 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); }
@@ -1188,7 +1226,7 @@ nested_function:
          declarator
                { push_c_function_context ();
                  if (! start_function (current_declspecs, $1,
-                                       prefix_attributes, 1))
+                                       prefix_attributes, NULL_TREE, 1))
                    {
                      pop_c_function_context ();
                      YYERROR1;
@@ -1211,7 +1249,7 @@ notype_nested_function:
          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;
@@ -1452,7 +1490,10 @@ component_declarator:
 enumlist:
          enumerator
        | enumlist ',' enumerator
-               { $$ = chainon ($3, $1); }
+               { if ($1 == error_mark_node)
+                   $$ = $1;
+                 else
+                   $$ = chainon ($3, $1); }
        | error
                { $$ = error_mark_node; }
        ;
@@ -1521,9 +1562,19 @@ absdcl1:  /* a nonempty absolute declarator */
    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:
@@ -1663,19 +1714,14 @@ lineno_labeled_stmt:
 
 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.  */
@@ -2118,16 +2164,52 @@ parms:
 /* 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
@@ -2399,15 +2481,17 @@ ivar_decls:
 
 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; }
        ;
@@ -2584,7 +2668,10 @@ mydecls:
 
 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 ';'
@@ -2602,12 +2689,21 @@ myparms:
    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: