%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
enum tree_code objc_inherit_code;
int objc_receiver_context;
int objc_public_flag;
+int objc_pq_context;
end ifobjc
/* | 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
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. */
{ $$ = $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
;
{ $$ = $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.
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;
}
}
;
-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;
}
;
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
;
= get_identifier (reswords[i].word + 1);
end ifobjc
}
-ifobjc
- save_and_forget_protocol_qualifiers ();
-end ifobjc
}
const char *
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);