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
This commit is contained in:
parent
8b44d68f7b
commit
cc93758139
8 changed files with 123 additions and 106 deletions
|
@ -1,3 +1,18 @@
|
|||
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>
|
||||
|
||||
* config/m68k/m68k.c (const_uint32_operand): Accept any
|
||||
|
|
|
@ -1014,7 +1014,6 @@ c_lex (value)
|
|||
|
||||
case CPP_STRING:
|
||||
case CPP_WSTRING:
|
||||
case CPP_OSTRING:
|
||||
*value = lex_string ((const char *)tok.val.str.text,
|
||||
tok.val.str.len, tok.type == CPP_WSTRING);
|
||||
break;
|
||||
|
|
164
gcc/c-parse.in
164
gcc/c-parse.in
|
@ -263,6 +263,7 @@ end ifobjc
|
|||
|
||||
static void yyprint PARAMS ((FILE *, int, YYSTYPE));
|
||||
static void yyerror PARAMS ((const char *));
|
||||
static int yylexname PARAMS ((void));
|
||||
static inline int _yylex PARAMS ((void));
|
||||
static int yylex PARAMS ((void));
|
||||
static void init_reswords PARAMS ((void));
|
||||
|
@ -3114,6 +3115,13 @@ 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 ()
|
||||
{
|
||||
|
@ -3139,6 +3147,16 @@ 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
|
||||
}
|
||||
ifobjc
|
||||
save_and_forget_protocol_qualifiers ();
|
||||
|
@ -3188,8 +3206,7 @@ yyerror (msgid)
|
|||
error ("%s before %s'\\x%x'", string, ell, val);
|
||||
}
|
||||
else if (last_token == CPP_STRING
|
||||
|| last_token == CPP_WSTRING
|
||||
|| last_token == CPP_OSTRING)
|
||||
|| last_token == CPP_WSTRING)
|
||||
error ("%s before string constant", string);
|
||||
else if (last_token == CPP_NUMBER
|
||||
|| last_token == CPP_INT
|
||||
|
@ -3201,12 +3218,65 @@ yyerror (msgid)
|
|||
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
|
||||
_yylex ()
|
||||
{
|
||||
retry:
|
||||
get_next:
|
||||
last_token = c_lex (&yylval.ttype);
|
||||
|
||||
ifobjc
|
||||
reconsider:
|
||||
end ifobjc
|
||||
switch (last_token)
|
||||
{
|
||||
case CPP_EQ: return '=';
|
||||
|
@ -3263,63 +3333,10 @@ _yylex ()
|
|||
case CPP_EOF:
|
||||
if (cpp_pop_buffer (parse_in) == 0)
|
||||
return 0;
|
||||
goto retry;
|
||||
goto get_next;
|
||||
|
||||
case CPP_NAME:
|
||||
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];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return yylexname ();
|
||||
|
||||
case CPP_INT:
|
||||
case CPP_FLOAT:
|
||||
|
@ -3332,9 +3349,27 @@ _yylex ()
|
|||
case CPP_WSTRING:
|
||||
return STRING;
|
||||
|
||||
case CPP_OSTRING:
|
||||
return OBJC_STRING;
|
||||
|
||||
/* This token is Objective-C specific. It gives the next
|
||||
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
|
||||
in C mode, but let's be cautious). */
|
||||
case CPP_SCOPE:
|
||||
|
@ -3347,13 +3382,12 @@ _yylex ()
|
|||
/* These tokens should not survive translation phase 4. */
|
||||
case CPP_HASH:
|
||||
case CPP_PASTE:
|
||||
error ("syntax error before '%s' token", NAME(last_token));
|
||||
goto retry;
|
||||
error ("syntax error at '%s' token", NAME(last_token));
|
||||
goto get_next;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2001-03-06 Zack Weinberg <zackw@stanford.edu>
|
||||
|
||||
* spew.c: Remove references to CPP_OSTRING.
|
||||
|
||||
2001-03-06 Andrew Haley <aph@redhat.com>
|
||||
|
||||
* typeck.c (convert_arguments): Check that we have an fndecl.
|
||||
|
|
|
@ -351,9 +351,6 @@ read_token (t)
|
|||
t->yychar = STRING;
|
||||
break;
|
||||
|
||||
/* This token should not be generated in C++ mode. */
|
||||
case CPP_OSTRING:
|
||||
|
||||
/* These tokens should not survive translation phase 4. */
|
||||
case CPP_HASH:
|
||||
case CPP_PASTE:
|
||||
|
@ -1499,8 +1496,7 @@ yyerror (msgid)
|
|||
error ("%s before %s'\\x%x'", string, ell, val);
|
||||
}
|
||||
else if (last_token == CPP_STRING
|
||||
|| last_token == CPP_WSTRING
|
||||
|| last_token == CPP_OSTRING)
|
||||
|| last_token == CPP_WSTRING)
|
||||
error ("%s before string constant", string);
|
||||
else if (last_token == CPP_NUMBER
|
||||
|| last_token == CPP_INT
|
||||
|
|
34
gcc/cpplex.c
34
gcc/cpplex.c
|
@ -1241,29 +1241,8 @@ _cpp_lex_token (pfile, result)
|
|||
case '}': result->type = CPP_CLOSE_BRACE; break;
|
||||
case ';': result->type = CPP_SEMICOLON; break;
|
||||
|
||||
case '@':
|
||||
if (CPP_OPTION (pfile, objc))
|
||||
{
|
||||
/* 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;
|
||||
/* @ is a punctuator in Objective C. */
|
||||
case '@': result->type = CPP_ATSIGN; break;
|
||||
|
||||
random_char:
|
||||
default:
|
||||
|
@ -1341,7 +1320,6 @@ cpp_spell_token (pfile, token, buffer)
|
|||
{
|
||||
case CPP_STRING: left = '"'; right = '"'; tag = '\0'; 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_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
|
||||
case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
|
||||
|
@ -1432,7 +1410,6 @@ cpp_output_token (token, fp)
|
|||
{
|
||||
case CPP_STRING: left = '"'; right = '"'; tag = '\0'; 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_WCHAR: left = '\''; right = '\''; tag = 'L'; break;
|
||||
case CPP_HEADER_NAME: left = '<'; right = '>'; tag = '\0'; break;
|
||||
|
@ -1580,13 +1557,6 @@ cpp_can_paste (pfile, token1, token2, digraph)
|
|||
return CPP_NUMBER;
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -119,6 +119,7 @@ struct file_name_map_list;
|
|||
OP(CPP_SCOPE, "::") \
|
||||
OP(CPP_DEREF_STAR, "->*") \
|
||||
OP(CPP_DOT_STAR, ".*") \
|
||||
OP(CPP_ATSIGN, "@") /* used in Objective C */ \
|
||||
\
|
||||
TK(CPP_NAME, SPELL_IDENT) /* word */ \
|
||||
TK(CPP_INT, SPELL_STRING) /* 23 */ \
|
||||
|
@ -131,7 +132,6 @@ struct file_name_map_list;
|
|||
\
|
||||
TK(CPP_STRING, SPELL_STRING) /* "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_COMMENT, SPELL_STRING) /* Only if output comments. */ \
|
||||
|
|
|
@ -291,8 +291,7 @@ stringify_arg (pfile, arg)
|
|||
unsigned int len = cpp_token_len (token);
|
||||
|
||||
escape_it = (token->type == CPP_STRING || token->type == CPP_WSTRING
|
||||
|| token->type == CPP_CHAR || token->type == CPP_WCHAR
|
||||
|| token->type == CPP_OSTRING);
|
||||
|| token->type == CPP_CHAR || token->type == CPP_WCHAR);
|
||||
|
||||
if (escape_it)
|
||||
/* Worst case is each char is octal. */
|
||||
|
|
Loading…
Add table
Reference in a new issue