Commit b8363a24 by Zack Weinberg Committed by Zack Weinberg

c-common.h (enum rid): Add RID_FIRST_AT, RID_LAST_AT, RID_LAST_PQ.

	* c-common.h (enum rid): Add RID_FIRST_AT, RID_LAST_AT,
	RID_LAST_PQ.  Move RID_FIRST_PQ down with the other FIRST/LAST
	enumerators.
	(OBJC_IS_AT_KEYWORD, OBJC_IS_PQ_KEYWORD): New macros.

	* c-parse.in (OBJC_STRING): Kill.
	(objc_string): Decompose to [objc_string] '@' STRING.
	(reswords): Take the leading '@' off all the Objective C keywords.
	(objc_rid_sans_at): Kill.
	(init_reswords): Don't initialize it.
	(yylexname): Use OBJC_IS_AT_KEYWORD and OBJC_IS_PQ_KEYWORD.
	(_yylex): Kill reconsider label.  Look ahead one token after
	an '@'; if we get an identifier, check whether it's an
	Objective C @-keyword.  If so, return the keyword.  Otherwise,
	put back the token and return the '@' as a terminal.

	* cpplib.c (lex_macro_node): Remove unnecessary check for
	leading '@' on identifier.  Clarify control flow and commentary.

From-SVN: r43674
parent 128e8aa9
2001-07-01 Zack Weinberg <zackw@stanford.edu>
* c-common.h (enum rid): Add RID_FIRST_AT, RID_LAST_AT,
RID_LAST_PQ. Move RID_FIRST_PQ down with the other FIRST/LAST
enumerators.
(OBJC_IS_AT_KEYWORD, OBJC_IS_PQ_KEYWORD): New macros.
* c-parse.in (OBJC_STRING): Kill.
(objc_string): Decompose to [objc_string] '@' STRING.
(reswords): Take the leading '@' off all the Objective C keywords.
(objc_rid_sans_at): Kill.
(init_reswords): Don't initialize it.
(yylexname): Use OBJC_IS_AT_KEYWORD and OBJC_IS_PQ_KEYWORD.
(_yylex): Kill reconsider label. Look ahead one token after
an '@'; if we get an identifier, check whether it's an
Objective C @-keyword. If so, return the keyword. Otherwise,
put back the token and return the '@' as a terminal.
* cpplib.c (lex_macro_node): Remove unnecessary check for
leading '@' on identifier. Clarify control flow and commentary.
Sun Jul 1 11:53:52 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* cse.c (new_label_ref): Variable deleted.
......
......@@ -63,7 +63,7 @@ enum rid
RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
/* ObjC */
RID_FIRST_PQ, RID_IN = RID_FIRST_PQ, RID_OUT, RID_INOUT, RID_BYCOPY, RID_BYREF, RID_ONEWAY,
RID_IN, RID_OUT, RID_INOUT, RID_BYCOPY, RID_BYREF, RID_ONEWAY,
/* C */
RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID,
......@@ -107,9 +107,22 @@ enum rid
RID_MAX,
RID_FIRST_MODIFIER = RID_STATIC,
RID_LAST_MODIFIER = RID_ONEWAY
RID_LAST_MODIFIER = RID_ONEWAY,
RID_FIRST_AT = RID_AT_ENCODE,
RID_LAST_AT = RID_AT_IMPLEMENTATION,
RID_FIRST_PQ = RID_IN,
RID_LAST_PQ = RID_ONEWAY
};
#define OBJC_IS_AT_KEYWORD(rid) \
((unsigned int)(rid) >= (unsigned int)RID_FIRST_AT && \
(unsigned int)(rid) <= (unsigned int)RID_LAST_AT)
#define OBJC_IS_PQ_KEYWORD(rid) \
((unsigned int)(rid) >= (unsigned int)RID_FIRST_PQ && \
(unsigned int)(rid) <= (unsigned int)RID_LAST_PQ)
/* The elements of `ridpointers' are identifier nodes for the reserved
type names and storage classes. It is indexed by a RID_... value. */
extern tree *ridpointers;
......
......@@ -157,11 +157,6 @@ end ifc
%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
/* Objective-C string constants in raw form.
yylval is an STRING_CST node. */
%token OBJC_STRING
%type <code> unop
%type <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
%type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF
......@@ -231,7 +226,7 @@ ifobjc
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
%type <ttype> objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
%type <ttype> CLASSNAME OBJC_STRING OBJECTNAME
%type <ttype> CLASSNAME OBJECTNAME
end ifobjc
%{
......@@ -767,9 +762,10 @@ ifobjc
/* Produces an STRING_CST with perhaps more STRING_CSTs chained
onto it, which is to be read as an ObjC string object. */
objc_string:
OBJC_STRING
| objc_string OBJC_STRING
{ $$ = chainon ($1, $2); }
'@' STRING
{ $$ = $2; }
| objc_string '@' STRING
{ $$ = chainon ($1, $3); }
;
end ifobjc
......@@ -3407,19 +3403,25 @@ static const struct resword reswords[] =
{ "volatile", RID_VOLATILE, D_TRAD },
{ "while", RID_WHILE, 0 },
ifobjc
{ "@class", RID_AT_CLASS, D_OBJC },
{ "@compatibility_alias", RID_AT_ALIAS, D_OBJC },
{ "@defs", RID_AT_DEFS, D_OBJC },
{ "@encode", RID_AT_ENCODE, D_OBJC },
{ "@end", RID_AT_END, D_OBJC },
{ "@implementation", RID_AT_IMPLEMENTATION, D_OBJC },
{ "@interface", RID_AT_INTERFACE, D_OBJC },
{ "@private", RID_AT_PRIVATE, D_OBJC },
{ "@protected", RID_AT_PROTECTED, D_OBJC },
{ "@protocol", RID_AT_PROTOCOL, D_OBJC },
{ "@public", RID_AT_PUBLIC, D_OBJC },
{ "@selector", RID_AT_SELECTOR, D_OBJC },
{ "id", RID_ID, D_OBJC },
/* These objc keywords are recognized only immediately after
an '@'. */
{ "class", RID_AT_CLASS, D_OBJC },
{ "compatibility_alias", RID_AT_ALIAS, D_OBJC },
{ "defs", RID_AT_DEFS, D_OBJC },
{ "encode", RID_AT_ENCODE, D_OBJC },
{ "end", RID_AT_END, D_OBJC },
{ "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
{ "interface", RID_AT_INTERFACE, D_OBJC },
{ "private", RID_AT_PRIVATE, D_OBJC },
{ "protected", RID_AT_PROTECTED, D_OBJC },
{ "protocol", RID_AT_PROTOCOL, D_OBJC },
{ "public", RID_AT_PUBLIC, D_OBJC },
{ "selector", RID_AT_SELECTOR, D_OBJC },
/* These are recognized only in protocol-qualifier context
(see above) */
{ "bycopy", RID_BYCOPY, D_OBJC },
{ "byref", RID_BYREF, D_OBJC },
{ "in", RID_IN, D_OBJC },
......@@ -3568,13 +3570,6 @@ static const short rid_to_yy[RID_MAX] =
/* RID_AT_IMPLEMENTATION */ IMPLEMENTATION
};
ifobjc
/* Lookup table for ObjC keywords beginning with '@'. Crude but
hopefully effective. */
#define N_at_reswords ((int) RID_AT_IMPLEMENTATION - (int)RID_AT_ENCODE + 1)
static tree objc_rid_sans_at[N_at_reswords];
end ifobjc
static void
init_reswords ()
{
......@@ -3602,16 +3597,6 @@ init_reswords ()
C_RID_CODE (id) = reswords[i].rid;
C_IS_RESERVED_WORD (id) = 1;
ridpointers [(int) reswords[i].rid] = id;
ifobjc
/* Enter ObjC @-prefixed keywords into the "sans" table
_without_ their leading at-sign. Again, all these
identifiers are reachable by the get_identifer table, so it's
not necessary to make objc_rid_sans_at a GC root. */
if (reswords[i].word[0] == '@')
objc_rid_sans_at[(int) reswords[i].rid - (int) RID_AT_ENCODE]
= get_identifier (reswords[i].word + 1);
end ifobjc
}
}
......@@ -3680,8 +3665,8 @@ yylexname ()
enum rid rid_code = C_RID_CODE (yylval.ttype);
ifobjc
if (!((unsigned int) rid_code - (unsigned int) RID_FIRST_PQ < 6)
|| objc_pq_context)
if (!OBJC_IS_AT_KEYWORD (rid_code)
&& (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
end ifobjc
{
int yycode = rid_to_yy[(int) rid_code];
......@@ -3730,9 +3715,6 @@ _yylex ()
{
get_next:
last_token = c_lex (&yylval.ttype);
ifobjc
reconsider:
end ifobjc
switch (last_token)
{
case CPP_EQ: return '=';
......@@ -3809,23 +3791,27 @@ end ifobjc
token special significance. */
case CPP_ATSIGN:
ifobjc
last_token = c_lex (&yylval.ttype);
if (last_token == CPP_STRING)
return OBJC_STRING;
else if (last_token == CPP_NAME)
{
int i;
for (i = 0; i < N_at_reswords; i++)
if (objc_rid_sans_at[i] == yylval.ttype)
{
int rid_code = i + (int) RID_AT_ENCODE;
yylval.ttype = ridpointers[rid_code];
return rid_to_yy[rid_code];
}
}
error ("syntax error at '@' token");
goto reconsider;
{
tree after_at;
enum cpp_ttype after_at_type;
cpp_start_lookahead (parse_in);
after_at_type = c_lex (&after_at);
if (after_at_type == CPP_NAME
&& C_IS_RESERVED_WORD (after_at)
&& OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at)))
{
cpp_stop_lookahead (parse_in, 1); /* accept this token */
yylval.ttype = after_at;
last_token = after_at_type;
return rid_to_yy [(int) C_RID_CODE (after_at)];
}
cpp_stop_lookahead (parse_in, 0); /* put back this token */
return '@';
}
end ifobjc
/* These tokens are C++ specific (and will not be generated
in C mode, but let's be cautious). */
case CPP_SCOPE:
......
......@@ -438,14 +438,17 @@ lex_macro_node (pfile)
cpp_reader *pfile;
{
cpp_token token;
cpp_hashnode *node;
/* Lex the macro name directly. */
_cpp_lex_token (pfile, &token);
/* The token immediately after #define must be an identifier. That
identifier is not allowed to be "defined". See predefined macro
names (6.10.8.4). In C++, it is not allowed to be any of the
<iso646.h> macro names (which are keywords in C++) either. */
identifier may not be "defined", per C99 6.10.8p4.
In C++, it may not be any of the "named operators" either,
per C++98 [lex.digraph], [lex.key].
Finally, the identifier may not have been poisoned. (In that case
the lexer has issued the error message for us.) */
if (token.type != CPP_NAME)
{
......@@ -454,25 +457,26 @@ lex_macro_node (pfile)
pfile->directive->name);
else if (token.flags & NAMED_OP)
cpp_error (pfile,
"\"%s\" cannot be used as a macro name as it is an operator in C++",
"\"%s\" cannot be used as a macro name as it is an operator in C++",
NODE_NAME (token.val.node));
else
cpp_error (pfile, "macro names must be identifiers");
return 0;
}
else
node = token.val.node;
if (node->flags & NODE_POISONED)
return 0;
if (node == pfile->spec_nodes.n_defined)
{
cpp_hashnode *node = token.val.node;
/* In Objective C, some keywords begin with '@', but general
identifiers do not, and you're not allowed to #define them. */
if (node == pfile->spec_nodes.n_defined || NODE_NAME (node)[0] == '@')
cpp_error (pfile, "\"%s\" cannot be used as a macro name",
NODE_NAME (node));
else if (!(node->flags & NODE_POISONED))
return node;
cpp_error (pfile, "\"%s\" cannot be used as a macro name",
NODE_NAME (node));
return 0;
}
return 0;
return node;
}
/* Process a #define directive. Most work is done in cppmacro.c. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment