Commit ba89d661 by Zack Weinberg

cpplex.c (parse_name): Might have to glue a CPP_OTHER token before the name.

	* cpplex.c (parse_name): Might have to glue a CPP_OTHER token
	before the name.
	(lex_line): Glue @ onto the beginning of identifiers and
	string constants, in Objective-C mode.
	(output_token, spell_token): Handle CPP_OSTRING.
	(can_paste, maybe_paste_with_next): Handle pasting @ onto the
	beginning of a NAME or a STRING, in objc mode.

	* cpplib.c (get_define_node): Do not permit identifiers that
	begin with @ to be #defined.
	* cppmacro.c (CAN_PASTE_AFTER): Add CPP_OTHER.
	* cpplib.h (TTYPE_TABLE): Add CPP_OSTRING.

	* c-lang.c, objc/objc-act.c (build_objc_string): Delete.
	* c-tree.h (build_objc_string): Delete prototype.
	* objc/objc-tree.def: Delete OBJC_STRING_CST.
	* c-lex.c (yylex): Use build_string for all three kinds of strings.

	* gcc.dg/cpp/20000625-2.c: Don't expect a warning on line 4.

From-SVN: r35470
parent d31772ca
2000-08-03 Zack Weinberg <zack@wolery.cumb.org>
* cpplex.c (parse_name): Might have to glue a CPP_OTHER token
before the name.
(lex_line): Glue @ onto the beginning of identifiers and
string constants, in Objective-C mode.
(output_token, spell_token): Handle CPP_OSTRING.
(can_paste, maybe_paste_with_next): Handle pasting @ onto the
beginning of a NAME or a STRING, in objc mode.
* cpplib.c (get_define_node): Do not permit identifiers that
begin with @ to be #defined.
* cppmacro.c (CAN_PASTE_AFTER): Add CPP_OTHER.
* cpplib.h (TTYPE_TABLE): Add CPP_OSTRING.
* c-lang.c, objc/objc-act.c (build_objc_string): Delete.
* c-tree.h (build_objc_string): Delete prototype.
* objc/objc-tree.def: Delete OBJC_STRING_CST.
* c-lex.c (yylex): Use build_string for all three kinds of strings.
* c-parse.in, objc/objc-act.c: Update commentary.
2000-08-03 Mark Mitchell <mark@codesourcery.com>
* extend.texi: Fix typo in last change.
......
......@@ -171,15 +171,6 @@ recognize_objc_keyword ()
return 0;
}
tree
build_objc_string (len, str)
int len ATTRIBUTE_UNUSED;
const char *str ATTRIBUTE_UNUSED;
{
abort ();
return NULL_TREE;
}
/* Used by c-typeck.c (build_external_ref), but only for objc. */
tree
......
......@@ -2268,25 +2268,19 @@ yylex ()
/* We have read the entire constant.
Construct a STRING_CST for the result. */
yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1);
if (wide_flag)
{
yylval.ttype = build_string (p - (token_buffer + 1),
token_buffer + 1);
TREE_TYPE (yylval.ttype) = wchar_array_type_node;
value = STRING;
}
else if (objc_flag)
{
/* Return an Objective-C @"..." constant string object. */
yylval.ttype = build_objc_string (p - (token_buffer + 1),
token_buffer + 1);
TREE_TYPE (yylval.ttype) = char_array_type_node;
value = OBJC_STRING;
}
else
{
yylval.ttype = build_string (p - (token_buffer + 1),
token_buffer + 1);
TREE_TYPE (yylval.ttype) = char_array_type_node;
value = STRING;
}
......
......@@ -150,7 +150,7 @@ end ifc
%token CLASSNAME PUBLIC PRIVATE PROTECTED PROTOCOL OBJECTNAME CLASS ALIAS
/* Objective-C string constants in raw form.
yylval is an OBJC_STRING_CST node. */
yylval is an STRING_CST node. */
%token OBJC_STRING
......@@ -753,8 +753,8 @@ end ifc
;
ifobjc
/* Produces an OBJC_STRING_CST with perhaps more OBJC_STRING_CSTs chained
onto it. */
/* 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
......
......@@ -142,7 +142,6 @@ extern int maybe_objc_comptypes PARAMS ((tree, tree, int));
extern tree maybe_building_objc_message_expr PARAMS ((void));
extern tree maybe_objc_method_name PARAMS ((tree));
extern int recognize_objc_keyword PARAMS ((void));
extern tree build_objc_string PARAMS ((int, const char *));
extern tree lookup_objc_ivar PARAMS ((tree));
/* in c-parse.in */
......
......@@ -1008,15 +1008,27 @@ parse_name (pfile, tok, cur, rlimit)
}
len = cur - name;
if (tok->val.node == 0)
if (tok->type == CPP_NAME && tok->val.node == 0)
tok->val.node = _cpp_lookup_with_hash (pfile, name, len, r);
else
{
unsigned int oldlen = tok->val.node->length;
U_CHAR *newname = alloca (oldlen + len);
unsigned int oldlen;
U_CHAR *newname;
if (tok->type == CPP_NAME)
oldlen = tok->val.node->length;
else
oldlen = 1;
newname = alloca (oldlen + len);
if (tok->type == CPP_NAME)
memcpy (newname, tok->val.node->name, oldlen);
else
newname[0] = tok->val.aux;
memcpy (newname + oldlen, name, len);
tok->val.node = cpp_lookup (pfile, newname, len + oldlen);
tok->type = CPP_NAME;
}
return cur;
......@@ -1373,8 +1385,16 @@ lex_line (pfile, list)
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
cur--; /* Backup character. */
/* In Objective C, '@' may begin certain keywords. */
if (CPP_OPTION (pfile, objc) && cur_token[-1].type == CPP_OTHER
&& cur_token[-1].val.aux == '@' && IMMED_TOKEN ())
cur_token--;
else
{
cur_token->val.node = 0;
cur_token->type = CPP_NAME; /* Identifier, macro etc. */
}
continue_name:
cur = parse_name (pfile, cur_token, cur, buffer->rlimit);
......@@ -1394,12 +1414,21 @@ lex_line (pfile, list)
break;
case '\'':
cur_token->type = CPP_CHAR;
if (cur_token[-1].type == CPP_NAME && IMMED_TOKEN ()
&& cur_token[-1].val.node == pfile->spec_nodes->n_L)
BACKUP_TOKEN (CPP_WCHAR);
goto do_parse_string;
case '\"':
cur_token->type = c == '\'' ? CPP_CHAR : CPP_STRING;
/* Do we have a wide string? */
cur_token->type = CPP_STRING;
if (cur_token[-1].type == CPP_NAME && IMMED_TOKEN ()
&& cur_token[-1].val.node == pfile->spec_nodes->n_L)
BACKUP_TOKEN (c == '\'' ? CPP_WCHAR : CPP_WSTRING);
BACKUP_TOKEN (CPP_WSTRING);
else if (CPP_OPTION (pfile, objc)
&& cur_token[-1].type == CPP_OTHER && IMMED_TOKEN ()
&& cur_token[-1].val.aux == '@')
BACKUP_TOKEN (CPP_OSTRING);
do_parse_string:
/* Here c is one of ' " or >. */
......@@ -1883,20 +1912,21 @@ output_token (pfile, fp, token, prev, white)
case SPELL_STRING:
{
if (token->type == CPP_WSTRING || token->type == CPP_WCHAR)
putc ('L', fp);
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
putc ('"', fp);
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
putc ('\'', fp);
int left, right, tag;
switch (token->type)
{
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;
default: left = '\0'; right = '\0'; tag = '\0'; break;
}
if (tag) putc (tag, fp);
if (left) putc (left, fp);
fwrite (token->val.str.text, 1, token->val.str.len, fp);
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
putc ('"', fp);
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
putc ('\'', fp);
if (right) putc (right, fp);
}
break;
......@@ -1999,21 +2029,22 @@ spell_token (pfile, token, buffer)
case SPELL_STRING:
{
if (token->type == CPP_WSTRING || token->type == CPP_WCHAR)
*buffer++ = 'L';
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
*buffer++ = '"';
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
*buffer++ = '\'';
int left, right, tag;
switch (token->type)
{
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;
default: left = '\0'; right = '\0'; tag = '\0'; break;
}
if (tag) *buffer++ = tag;
if (left) *buffer++ = left;
memcpy (buffer, token->val.str.text, token->val.str.len);
buffer += token->val.str.len;
if (token->type == CPP_STRING || token->type == CPP_WSTRING)
*buffer++ = '"';
if (token->type == CPP_CHAR || token->type == CPP_WCHAR)
*buffer++ = '\'';
if (right) *buffer++ = right;
}
break;
......@@ -2700,6 +2731,13 @@ can_paste (pfile, token1, token2, digraph)
return CPP_NUMBER;
break;
case CPP_OTHER:
if (CPP_OPTION (pfile, objc) && token1->val.aux == '@')
{
if (b == CPP_NAME) return CPP_NAME;
if (b == CPP_STRING) return CPP_OSTRING;
}
default:
break;
}
......@@ -2789,7 +2827,8 @@ maybe_paste_with_next (pfile, token)
pasted->val.str.len = end - buf;
}
}
else if (type == CPP_WCHAR || type == CPP_WSTRING)
else if (type == CPP_WCHAR || type == CPP_WSTRING
|| type == CPP_OSTRING)
pasted = duplicate_token (pfile, second);
else
{
......
......@@ -242,6 +242,16 @@ get_define_node (pfile)
return 0;
}
/* In Objective C, some keywords begin with '@', but general identifiers
do not, and you're not allowed to #define them. */
if (token->val.node->name[0] == '@')
{
cpp_error_with_line (pfile, token->line, token->col,
"\"%s\" cannot be used as a macro name",
token->val.node->name);
return 0;
}
/* Check for poisoned identifiers now. */
if (token->val.node->type == T_POISON)
{
......
......@@ -123,6 +123,7 @@ typedef struct cpp_hashnode cpp_hashnode;
\
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. */ \
......
......@@ -55,12 +55,14 @@ static cpp_toklist * alloc_macro PARAMS ((cpp_reader *, struct macro_info *));
/* These are all the tokens that can have something pasted after them.
Comma is included in the list only to support the GNU varargs extension
(where you write a ## b and a disappears if b is an empty rest argument). */
(where you write a ## b and a disappears if b is an empty rest argument).
CPP_OTHER is included because of Objective C's use of '@'. */
#define CAN_PASTE_AFTER(type) \
((type) <= CPP_LAST_EQ || (type) == CPP_COLON || (type) == CPP_HASH \
|| (type) == CPP_DEREF || (type) == CPP_DOT || (type) == CPP_NAME \
|| (type) == CPP_INT || (type) == CPP_FLOAT || (type) == CPP_NUMBER \
|| (type) == CPP_MACRO_ARG || (type) == CPP_PLACEMARKER || (type) == CPP_COMMA)
|| (type) == CPP_MACRO_ARG || (type) == CPP_PLACEMARKER \
|| (type) == CPP_COMMA || (type) == CPP_OTHER)
/* Scans for a given token, returning the parameter number if found,
or 0 if not found. Scans from FIRST to TOKEN - 1 or the first
......
......@@ -1410,22 +1410,7 @@ my_build_string (len, str)
return a_string;
}
/* Return a newly constructed OBJC_STRING_CST node whose value is
the LEN characters at STR.
The TREE_TYPE is not initialized. */
tree
build_objc_string (len, str)
int len;
const char *str;
{
tree s = build_string (len, str);
TREE_SET_CODE (s, OBJC_STRING_CST);
return s;
}
/* Given a chain of OBJC_STRING_CST's, build a static instance of
/* Given a chain of STRING_CST's, build a static instance of
NXConstanString which points at the concatenation of those strings.
We place the string object in the __string_objects section of the
__OBJC segment. The Objective-C runtime will initialize the isa
......@@ -1451,7 +1436,6 @@ build_objc_string_object (strings)
add_class_reference (constant_string_id);
/* Combine_strings will work for OBJC_STRING_CST's too. */
string = combine_strings (strings);
TREE_SET_CODE (string, STRING_CST);
length = TREE_STRING_LENGTH (string) - 1;
......
......@@ -32,6 +32,3 @@ DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", 't', 0)
DEFTREECODE (KEYWORD_DECL, "keyword_decl", 'd', 0)
DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", 'd', 0)
DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", 'd', 0)
/* Objective-C constants. */
DEFTREECODE (OBJC_STRING_CST, "objc_string_cst", 'c', 3)
2000-08-03 Zack Weinberg <zack@wolery.cumb.org>
* gcc.dg/cpp/20000625-2.c: Don't expect a warning on line 4.
Thu Aug 3 01:46:33 2000 Jeffrey A Law (law@cygnus.com)
* gcc.c-torture/compile/20000803-1.c: New test.
......
......@@ -2,7 +2,6 @@
/* { dg-do run } */
#define symbol_version(name, version) name##@##version
/* { dg-warning "nothing can be pasted" "" { target *-*-* } 4 } */
#define str(x) xstr(x)
#define xstr(x) #x
......
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