+ }
+
+ copy = (char *) alloca (copylen + 1);
+ memcpy (copy, token->val.str.text, copylen);
+ copy[copylen] = '\0';
+
+ fixed_from_string (&fixed, copy, TYPE_MODE (type));
+
+ /* Create a node with determined type and value. */
+ value = build_fixed (type, fixed);
+
+ return value;
+}
+
+/* Convert a series of STRING, WSTRING, STRING16, STRING32 and/or
+ UTF8STRING tokens into a tree, performing string constant
+ concatenation. TOK is the first of these. VALP is the location
+ to write the string into. OBJC_STRING indicates whether an '@' token
+ preceded the incoming token.
+ Returns the CPP token type of the result (CPP_STRING, CPP_WSTRING,
+ CPP_STRING32, CPP_STRING16, CPP_UTF8STRING, or CPP_OBJC_STRING).
+
+ This is unfortunately more work than it should be. If any of the
+ strings in the series has an L prefix, the result is a wide string
+ (6.4.5p4). Whether or not the result is a wide string affects the
+ meaning of octal and hexadecimal escapes (6.4.4.4p6,9). But escape
+ sequences do not continue across the boundary between two strings in
+ a series (6.4.5p7), so we must not lose the boundaries. Therefore
+ cpp_interpret_string takes a vector of cpp_string structures, which
+ we must arrange to provide. */
+
+static enum cpp_ttype
+lex_string (const cpp_token *tok, tree *valp, bool objc_string, bool translate)
+{
+ tree value;
+ size_t concats = 0;
+ struct obstack str_ob;
+ cpp_string istr;
+ enum cpp_ttype type = tok->type;
+
+ /* Try to avoid the overhead of creating and destroying an obstack
+ for the common case of just one string. */
+ cpp_string str = tok->val.str;
+ cpp_string *strs = &str;
+
+ retry:
+ tok = cpp_get_token (parse_in);
+ switch (tok->type)
+ {
+ case CPP_PADDING:
+ goto retry;
+ case CPP_ATSIGN:
+ if (c_dialect_objc ())
+ {
+ objc_string = true;
+ goto retry;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ break;
+
+ case CPP_WSTRING:
+ case CPP_STRING16:
+ case CPP_STRING32:
+ case CPP_UTF8STRING:
+ if (type != tok->type)