* c-lex.c, c-parse.in, c-typeck.c: Revert concatenation changes.
cp:
* parse.y, semantics.c: Similarly.
From-SVN: r47848
+2001-12-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * c-lex.c, c-parse.in, c-typeck.c: Revert concatenation changes.
+
Mon Dec 10 09:19:11 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* config/i386/i386.md (leave, leave_rex64): Adjust pattern to match
tree *value;
{
const cpp_token *tok;
- enum cpp_ttype result;
retry:
timevar_push (TV_CPP);
lineno = src_lineno;
*value = NULL_TREE;
- result = tok->type;
-
- switch (result)
+ switch (tok->type)
{
case CPP_OPEN_BRACE: indent_level++; break;
case CPP_CLOSE_BRACE: indent_level--; break;
case CPP_STRING:
case CPP_WSTRING:
- {
- tree full_str = NULL_TREE;
-
- do
- {
- /* Translate escape sequences in this string, then append it. */
- tree str = lex_string ((const char *) tok->val.str.text,
- tok->val.str.len,
- tok->type == CPP_WSTRING);
-
- if (full_str && c_language == clk_c && warn_traditional
- && !in_system_header)
- {
- static int last_lineno;
- static const char *last_input_filename;
-
- if (lineno != last_lineno || !last_input_filename
- || strcmp (last_input_filename, input_filename))
- {
- warning ("traditional C rejects string concatenation");
- last_lineno = lineno;
- last_input_filename = input_filename;
- }
- }
-
- full_str = chainon (full_str, str);
-
- /* Wide and non-wide give a wide result. */
- if (tok->type == CPP_WSTRING)
- result = CPP_WSTRING;
-
- /* Look ahead for another string token. */
- do
- tok = cpp_get_token (parse_in);
- while (tok->type == CPP_PADDING);
- }
- while (tok->type == CPP_STRING || tok->type == CPP_WSTRING);
-
- _cpp_backup_tokens (parse_in, 1);
-
- *value = combine_strings (full_str);
- }
+ *value = lex_string ((const char *)tok->val.str.text,
+ tok->val.str.len, tok->type == CPP_WSTRING);
break;
/* These tokens should not be visible outside cpplib. */
default: break;
}
- return result;
+ return tok->type;
}
#define ERROR(msgid) do { error(msgid); goto syntax_error; } while(0)
yylval is the node for the constant. */
%token CONSTANT
-/* A STRING_CST with type an array of the appropriate character type. */
-%token STRING OBJC_STRING
+/* String constants in raw form.
+ yylval is a STRING_CST node. */
+%token STRING
/* "...", used for functions with variable arglists. */
%token ELLIPSIS
%type <ttype> BREAK CONTINUE RETURN GOTO ASM_KEYWORD SIZEOF TYPEOF ALIGNOF
%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
-%type <ttype> expr_no_commas cast_expr unary_expr primary STRING
+%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING
%type <ttype> declspecs_nosc_nots_nosa_noea declspecs_nosc_nots_nosa_ea
%type <ttype> declspecs_nosc_nots_sa_noea declspecs_nosc_nots_sa_ea
%type <ttype> declspecs_nosc_ts_nosa_noea declspecs_nosc_ts_nosa_ea
%type <lineno> save_lineno
\f
ifobjc
-%token OBJC_STRING
-
/* the Objective-C nonterminals */
%type <ttype> ivar_decl_list ivar_decls ivar_decl ivars ivar_declarator
%type <ttype> selectorarg keywordnamelist keywordname objcencodeexpr
%type <ttype> objc_string non_empty_protocolrefs protocolrefs identifier_list objcprotocolexpr
-%type <ttype> CLASSNAME OBJECTNAME OBJC_STRING
+%type <ttype> CLASSNAME OBJECTNAME
end ifobjc
\f
%{
ifobjc
| objcdef
end ifobjc
- | ASM_KEYWORD '(' STRING ')' ';'
- { assemble_asm ($3); }
+ | ASM_KEYWORD '(' expr ')' ';'
+ { STRIP_NOPS ($3);
+ if ((TREE_CODE ($3) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND ($3, 0)) == STRING_CST)
+ || TREE_CODE ($3) == STRING_CST)
+ assemble_asm ($3);
+ else
+ error ("argument of `asm' is not a constant string"); }
| extension extdef
{ RESTORE_WARN_FLAGS ($1); }
;
$$ = build_external_ref ($1, yychar == '(');
}
| CONSTANT
- | STRING
- { $$ = $1; }
+ | string
+ { $$ = combine_strings ($1); }
| VAR_FUNC_NAME
{ $$ = fname_decl (C_RID_CODE ($$), $$); }
| '(' typename ')' '{'
end ifobjc
;
+/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
+string:
+ STRING
+ | string STRING
+ {
+ifc
+ static int last_lineno = 0;
+ static const char *last_input_filename = 0;
+end ifc
+ $$ = chainon ($1, $2);
+ifc
+ if (warn_traditional && !in_system_header
+ && (lineno != last_lineno || !last_input_filename ||
+ strcmp (last_input_filename, input_filename)))
+ {
+ warning ("traditional C rejects string concatenation");
+ last_lineno = lineno;
+ last_input_filename = input_filename;
+ }
+end ifc
+ }
+ ;
+
ifobjc
-/* Chains ObjC string objects together. */
+/* 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
- { $$ = $1; }
- | objc_string OBJC_STRING
- { $$ = chainon ($1, $2); }
+ '@' STRING
+ { $$ = $2; }
+ | objc_string '@' STRING
+ { $$ = chainon ($1, $3); }
;
end ifobjc
maybeasm:
/* empty */
{ $$ = NULL_TREE; }
- | ASM_KEYWORD '(' STRING ')'
- { $$ = $3; }
+ | ASM_KEYWORD '(' string ')'
+ { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
+ $$ = $3;
+ }
;
initdcl:
| RETURN expr ';'
{ stmt_count++;
$$ = c_expand_return ($2); }
- | ASM_KEYWORD maybe_type_qual '(' STRING ')' ';'
+ | ASM_KEYWORD maybe_type_qual '(' expr ')' ';'
{ stmt_count++;
$$ = simple_asm_stmt ($4); }
/* This is the case with just output operands. */
- | ASM_KEYWORD maybe_type_qual '(' STRING ':' asm_operands ')' ';'
+ | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ')' ';'
{ stmt_count++;
$$ = build_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); }
/* This is the case with input operands as well. */
- | ASM_KEYWORD maybe_type_qual '(' STRING ':' asm_operands ':'
+ | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
asm_operands ')' ';'
{ stmt_count++;
$$ = build_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
/* This is the case with clobbered registers as well. */
- | ASM_KEYWORD maybe_type_qual '(' STRING ':' asm_operands ':'
+ | ASM_KEYWORD maybe_type_qual '(' expr ':' asm_operands ':'
asm_operands ':' asm_clobbers ')' ';'
{ stmt_count++;
$$ = build_asm_stmt ($2, $4, $6, $8, $10); }
;
asm_clobbers:
- STRING
- { $$ = tree_cons (NULL_TREE, $1, NULL_TREE); }
- | asm_clobbers ',' STRING
- { $$ = tree_cons (NULL_TREE, $3, $1); }
+ string
+ { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE); }
+ | asm_clobbers ',' string
+ { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
;
\f
/* This is what appears inside the parens in a function declarator.
to string constants. */
const char *name = fname_string (rid_code);
- yylval.ttype
- = combine_strings (build_string (strlen (name) + 1, name));
+ yylval.ttype = build_string (strlen (name) + 1, name);
last_token = CPP_STRING; /* so yyerror won't choke */
return STRING;
}
special significance. */
case CPP_ATSIGN:
ifobjc
- last_token = c_lex (&yylval.ttype);
+ {
+ tree after_at;
+ enum cpp_ttype after_at_type;
- if (last_token == CPP_NAME
- && C_IS_RESERVED_WORD (yylval.ttype)
- && OBJC_IS_AT_KEYWORD (C_RID_CODE (yylval.ttype)))
- return rid_to_yy [(int) C_RID_CODE (yylval.ttype)];
- else if (last_token == CPP_STRING || last_token == CPP_WSTRING)
- return OBJC_STRING;
+ after_at_type = c_lex (&after_at);
- /* Fall through... */
+ if (after_at_type == CPP_NAME
+ && C_IS_RESERVED_WORD (after_at)
+ && OBJC_IS_AT_KEYWORD (C_RID_CODE (after_at)))
+ {
+ yylval.ttype = after_at;
+ last_token = after_at_type;
+ return rid_to_yy [(int) C_RID_CODE (after_at)];
+ }
+ _cpp_backup_tokens (parse_in, 1);
+ return '@';
+ }
end ifobjc
/* These tokens are C++ specific (and will not be generated
\f
/* Build a simple asm-statement, from one string literal. */
tree
-simple_asm_stmt (string)
- tree string;
+simple_asm_stmt (expr)
+ tree expr;
{
- tree stmt;
+ STRIP_NOPS (expr);
+
+ if (TREE_CODE (expr) == ADDR_EXPR)
+ expr = TREE_OPERAND (expr, 0);
- stmt = add_stmt (build_stmt (ASM_STMT, NULL_TREE, string,
- NULL_TREE, NULL_TREE,
- NULL_TREE));
- ASM_INPUT_P (stmt) = 1;
- return stmt;
+ if (TREE_CODE (expr) == STRING_CST)
+ {
+ tree stmt;
+
+ if (TREE_CHAIN (expr))
+ expr = combine_strings (expr);
+ stmt = add_stmt (build_stmt (ASM_STMT, NULL_TREE, expr,
+ NULL_TREE, NULL_TREE,
+ NULL_TREE));
+ ASM_INPUT_P (stmt) = 1;
+ return stmt;
+ }
+
+ error ("argument of `asm' is not a constant string");
+ return NULL_TREE;
}
/* Build an asm-statement, whose components are a CV_QUALIFIER, a
{
tree tail;
+ if (TREE_CHAIN (string))
+ string = combine_strings (string);
+ if (TREE_CODE (string) != STRING_CST)
+ {
+ error ("asm template is not a string constant");
+ return NULL_TREE;
+ }
+
if (cv_qualifier != NULL_TREE
&& cv_qualifier != ridpointers[(int) RID_VOLATILE])
{
+2001-12-10 Neil Booth <neil@daikokuya.demon.co.uk>
+
+ * parse.y, semantics.c: Similarly.
+
2001-12-04 Nathan Sidwell <nathan@codesourcery.com>
PR g++/87
yylval contains an IDENTIFIER_NODE which indicates which one. */
%token VAR_FUNC_NAME
-/* String constants as arrays of a suitable type. */
+/* String constants in raw form.
+ yylval is a STRING_CST node. */
%token STRING
/* "...", used for functions with variable arglists. */
%type <ttype> PFUNCNAME maybe_identifier
%type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME
%type <ttype> expr_no_commas expr_no_comma_rangle
-%type <ttype> cast_expr unary_expr primary STRING
+%type <ttype> cast_expr unary_expr primary string STRING
%type <ttype> reserved_declspecs boolean.literal
%type <ttype> reserved_typespecquals
%type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier
{ do_pending_inlines (); }
| template_def
{ do_pending_inlines (); }
- | asm_keyword '(' STRING ')' ';'
- { assemble_asm ($3); }
+ | asm_keyword '(' string ')' ';'
+ { if (TREE_CHAIN ($3)) $3 = combine_strings ($3);
+ assemble_asm ($3); }
| extern_lang_string '{' extdefs_opt '}'
{ pop_lang_context (); }
| extern_lang_string .hush_warning fndef .warning_ok eat_saved_input
}
| CONSTANT
| boolean.literal
- | STRING
+ | string
{
+ $$ = combine_strings ($$);
/* combine_strings doesn't set up TYPE_MAIN_VARIANT of
a const array the way we want, so fix it. */
if (flag_const_strings)
{ $$ = boolean_false_node; }
;
+/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
+string:
+ STRING
+ | string STRING
+ { $$ = chainon ($$, $2); }
+ ;
+
nodecls:
/* empty */
{
maybeasm:
/* empty */
{ $$ = NULL_TREE; }
- | asm_keyword '(' STRING ')'
- { $$ = $3; }
+ | asm_keyword '(' string ')'
+ { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; }
;
initdcl:
{ $$ = finish_return_stmt (NULL_TREE); }
| RETURN_KEYWORD expr ';'
{ $$ = finish_return_stmt ($2); }
- | asm_keyword maybe_cv_qualifier '(' STRING ')' ';'
+ | asm_keyword maybe_cv_qualifier '(' string ')' ';'
{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE,
NULL_TREE);
ASM_INPUT_P ($$) = 1; }
/* This is the case with just output operands. */
- | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ')' ';'
+ | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ')' ';'
{ $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, NULL_TREE); }
/* This is the case with input operands as well. */
- | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':'
+ | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':'
asm_operands ')' ';'
{ $$ = finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); }
- | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ')' ';'
+ | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ')' ';'
{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, NULL_TREE); }
/* This is the case with clobbered registers as well. */
- | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands ':'
+ | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':'
asm_operands ':' asm_clobbers ')' ';'
{ $$ = finish_asm_stmt ($2, $4, $6, $8, $10); }
- | asm_keyword maybe_cv_qualifier '(' STRING SCOPE asm_operands ':'
+ | asm_keyword maybe_cv_qualifier '(' string SCOPE asm_operands ':'
asm_clobbers ')' ';'
{ $$ = finish_asm_stmt ($2, $4, NULL_TREE, $6, $8); }
- | asm_keyword maybe_cv_qualifier '(' STRING ':' asm_operands SCOPE
+ | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands SCOPE
asm_clobbers ')' ';'
{ $$ = finish_asm_stmt ($2, $4, $6, NULL_TREE, $8); }
| GOTO '*' expr ';'
;
asm_clobbers:
- STRING
- { $$ = tree_cons (NULL_TREE, $1, NULL_TREE);}
- | asm_clobbers ',' STRING
- { $$ = tree_cons (NULL_TREE, $3, $1); }
+ string
+ { $$ = tree_cons (NULL_TREE, combine_strings ($1), NULL_TREE);}
+ | asm_clobbers ',' string
+ { $$ = tree_cons (NULL_TREE, combine_strings ($3), $1); }
;
/* This is what appears inside the parens in a function declarator.
tree r;
tree t;
+ if (TREE_CHAIN (string))
+ string = combine_strings (string);
+
if (cv_qualifier != NULL_TREE
&& cv_qualifier != ridpointers[(int) RID_VOLATILE])
{