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> Sun Jul 1 11:53:52 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* cse.c (new_label_ref): Variable deleted. * cse.c (new_label_ref): Variable deleted.
......
...@@ -63,7 +63,7 @@ enum rid ...@@ -63,7 +63,7 @@ enum rid
RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE, RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, RID_EXPORT, RID_MUTABLE,
/* ObjC */ /* 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 */ /* C */
RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID, RID_INT, RID_CHAR, RID_FLOAT, RID_DOUBLE, RID_VOID,
...@@ -107,9 +107,22 @@ enum rid ...@@ -107,9 +107,22 @@ enum rid
RID_MAX, RID_MAX,
RID_FIRST_MODIFIER = RID_STATIC, 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 /* The elements of `ridpointers' are identifier nodes for the reserved
type names and storage classes. It is indexed by a RID_... value. */ type names and storage classes. It is indexed by a RID_... value. */
extern tree *ridpointers; extern tree *ridpointers;
......
...@@ -157,11 +157,6 @@ end ifc ...@@ -157,11 +157,6 @@ end ifc
%token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE %token INTERFACE IMPLEMENTATION END SELECTOR DEFS ENCODE
%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS %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 <code> unop
%type <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT %type <ttype> ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
%type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF %type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF
...@@ -231,7 +226,7 @@ ifobjc ...@@ -231,7 +226,7 @@ ifobjc
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr %type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
%type <ttype> objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr %type <ttype> objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
%type <ttype> CLASSNAME OBJC_STRING OBJECTNAME %type <ttype> CLASSNAME OBJECTNAME
end ifobjc end ifobjc
%{ %{
...@@ -767,9 +762,10 @@ ifobjc ...@@ -767,9 +762,10 @@ ifobjc
/* Produces an STRING_CST with perhaps more STRING_CSTs chained /* Produces an STRING_CST with perhaps more STRING_CSTs chained
onto it, which is to be read as an ObjC string object. */ onto it, which is to be read as an ObjC string object. */
objc_string: objc_string:
OBJC_STRING '@' STRING
| objc_string OBJC_STRING { $$ = $2; }
{ $$ = chainon ($1, $2); } | objc_string '@' STRING
{ $$ = chainon ($1, $3); }
; ;
end ifobjc end ifobjc
...@@ -3407,19 +3403,25 @@ static const struct resword reswords[] = ...@@ -3407,19 +3403,25 @@ static const struct resword reswords[] =
{ "volatile", RID_VOLATILE, D_TRAD }, { "volatile", RID_VOLATILE, D_TRAD },
{ "while", RID_WHILE, 0 }, { "while", RID_WHILE, 0 },
ifobjc 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 }, { "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 }, { "bycopy", RID_BYCOPY, D_OBJC },
{ "byref", RID_BYREF, D_OBJC }, { "byref", RID_BYREF, D_OBJC },
{ "in", RID_IN, D_OBJC }, { "in", RID_IN, D_OBJC },
...@@ -3568,13 +3570,6 @@ static const short rid_to_yy[RID_MAX] = ...@@ -3568,13 +3570,6 @@ static const short rid_to_yy[RID_MAX] =
/* RID_AT_IMPLEMENTATION */ IMPLEMENTATION /* 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 static void
init_reswords () init_reswords ()
{ {
...@@ -3602,16 +3597,6 @@ init_reswords () ...@@ -3602,16 +3597,6 @@ init_reswords ()
C_RID_CODE (id) = reswords[i].rid; C_RID_CODE (id) = reswords[i].rid;
C_IS_RESERVED_WORD (id) = 1; C_IS_RESERVED_WORD (id) = 1;
ridpointers [(int) reswords[i].rid] = id; 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 () ...@@ -3680,8 +3665,8 @@ yylexname ()
enum rid rid_code = C_RID_CODE (yylval.ttype); enum rid rid_code = C_RID_CODE (yylval.ttype);
ifobjc ifobjc
if (!((unsigned int) rid_code - (unsigned int) RID_FIRST_PQ < 6) if (!OBJC_IS_AT_KEYWORD (rid_code)
|| objc_pq_context) && (!OBJC_IS_PQ_KEYWORD (rid_code) || objc_pq_context))
end ifobjc end ifobjc
{ {
int yycode = rid_to_yy[(int) rid_code]; int yycode = rid_to_yy[(int) rid_code];
...@@ -3730,9 +3715,6 @@ _yylex () ...@@ -3730,9 +3715,6 @@ _yylex ()
{ {
get_next: get_next:
last_token = c_lex (&yylval.ttype); last_token = c_lex (&yylval.ttype);
ifobjc
reconsider:
end ifobjc
switch (last_token) switch (last_token)
{ {
case CPP_EQ: return '='; case CPP_EQ: return '=';
...@@ -3809,23 +3791,27 @@ end ifobjc ...@@ -3809,23 +3791,27 @@ end ifobjc
token special significance. */ token special significance. */
case CPP_ATSIGN: case CPP_ATSIGN:
ifobjc ifobjc
last_token = c_lex (&yylval.ttype); {
if (last_token == CPP_STRING) tree after_at;
return OBJC_STRING; enum cpp_ttype after_at_type;
else if (last_token == CPP_NAME)
{ cpp_start_lookahead (parse_in);
int i; after_at_type = c_lex (&after_at);
for (i = 0; i < N_at_reswords; i++)
if (objc_rid_sans_at[i] == yylval.ttype) if (after_at_type == CPP_NAME
{ && C_IS_RESERVED_WORD (after_at)
int rid_code = i + (int) RID_AT_ENCODE; && OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at)))
yylval.ttype = ridpointers[rid_code]; {
return rid_to_yy[rid_code]; cpp_stop_lookahead (parse_in, 1); /* accept this token */
} yylval.ttype = after_at;
} last_token = after_at_type;
error ("syntax error at '@' token"); return rid_to_yy [(int) C_RID_CODE (after_at)];
goto reconsider; }
cpp_stop_lookahead (parse_in, 0); /* put back this token */
return '@';
}
end ifobjc end ifobjc
/* These tokens are C++ specific (and will not be generated /* These tokens are C++ specific (and will not be generated
in C mode, but let's be cautious). */ in C mode, but let's be cautious). */
case CPP_SCOPE: case CPP_SCOPE:
......
...@@ -438,14 +438,17 @@ lex_macro_node (pfile) ...@@ -438,14 +438,17 @@ lex_macro_node (pfile)
cpp_reader *pfile; cpp_reader *pfile;
{ {
cpp_token token; cpp_token token;
cpp_hashnode *node;
/* Lex the macro name directly. */ /* Lex the macro name directly. */
_cpp_lex_token (pfile, &token); _cpp_lex_token (pfile, &token);
/* The token immediately after #define must be an identifier. That /* The token immediately after #define must be an identifier. That
identifier is not allowed to be "defined". See predefined macro identifier may not be "defined", per C99 6.10.8p4.
names (6.10.8.4). In C++, it is not allowed to be any of the In C++, it may not be any of the "named operators" either,
<iso646.h> macro names (which are keywords in C++) 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) if (token.type != CPP_NAME)
{ {
...@@ -454,25 +457,26 @@ lex_macro_node (pfile) ...@@ -454,25 +457,26 @@ lex_macro_node (pfile)
pfile->directive->name); pfile->directive->name);
else if (token.flags & NAMED_OP) else if (token.flags & NAMED_OP)
cpp_error (pfile, 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)); NODE_NAME (token.val.node));
else else
cpp_error (pfile, "macro names must be identifiers"); 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; cpp_error (pfile, "\"%s\" cannot be used as a macro name",
NODE_NAME (node));
/* In Objective C, some keywords begin with '@', but general return 0;
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;
} }
return 0; return node;
} }
/* Process a #define directive. Most work is done in cppmacro.c. */ /* 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