Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996,
1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+along with GCC; see the file COPYING. If not, write to 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 31
+%expect 31 /* shift/reduce conflicts, and 1 reduce/reduce conflict. */
end ifobjc
ifc
-%expect 10
+%expect 10 /* shift/reduce conflicts, and no reduce/reduce conflicts. */
end ifc
%{
#include "config.h"
#include "system.h"
-#include <setjmp.h>
#include "tree.h"
#include "input.h"
#include "cpplib.h"
static tree current_declspecs = NULL_TREE;
static tree prefix_attributes = NULL_TREE;
-/* Stack of saved values of current_declspecs and prefix_attributes. */
+/* List of all the attributes applying to the identifier currently being
+ declared; includes prefix_attributes and possibly some more attributes
+ just after a comma. */
+static tree all_prefix_attributes = NULL_TREE;
+
+/* Stack of saved values of current_declspecs, prefix_attributes and
+ all_prefix_attributes. */
static tree declspec_stack;
+/* PUSH_DECLSPEC_STACK is called from setspecs; POP_DECLSPEC_STACK
+ should be called from the productions making use of setspecs. */
+#define PUSH_DECLSPEC_STACK \
+ do { \
+ declspec_stack = tree_cons (build_tree_list (prefix_attributes, \
+ all_prefix_attributes), \
+ current_declspecs, \
+ declspec_stack); \
+ } while (0)
+
+#define POP_DECLSPEC_STACK \
+ do { \
+ current_declspecs = TREE_VALUE (declspec_stack); \
+ prefix_attributes = TREE_PURPOSE (TREE_PURPOSE (declspec_stack)); \
+ all_prefix_attributes = TREE_VALUE (TREE_PURPOSE (declspec_stack)); \
+ declspec_stack = TREE_CHAIN (declspec_stack); \
+ } while (0)
+
/* For __extension__, save/restore the warning flags which are
controlled by __extension__. */
#define SAVE_WARN_FLAGS() \
int objc_public_flag;
int objc_pq_context;
+/* The following flag is needed to contextualize ObjC lexical analysis.
+ In some cases (e.g., 'int NSObject;'), it is undesirable to bind
+ an identifier to an ObjC class, even if a class with that name
+ exists. */
+int objc_need_raw_identifier;
+#define OBJC_NEED_RAW_IDENTIFIER(VAL) objc_need_raw_identifier = VAL
end ifobjc
+ifc
+#define OBJC_NEED_RAW_IDENTIFIER(VAL) /* nothing */
+end ifc
+
/* Tell yyparse how to print a token's value, if yydebug is set. */
#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL)
ggc_add_tree_root (&declspec_stack, 1);
ggc_add_tree_root (¤t_declspecs, 1);
ggc_add_tree_root (&prefix_attributes, 1);
+ ggc_add_tree_root (&all_prefix_attributes, 1);
ifobjc
ggc_add_tree_root (&objc_interface_context, 1);
ggc_add_tree_root (&objc_implementation_context, 1);
else if (!flag_traditional)
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); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts setspecs initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs ';'
{ shadow_tag ($1); }
| error ';'
fndef:
declspecs_ts setspecs declarator
{ if (! start_function (current_declspecs, $3,
- prefix_attributes))
+ all_prefix_attributes))
YYERROR1;
}
old_style_parm_decls
{ DECL_SOURCE_FILE (current_function_decl) = $7;
DECL_SOURCE_LINE (current_function_decl) = $8;
finish_function (0);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_ts setspecs declarator error
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator
{ if (! start_function (current_declspecs, $3,
- prefix_attributes))
+ all_prefix_attributes))
YYERROR1;
}
old_style_parm_decls
{ DECL_SOURCE_FILE (current_function_decl) = $7;
DECL_SOURCE_LINE (current_function_decl) = $8;
finish_function (0);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator error
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| setspecs notype_declarator
{ if (! start_function (NULL_TREE, $2,
- prefix_attributes))
+ all_prefix_attributes))
YYERROR1;
}
old_style_parm_decls
{ DECL_SOURCE_FILE (current_function_decl) = $6;
DECL_SOURCE_LINE (current_function_decl) = $7;
finish_function (0);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| setspecs notype_declarator error
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
;
identifier:
| TYPENAME
ifobjc
| OBJECTNAME
- | CLASSNAME
+ | CLASSNAME
end ifobjc
;
style parm. */
datadecl:
declspecs_ts_nosa setspecs initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots_nosa setspecs notype_initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts_nosa ';'
{ shadow_tag_warned ($1, 1);
pedwarn ("empty declaration"); }
for the sake of parm declarations nested in function declarators. */
setspecs: /* empty */
{ pending_xref_error ();
- declspec_stack = tree_cons (prefix_attributes,
- current_declspecs,
- declspec_stack);
+ PUSH_DECLSPEC_STACK;
split_specs_attrs ($<ttype>0,
- ¤t_declspecs, &prefix_attributes); }
+ ¤t_declspecs, &prefix_attributes);
+ all_prefix_attributes = prefix_attributes; }
;
/* ??? Yuck. See maybe_setattrs. */
setattrs: /* empty */
- { prefix_attributes = chainon (prefix_attributes, $<ttype>0); }
+ { all_prefix_attributes = chainon ($<ttype>0, all_prefix_attributes); }
;
maybe_setattrs:
maybe_attribute setattrs
;
+/* Possibly attributes after a comma, which should reset all_prefix_attributes
+ to prefix_attributes with these ones chained on the front. */
+maybe_resetattrs:
+ { all_prefix_attributes = prefix_attributes; }
+ maybe_setattrs
+ ;
+
decl:
declspecs_ts setspecs initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_initdecls ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts setspecs nested_function
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_nested_function
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs ';'
{ shadow_tag ($1); }
| extension decl
split_specs_attrs ($1, &specs, &attrs);
/* ??? Yuck. See maybe_setattrs. */
if (attrs != NULL_TREE)
- prefix_attributes = chainon (prefix_attributes, attrs);
+ all_prefix_attributes = chainon (attrs, all_prefix_attributes);
$$ = specs; }
;
typespec_reserved_nonattr:
TYPESPEC
+ { OBJC_NEED_RAW_IDENTIFIER (1); }
| structsp_nonattr
;
initdecls:
initdcl
- | initdecls ',' maybe_setattrs initdcl
+ | initdecls ',' maybe_resetattrs initdcl
;
notype_initdecls:
notype_initdcl
- | notype_initdecls ',' maybe_setattrs notype_initdcl
+ | notype_initdecls ',' maybe_resetattrs notype_initdcl
;
maybeasm:
initdcl:
declarator maybeasm maybe_attribute '='
{ $<ttype>$ = start_decl ($1, current_declspecs, 1,
- chainon ($3, prefix_attributes));
+ chainon ($3, all_prefix_attributes));
start_init ($<ttype>$, $2, global_bindings_p ()); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
finish_decl ($<ttype>5, $6, $2); }
| declarator maybeasm maybe_attribute
{ tree d = start_decl ($1, current_declspecs, 0,
- chainon ($3, prefix_attributes));
+ chainon ($3, all_prefix_attributes));
finish_decl (d, NULL_TREE, $2);
}
;
notype_initdcl:
notype_declarator maybeasm maybe_attribute '='
{ $<ttype>$ = start_decl ($1, current_declspecs, 1,
- chainon ($3, prefix_attributes));
+ chainon ($3, all_prefix_attributes));
start_init ($<ttype>$, $2, global_bindings_p ()); }
init
/* Note how the declaration of the variable is in effect while its init is parsed! */
finish_decl ($<ttype>5, $6, $2); }
| notype_declarator maybeasm maybe_attribute
{ tree d = start_decl ($1, current_declspecs, 0,
- chainon ($3, prefix_attributes));
+ chainon ($3, all_prefix_attributes));
finish_decl (d, NULL_TREE, $2); }
;
/* the * rules are dummies to accept the Apollo extended syntax
push_function_context ();
if (! start_function (current_declspecs, $1,
- prefix_attributes))
+ all_prefix_attributes))
{
pop_function_context ();
YYERROR1;
push_function_context ();
if (! start_function (current_declspecs, $1,
- prefix_attributes))
+ all_prefix_attributes))
{
pop_function_context ();
YYERROR1;
| parm_declarator_starttypename array_declarator %prec '.'
{ $$ = set_array_declarator_type ($2, $1, 0); }
| TYPENAME
+ifobjc
+ | OBJECTNAME
+end ifobjc
;
parm_declarator_nostarttypename:
component_decl:
declspecs_nosc_ts setspecs components
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_ts setspecs save_filename save_lineno
{
/* Support for unnamed structs or unions as members of
pedwarn ("ISO C doesn't support unnamed structs/unions");
$$ = grokfield($3, $4, NULL, current_declspecs, NULL_TREE);
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack);
- }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_nots setspecs components_notype
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_nots
{ if (pedantic)
pedwarn ("ISO C forbids member declarations with no members");
components:
component_declarator
- | components ',' maybe_setattrs component_declarator
+ | components ',' maybe_resetattrs component_declarator
{ $$ = chainon ($1, $4); }
;
components_notype:
component_notype_declarator
- | components_notype ',' maybe_setattrs component_notype_declarator
+ | components_notype ',' maybe_resetattrs component_notype_declarator
{ $$ = chainon ($1, $4); }
;
component_declarator:
save_filename save_lineno declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes (&$$, chainon ($4, prefix_attributes), 0); }
+ decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); }
| save_filename save_lineno
declarator ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes (&$$, chainon ($6, prefix_attributes), 0); }
+ decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); }
| save_filename save_lineno ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes (&$$, chainon ($5, prefix_attributes), 0); }
+ decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); }
;
component_notype_declarator:
save_filename save_lineno notype_declarator maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, NULL_TREE);
- decl_attributes (&$$, chainon ($4, prefix_attributes), 0); }
+ decl_attributes (&$$, chainon ($4, all_prefix_attributes), 0); }
| save_filename save_lineno
notype_declarator ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, $3, current_declspecs, $5);
- decl_attributes (&$$, chainon ($6, prefix_attributes), 0); }
+ decl_attributes (&$$, chainon ($6, all_prefix_attributes), 0); }
| save_filename save_lineno ':' expr_no_commas maybe_attribute
{ $$ = grokfield ($1, $2, NULL_TREE, current_declspecs, $4);
- decl_attributes (&$$, chainon ($5, prefix_attributes), 0); }
+ decl_attributes (&$$, chainon ($5, all_prefix_attributes), 0); }
;
/* We chain the enumerators in reverse order.
/* empty */
{ $$ = build_tree_list (build_tree_list (current_declspecs,
NULL_TREE),
- prefix_attributes); }
+ all_prefix_attributes); }
| absdcl1
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- prefix_attributes); }
+ all_prefix_attributes); }
| absdcl1_noea attributes
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- chainon ($2, prefix_attributes)); }
+ chainon ($2, all_prefix_attributes)); }
;
absdcl1: /* a nonempty absolute declarator */
declspecs_ts setspecs parm_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- chainon ($4, prefix_attributes));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts setspecs notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- chainon ($4, prefix_attributes));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts setspecs absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- chainon ($4, prefix_attributes));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_nots setspecs absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
;
/* The first parm, which must suck attributes from off the top of the parser
declspecs_ts_nosa setspecs_fp parm_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- chainon ($4, prefix_attributes));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts_nosa setspecs_fp notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- chainon ($4, prefix_attributes));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_ts_nosa setspecs_fp absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nots_nosa setspecs_fp notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$3),
- chainon ($4, prefix_attributes));
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ chainon ($4, all_prefix_attributes));
+ POP_DECLSPEC_STACK; }
| declspecs_nots_nosa setspecs_fp absdcl_maybe_attribute
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
;
setspecs_fp:
setspecs
- { prefix_attributes = chainon (prefix_attributes, $<ttype>-2); }
+ { prefix_attributes = chainon (prefix_attributes, $<ttype>-2);
+ all_prefix_attributes = prefix_attributes; }
;
/* This is used in a function definition
finish_protocol(objc_interface_context);
objc_interface_context = NULL_TREE;
}
+ /* The @protocol forward-declaration production introduces a
+ reduce/reduce conflict on ';', which should be resolved in
+ favor of the production 'identifier_list -> identifier'. */
+ | PROTOCOL identifier_list ';'
+ {
+ objc_declare_protocols ($2);
+ }
;
protocolrefs:
ivar_decl:
declspecs_nosc_ts setspecs ivars
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| declspecs_nosc_nots setspecs ivars
{ $$ = $3;
- current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ POP_DECLSPEC_STACK; }
| error
{ $$ = NULL_TREE; }
;
/* empty */
{ $$ = NULL_TREE; }
| ivar_declarator
- | ivars ',' maybe_setattrs ivar_declarator
+ | ivars ',' maybe_resetattrs ivar_declarator
;
ivar_declarator:
mydecl:
declspecs_ts setspecs myparms ';'
- { current_declspecs = TREE_VALUE (declspec_stack);
- prefix_attributes = TREE_PURPOSE (declspec_stack);
- declspec_stack = TREE_CHAIN (declspec_stack); }
+ { POP_DECLSPEC_STACK; }
| declspecs_ts ';'
{ shadow_tag ($1); }
| declspecs_nots ';'
parm_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- chainon ($2, prefix_attributes)); }
+ chainon ($2, all_prefix_attributes)); }
| notype_declarator maybe_attribute
{ $$ = build_tree_list (build_tree_list (current_declspecs,
$1),
- chainon ($2, prefix_attributes)); }
+ chainon ($2, all_prefix_attributes)); }
| absdcl_maybe_attribute
{ $$ = $1; }
;
selector:
IDENTIFIER
- | TYPENAME
- | OBJECTNAME
+ | TYPENAME
+ | CLASSNAME
+ | OBJECTNAME
| reservedwords
;
else if (last_token == CPP_STRING
|| last_token == CPP_WSTRING)
error ("%s before string constant", string);
- else if (last_token == CPP_NUMBER
- || last_token == CPP_INT
- || last_token == CPP_FLOAT)
+ else if (last_token == CPP_NUMBER)
error ("%s before numeric constant", string);
else if (last_token == CPP_NAME)
error ("%s before \"%s\"", string, IDENTIFIER_POINTER (yylval.ttype));
yylexname ()
{
tree decl;
-
+
+ifobjc
+ int objc_force_identifier = objc_need_raw_identifier;
+ OBJC_NEED_RAW_IDENTIFIER (0);
+end ifobjc
+
if (C_IS_RESERVED_WORD (yylval.ttype))
{
enum rid rid_code = C_RID_CODE (yylval.ttype);
ifobjc
+ /* Turn non-typedefed refs to "id" into plain identifiers; this
+ allows constructs like "void foo(id id);" to work. */
+ if (rid_code == RID_ID)
+ {
+ decl = lookup_name (yylval.ttype);
+ if (decl == NULL_TREE || TREE_CODE (decl) != TYPE_DECL)
+ return IDENTIFIER;
+ }
+
if (!OBJC_IS_AT_KEYWORD (rid_code)
&& (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
end ifobjc
else
{
tree objc_interface_decl = is_class_name (yylval.ttype);
-
- if (objc_interface_decl)
+ /* ObjC class names are in the same namespace as variables and
+ typedefs, and hence are shadowed by local declarations. */
+ if (objc_interface_decl
+ && (global_bindings_p ()
+ || (!objc_force_identifier && !decl)))
{
yylval.ttype = objc_interface_decl;
return CLASSNAME;
case CPP_AND_AND: return ANDAND;
case CPP_OR_OR: return OROR;
case CPP_QUERY: return '?';
- case CPP_COLON: return ':';
- case CPP_COMMA: return ',';
case CPP_OPEN_PAREN: return '(';
- case CPP_CLOSE_PAREN: return ')';
case CPP_EQ_EQ: yylval.code = EQ_EXPR; return EQCOMPARE;
case CPP_NOT_EQ: yylval.code = NE_EXPR; return EQCOMPARE;
case CPP_GREATER_EQ:yylval.code = GE_EXPR; return ARITHCOMPARE;
case CPP_CLOSE_SQUARE: return ']';
case CPP_OPEN_BRACE: return '{';
case CPP_CLOSE_BRACE: return '}';
- case CPP_SEMICOLON: return ';';
case CPP_ELLIPSIS: return ELLIPSIS;
case CPP_PLUS_PLUS: return PLUSPLUS;
case CPP_DEREF: return POINTSAT;
case CPP_DOT: return '.';
+ /* The following tokens may affect the interpretation of any
+ identifiers following, if doing Objective-C. */
+ case CPP_COLON: OBJC_NEED_RAW_IDENTIFIER (0); return ':';
+ case CPP_COMMA: OBJC_NEED_RAW_IDENTIFIER (0); return ',';
+ case CPP_CLOSE_PAREN: OBJC_NEED_RAW_IDENTIFIER (0); return ')';
+ case CPP_SEMICOLON: OBJC_NEED_RAW_IDENTIFIER (0); return ';';
+
case CPP_EOF:
- if (cpp_pop_buffer (parse_in) == 0)
- return 0;
- goto get_next;
+ return 0;
case CPP_NAME:
return yylexname ();
- case CPP_INT:
- case CPP_FLOAT:
case CPP_NUMBER:
case CPP_CHAR:
case CPP_WCHAR:
case CPP_WSTRING:
return STRING;
- /* This token is Objective-C specific. It gives the next
- token special significance. */
+ /* This token is Objective-C specific. It gives the next token
+ special significance. */
case CPP_ATSIGN:
ifobjc
{