Commit cc937581 by Zack Weinberg Committed by Zack Weinberg

c-parse.in (yylexname): New function, split out of _yylex.


	* c-parse.in (yylexname): New function, split out of _yylex.
	(objc_rid_sans_at): New table.
	(init_reswords): Initialize it.
	(_yylex): Give labels clearer names.  Handle CPP_ATSIGN by
	retrieving the next token and checking it for significance as
	an ObjC keyword or string constant.

	* cpplex.c (_cpp_lex_token): Just return CPP_ATSIGN for '@'.
	* cpplib.h (TTYPE_TABLE): Add CPP_ATSIGN, drop CPP_OSTRING.

	* c-lex.c, c-parse.in, cppmacro.c, cpplex.c, cp/spew.c: Remove
	references to CPP_OSTRING.

From-SVN: r40279
parent 8b44d68f
2001-03-06 Zack Weinberg <zackw@stanford.edu>
* c-parse.in (yylexname): New function, split out of _yylex.
(objc_rid_sans_at): New table.
(init_reswords): Initialize it.
(_yylex): Give labels clearer names. Handle CPP_ATSIGN by
retrieving the next token and checking it for significance as
an ObjC keyword or string constant.
* cpplex.c (_cpp_lex_token): Just return CPP_ATSIGN for '@'.
* cpplib.h (TTYPE_TABLE): Add CPP_ATSIGN, drop CPP_OSTRING.
* c-lex.c, c-parse.in, cppmacro.c, cpplex.c: Remove references
to CPP_OSTRING.
2001-03-06 Stephen L Moshier <moshier@mediaone.net> 2001-03-06 Stephen L Moshier <moshier@mediaone.net>
* config/m68k/m68k.c (const_uint32_operand): Accept any * config/m68k/m68k.c (const_uint32_operand): Accept any
......
...@@ -1014,7 +1014,6 @@ c_lex (value) ...@@ -1014,7 +1014,6 @@ c_lex (value)
case CPP_STRING: case CPP_STRING:
case CPP_WSTRING: case CPP_WSTRING:
case CPP_OSTRING:
*value = lex_string ((const char *)tok.val.str.text, *value = lex_string ((const char *)tok.val.str.text,
tok.val.str.len, tok.type == CPP_WSTRING); tok.val.str.len, tok.type == CPP_WSTRING);
break; break;
......
...@@ -263,6 +263,7 @@ end ifobjc ...@@ -263,6 +263,7 @@ end ifobjc
static void yyprint PARAMS ((FILE *, int, YYSTYPE)); static void yyprint PARAMS ((FILE *, int, YYSTYPE));
static void yyerror PARAMS ((const char *)); static void yyerror PARAMS ((const char *));
static int yylexname PARAMS ((void));
static inline int _yylex PARAMS ((void)); static inline int _yylex PARAMS ((void));
static int yylex PARAMS ((void)); static int yylex PARAMS ((void));
static void init_reswords PARAMS ((void)); static void init_reswords PARAMS ((void));
...@@ -3114,6 +3115,13 @@ static const short rid_to_yy[RID_MAX] = ...@@ -3114,6 +3115,13 @@ 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 ()
{ {
...@@ -3139,6 +3147,16 @@ init_reswords () ...@@ -3139,6 +3147,16 @@ 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
} }
ifobjc ifobjc
save_and_forget_protocol_qualifiers (); save_and_forget_protocol_qualifiers ();
...@@ -3188,8 +3206,7 @@ yyerror (msgid) ...@@ -3188,8 +3206,7 @@ yyerror (msgid)
error ("%s before %s'\\x%x'", string, ell, val); error ("%s before %s'\\x%x'", string, ell, val);
} }
else if (last_token == CPP_STRING else if (last_token == CPP_STRING
|| last_token == CPP_WSTRING || last_token == CPP_WSTRING)
|| last_token == CPP_OSTRING)
error ("%s before string constant", string); error ("%s before string constant", string);
else if (last_token == CPP_NUMBER else if (last_token == CPP_NUMBER
|| last_token == CPP_INT || last_token == CPP_INT
...@@ -3201,12 +3218,65 @@ yyerror (msgid) ...@@ -3201,12 +3218,65 @@ yyerror (msgid)
error ("%s before '%s' token", string, NAME(last_token)); error ("%s before '%s' token", string, NAME(last_token));
} }
static int
yylexname ()
{
tree decl;
if (C_IS_RESERVED_WORD (yylval.ttype))
{
enum rid rid_code = C_RID_CODE (yylval.ttype);
/* Return the canonical spelling for this keyword. */
yylval.ttype = ridpointers[(int) rid_code];
return rid_to_yy[(int) rid_code];
}
decl = lookup_name (yylval.ttype);
if (decl)
{
if (TREE_CODE (decl) == TYPE_DECL)
return TYPENAME;
/* A user-invisible read-only initialized variable
should be replaced by its value.
We handle only strings since that's the only case used in C. */
else if (TREE_CODE (decl) == VAR_DECL
&& DECL_IGNORED_P (decl)
&& TREE_READONLY (decl)
&& DECL_INITIAL (decl) != 0
&& TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
{
tree stringval = DECL_INITIAL (decl);
/* Copy the string value so that we won't clobber anything
if we put something in the TREE_CHAIN of this one. */
yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
TREE_STRING_POINTER (stringval));
return STRING;
}
}
else if (doing_objc_thang)
{
tree objc_interface_decl = is_class_name (yylval.ttype);
if (objc_interface_decl)
{
yylval.ttype = objc_interface_decl;
return CLASSNAME;
}
}
return IDENTIFIER;
}
static inline int static inline int
_yylex () _yylex ()
{ {
retry: 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 '=';
...@@ -3263,63 +3333,10 @@ _yylex () ...@@ -3263,63 +3333,10 @@ _yylex ()
case CPP_EOF: case CPP_EOF:
if (cpp_pop_buffer (parse_in) == 0) if (cpp_pop_buffer (parse_in) == 0)
return 0; return 0;
goto retry; goto get_next;
case CPP_NAME: case CPP_NAME:
if (C_IS_RESERVED_WORD (yylval.ttype)) return yylexname ();
{
enum rid rid_code = C_RID_CODE (yylval.ttype);
/* Return the canonical spelling for this keyword. */
yylval.ttype = ridpointers[(int) rid_code];
return rid_to_yy[(int) rid_code];
}
if (IDENTIFIER_POINTER (yylval.ttype)[0] == '@')
{
error ("invalid identifier `%s'", IDENTIFIER_POINTER (yylval.ttype));
return IDENTIFIER;
}
{
tree decl;
decl = lookup_name (yylval.ttype);
if (decl)
{
if (TREE_CODE (decl) == TYPE_DECL)
return TYPENAME;
/* A user-invisible read-only initialized variable
should be replaced by its value.
We handle only strings since that's the only case used in C. */
else if (TREE_CODE (decl) == VAR_DECL
&& DECL_IGNORED_P (decl)
&& TREE_READONLY (decl)
&& DECL_INITIAL (decl) != 0
&& TREE_CODE (DECL_INITIAL (decl)) == STRING_CST)
{
tree stringval = DECL_INITIAL (decl);
/* Copy the string value so that we won't clobber anything
if we put something in the TREE_CHAIN of this one. */
yylval.ttype = build_string (TREE_STRING_LENGTH (stringval),
TREE_STRING_POINTER (stringval));
return STRING;
}
}
else if (doing_objc_thang)
{
tree objc_interface_decl = is_class_name (yylval.ttype);
if (objc_interface_decl)
{
yylval.ttype = objc_interface_decl;
return CLASSNAME;
}
}
return IDENTIFIER;
}
case CPP_INT: case CPP_INT:
case CPP_FLOAT: case CPP_FLOAT:
...@@ -3332,9 +3349,27 @@ _yylex () ...@@ -3332,9 +3349,27 @@ _yylex ()
case CPP_WSTRING: case CPP_WSTRING:
return STRING; return STRING;
case CPP_OSTRING: /* This token is Objective-C specific. It gives the next
return OBJC_STRING; 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;
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:
...@@ -3347,13 +3382,12 @@ _yylex () ...@@ -3347,13 +3382,12 @@ _yylex ()
/* These tokens should not survive translation phase 4. */ /* These tokens should not survive translation phase 4. */
case CPP_HASH: case CPP_HASH:
case CPP_PASTE: case CPP_PASTE:
error ("syntax error before '%s' token", NAME(last_token)); error ("syntax error at '%s' token", NAME(last_token));
goto retry; goto get_next;
default: default:
abort (); abort ();
} }
/* NOTREACHED */ /* NOTREACHED */
} }
......
2001-03-06 Zack Weinberg <zackw@stanford.edu>
* spew.c: Remove references to CPP_OSTRING.
2001-03-06 Andrew Haley <aph@redhat.com> 2001-03-06 Andrew Haley <aph@redhat.com>
* typeck.c (convert_arguments): Check that we have an fndecl. * typeck.c (convert_arguments): Check that we have an fndecl.
......
...@@ -351,9 +351,6 @@ read_token (t) ...@@ -351,9 +351,6 @@ read_token (t)
t->yychar = STRING; t->yychar = STRING;
break; break;
/* This token should not be generated in C++ mode. */
case CPP_OSTRING:
/* These tokens should not survive translation phase 4. */ /* These tokens should not survive translation phase 4. */
case CPP_HASH: case CPP_HASH:
case CPP_PASTE: case CPP_PASTE:
...@@ -1499,8 +1496,7 @@ yyerror (msgid) ...@@ -1499,8 +1496,7 @@ yyerror (msgid)
error ("%s before %s'\\x%x'", string, ell, val); error ("%s before %s'\\x%x'", string, ell, val);
} }
else if (last_token == CPP_STRING else if (last_token == CPP_STRING
|| last_token == CPP_WSTRING || last_token == CPP_WSTRING)
|| last_token == CPP_OSTRING)
error ("%s before string constant", string); error ("%s before string constant", string);
else if (last_token == CPP_NUMBER else if (last_token == CPP_NUMBER
|| last_token == CPP_INT || last_token == CPP_INT
......
...@@ -1241,29 +1241,8 @@ _cpp_lex_token (pfile, result) ...@@ -1241,29 +1241,8 @@ _cpp_lex_token (pfile, result)
case '}': result->type = CPP_CLOSE_BRACE; break; case '}': result->type = CPP_CLOSE_BRACE; break;
case ';': result->type = CPP_SEMICOLON; break; case ';': result->type = CPP_SEMICOLON; break;
case '@': /* @ is a punctuator in Objective C. */
if (CPP_OPTION (pfile, objc)) case '@': result->type = CPP_ATSIGN; break;
{
/* In Objective C, '@' may begin keywords or strings, like
@keyword or @"string". It would be nice to call
get_effective_char here and test the result. However, we
would then need to pass 2 characters to parse_identifier,
making it ugly and slowing down its main loop. Instead,
we assume we have an identifier, and recover if not. */
result->type = CPP_NAME;
result->val.node = parse_identifier (pfile, c);
if (result->val.node->length != 1)
break;
/* OK, so it wasn't an identifier. Maybe a string? */
if (buffer->read_ahead == '"')
{
c = '"';
ACCEPT_CHAR (CPP_OSTRING);
goto make_string;
}
}
goto random_char;
random_char: random_char:
default: default:
...@@ -1341,7 +1320,6 @@ cpp_spell_token (pfile, token, buffer) ...@@ -1341,7 +1320,6 @@ cpp_spell_token (pfile, token, buffer)
{ {
case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break; case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break; case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
case CPP_OSTRING: left = '"'; right = '"'; tag = '@'; break;
case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break; case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break; case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break; case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
...@@ -1432,7 +1410,6 @@ cpp_output_token (token, fp) ...@@ -1432,7 +1410,6 @@ cpp_output_token (token, fp)
{ {
case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break; case CPP_STRING: left = '"'; right = '"'; tag = '\0'; break;
case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break; case CPP_WSTRING: left = '"'; right = '"'; tag = 'L'; break;
case CPP_OSTRING: left = '"'; right = '"'; tag = '@'; break;
case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break; case CPP_CHAR: left = '\''; right = '\''; tag = '\0'; break;
case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break; case CPP_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break; case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
...@@ -1580,13 +1557,6 @@ cpp_can_paste (pfile, token1, token2, digraph) ...@@ -1580,13 +1557,6 @@ cpp_can_paste (pfile, token1, token2, digraph)
return CPP_NUMBER; return CPP_NUMBER;
break; break;
case CPP_OTHER:
if (CPP_OPTION (pfile, objc) && token1->val.c == '@')
{
if (b == CPP_NAME) return CPP_NAME;
if (b == CPP_STRING) return CPP_OSTRING;
}
default: default:
break; break;
} }
......
...@@ -119,6 +119,7 @@ struct file_name_map_list; ...@@ -119,6 +119,7 @@ struct file_name_map_list;
OP(CPP_SCOPE, "::") \ OP(CPP_SCOPE, "::") \
OP(CPP_DEREF_STAR, "->*") \ OP(CPP_DEREF_STAR, "->*") \
OP(CPP_DOT_STAR, ".*") \ OP(CPP_DOT_STAR, ".*") \
OP(CPP_ATSIGN, "@") /* used in Objective C */ \
\ \
TK(CPP_NAME, SPELL_IDENT) /* word */ \ TK(CPP_NAME, SPELL_IDENT) /* word */ \
TK(CPP_INT, SPELL_STRING) /* 23 */ \ TK(CPP_INT, SPELL_STRING) /* 23 */ \
...@@ -131,7 +132,6 @@ struct file_name_map_list; ...@@ -131,7 +132,6 @@ struct file_name_map_list;
\ \
TK(CPP_STRING, SPELL_STRING) /* "string" */ \ TK(CPP_STRING, SPELL_STRING) /* "string" */ \
TK(CPP_WSTRING, SPELL_STRING) /* L"string" */ \ TK(CPP_WSTRING, SPELL_STRING) /* L"string" */ \
TK(CPP_OSTRING, SPELL_STRING) /* @"string" - Objective C */ \
TK(CPP_HEADER_NAME, SPELL_STRING) /* <stdio.h> in #include */ \ TK(CPP_HEADER_NAME, SPELL_STRING) /* <stdio.h> in #include */ \
\ \
TK(CPP_COMMENT, SPELL_STRING) /* Only if output comments. */ \ TK(CPP_COMMENT, SPELL_STRING) /* Only if output comments. */ \
......
...@@ -291,8 +291,7 @@ stringify_arg (pfile, arg) ...@@ -291,8 +291,7 @@ stringify_arg (pfile, arg)
unsigned int len = cpp_token_len (token); unsigned int len = cpp_token_len (token);
escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING
|| token->type == CPP_CHAR || token->type == CPP_WCHAR || token->type == CPP_CHAR || token->type == CPP_WCHAR);
|| token->type == CPP_OSTRING);
if (escape_it) if (escape_it)
/* Worst case is each char is octal. */ /* Worst case is each char is octal. */
......
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