OSDN Git Service

* c-parse.in (array_declarator): New. Handle C99 constructs.
[pf3gnuchains/gcc-fork.git] / gcc / c-parse.in
index ab2073e..e64e140 100644 (file)
@@ -197,6 +197,8 @@ end ifc
 %type <ttype> declarator
 %type <ttype> notype_declarator after_type_declarator
 %type <ttype> parm_declarator
+%type <ttype> parm_declarator_starttypename parm_declarator_nostarttypename
+%type <ttype> array_declarator
 
 %type <ttype> structsp_attr structsp_nonattr
 %type <ttype> component_decl_list component_decl_list2
@@ -271,6 +273,7 @@ tree objc_ivar_context;
 enum tree_code objc_inherit_code;
 int objc_receiver_context;
 int objc_public_flag;
+int objc_pq_context;
 
 end ifobjc
 
@@ -1666,10 +1669,8 @@ after_type_declarator:
 /*     | after_type_declarator '(' error ')'  %prec '.'
                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
                  poplevel (0, 0, 0); }  */
-       | after_type_declarator '[' expr ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, $3); }
-       | after_type_declarator '[' ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+       | after_type_declarator array_declarator  %prec '.'
+               { $$ = set_array_declarator_type ($2, $1, 0); }
        | '*' maybe_type_quals_setattrs after_type_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
        | TYPENAME
@@ -1682,29 +1683,38 @@ end ifobjc
    in addition to notype_declarator.  This is like after_type_declarator
    but does not allow a typedef name in parentheses as an identifier
    (because it would conflict with a function with that typedef as arg).  */
-
 parm_declarator:
-         parm_declarator '(' parmlist_or_identifiers  %prec '.'
+         parm_declarator_starttypename
+       | parm_declarator_nostarttypename
+       ;
+
+parm_declarator_starttypename:
+         parm_declarator_starttypename '(' parmlist_or_identifiers  %prec '.'
                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
-/*     | parm_declarator '(' error ')'  %prec '.'
+/*     | parm_declarator_starttypename '(' error ')'  %prec '.'
                { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
                  poplevel (0, 0, 0); }  */
-ifc
-       | parm_declarator '[' '*' ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
-                 if (! flag_isoc99)
-                   error ("`[*]' in parameter declaration only allowed in ISO C 99");
-               }
-end ifc
-       | parm_declarator '[' expr ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, $3); }
-       | parm_declarator '[' ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
-       | '*' maybe_type_quals_setattrs parm_declarator  %prec UNARY
-               { $$ = make_pointer_declarator ($2, $3); }
+       | parm_declarator_starttypename array_declarator  %prec '.'
+               { $$ = set_array_declarator_type ($2, $1, 0); }
        | TYPENAME
        ;
 
+parm_declarator_nostarttypename:
+         parm_declarator_nostarttypename '(' parmlist_or_identifiers  %prec '.'
+               { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
+/*     | parm_declarator_nostarttypename '(' error ')'  %prec '.'
+               { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE);
+                 poplevel (0, 0, 0); }  */
+       | parm_declarator_nostarttypename array_declarator  %prec '.'
+               { $$ = set_array_declarator_type ($2, $1, 0); }
+       | '*' maybe_type_quals_setattrs parm_declarator_starttypename  %prec UNARY
+               { $$ = make_pointer_declarator ($2, $3); }
+       | '*' maybe_type_quals_setattrs parm_declarator_nostarttypename  %prec UNARY
+               { $$ = make_pointer_declarator ($2, $3); }
+       | '(' maybe_setattrs parm_declarator_nostarttypename ')'
+               { $$ = $3; }
+       ;
+
 /* A declarator allowed whether or not there has been
    an explicit typespec.  These cannot redeclare a typedef-name.  */
 
@@ -1718,17 +1728,8 @@ notype_declarator:
                { $$ = $3; }
        | '*' maybe_type_quals_setattrs notype_declarator  %prec UNARY
                { $$ = make_pointer_declarator ($2, $3); }
-ifc
-       | notype_declarator '[' '*' ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, NULL_TREE);
-                 if (! flag_isoc99)
-                   error ("`[*]' in parameter declaration only allowed in ISO C 99");
-               }
-end ifc
-       | notype_declarator '[' expr ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, $3); }
-       | notype_declarator '[' ']'  %prec '.'
-               { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+       | notype_declarator array_declarator  %prec '.'
+               { $$ = set_array_declarator_type ($2, $1, 0); }
        | IDENTIFIER
        ;
 
@@ -2006,16 +2007,42 @@ direct_absdcl1:
                { $$ = $3; }
        | direct_absdcl1 '(' parmlist
                { $$ = build_nt (CALL_EXPR, $1, $3, NULL_TREE); }
-       | direct_absdcl1 '[' expr ']'
-               { $$ = build_nt (ARRAY_REF, $1, $3); }
-       | direct_absdcl1 '[' ']'
-               { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); }
+       | direct_absdcl1 array_declarator
+               { $$ = set_array_declarator_type ($2, $1, 1); }
        | '(' parmlist
                { $$ = build_nt (CALL_EXPR, NULL_TREE, $2, NULL_TREE); }
-       | '[' expr ']'
-               { $$ = build_nt (ARRAY_REF, NULL_TREE, $2); }
+       | array_declarator
+               { $$ = set_array_declarator_type ($1, NULL_TREE, 1); }
+       ;
+
+/* The [...] part of a declarator for an array type.  */
+
+array_declarator:
+         '[' expr ']'
+               { $$ = build_array_declarator ($2, NULL_TREE, 0, 0); }
+       | '[' declspecs_nosc expr ']'
+               { $$ = build_array_declarator ($3, $2, 0, 0); }
        | '[' ']'
-               { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); }
+               { $$ = build_array_declarator (NULL_TREE, NULL_TREE, 0, 0); }
+       | '[' declspecs_nosc ']'
+               { $$ = build_array_declarator (NULL_TREE, $2, 0, 0); }
+       | '[' '*' ']'
+               { $$ = build_array_declarator (NULL_TREE, NULL_TREE, 0, 1); }
+       | '[' declspecs_nosc '*' ']'
+               { $$ = build_array_declarator (NULL_TREE, $2, 0, 1); }
+       | '[' SCSPEC expr ']'
+               { if (C_RID_CODE ($2) != RID_STATIC)
+                   error ("storage class specifier in array declarator");
+                 $$ = build_array_declarator ($3, NULL_TREE, 1, 0); }
+       | '[' SCSPEC declspecs_nosc expr ']'
+               { if (C_RID_CODE ($2) != RID_STATIC)
+                   error ("storage class specifier in array declarator");
+                 $$ = build_array_declarator ($4, $3, 1, 0); }
+       | '[' declspecs_nosc SCSPEC expr ']'
+               { if (C_RID_CODE ($3) != RID_STATIC)
+                   error ("storage class specifier in array declarator");
+                 $$ = build_array_declarator ($4, $2, 1, 0); }
+       ;
 
 /* A nonempty series of declarations and statements (possibly followed by
    some labels) that can form the body of a compound statement.
@@ -2837,13 +2864,13 @@ classdef:
 protocoldef:
          PROTOCOL identifier protocolrefs
                {
-                 remember_protocol_qualifiers ();
+                 objc_pq_context = 1;
                  objc_interface_context
                    = start_protocol(PROTOCOL_INTERFACE_TYPE, $2, $3);
                }
          methodprotolist END
                {
-                 forget_protocol_qualifiers();
+                 objc_pq_context = 0;
                  finish_protocol(objc_interface_context);
                  objc_interface_context = NULL_TREE;
                }
@@ -2946,44 +2973,27 @@ ivar_declarator:
                 }
        ;
 
-methoddef:
+methodtype:
          '+'
-               {
-                 remember_protocol_qualifiers ();
-                 if (objc_implementation_context)
-                   objc_inherit_code = CLASS_METHOD_DECL;
-                  else
-                   fatal_error ("method definition not in class context");
-               }
-         methoddecl
-               {
-                 forget_protocol_qualifiers ();
-                 add_class_method (objc_implementation_context, $3);
-                 start_method_def ($3);
-                 objc_method_context = $3;
-               }
-         optarglist
-               {
-                 continue_method_def ();
-               }
-         compstmt_or_error
-               {
-                 finish_method_def ();
-                 objc_method_context = NULL_TREE;
-               }
-
+               { objc_inherit_code = CLASS_METHOD_DECL; }
        | '-'
+               { objc_inherit_code = INSTANCE_METHOD_DECL; }
+       ;
+
+methoddef:
+         methodtype
                {
-                 remember_protocol_qualifiers ();
-                 if (objc_implementation_context)
-                   objc_inherit_code = INSTANCE_METHOD_DECL;
-                  else
+                 objc_pq_context = 1;
+                 if (!objc_implementation_context)
                    fatal_error ("method definition not in class context");
                }
          methoddecl
                {
-                 forget_protocol_qualifiers ();
-                 add_instance_method (objc_implementation_context, $3);
+                 objc_pq_context = 0;
+                 if (objc_inherit_code == CLASS_METHOD_DECL)
+                   add_class_method (objc_implementation_context, $3);
+                 else
+                   add_instance_method (objc_implementation_context, $3);
                  start_method_def ($3);
                  objc_method_context = $3;
                }
@@ -3020,31 +3030,19 @@ semi_or_error:
        ;
 
 methodproto:
-         '+'
+         methodtype
                {
                  /* Remember protocol qualifiers in prototypes.  */
-                 remember_protocol_qualifiers ();
-                 objc_inherit_code = CLASS_METHOD_DECL;
+                 objc_pq_context = 1;
                }
          methoddecl
                {
                  /* Forget protocol qualifiers here.  */
-                 forget_protocol_qualifiers ();
-                 add_class_method (objc_interface_context, $3);
-               }
-         semi_or_error
-
-       | '-'
-               {
-                 /* Remember protocol qualifiers in prototypes.  */
-                 remember_protocol_qualifiers ();
-                 objc_inherit_code = INSTANCE_METHOD_DECL;
-               }
-         methoddecl
-               {
-                 /* Forget protocol qualifiers here.  */
-                 forget_protocol_qualifiers ();
-                 add_instance_method (objc_interface_context, $3);
+                 objc_pq_context = 0;
+                 if (objc_inherit_code == CLASS_METHOD_DECL)
+                   add_class_method (objc_interface_context, $3);
+                 else
+                   add_instance_method (objc_interface_context, $3);
                }
          semi_or_error
        ;
@@ -3615,9 +3613,6 @@ ifobjc
          = get_identifier (reswords[i].word + 1);
 end ifobjc
     }
-ifobjc
-  save_and_forget_protocol_qualifiers ();
-end ifobjc
 }
 
 const char *
@@ -3683,22 +3678,28 @@ yylexname ()
   if (C_IS_RESERVED_WORD (yylval.ttype))
     {
       enum rid rid_code = C_RID_CODE (yylval.ttype);
-      int yycode = rid_to_yy[(int) rid_code];
 
-      if (yycode == STRING_FUNC_NAME)
-       {
-          /* __FUNCTION__ and __PRETTY_FUNCTION__ get converted
-             to string constants.  */
-         const char *name = fname_string (rid_code);
+ifobjc
+      if (!((unsigned int) rid_code - (unsigned int) RID_FIRST_PQ < 6)
+         || objc_pq_context)
+end ifobjc
+      {
+       int yycode = rid_to_yy[(int) rid_code];
+       if (yycode == STRING_FUNC_NAME)
+         {
+           /* __FUNCTION__ and __PRETTY_FUNCTION__ get converted
+              to string constants.  */
+           const char *name = fname_string (rid_code);
          
-         yylval.ttype = build_string (strlen (name) + 1, name);
-         last_token = CPP_STRING;  /* so yyerror won't choke */
-         return STRING;
-       }
+           yylval.ttype = build_string (strlen (name) + 1, name);
+           last_token = CPP_STRING;  /* so yyerror won't choke */
+           return STRING;
+         }
       
-      /* Return the canonical spelling for this keyword.  */
-      yylval.ttype = ridpointers[(int) rid_code];
-      return yycode;
+       /* Return the canonical spelling for this keyword.  */
+       yylval.ttype = ridpointers[(int) rid_code];
+       return yycode;
+      }
     }
 
   decl = lookup_name (yylval.ttype);