1e5dd7070Spatrick //===--- LiteralSupport.cpp - Code to parse and process literals ----------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements the NumericLiteralParser, CharLiteralParser, and
10e5dd7070Spatrick // StringLiteralParser interfaces.
11e5dd7070Spatrick //
12e5dd7070Spatrick //===----------------------------------------------------------------------===//
13e5dd7070Spatrick
14e5dd7070Spatrick #include "clang/Lex/LiteralSupport.h"
15e5dd7070Spatrick #include "clang/Basic/CharInfo.h"
16e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
17e5dd7070Spatrick #include "clang/Basic/SourceLocation.h"
18e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
19e5dd7070Spatrick #include "clang/Lex/LexDiagnostic.h"
20e5dd7070Spatrick #include "clang/Lex/Lexer.h"
21e5dd7070Spatrick #include "clang/Lex/Preprocessor.h"
22e5dd7070Spatrick #include "clang/Lex/Token.h"
23e5dd7070Spatrick #include "llvm/ADT/APInt.h"
24e5dd7070Spatrick #include "llvm/ADT/SmallVector.h"
25e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
26e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
27e5dd7070Spatrick #include "llvm/Support/ConvertUTF.h"
28ec727ea7Spatrick #include "llvm/Support/Error.h"
29e5dd7070Spatrick #include "llvm/Support/ErrorHandling.h"
30*12c85518Srobert #include "llvm/Support/Unicode.h"
31e5dd7070Spatrick #include <algorithm>
32e5dd7070Spatrick #include <cassert>
33e5dd7070Spatrick #include <cstddef>
34e5dd7070Spatrick #include <cstdint>
35e5dd7070Spatrick #include <cstring>
36e5dd7070Spatrick #include <string>
37e5dd7070Spatrick
38e5dd7070Spatrick using namespace clang;
39e5dd7070Spatrick
getCharWidth(tok::TokenKind kind,const TargetInfo & Target)40e5dd7070Spatrick static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target) {
41e5dd7070Spatrick switch (kind) {
42e5dd7070Spatrick default: llvm_unreachable("Unknown token type!");
43e5dd7070Spatrick case tok::char_constant:
44e5dd7070Spatrick case tok::string_literal:
45e5dd7070Spatrick case tok::utf8_char_constant:
46e5dd7070Spatrick case tok::utf8_string_literal:
47e5dd7070Spatrick return Target.getCharWidth();
48e5dd7070Spatrick case tok::wide_char_constant:
49e5dd7070Spatrick case tok::wide_string_literal:
50e5dd7070Spatrick return Target.getWCharWidth();
51e5dd7070Spatrick case tok::utf16_char_constant:
52e5dd7070Spatrick case tok::utf16_string_literal:
53e5dd7070Spatrick return Target.getChar16Width();
54e5dd7070Spatrick case tok::utf32_char_constant:
55e5dd7070Spatrick case tok::utf32_string_literal:
56e5dd7070Spatrick return Target.getChar32Width();
57e5dd7070Spatrick }
58e5dd7070Spatrick }
59e5dd7070Spatrick
MakeCharSourceRange(const LangOptions & Features,FullSourceLoc TokLoc,const char * TokBegin,const char * TokRangeBegin,const char * TokRangeEnd)60e5dd7070Spatrick static CharSourceRange MakeCharSourceRange(const LangOptions &Features,
61e5dd7070Spatrick FullSourceLoc TokLoc,
62e5dd7070Spatrick const char *TokBegin,
63e5dd7070Spatrick const char *TokRangeBegin,
64e5dd7070Spatrick const char *TokRangeEnd) {
65e5dd7070Spatrick SourceLocation Begin =
66e5dd7070Spatrick Lexer::AdvanceToTokenCharacter(TokLoc, TokRangeBegin - TokBegin,
67e5dd7070Spatrick TokLoc.getManager(), Features);
68e5dd7070Spatrick SourceLocation End =
69e5dd7070Spatrick Lexer::AdvanceToTokenCharacter(Begin, TokRangeEnd - TokRangeBegin,
70e5dd7070Spatrick TokLoc.getManager(), Features);
71e5dd7070Spatrick return CharSourceRange::getCharRange(Begin, End);
72e5dd7070Spatrick }
73e5dd7070Spatrick
74e5dd7070Spatrick /// Produce a diagnostic highlighting some portion of a literal.
75e5dd7070Spatrick ///
76e5dd7070Spatrick /// Emits the diagnostic \p DiagID, highlighting the range of characters from
77e5dd7070Spatrick /// \p TokRangeBegin (inclusive) to \p TokRangeEnd (exclusive), which must be
78e5dd7070Spatrick /// a substring of a spelling buffer for the token beginning at \p TokBegin.
Diag(DiagnosticsEngine * Diags,const LangOptions & Features,FullSourceLoc TokLoc,const char * TokBegin,const char * TokRangeBegin,const char * TokRangeEnd,unsigned DiagID)79e5dd7070Spatrick static DiagnosticBuilder Diag(DiagnosticsEngine *Diags,
80e5dd7070Spatrick const LangOptions &Features, FullSourceLoc TokLoc,
81e5dd7070Spatrick const char *TokBegin, const char *TokRangeBegin,
82e5dd7070Spatrick const char *TokRangeEnd, unsigned DiagID) {
83e5dd7070Spatrick SourceLocation Begin =
84e5dd7070Spatrick Lexer::AdvanceToTokenCharacter(TokLoc, TokRangeBegin - TokBegin,
85e5dd7070Spatrick TokLoc.getManager(), Features);
86e5dd7070Spatrick return Diags->Report(Begin, DiagID) <<
87e5dd7070Spatrick MakeCharSourceRange(Features, TokLoc, TokBegin, TokRangeBegin, TokRangeEnd);
88e5dd7070Spatrick }
89e5dd7070Spatrick
90e5dd7070Spatrick /// ProcessCharEscape - Parse a standard C escape sequence, which can occur in
91e5dd7070Spatrick /// either a character or a string literal.
ProcessCharEscape(const char * ThisTokBegin,const char * & ThisTokBuf,const char * ThisTokEnd,bool & HadError,FullSourceLoc Loc,unsigned CharWidth,DiagnosticsEngine * Diags,const LangOptions & Features)92e5dd7070Spatrick static unsigned ProcessCharEscape(const char *ThisTokBegin,
93e5dd7070Spatrick const char *&ThisTokBuf,
94e5dd7070Spatrick const char *ThisTokEnd, bool &HadError,
95e5dd7070Spatrick FullSourceLoc Loc, unsigned CharWidth,
96e5dd7070Spatrick DiagnosticsEngine *Diags,
97e5dd7070Spatrick const LangOptions &Features) {
98e5dd7070Spatrick const char *EscapeBegin = ThisTokBuf;
99*12c85518Srobert bool Delimited = false;
100*12c85518Srobert bool EndDelimiterFound = false;
101e5dd7070Spatrick
102e5dd7070Spatrick // Skip the '\' char.
103e5dd7070Spatrick ++ThisTokBuf;
104e5dd7070Spatrick
105e5dd7070Spatrick // We know that this character can't be off the end of the buffer, because
106e5dd7070Spatrick // that would have been \", which would not have been the end of string.
107e5dd7070Spatrick unsigned ResultChar = *ThisTokBuf++;
108e5dd7070Spatrick switch (ResultChar) {
109e5dd7070Spatrick // These map to themselves.
110e5dd7070Spatrick case '\\': case '\'': case '"': case '?': break;
111e5dd7070Spatrick
112e5dd7070Spatrick // These have fixed mappings.
113e5dd7070Spatrick case 'a':
114e5dd7070Spatrick // TODO: K&R: the meaning of '\\a' is different in traditional C
115e5dd7070Spatrick ResultChar = 7;
116e5dd7070Spatrick break;
117e5dd7070Spatrick case 'b':
118e5dd7070Spatrick ResultChar = 8;
119e5dd7070Spatrick break;
120e5dd7070Spatrick case 'e':
121e5dd7070Spatrick if (Diags)
122e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
123e5dd7070Spatrick diag::ext_nonstandard_escape) << "e";
124e5dd7070Spatrick ResultChar = 27;
125e5dd7070Spatrick break;
126e5dd7070Spatrick case 'E':
127e5dd7070Spatrick if (Diags)
128e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
129e5dd7070Spatrick diag::ext_nonstandard_escape) << "E";
130e5dd7070Spatrick ResultChar = 27;
131e5dd7070Spatrick break;
132e5dd7070Spatrick case 'f':
133e5dd7070Spatrick ResultChar = 12;
134e5dd7070Spatrick break;
135e5dd7070Spatrick case 'n':
136e5dd7070Spatrick ResultChar = 10;
137e5dd7070Spatrick break;
138e5dd7070Spatrick case 'r':
139e5dd7070Spatrick ResultChar = 13;
140e5dd7070Spatrick break;
141e5dd7070Spatrick case 't':
142e5dd7070Spatrick ResultChar = 9;
143e5dd7070Spatrick break;
144e5dd7070Spatrick case 'v':
145e5dd7070Spatrick ResultChar = 11;
146e5dd7070Spatrick break;
147e5dd7070Spatrick case 'x': { // Hex escape.
148e5dd7070Spatrick ResultChar = 0;
149*12c85518Srobert if (ThisTokBuf != ThisTokEnd && *ThisTokBuf == '{') {
150*12c85518Srobert Delimited = true;
151*12c85518Srobert ThisTokBuf++;
152*12c85518Srobert if (*ThisTokBuf == '}') {
153*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
154*12c85518Srobert diag::err_delimited_escape_empty);
155*12c85518Srobert return ResultChar;
156*12c85518Srobert }
157*12c85518Srobert } else if (ThisTokBuf == ThisTokEnd || !isHexDigit(*ThisTokBuf)) {
158e5dd7070Spatrick if (Diags)
159e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
160e5dd7070Spatrick diag::err_hex_escape_no_digits) << "x";
161*12c85518Srobert return ResultChar;
162e5dd7070Spatrick }
163e5dd7070Spatrick
164e5dd7070Spatrick // Hex escapes are a maximal series of hex digits.
165e5dd7070Spatrick bool Overflow = false;
166e5dd7070Spatrick for (; ThisTokBuf != ThisTokEnd; ++ThisTokBuf) {
167*12c85518Srobert if (Delimited && *ThisTokBuf == '}') {
168*12c85518Srobert ThisTokBuf++;
169*12c85518Srobert EndDelimiterFound = true;
170*12c85518Srobert break;
171*12c85518Srobert }
172*12c85518Srobert int CharVal = llvm::hexDigitValue(*ThisTokBuf);
173*12c85518Srobert if (CharVal == -1) {
174*12c85518Srobert // Non delimited hex escape sequences stop at the first non-hex digit.
175*12c85518Srobert if (!Delimited)
176*12c85518Srobert break;
177*12c85518Srobert HadError = true;
178*12c85518Srobert if (Diags)
179*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
180*12c85518Srobert diag::err_delimited_escape_invalid)
181*12c85518Srobert << StringRef(ThisTokBuf, 1);
182*12c85518Srobert continue;
183*12c85518Srobert }
184e5dd7070Spatrick // About to shift out a digit?
185e5dd7070Spatrick if (ResultChar & 0xF0000000)
186e5dd7070Spatrick Overflow = true;
187e5dd7070Spatrick ResultChar <<= 4;
188e5dd7070Spatrick ResultChar |= CharVal;
189e5dd7070Spatrick }
190e5dd7070Spatrick // See if any bits will be truncated when evaluated as a character.
191e5dd7070Spatrick if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
192e5dd7070Spatrick Overflow = true;
193e5dd7070Spatrick ResultChar &= ~0U >> (32-CharWidth);
194e5dd7070Spatrick }
195e5dd7070Spatrick
196e5dd7070Spatrick // Check for overflow.
197*12c85518Srobert if (!HadError && Overflow) { // Too many digits to fit in
198*12c85518Srobert HadError = true;
199*12c85518Srobert if (Diags)
200e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
201*12c85518Srobert diag::err_escape_too_large)
202*12c85518Srobert << 0;
203*12c85518Srobert }
204e5dd7070Spatrick break;
205e5dd7070Spatrick }
206e5dd7070Spatrick case '0': case '1': case '2': case '3':
207e5dd7070Spatrick case '4': case '5': case '6': case '7': {
208e5dd7070Spatrick // Octal escapes.
209e5dd7070Spatrick --ThisTokBuf;
210e5dd7070Spatrick ResultChar = 0;
211e5dd7070Spatrick
212e5dd7070Spatrick // Octal escapes are a series of octal digits with maximum length 3.
213e5dd7070Spatrick // "\0123" is a two digit sequence equal to "\012" "3".
214e5dd7070Spatrick unsigned NumDigits = 0;
215e5dd7070Spatrick do {
216e5dd7070Spatrick ResultChar <<= 3;
217e5dd7070Spatrick ResultChar |= *ThisTokBuf++ - '0';
218e5dd7070Spatrick ++NumDigits;
219e5dd7070Spatrick } while (ThisTokBuf != ThisTokEnd && NumDigits < 3 &&
220e5dd7070Spatrick ThisTokBuf[0] >= '0' && ThisTokBuf[0] <= '7');
221e5dd7070Spatrick
222e5dd7070Spatrick // Check for overflow. Reject '\777', but not L'\777'.
223e5dd7070Spatrick if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
224e5dd7070Spatrick if (Diags)
225e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
226e5dd7070Spatrick diag::err_escape_too_large) << 1;
227e5dd7070Spatrick ResultChar &= ~0U >> (32-CharWidth);
228e5dd7070Spatrick }
229e5dd7070Spatrick break;
230e5dd7070Spatrick }
231*12c85518Srobert case 'o': {
232*12c85518Srobert bool Overflow = false;
233*12c85518Srobert if (ThisTokBuf == ThisTokEnd || *ThisTokBuf != '{') {
234*12c85518Srobert HadError = true;
235*12c85518Srobert if (Diags)
236*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
237*12c85518Srobert diag::err_delimited_escape_missing_brace)
238*12c85518Srobert << "o";
239e5dd7070Spatrick
240*12c85518Srobert break;
241*12c85518Srobert }
242*12c85518Srobert ResultChar = 0;
243*12c85518Srobert Delimited = true;
244*12c85518Srobert ++ThisTokBuf;
245*12c85518Srobert if (*ThisTokBuf == '}') {
246*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
247*12c85518Srobert diag::err_delimited_escape_empty);
248*12c85518Srobert return ResultChar;
249*12c85518Srobert }
250*12c85518Srobert
251*12c85518Srobert while (ThisTokBuf != ThisTokEnd) {
252*12c85518Srobert if (*ThisTokBuf == '}') {
253*12c85518Srobert EndDelimiterFound = true;
254*12c85518Srobert ThisTokBuf++;
255*12c85518Srobert break;
256*12c85518Srobert }
257*12c85518Srobert if (*ThisTokBuf < '0' || *ThisTokBuf > '7') {
258*12c85518Srobert HadError = true;
259*12c85518Srobert if (Diags)
260*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
261*12c85518Srobert diag::err_delimited_escape_invalid)
262*12c85518Srobert << StringRef(ThisTokBuf, 1);
263*12c85518Srobert ThisTokBuf++;
264*12c85518Srobert continue;
265*12c85518Srobert }
266*12c85518Srobert if (ResultChar & 0x020000000)
267*12c85518Srobert Overflow = true;
268*12c85518Srobert
269*12c85518Srobert ResultChar <<= 3;
270*12c85518Srobert ResultChar |= *ThisTokBuf++ - '0';
271*12c85518Srobert }
272*12c85518Srobert // Check for overflow. Reject '\777', but not L'\777'.
273*12c85518Srobert if (!HadError &&
274*12c85518Srobert (Overflow || (CharWidth != 32 && (ResultChar >> CharWidth) != 0))) {
275*12c85518Srobert HadError = true;
276*12c85518Srobert if (Diags)
277*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
278*12c85518Srobert diag::err_escape_too_large)
279*12c85518Srobert << 1;
280*12c85518Srobert ResultChar &= ~0U >> (32 - CharWidth);
281*12c85518Srobert }
282*12c85518Srobert break;
283*12c85518Srobert }
284e5dd7070Spatrick // Otherwise, these are not valid escapes.
285e5dd7070Spatrick case '(': case '{': case '[': case '%':
286e5dd7070Spatrick // GCC accepts these as extensions. We warn about them as such though.
287e5dd7070Spatrick if (Diags)
288e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
289e5dd7070Spatrick diag::ext_nonstandard_escape)
290e5dd7070Spatrick << std::string(1, ResultChar);
291e5dd7070Spatrick break;
292e5dd7070Spatrick default:
293e5dd7070Spatrick if (!Diags)
294e5dd7070Spatrick break;
295e5dd7070Spatrick
296e5dd7070Spatrick if (isPrintable(ResultChar))
297e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
298e5dd7070Spatrick diag::ext_unknown_escape)
299e5dd7070Spatrick << std::string(1, ResultChar);
300e5dd7070Spatrick else
301e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
302e5dd7070Spatrick diag::ext_unknown_escape)
303e5dd7070Spatrick << "x" + llvm::utohexstr(ResultChar);
304e5dd7070Spatrick break;
305e5dd7070Spatrick }
306e5dd7070Spatrick
307*12c85518Srobert if (Delimited && Diags) {
308*12c85518Srobert if (!EndDelimiterFound)
309*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
310*12c85518Srobert diag::err_expected)
311*12c85518Srobert << tok::r_brace;
312*12c85518Srobert else if (!HadError) {
313*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
314*12c85518Srobert Features.CPlusPlus2b ? diag::warn_cxx2b_delimited_escape_sequence
315*12c85518Srobert : diag::ext_delimited_escape_sequence)
316*12c85518Srobert << /*delimited*/ 0 << (Features.CPlusPlus ? 1 : 0);
317*12c85518Srobert }
318*12c85518Srobert }
319*12c85518Srobert
320e5dd7070Spatrick return ResultChar;
321e5dd7070Spatrick }
322e5dd7070Spatrick
appendCodePoint(unsigned Codepoint,llvm::SmallVectorImpl<char> & Str)323e5dd7070Spatrick static void appendCodePoint(unsigned Codepoint,
324e5dd7070Spatrick llvm::SmallVectorImpl<char> &Str) {
325e5dd7070Spatrick char ResultBuf[4];
326e5dd7070Spatrick char *ResultPtr = ResultBuf;
327*12c85518Srobert if (llvm::ConvertCodePointToUTF8(Codepoint, ResultPtr))
328e5dd7070Spatrick Str.append(ResultBuf, ResultPtr);
329e5dd7070Spatrick }
330e5dd7070Spatrick
expandUCNs(SmallVectorImpl<char> & Buf,StringRef Input)331e5dd7070Spatrick void clang::expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input) {
332e5dd7070Spatrick for (StringRef::iterator I = Input.begin(), E = Input.end(); I != E; ++I) {
333e5dd7070Spatrick if (*I != '\\') {
334e5dd7070Spatrick Buf.push_back(*I);
335e5dd7070Spatrick continue;
336e5dd7070Spatrick }
337e5dd7070Spatrick
338e5dd7070Spatrick ++I;
339*12c85518Srobert char Kind = *I;
340*12c85518Srobert ++I;
341*12c85518Srobert
342*12c85518Srobert assert(Kind == 'u' || Kind == 'U' || Kind == 'N');
343*12c85518Srobert uint32_t CodePoint = 0;
344*12c85518Srobert
345*12c85518Srobert if (Kind == 'u' && *I == '{') {
346*12c85518Srobert for (++I; *I != '}'; ++I) {
347*12c85518Srobert unsigned Value = llvm::hexDigitValue(*I);
348*12c85518Srobert assert(Value != -1U);
349*12c85518Srobert CodePoint <<= 4;
350*12c85518Srobert CodePoint += Value;
351*12c85518Srobert }
352*12c85518Srobert appendCodePoint(CodePoint, Buf);
353*12c85518Srobert continue;
354*12c85518Srobert }
355*12c85518Srobert
356*12c85518Srobert if (Kind == 'N') {
357*12c85518Srobert assert(*I == '{');
358*12c85518Srobert ++I;
359*12c85518Srobert auto Delim = std::find(I, Input.end(), '}');
360*12c85518Srobert assert(Delim != Input.end());
361*12c85518Srobert std::optional<llvm::sys::unicode::LooseMatchingResult> Res =
362*12c85518Srobert llvm::sys::unicode::nameToCodepointLooseMatching(
363*12c85518Srobert StringRef(I, std::distance(I, Delim)));
364*12c85518Srobert assert(Res);
365*12c85518Srobert CodePoint = Res->CodePoint;
366*12c85518Srobert assert(CodePoint != 0xFFFFFFFF);
367*12c85518Srobert appendCodePoint(CodePoint, Buf);
368*12c85518Srobert I = Delim;
369*12c85518Srobert continue;
370*12c85518Srobert }
371e5dd7070Spatrick
372e5dd7070Spatrick unsigned NumHexDigits;
373*12c85518Srobert if (Kind == 'u')
374e5dd7070Spatrick NumHexDigits = 4;
375e5dd7070Spatrick else
376e5dd7070Spatrick NumHexDigits = 8;
377e5dd7070Spatrick
378e5dd7070Spatrick assert(I + NumHexDigits <= E);
379e5dd7070Spatrick
380*12c85518Srobert for (; NumHexDigits != 0; ++I, --NumHexDigits) {
381e5dd7070Spatrick unsigned Value = llvm::hexDigitValue(*I);
382e5dd7070Spatrick assert(Value != -1U);
383e5dd7070Spatrick
384e5dd7070Spatrick CodePoint <<= 4;
385e5dd7070Spatrick CodePoint += Value;
386e5dd7070Spatrick }
387e5dd7070Spatrick
388e5dd7070Spatrick appendCodePoint(CodePoint, Buf);
389e5dd7070Spatrick --I;
390e5dd7070Spatrick }
391e5dd7070Spatrick }
392e5dd7070Spatrick
ProcessNumericUCNEscape(const char * ThisTokBegin,const char * & ThisTokBuf,const char * ThisTokEnd,uint32_t & UcnVal,unsigned short & UcnLen,bool & Delimited,FullSourceLoc Loc,DiagnosticsEngine * Diags,const LangOptions & Features,bool in_char_string_literal=false)393*12c85518Srobert static bool ProcessNumericUCNEscape(const char *ThisTokBegin,
394*12c85518Srobert const char *&ThisTokBuf,
395*12c85518Srobert const char *ThisTokEnd, uint32_t &UcnVal,
396*12c85518Srobert unsigned short &UcnLen, bool &Delimited,
397e5dd7070Spatrick FullSourceLoc Loc, DiagnosticsEngine *Diags,
398e5dd7070Spatrick const LangOptions &Features,
399e5dd7070Spatrick bool in_char_string_literal = false) {
400e5dd7070Spatrick const char *UcnBegin = ThisTokBuf;
401*12c85518Srobert bool HasError = false;
402*12c85518Srobert bool EndDelimiterFound = false;
403e5dd7070Spatrick
404e5dd7070Spatrick // Skip the '\u' char's.
405e5dd7070Spatrick ThisTokBuf += 2;
406*12c85518Srobert Delimited = false;
407*12c85518Srobert if (UcnBegin[1] == 'u' && in_char_string_literal &&
408*12c85518Srobert ThisTokBuf != ThisTokEnd && *ThisTokBuf == '{') {
409*12c85518Srobert Delimited = true;
410*12c85518Srobert ThisTokBuf++;
411*12c85518Srobert } else if (ThisTokBuf == ThisTokEnd || !isHexDigit(*ThisTokBuf)) {
412e5dd7070Spatrick if (Diags)
413e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
414*12c85518Srobert diag::err_hex_escape_no_digits)
415*12c85518Srobert << StringRef(&ThisTokBuf[-1], 1);
416e5dd7070Spatrick return false;
417e5dd7070Spatrick }
418e5dd7070Spatrick UcnLen = (ThisTokBuf[-1] == 'u' ? 4 : 8);
419*12c85518Srobert
420*12c85518Srobert bool Overflow = false;
421*12c85518Srobert unsigned short Count = 0;
422*12c85518Srobert for (; ThisTokBuf != ThisTokEnd && (Delimited || Count != UcnLen);
423*12c85518Srobert ++ThisTokBuf) {
424*12c85518Srobert if (Delimited && *ThisTokBuf == '}') {
425*12c85518Srobert ++ThisTokBuf;
426*12c85518Srobert EndDelimiterFound = true;
427*12c85518Srobert break;
428*12c85518Srobert }
429*12c85518Srobert int CharVal = llvm::hexDigitValue(*ThisTokBuf);
430*12c85518Srobert if (CharVal == -1) {
431*12c85518Srobert HasError = true;
432*12c85518Srobert if (!Delimited)
433*12c85518Srobert break;
434*12c85518Srobert if (Diags) {
435*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
436*12c85518Srobert diag::err_delimited_escape_invalid)
437*12c85518Srobert << StringRef(ThisTokBuf, 1);
438*12c85518Srobert }
439*12c85518Srobert Count++;
440*12c85518Srobert continue;
441*12c85518Srobert }
442*12c85518Srobert if (UcnVal & 0xF0000000) {
443*12c85518Srobert Overflow = true;
444*12c85518Srobert continue;
445*12c85518Srobert }
446e5dd7070Spatrick UcnVal <<= 4;
447e5dd7070Spatrick UcnVal |= CharVal;
448*12c85518Srobert Count++;
449e5dd7070Spatrick }
450*12c85518Srobert
451*12c85518Srobert if (Overflow) {
452e5dd7070Spatrick if (Diags)
453e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
454*12c85518Srobert diag::err_escape_too_large)
455*12c85518Srobert << 0;
456e5dd7070Spatrick return false;
457e5dd7070Spatrick }
458e5dd7070Spatrick
459*12c85518Srobert if (Delimited && !EndDelimiterFound) {
460*12c85518Srobert if (Diags) {
461*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
462*12c85518Srobert diag::err_expected)
463*12c85518Srobert << tok::r_brace;
464*12c85518Srobert }
465*12c85518Srobert return false;
466*12c85518Srobert }
467*12c85518Srobert
468*12c85518Srobert // If we didn't consume the proper number of digits, there is a problem.
469*12c85518Srobert if (Count == 0 || (!Delimited && Count != UcnLen)) {
470*12c85518Srobert if (Diags)
471*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
472*12c85518Srobert Delimited ? diag::err_delimited_escape_empty
473*12c85518Srobert : diag::err_ucn_escape_incomplete);
474*12c85518Srobert return false;
475*12c85518Srobert }
476*12c85518Srobert return !HasError;
477*12c85518Srobert }
478*12c85518Srobert
DiagnoseInvalidUnicodeCharacterName(DiagnosticsEngine * Diags,const LangOptions & Features,FullSourceLoc Loc,const char * TokBegin,const char * TokRangeBegin,const char * TokRangeEnd,llvm::StringRef Name)479*12c85518Srobert static void DiagnoseInvalidUnicodeCharacterName(
480*12c85518Srobert DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc Loc,
481*12c85518Srobert const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd,
482*12c85518Srobert llvm::StringRef Name) {
483*12c85518Srobert
484*12c85518Srobert Diag(Diags, Features, Loc, TokBegin, TokRangeBegin, TokRangeEnd,
485*12c85518Srobert diag::err_invalid_ucn_name)
486*12c85518Srobert << Name;
487*12c85518Srobert
488*12c85518Srobert namespace u = llvm::sys::unicode;
489*12c85518Srobert
490*12c85518Srobert std::optional<u::LooseMatchingResult> Res =
491*12c85518Srobert u::nameToCodepointLooseMatching(Name);
492*12c85518Srobert if (Res) {
493*12c85518Srobert Diag(Diags, Features, Loc, TokBegin, TokRangeBegin, TokRangeEnd,
494*12c85518Srobert diag::note_invalid_ucn_name_loose_matching)
495*12c85518Srobert << FixItHint::CreateReplacement(
496*12c85518Srobert MakeCharSourceRange(Features, Loc, TokBegin, TokRangeBegin,
497*12c85518Srobert TokRangeEnd),
498*12c85518Srobert Res->Name);
499*12c85518Srobert return;
500*12c85518Srobert }
501*12c85518Srobert
502*12c85518Srobert unsigned Distance = 0;
503*12c85518Srobert SmallVector<u::MatchForCodepointName> Matches =
504*12c85518Srobert u::nearestMatchesForCodepointName(Name, 5);
505*12c85518Srobert assert(!Matches.empty() && "No unicode characters found");
506*12c85518Srobert
507*12c85518Srobert for (const auto &Match : Matches) {
508*12c85518Srobert if (Distance == 0)
509*12c85518Srobert Distance = Match.Distance;
510*12c85518Srobert if (std::max(Distance, Match.Distance) -
511*12c85518Srobert std::min(Distance, Match.Distance) >
512*12c85518Srobert 3)
513*12c85518Srobert break;
514*12c85518Srobert Distance = Match.Distance;
515*12c85518Srobert
516*12c85518Srobert std::string Str;
517*12c85518Srobert llvm::UTF32 V = Match.Value;
518*12c85518Srobert bool Converted =
519*12c85518Srobert llvm::convertUTF32ToUTF8String(llvm::ArrayRef<llvm::UTF32>(&V, 1), Str);
520*12c85518Srobert (void)Converted;
521*12c85518Srobert assert(Converted && "Found a match wich is not a unicode character");
522*12c85518Srobert
523*12c85518Srobert Diag(Diags, Features, Loc, TokBegin, TokRangeBegin, TokRangeEnd,
524*12c85518Srobert diag::note_invalid_ucn_name_candidate)
525*12c85518Srobert << Match.Name << llvm::utohexstr(Match.Value)
526*12c85518Srobert << Str // FIXME: Fix the rendering of non printable characters
527*12c85518Srobert << FixItHint::CreateReplacement(
528*12c85518Srobert MakeCharSourceRange(Features, Loc, TokBegin, TokRangeBegin,
529*12c85518Srobert TokRangeEnd),
530*12c85518Srobert Match.Name);
531*12c85518Srobert }
532*12c85518Srobert }
533*12c85518Srobert
ProcessNamedUCNEscape(const char * ThisTokBegin,const char * & ThisTokBuf,const char * ThisTokEnd,uint32_t & UcnVal,unsigned short & UcnLen,FullSourceLoc Loc,DiagnosticsEngine * Diags,const LangOptions & Features)534*12c85518Srobert static bool ProcessNamedUCNEscape(const char *ThisTokBegin,
535*12c85518Srobert const char *&ThisTokBuf,
536*12c85518Srobert const char *ThisTokEnd, uint32_t &UcnVal,
537*12c85518Srobert unsigned short &UcnLen, FullSourceLoc Loc,
538*12c85518Srobert DiagnosticsEngine *Diags,
539*12c85518Srobert const LangOptions &Features) {
540*12c85518Srobert const char *UcnBegin = ThisTokBuf;
541*12c85518Srobert assert(UcnBegin[0] == '\\' && UcnBegin[1] == 'N');
542*12c85518Srobert ThisTokBuf += 2;
543*12c85518Srobert if (ThisTokBuf == ThisTokEnd || *ThisTokBuf != '{') {
544*12c85518Srobert if (Diags) {
545*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
546*12c85518Srobert diag::err_delimited_escape_missing_brace)
547*12c85518Srobert << StringRef(&ThisTokBuf[-1], 1);
548*12c85518Srobert }
549*12c85518Srobert return false;
550*12c85518Srobert }
551*12c85518Srobert ThisTokBuf++;
552*12c85518Srobert const char *ClosingBrace = std::find_if(ThisTokBuf, ThisTokEnd, [](char C) {
553*12c85518Srobert return C == '}' || isVerticalWhitespace(C);
554*12c85518Srobert });
555*12c85518Srobert bool Incomplete = ClosingBrace == ThisTokEnd;
556*12c85518Srobert bool Empty = ClosingBrace == ThisTokBuf;
557*12c85518Srobert if (Incomplete || Empty) {
558*12c85518Srobert if (Diags) {
559*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
560*12c85518Srobert Incomplete ? diag::err_ucn_escape_incomplete
561*12c85518Srobert : diag::err_delimited_escape_empty)
562*12c85518Srobert << StringRef(&UcnBegin[1], 1);
563*12c85518Srobert }
564*12c85518Srobert ThisTokBuf = ClosingBrace == ThisTokEnd ? ClosingBrace : ClosingBrace + 1;
565*12c85518Srobert return false;
566*12c85518Srobert }
567*12c85518Srobert StringRef Name(ThisTokBuf, ClosingBrace - ThisTokBuf);
568*12c85518Srobert ThisTokBuf = ClosingBrace + 1;
569*12c85518Srobert std::optional<char32_t> Res = llvm::sys::unicode::nameToCodepointStrict(Name);
570*12c85518Srobert if (!Res) {
571*12c85518Srobert if (Diags)
572*12c85518Srobert DiagnoseInvalidUnicodeCharacterName(Diags, Features, Loc, ThisTokBegin,
573*12c85518Srobert &UcnBegin[3], ClosingBrace, Name);
574*12c85518Srobert return false;
575*12c85518Srobert }
576*12c85518Srobert UcnVal = *Res;
577*12c85518Srobert UcnLen = UcnVal > 0xFFFF ? 8 : 4;
578*12c85518Srobert return true;
579*12c85518Srobert }
580*12c85518Srobert
581*12c85518Srobert /// ProcessUCNEscape - Read the Universal Character Name, check constraints and
582*12c85518Srobert /// return the UTF32.
ProcessUCNEscape(const char * ThisTokBegin,const char * & ThisTokBuf,const char * ThisTokEnd,uint32_t & UcnVal,unsigned short & UcnLen,FullSourceLoc Loc,DiagnosticsEngine * Diags,const LangOptions & Features,bool in_char_string_literal=false)583*12c85518Srobert static bool ProcessUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
584*12c85518Srobert const char *ThisTokEnd, uint32_t &UcnVal,
585*12c85518Srobert unsigned short &UcnLen, FullSourceLoc Loc,
586*12c85518Srobert DiagnosticsEngine *Diags,
587*12c85518Srobert const LangOptions &Features,
588*12c85518Srobert bool in_char_string_literal = false) {
589*12c85518Srobert
590*12c85518Srobert bool HasError;
591*12c85518Srobert const char *UcnBegin = ThisTokBuf;
592*12c85518Srobert bool IsDelimitedEscapeSequence = false;
593*12c85518Srobert bool IsNamedEscapeSequence = false;
594*12c85518Srobert if (ThisTokBuf[1] == 'N') {
595*12c85518Srobert IsNamedEscapeSequence = true;
596*12c85518Srobert HasError = !ProcessNamedUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd,
597*12c85518Srobert UcnVal, UcnLen, Loc, Diags, Features);
598*12c85518Srobert } else {
599*12c85518Srobert HasError =
600*12c85518Srobert !ProcessNumericUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal,
601*12c85518Srobert UcnLen, IsDelimitedEscapeSequence, Loc, Diags,
602*12c85518Srobert Features, in_char_string_literal);
603*12c85518Srobert }
604*12c85518Srobert if (HasError)
605*12c85518Srobert return false;
606*12c85518Srobert
607e5dd7070Spatrick // Check UCN constraints (C99 6.4.3p2) [C++11 lex.charset p2]
608e5dd7070Spatrick if ((0xD800 <= UcnVal && UcnVal <= 0xDFFF) || // surrogate codepoints
609e5dd7070Spatrick UcnVal > 0x10FFFF) { // maximum legal UTF32 value
610e5dd7070Spatrick if (Diags)
611e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
612e5dd7070Spatrick diag::err_ucn_escape_invalid);
613e5dd7070Spatrick return false;
614e5dd7070Spatrick }
615e5dd7070Spatrick
616e5dd7070Spatrick // C++11 allows UCNs that refer to control characters and basic source
617e5dd7070Spatrick // characters inside character and string literals
618e5dd7070Spatrick if (UcnVal < 0xa0 &&
619e5dd7070Spatrick (UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60)) { // $, @, `
620e5dd7070Spatrick bool IsError = (!Features.CPlusPlus11 || !in_char_string_literal);
621e5dd7070Spatrick if (Diags) {
622e5dd7070Spatrick char BasicSCSChar = UcnVal;
623e5dd7070Spatrick if (UcnVal >= 0x20 && UcnVal < 0x7f)
624e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
625e5dd7070Spatrick IsError ? diag::err_ucn_escape_basic_scs :
626e5dd7070Spatrick diag::warn_cxx98_compat_literal_ucn_escape_basic_scs)
627e5dd7070Spatrick << StringRef(&BasicSCSChar, 1);
628e5dd7070Spatrick else
629e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
630e5dd7070Spatrick IsError ? diag::err_ucn_control_character :
631e5dd7070Spatrick diag::warn_cxx98_compat_literal_ucn_control_character);
632e5dd7070Spatrick }
633e5dd7070Spatrick if (IsError)
634e5dd7070Spatrick return false;
635e5dd7070Spatrick }
636e5dd7070Spatrick
637e5dd7070Spatrick if (!Features.CPlusPlus && !Features.C99 && Diags)
638e5dd7070Spatrick Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
639e5dd7070Spatrick diag::warn_ucn_not_valid_in_c89_literal);
640e5dd7070Spatrick
641*12c85518Srobert if ((IsDelimitedEscapeSequence || IsNamedEscapeSequence) && Diags)
642*12c85518Srobert Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
643*12c85518Srobert Features.CPlusPlus2b ? diag::warn_cxx2b_delimited_escape_sequence
644*12c85518Srobert : diag::ext_delimited_escape_sequence)
645*12c85518Srobert << (IsNamedEscapeSequence ? 1 : 0) << (Features.CPlusPlus ? 1 : 0);
646*12c85518Srobert
647e5dd7070Spatrick return true;
648e5dd7070Spatrick }
649e5dd7070Spatrick
650e5dd7070Spatrick /// MeasureUCNEscape - Determine the number of bytes within the resulting string
651e5dd7070Spatrick /// which this UCN will occupy.
MeasureUCNEscape(const char * ThisTokBegin,const char * & ThisTokBuf,const char * ThisTokEnd,unsigned CharByteWidth,const LangOptions & Features,bool & HadError)652e5dd7070Spatrick static int MeasureUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
653e5dd7070Spatrick const char *ThisTokEnd, unsigned CharByteWidth,
654e5dd7070Spatrick const LangOptions &Features, bool &HadError) {
655e5dd7070Spatrick // UTF-32: 4 bytes per escape.
656e5dd7070Spatrick if (CharByteWidth == 4)
657e5dd7070Spatrick return 4;
658e5dd7070Spatrick
659e5dd7070Spatrick uint32_t UcnVal = 0;
660e5dd7070Spatrick unsigned short UcnLen = 0;
661e5dd7070Spatrick FullSourceLoc Loc;
662e5dd7070Spatrick
663e5dd7070Spatrick if (!ProcessUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal,
664e5dd7070Spatrick UcnLen, Loc, nullptr, Features, true)) {
665e5dd7070Spatrick HadError = true;
666e5dd7070Spatrick return 0;
667e5dd7070Spatrick }
668e5dd7070Spatrick
669e5dd7070Spatrick // UTF-16: 2 bytes for BMP, 4 bytes otherwise.
670e5dd7070Spatrick if (CharByteWidth == 2)
671e5dd7070Spatrick return UcnVal <= 0xFFFF ? 2 : 4;
672e5dd7070Spatrick
673e5dd7070Spatrick // UTF-8.
674e5dd7070Spatrick if (UcnVal < 0x80)
675e5dd7070Spatrick return 1;
676e5dd7070Spatrick if (UcnVal < 0x800)
677e5dd7070Spatrick return 2;
678e5dd7070Spatrick if (UcnVal < 0x10000)
679e5dd7070Spatrick return 3;
680e5dd7070Spatrick return 4;
681e5dd7070Spatrick }
682e5dd7070Spatrick
683e5dd7070Spatrick /// EncodeUCNEscape - Read the Universal Character Name, check constraints and
684e5dd7070Spatrick /// convert the UTF32 to UTF8 or UTF16. This is a subroutine of
685e5dd7070Spatrick /// StringLiteralParser. When we decide to implement UCN's for identifiers,
686e5dd7070Spatrick /// we will likely rework our support for UCN's.
EncodeUCNEscape(const char * ThisTokBegin,const char * & ThisTokBuf,const char * ThisTokEnd,char * & ResultBuf,bool & HadError,FullSourceLoc Loc,unsigned CharByteWidth,DiagnosticsEngine * Diags,const LangOptions & Features)687e5dd7070Spatrick static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
688e5dd7070Spatrick const char *ThisTokEnd,
689e5dd7070Spatrick char *&ResultBuf, bool &HadError,
690e5dd7070Spatrick FullSourceLoc Loc, unsigned CharByteWidth,
691e5dd7070Spatrick DiagnosticsEngine *Diags,
692e5dd7070Spatrick const LangOptions &Features) {
693e5dd7070Spatrick typedef uint32_t UTF32;
694e5dd7070Spatrick UTF32 UcnVal = 0;
695e5dd7070Spatrick unsigned short UcnLen = 0;
696e5dd7070Spatrick if (!ProcessUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal, UcnLen,
697e5dd7070Spatrick Loc, Diags, Features, true)) {
698e5dd7070Spatrick HadError = true;
699e5dd7070Spatrick return;
700e5dd7070Spatrick }
701e5dd7070Spatrick
702e5dd7070Spatrick assert((CharByteWidth == 1 || CharByteWidth == 2 || CharByteWidth == 4) &&
703e5dd7070Spatrick "only character widths of 1, 2, or 4 bytes supported");
704e5dd7070Spatrick
705e5dd7070Spatrick (void)UcnLen;
706e5dd7070Spatrick assert((UcnLen== 4 || UcnLen== 8) && "only ucn length of 4 or 8 supported");
707e5dd7070Spatrick
708e5dd7070Spatrick if (CharByteWidth == 4) {
709e5dd7070Spatrick // FIXME: Make the type of the result buffer correct instead of
710e5dd7070Spatrick // using reinterpret_cast.
711e5dd7070Spatrick llvm::UTF32 *ResultPtr = reinterpret_cast<llvm::UTF32*>(ResultBuf);
712e5dd7070Spatrick *ResultPtr = UcnVal;
713e5dd7070Spatrick ResultBuf += 4;
714e5dd7070Spatrick return;
715e5dd7070Spatrick }
716e5dd7070Spatrick
717e5dd7070Spatrick if (CharByteWidth == 2) {
718e5dd7070Spatrick // FIXME: Make the type of the result buffer correct instead of
719e5dd7070Spatrick // using reinterpret_cast.
720e5dd7070Spatrick llvm::UTF16 *ResultPtr = reinterpret_cast<llvm::UTF16*>(ResultBuf);
721e5dd7070Spatrick
722e5dd7070Spatrick if (UcnVal <= (UTF32)0xFFFF) {
723e5dd7070Spatrick *ResultPtr = UcnVal;
724e5dd7070Spatrick ResultBuf += 2;
725e5dd7070Spatrick return;
726e5dd7070Spatrick }
727e5dd7070Spatrick
728e5dd7070Spatrick // Convert to UTF16.
729e5dd7070Spatrick UcnVal -= 0x10000;
730e5dd7070Spatrick *ResultPtr = 0xD800 + (UcnVal >> 10);
731e5dd7070Spatrick *(ResultPtr+1) = 0xDC00 + (UcnVal & 0x3FF);
732e5dd7070Spatrick ResultBuf += 4;
733e5dd7070Spatrick return;
734e5dd7070Spatrick }
735e5dd7070Spatrick
736e5dd7070Spatrick assert(CharByteWidth == 1 && "UTF-8 encoding is only for 1 byte characters");
737e5dd7070Spatrick
738e5dd7070Spatrick // Now that we've parsed/checked the UCN, we convert from UTF32->UTF8.
739e5dd7070Spatrick // The conversion below was inspired by:
740e5dd7070Spatrick // http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
741e5dd7070Spatrick // First, we determine how many bytes the result will require.
742e5dd7070Spatrick typedef uint8_t UTF8;
743e5dd7070Spatrick
744e5dd7070Spatrick unsigned short bytesToWrite = 0;
745e5dd7070Spatrick if (UcnVal < (UTF32)0x80)
746e5dd7070Spatrick bytesToWrite = 1;
747e5dd7070Spatrick else if (UcnVal < (UTF32)0x800)
748e5dd7070Spatrick bytesToWrite = 2;
749e5dd7070Spatrick else if (UcnVal < (UTF32)0x10000)
750e5dd7070Spatrick bytesToWrite = 3;
751e5dd7070Spatrick else
752e5dd7070Spatrick bytesToWrite = 4;
753e5dd7070Spatrick
754e5dd7070Spatrick const unsigned byteMask = 0xBF;
755e5dd7070Spatrick const unsigned byteMark = 0x80;
756e5dd7070Spatrick
757e5dd7070Spatrick // Once the bits are split out into bytes of UTF8, this is a mask OR-ed
758e5dd7070Spatrick // into the first byte, depending on how many bytes follow.
759e5dd7070Spatrick static const UTF8 firstByteMark[5] = {
760e5dd7070Spatrick 0x00, 0x00, 0xC0, 0xE0, 0xF0
761e5dd7070Spatrick };
762e5dd7070Spatrick // Finally, we write the bytes into ResultBuf.
763e5dd7070Spatrick ResultBuf += bytesToWrite;
764e5dd7070Spatrick switch (bytesToWrite) { // note: everything falls through.
765e5dd7070Spatrick case 4:
766e5dd7070Spatrick *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
767*12c85518Srobert [[fallthrough]];
768e5dd7070Spatrick case 3:
769e5dd7070Spatrick *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
770*12c85518Srobert [[fallthrough]];
771e5dd7070Spatrick case 2:
772e5dd7070Spatrick *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
773*12c85518Srobert [[fallthrough]];
774e5dd7070Spatrick case 1:
775e5dd7070Spatrick *--ResultBuf = (UTF8) (UcnVal | firstByteMark[bytesToWrite]);
776e5dd7070Spatrick }
777e5dd7070Spatrick // Update the buffer.
778e5dd7070Spatrick ResultBuf += bytesToWrite;
779e5dd7070Spatrick }
780e5dd7070Spatrick
781e5dd7070Spatrick /// integer-constant: [C99 6.4.4.1]
782e5dd7070Spatrick /// decimal-constant integer-suffix
783e5dd7070Spatrick /// octal-constant integer-suffix
784e5dd7070Spatrick /// hexadecimal-constant integer-suffix
785e5dd7070Spatrick /// binary-literal integer-suffix [GNU, C++1y]
786e5dd7070Spatrick /// user-defined-integer-literal: [C++11 lex.ext]
787e5dd7070Spatrick /// decimal-literal ud-suffix
788e5dd7070Spatrick /// octal-literal ud-suffix
789e5dd7070Spatrick /// hexadecimal-literal ud-suffix
790e5dd7070Spatrick /// binary-literal ud-suffix [GNU, C++1y]
791e5dd7070Spatrick /// decimal-constant:
792e5dd7070Spatrick /// nonzero-digit
793e5dd7070Spatrick /// decimal-constant digit
794e5dd7070Spatrick /// octal-constant:
795e5dd7070Spatrick /// 0
796e5dd7070Spatrick /// octal-constant octal-digit
797e5dd7070Spatrick /// hexadecimal-constant:
798e5dd7070Spatrick /// hexadecimal-prefix hexadecimal-digit
799e5dd7070Spatrick /// hexadecimal-constant hexadecimal-digit
800e5dd7070Spatrick /// hexadecimal-prefix: one of
801e5dd7070Spatrick /// 0x 0X
802e5dd7070Spatrick /// binary-literal:
803e5dd7070Spatrick /// 0b binary-digit
804e5dd7070Spatrick /// 0B binary-digit
805e5dd7070Spatrick /// binary-literal binary-digit
806e5dd7070Spatrick /// integer-suffix:
807e5dd7070Spatrick /// unsigned-suffix [long-suffix]
808e5dd7070Spatrick /// unsigned-suffix [long-long-suffix]
809e5dd7070Spatrick /// long-suffix [unsigned-suffix]
810e5dd7070Spatrick /// long-long-suffix [unsigned-sufix]
811e5dd7070Spatrick /// nonzero-digit:
812e5dd7070Spatrick /// 1 2 3 4 5 6 7 8 9
813e5dd7070Spatrick /// octal-digit:
814e5dd7070Spatrick /// 0 1 2 3 4 5 6 7
815e5dd7070Spatrick /// hexadecimal-digit:
816e5dd7070Spatrick /// 0 1 2 3 4 5 6 7 8 9
817e5dd7070Spatrick /// a b c d e f
818e5dd7070Spatrick /// A B C D E F
819e5dd7070Spatrick /// binary-digit:
820e5dd7070Spatrick /// 0
821e5dd7070Spatrick /// 1
822e5dd7070Spatrick /// unsigned-suffix: one of
823e5dd7070Spatrick /// u U
824e5dd7070Spatrick /// long-suffix: one of
825e5dd7070Spatrick /// l L
826e5dd7070Spatrick /// long-long-suffix: one of
827e5dd7070Spatrick /// ll LL
828e5dd7070Spatrick ///
829e5dd7070Spatrick /// floating-constant: [C99 6.4.4.2]
830e5dd7070Spatrick /// TODO: add rules...
831e5dd7070Spatrick ///
NumericLiteralParser(StringRef TokSpelling,SourceLocation TokLoc,const SourceManager & SM,const LangOptions & LangOpts,const TargetInfo & Target,DiagnosticsEngine & Diags)832e5dd7070Spatrick NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
833e5dd7070Spatrick SourceLocation TokLoc,
834ec727ea7Spatrick const SourceManager &SM,
835ec727ea7Spatrick const LangOptions &LangOpts,
836ec727ea7Spatrick const TargetInfo &Target,
837ec727ea7Spatrick DiagnosticsEngine &Diags)
838ec727ea7Spatrick : SM(SM), LangOpts(LangOpts), Diags(Diags),
839ec727ea7Spatrick ThisTokBegin(TokSpelling.begin()), ThisTokEnd(TokSpelling.end()) {
840e5dd7070Spatrick
841e5dd7070Spatrick s = DigitsBegin = ThisTokBegin;
842e5dd7070Spatrick saw_exponent = false;
843e5dd7070Spatrick saw_period = false;
844e5dd7070Spatrick saw_ud_suffix = false;
845e5dd7070Spatrick saw_fixed_point_suffix = false;
846e5dd7070Spatrick isLong = false;
847e5dd7070Spatrick isUnsigned = false;
848e5dd7070Spatrick isLongLong = false;
849a9ac8606Spatrick isSizeT = false;
850e5dd7070Spatrick isHalf = false;
851e5dd7070Spatrick isFloat = false;
852e5dd7070Spatrick isImaginary = false;
853e5dd7070Spatrick isFloat16 = false;
854e5dd7070Spatrick isFloat128 = false;
855e5dd7070Spatrick MicrosoftInteger = 0;
856e5dd7070Spatrick isFract = false;
857e5dd7070Spatrick isAccum = false;
858e5dd7070Spatrick hadError = false;
859*12c85518Srobert isBitInt = false;
860*12c85518Srobert
861*12c85518Srobert // This routine assumes that the range begin/end matches the regex for integer
862*12c85518Srobert // and FP constants (specifically, the 'pp-number' regex), and assumes that
863*12c85518Srobert // the byte at "*end" is both valid and not part of the regex. Because of
864*12c85518Srobert // this, it doesn't have to check for 'overscan' in various places.
865*12c85518Srobert if (isPreprocessingNumberBody(*ThisTokEnd)) {
866*12c85518Srobert Diags.Report(TokLoc, diag::err_lexing_numeric);
867*12c85518Srobert hadError = true;
868*12c85518Srobert return;
869*12c85518Srobert }
870e5dd7070Spatrick
871e5dd7070Spatrick if (*s == '0') { // parse radix
872e5dd7070Spatrick ParseNumberStartingWithZero(TokLoc);
873e5dd7070Spatrick if (hadError)
874e5dd7070Spatrick return;
875e5dd7070Spatrick } else { // the first digit is non-zero
876e5dd7070Spatrick radix = 10;
877e5dd7070Spatrick s = SkipDigits(s);
878e5dd7070Spatrick if (s == ThisTokEnd) {
879e5dd7070Spatrick // Done.
880e5dd7070Spatrick } else {
881e5dd7070Spatrick ParseDecimalOrOctalCommon(TokLoc);
882e5dd7070Spatrick if (hadError)
883e5dd7070Spatrick return;
884e5dd7070Spatrick }
885e5dd7070Spatrick }
886e5dd7070Spatrick
887e5dd7070Spatrick SuffixBegin = s;
888e5dd7070Spatrick checkSeparator(TokLoc, s, CSK_AfterDigits);
889e5dd7070Spatrick
890e5dd7070Spatrick // Initial scan to lookahead for fixed point suffix.
891ec727ea7Spatrick if (LangOpts.FixedPoint) {
892e5dd7070Spatrick for (const char *c = s; c != ThisTokEnd; ++c) {
893e5dd7070Spatrick if (*c == 'r' || *c == 'k' || *c == 'R' || *c == 'K') {
894e5dd7070Spatrick saw_fixed_point_suffix = true;
895e5dd7070Spatrick break;
896e5dd7070Spatrick }
897e5dd7070Spatrick }
898e5dd7070Spatrick }
899e5dd7070Spatrick
900e5dd7070Spatrick // Parse the suffix. At this point we can classify whether we have an FP or
901e5dd7070Spatrick // integer constant.
902ec727ea7Spatrick bool isFixedPointConstant = isFixedPointLiteral();
903e5dd7070Spatrick bool isFPConstant = isFloatingLiteral();
904a9ac8606Spatrick bool HasSize = false;
905e5dd7070Spatrick
906e5dd7070Spatrick // Loop over all of the characters of the suffix. If we see something bad,
907e5dd7070Spatrick // we break out of the loop.
908e5dd7070Spatrick for (; s != ThisTokEnd; ++s) {
909e5dd7070Spatrick switch (*s) {
910e5dd7070Spatrick case 'R':
911e5dd7070Spatrick case 'r':
912ec727ea7Spatrick if (!LangOpts.FixedPoint)
913ec727ea7Spatrick break;
914e5dd7070Spatrick if (isFract || isAccum) break;
915e5dd7070Spatrick if (!(saw_period || saw_exponent)) break;
916e5dd7070Spatrick isFract = true;
917e5dd7070Spatrick continue;
918e5dd7070Spatrick case 'K':
919e5dd7070Spatrick case 'k':
920ec727ea7Spatrick if (!LangOpts.FixedPoint)
921ec727ea7Spatrick break;
922e5dd7070Spatrick if (isFract || isAccum) break;
923e5dd7070Spatrick if (!(saw_period || saw_exponent)) break;
924e5dd7070Spatrick isAccum = true;
925e5dd7070Spatrick continue;
926e5dd7070Spatrick case 'h': // FP Suffix for "half".
927e5dd7070Spatrick case 'H':
928e5dd7070Spatrick // OpenCL Extension v1.2 s9.5 - h or H suffix for half type.
929ec727ea7Spatrick if (!(LangOpts.Half || LangOpts.FixedPoint))
930ec727ea7Spatrick break;
931e5dd7070Spatrick if (isIntegerLiteral()) break; // Error for integer constant.
932a9ac8606Spatrick if (HasSize)
933a9ac8606Spatrick break;
934a9ac8606Spatrick HasSize = true;
935e5dd7070Spatrick isHalf = true;
936e5dd7070Spatrick continue; // Success.
937e5dd7070Spatrick case 'f': // FP Suffix for "float"
938e5dd7070Spatrick case 'F':
939e5dd7070Spatrick if (!isFPConstant) break; // Error for integer constant.
940a9ac8606Spatrick if (HasSize)
941a9ac8606Spatrick break;
942a9ac8606Spatrick HasSize = true;
943e5dd7070Spatrick
944e5dd7070Spatrick // CUDA host and device may have different _Float16 support, therefore
945e5dd7070Spatrick // allows f16 literals to avoid false alarm.
946*12c85518Srobert // When we compile for OpenMP target offloading on NVPTX, f16 suffix
947*12c85518Srobert // should also be supported.
948e5dd7070Spatrick // ToDo: more precise check for CUDA.
949*12c85518Srobert // TODO: AMDGPU might also support it in the future.
950*12c85518Srobert if ((Target.hasFloat16Type() || LangOpts.CUDA ||
951*12c85518Srobert (LangOpts.OpenMPIsDevice && Target.getTriple().isNVPTX())) &&
952*12c85518Srobert s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') {
953e5dd7070Spatrick s += 2; // success, eat up 2 characters.
954e5dd7070Spatrick isFloat16 = true;
955e5dd7070Spatrick continue;
956e5dd7070Spatrick }
957e5dd7070Spatrick
958e5dd7070Spatrick isFloat = true;
959e5dd7070Spatrick continue; // Success.
960e5dd7070Spatrick case 'q': // FP Suffix for "__float128"
961e5dd7070Spatrick case 'Q':
962e5dd7070Spatrick if (!isFPConstant) break; // Error for integer constant.
963a9ac8606Spatrick if (HasSize)
964a9ac8606Spatrick break;
965a9ac8606Spatrick HasSize = true;
966e5dd7070Spatrick isFloat128 = true;
967e5dd7070Spatrick continue; // Success.
968e5dd7070Spatrick case 'u':
969e5dd7070Spatrick case 'U':
970e5dd7070Spatrick if (isFPConstant) break; // Error for floating constant.
971e5dd7070Spatrick if (isUnsigned) break; // Cannot be repeated.
972e5dd7070Spatrick isUnsigned = true;
973e5dd7070Spatrick continue; // Success.
974e5dd7070Spatrick case 'l':
975e5dd7070Spatrick case 'L':
976a9ac8606Spatrick if (HasSize)
977a9ac8606Spatrick break;
978a9ac8606Spatrick HasSize = true;
979e5dd7070Spatrick
980e5dd7070Spatrick // Check for long long. The L's need to be adjacent and the same case.
981e5dd7070Spatrick if (s[1] == s[0]) {
982e5dd7070Spatrick assert(s + 1 < ThisTokEnd && "didn't maximally munch?");
983e5dd7070Spatrick if (isFPConstant) break; // long long invalid for floats.
984e5dd7070Spatrick isLongLong = true;
985e5dd7070Spatrick ++s; // Eat both of them.
986e5dd7070Spatrick } else {
987e5dd7070Spatrick isLong = true;
988e5dd7070Spatrick }
989e5dd7070Spatrick continue; // Success.
990a9ac8606Spatrick case 'z':
991a9ac8606Spatrick case 'Z':
992a9ac8606Spatrick if (isFPConstant)
993a9ac8606Spatrick break; // Invalid for floats.
994a9ac8606Spatrick if (HasSize)
995a9ac8606Spatrick break;
996a9ac8606Spatrick HasSize = true;
997a9ac8606Spatrick isSizeT = true;
998a9ac8606Spatrick continue;
999e5dd7070Spatrick case 'i':
1000e5dd7070Spatrick case 'I':
1001a9ac8606Spatrick if (LangOpts.MicrosoftExt && !isFPConstant) {
1002a9ac8606Spatrick // Allow i8, i16, i32, and i64. First, look ahead and check if
1003a9ac8606Spatrick // suffixes are Microsoft integers and not the imaginary unit.
1004a9ac8606Spatrick uint8_t Bits = 0;
1005a9ac8606Spatrick size_t ToSkip = 0;
1006e5dd7070Spatrick switch (s[1]) {
1007a9ac8606Spatrick case '8': // i8 suffix
1008a9ac8606Spatrick Bits = 8;
1009a9ac8606Spatrick ToSkip = 2;
1010e5dd7070Spatrick break;
1011e5dd7070Spatrick case '1':
1012a9ac8606Spatrick if (s[2] == '6') { // i16 suffix
1013a9ac8606Spatrick Bits = 16;
1014a9ac8606Spatrick ToSkip = 3;
1015e5dd7070Spatrick }
1016e5dd7070Spatrick break;
1017e5dd7070Spatrick case '3':
1018a9ac8606Spatrick if (s[2] == '2') { // i32 suffix
1019a9ac8606Spatrick Bits = 32;
1020a9ac8606Spatrick ToSkip = 3;
1021e5dd7070Spatrick }
1022e5dd7070Spatrick break;
1023e5dd7070Spatrick case '6':
1024a9ac8606Spatrick if (s[2] == '4') { // i64 suffix
1025a9ac8606Spatrick Bits = 64;
1026a9ac8606Spatrick ToSkip = 3;
1027e5dd7070Spatrick }
1028e5dd7070Spatrick break;
1029e5dd7070Spatrick default:
1030e5dd7070Spatrick break;
1031e5dd7070Spatrick }
1032a9ac8606Spatrick if (Bits) {
1033a9ac8606Spatrick if (HasSize)
1034a9ac8606Spatrick break;
1035a9ac8606Spatrick HasSize = true;
1036a9ac8606Spatrick MicrosoftInteger = Bits;
1037a9ac8606Spatrick s += ToSkip;
1038e5dd7070Spatrick assert(s <= ThisTokEnd && "didn't maximally munch?");
1039e5dd7070Spatrick break;
1040e5dd7070Spatrick }
1041e5dd7070Spatrick }
1042*12c85518Srobert [[fallthrough]];
1043e5dd7070Spatrick case 'j':
1044e5dd7070Spatrick case 'J':
1045e5dd7070Spatrick if (isImaginary) break; // Cannot be repeated.
1046e5dd7070Spatrick isImaginary = true;
1047e5dd7070Spatrick continue; // Success.
1048*12c85518Srobert case 'w':
1049*12c85518Srobert case 'W':
1050*12c85518Srobert if (isFPConstant)
1051*12c85518Srobert break; // Invalid for floats.
1052*12c85518Srobert if (HasSize)
1053*12c85518Srobert break; // Invalid if we already have a size for the literal.
1054*12c85518Srobert
1055*12c85518Srobert // wb and WB are allowed, but a mixture of cases like Wb or wB is not. We
1056*12c85518Srobert // explicitly do not support the suffix in C++ as an extension because a
1057*12c85518Srobert // library-based UDL that resolves to a library type may be more
1058*12c85518Srobert // appropriate there.
1059*12c85518Srobert if (!LangOpts.CPlusPlus && ((s[0] == 'w' && s[1] == 'b') ||
1060*12c85518Srobert (s[0] == 'W' && s[1] == 'B'))) {
1061*12c85518Srobert isBitInt = true;
1062*12c85518Srobert HasSize = true;
1063*12c85518Srobert ++s; // Skip both characters (2nd char skipped on continue).
1064*12c85518Srobert continue; // Success.
1065*12c85518Srobert }
1066e5dd7070Spatrick }
1067e5dd7070Spatrick // If we reached here, there was an error or a ud-suffix.
1068e5dd7070Spatrick break;
1069e5dd7070Spatrick }
1070e5dd7070Spatrick
1071e5dd7070Spatrick // "i", "if", and "il" are user-defined suffixes in C++1y.
1072e5dd7070Spatrick if (s != ThisTokEnd || isImaginary) {
1073e5dd7070Spatrick // FIXME: Don't bother expanding UCNs if !tok.hasUCN().
1074e5dd7070Spatrick expandUCNs(UDSuffixBuf, StringRef(SuffixBegin, ThisTokEnd - SuffixBegin));
1075ec727ea7Spatrick if (isValidUDSuffix(LangOpts, UDSuffixBuf)) {
1076e5dd7070Spatrick if (!isImaginary) {
1077e5dd7070Spatrick // Any suffix pieces we might have parsed are actually part of the
1078e5dd7070Spatrick // ud-suffix.
1079e5dd7070Spatrick isLong = false;
1080e5dd7070Spatrick isUnsigned = false;
1081e5dd7070Spatrick isLongLong = false;
1082a9ac8606Spatrick isSizeT = false;
1083e5dd7070Spatrick isFloat = false;
1084e5dd7070Spatrick isFloat16 = false;
1085e5dd7070Spatrick isHalf = false;
1086e5dd7070Spatrick isImaginary = false;
1087*12c85518Srobert isBitInt = false;
1088e5dd7070Spatrick MicrosoftInteger = 0;
1089e5dd7070Spatrick saw_fixed_point_suffix = false;
1090e5dd7070Spatrick isFract = false;
1091e5dd7070Spatrick isAccum = false;
1092e5dd7070Spatrick }
1093e5dd7070Spatrick
1094e5dd7070Spatrick saw_ud_suffix = true;
1095e5dd7070Spatrick return;
1096e5dd7070Spatrick }
1097e5dd7070Spatrick
1098e5dd7070Spatrick if (s != ThisTokEnd) {
1099e5dd7070Spatrick // Report an error if there are any.
1100ec727ea7Spatrick Diags.Report(Lexer::AdvanceToTokenCharacter(
1101ec727ea7Spatrick TokLoc, SuffixBegin - ThisTokBegin, SM, LangOpts),
1102e5dd7070Spatrick diag::err_invalid_suffix_constant)
1103ec727ea7Spatrick << StringRef(SuffixBegin, ThisTokEnd - SuffixBegin)
1104ec727ea7Spatrick << (isFixedPointConstant ? 2 : isFPConstant);
1105e5dd7070Spatrick hadError = true;
1106e5dd7070Spatrick }
1107e5dd7070Spatrick }
1108e5dd7070Spatrick
1109e5dd7070Spatrick if (!hadError && saw_fixed_point_suffix) {
1110e5dd7070Spatrick assert(isFract || isAccum);
1111e5dd7070Spatrick }
1112e5dd7070Spatrick }
1113e5dd7070Spatrick
1114e5dd7070Spatrick /// ParseDecimalOrOctalCommon - This method is called for decimal or octal
1115e5dd7070Spatrick /// numbers. It issues an error for illegal digits, and handles floating point
1116e5dd7070Spatrick /// parsing. If it detects a floating point number, the radix is set to 10.
ParseDecimalOrOctalCommon(SourceLocation TokLoc)1117e5dd7070Spatrick void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){
1118e5dd7070Spatrick assert((radix == 8 || radix == 10) && "Unexpected radix");
1119e5dd7070Spatrick
1120e5dd7070Spatrick // If we have a hex digit other than 'e' (which denotes a FP exponent) then
1121e5dd7070Spatrick // the code is using an incorrect base.
1122e5dd7070Spatrick if (isHexDigit(*s) && *s != 'e' && *s != 'E' &&
1123ec727ea7Spatrick !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) {
1124ec727ea7Spatrick Diags.Report(
1125ec727ea7Spatrick Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, LangOpts),
1126ec727ea7Spatrick diag::err_invalid_digit)
1127ec727ea7Spatrick << StringRef(s, 1) << (radix == 8 ? 1 : 0);
1128e5dd7070Spatrick hadError = true;
1129e5dd7070Spatrick return;
1130e5dd7070Spatrick }
1131e5dd7070Spatrick
1132e5dd7070Spatrick if (*s == '.') {
1133e5dd7070Spatrick checkSeparator(TokLoc, s, CSK_AfterDigits);
1134e5dd7070Spatrick s++;
1135e5dd7070Spatrick radix = 10;
1136e5dd7070Spatrick saw_period = true;
1137e5dd7070Spatrick checkSeparator(TokLoc, s, CSK_BeforeDigits);
1138e5dd7070Spatrick s = SkipDigits(s); // Skip suffix.
1139e5dd7070Spatrick }
1140e5dd7070Spatrick if (*s == 'e' || *s == 'E') { // exponent
1141e5dd7070Spatrick checkSeparator(TokLoc, s, CSK_AfterDigits);
1142e5dd7070Spatrick const char *Exponent = s;
1143e5dd7070Spatrick s++;
1144e5dd7070Spatrick radix = 10;
1145e5dd7070Spatrick saw_exponent = true;
1146e5dd7070Spatrick if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign
1147e5dd7070Spatrick const char *first_non_digit = SkipDigits(s);
1148e5dd7070Spatrick if (containsDigits(s, first_non_digit)) {
1149e5dd7070Spatrick checkSeparator(TokLoc, s, CSK_BeforeDigits);
1150e5dd7070Spatrick s = first_non_digit;
1151e5dd7070Spatrick } else {
1152e5dd7070Spatrick if (!hadError) {
1153ec727ea7Spatrick Diags.Report(Lexer::AdvanceToTokenCharacter(
1154ec727ea7Spatrick TokLoc, Exponent - ThisTokBegin, SM, LangOpts),
1155e5dd7070Spatrick diag::err_exponent_has_no_digits);
1156e5dd7070Spatrick hadError = true;
1157e5dd7070Spatrick }
1158e5dd7070Spatrick return;
1159e5dd7070Spatrick }
1160e5dd7070Spatrick }
1161e5dd7070Spatrick }
1162e5dd7070Spatrick
1163e5dd7070Spatrick /// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved
1164e5dd7070Spatrick /// suffixes as ud-suffixes, because the diagnostic experience is better if we
1165e5dd7070Spatrick /// treat it as an invalid suffix.
isValidUDSuffix(const LangOptions & LangOpts,StringRef Suffix)1166e5dd7070Spatrick bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts,
1167e5dd7070Spatrick StringRef Suffix) {
1168e5dd7070Spatrick if (!LangOpts.CPlusPlus11 || Suffix.empty())
1169e5dd7070Spatrick return false;
1170e5dd7070Spatrick
1171e5dd7070Spatrick // By C++11 [lex.ext]p10, ud-suffixes starting with an '_' are always valid.
1172e5dd7070Spatrick if (Suffix[0] == '_')
1173e5dd7070Spatrick return true;
1174e5dd7070Spatrick
1175e5dd7070Spatrick // In C++11, there are no library suffixes.
1176e5dd7070Spatrick if (!LangOpts.CPlusPlus14)
1177e5dd7070Spatrick return false;
1178e5dd7070Spatrick
1179e5dd7070Spatrick // In C++14, "s", "h", "min", "ms", "us", and "ns" are used in the library.
1180e5dd7070Spatrick // Per tweaked N3660, "il", "i", and "if" are also used in the library.
1181e5dd7070Spatrick // In C++2a "d" and "y" are used in the library.
1182e5dd7070Spatrick return llvm::StringSwitch<bool>(Suffix)
1183e5dd7070Spatrick .Cases("h", "min", "s", true)
1184e5dd7070Spatrick .Cases("ms", "us", "ns", true)
1185e5dd7070Spatrick .Cases("il", "i", "if", true)
1186ec727ea7Spatrick .Cases("d", "y", LangOpts.CPlusPlus20)
1187e5dd7070Spatrick .Default(false);
1188e5dd7070Spatrick }
1189e5dd7070Spatrick
checkSeparator(SourceLocation TokLoc,const char * Pos,CheckSeparatorKind IsAfterDigits)1190e5dd7070Spatrick void NumericLiteralParser::checkSeparator(SourceLocation TokLoc,
1191e5dd7070Spatrick const char *Pos,
1192e5dd7070Spatrick CheckSeparatorKind IsAfterDigits) {
1193e5dd7070Spatrick if (IsAfterDigits == CSK_AfterDigits) {
1194e5dd7070Spatrick if (Pos == ThisTokBegin)
1195e5dd7070Spatrick return;
1196e5dd7070Spatrick --Pos;
1197e5dd7070Spatrick } else if (Pos == ThisTokEnd)
1198e5dd7070Spatrick return;
1199e5dd7070Spatrick
1200e5dd7070Spatrick if (isDigitSeparator(*Pos)) {
1201ec727ea7Spatrick Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin, SM,
1202ec727ea7Spatrick LangOpts),
1203e5dd7070Spatrick diag::err_digit_separator_not_between_digits)
1204e5dd7070Spatrick << IsAfterDigits;
1205e5dd7070Spatrick hadError = true;
1206e5dd7070Spatrick }
1207e5dd7070Spatrick }
1208e5dd7070Spatrick
1209e5dd7070Spatrick /// ParseNumberStartingWithZero - This method is called when the first character
1210e5dd7070Spatrick /// of the number is found to be a zero. This means it is either an octal
1211e5dd7070Spatrick /// number (like '04') or a hex number ('0x123a') a binary number ('0b1010') or
1212e5dd7070Spatrick /// a floating point number (01239.123e4). Eat the prefix, determining the
1213e5dd7070Spatrick /// radix etc.
ParseNumberStartingWithZero(SourceLocation TokLoc)1214e5dd7070Spatrick void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
1215e5dd7070Spatrick assert(s[0] == '0' && "Invalid method call");
1216e5dd7070Spatrick s++;
1217e5dd7070Spatrick
1218e5dd7070Spatrick int c1 = s[0];
1219e5dd7070Spatrick
1220e5dd7070Spatrick // Handle a hex number like 0x1234.
1221e5dd7070Spatrick if ((c1 == 'x' || c1 == 'X') && (isHexDigit(s[1]) || s[1] == '.')) {
1222e5dd7070Spatrick s++;
1223e5dd7070Spatrick assert(s < ThisTokEnd && "didn't maximally munch?");
1224e5dd7070Spatrick radix = 16;
1225e5dd7070Spatrick DigitsBegin = s;
1226e5dd7070Spatrick s = SkipHexDigits(s);
1227e5dd7070Spatrick bool HasSignificandDigits = containsDigits(DigitsBegin, s);
1228e5dd7070Spatrick if (s == ThisTokEnd) {
1229e5dd7070Spatrick // Done.
1230e5dd7070Spatrick } else if (*s == '.') {
1231e5dd7070Spatrick s++;
1232e5dd7070Spatrick saw_period = true;
1233e5dd7070Spatrick const char *floatDigitsBegin = s;
1234e5dd7070Spatrick s = SkipHexDigits(s);
1235e5dd7070Spatrick if (containsDigits(floatDigitsBegin, s))
1236e5dd7070Spatrick HasSignificandDigits = true;
1237e5dd7070Spatrick if (HasSignificandDigits)
1238e5dd7070Spatrick checkSeparator(TokLoc, floatDigitsBegin, CSK_BeforeDigits);
1239e5dd7070Spatrick }
1240e5dd7070Spatrick
1241e5dd7070Spatrick if (!HasSignificandDigits) {
1242ec727ea7Spatrick Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM,
1243ec727ea7Spatrick LangOpts),
1244e5dd7070Spatrick diag::err_hex_constant_requires)
1245ec727ea7Spatrick << LangOpts.CPlusPlus << 1;
1246e5dd7070Spatrick hadError = true;
1247e5dd7070Spatrick return;
1248e5dd7070Spatrick }
1249e5dd7070Spatrick
1250e5dd7070Spatrick // A binary exponent can appear with or with a '.'. If dotted, the
1251e5dd7070Spatrick // binary exponent is required.
1252e5dd7070Spatrick if (*s == 'p' || *s == 'P') {
1253e5dd7070Spatrick checkSeparator(TokLoc, s, CSK_AfterDigits);
1254e5dd7070Spatrick const char *Exponent = s;
1255e5dd7070Spatrick s++;
1256e5dd7070Spatrick saw_exponent = true;
1257e5dd7070Spatrick if (s != ThisTokEnd && (*s == '+' || *s == '-')) s++; // sign
1258e5dd7070Spatrick const char *first_non_digit = SkipDigits(s);
1259e5dd7070Spatrick if (!containsDigits(s, first_non_digit)) {
1260e5dd7070Spatrick if (!hadError) {
1261ec727ea7Spatrick Diags.Report(Lexer::AdvanceToTokenCharacter(
1262ec727ea7Spatrick TokLoc, Exponent - ThisTokBegin, SM, LangOpts),
1263e5dd7070Spatrick diag::err_exponent_has_no_digits);
1264e5dd7070Spatrick hadError = true;
1265e5dd7070Spatrick }
1266e5dd7070Spatrick return;
1267e5dd7070Spatrick }
1268e5dd7070Spatrick checkSeparator(TokLoc, s, CSK_BeforeDigits);
1269e5dd7070Spatrick s = first_non_digit;
1270e5dd7070Spatrick
1271ec727ea7Spatrick if (!LangOpts.HexFloats)
1272ec727ea7Spatrick Diags.Report(TokLoc, LangOpts.CPlusPlus
1273e5dd7070Spatrick ? diag::ext_hex_literal_invalid
1274e5dd7070Spatrick : diag::ext_hex_constant_invalid);
1275ec727ea7Spatrick else if (LangOpts.CPlusPlus17)
1276ec727ea7Spatrick Diags.Report(TokLoc, diag::warn_cxx17_hex_literal);
1277e5dd7070Spatrick } else if (saw_period) {
1278ec727ea7Spatrick Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM,
1279ec727ea7Spatrick LangOpts),
1280e5dd7070Spatrick diag::err_hex_constant_requires)
1281ec727ea7Spatrick << LangOpts.CPlusPlus << 0;
1282e5dd7070Spatrick hadError = true;
1283e5dd7070Spatrick }
1284e5dd7070Spatrick return;
1285e5dd7070Spatrick }
1286e5dd7070Spatrick
1287e5dd7070Spatrick // Handle simple binary numbers 0b01010
1288e5dd7070Spatrick if ((c1 == 'b' || c1 == 'B') && (s[1] == '0' || s[1] == '1')) {
1289e5dd7070Spatrick // 0b101010 is a C++1y / GCC extension.
1290ec727ea7Spatrick Diags.Report(TokLoc, LangOpts.CPlusPlus14
1291e5dd7070Spatrick ? diag::warn_cxx11_compat_binary_literal
1292ec727ea7Spatrick : LangOpts.CPlusPlus ? diag::ext_binary_literal_cxx14
1293e5dd7070Spatrick : diag::ext_binary_literal);
1294e5dd7070Spatrick ++s;
1295e5dd7070Spatrick assert(s < ThisTokEnd && "didn't maximally munch?");
1296e5dd7070Spatrick radix = 2;
1297e5dd7070Spatrick DigitsBegin = s;
1298e5dd7070Spatrick s = SkipBinaryDigits(s);
1299e5dd7070Spatrick if (s == ThisTokEnd) {
1300e5dd7070Spatrick // Done.
1301e5dd7070Spatrick } else if (isHexDigit(*s) &&
1302ec727ea7Spatrick !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) {
1303ec727ea7Spatrick Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM,
1304ec727ea7Spatrick LangOpts),
1305ec727ea7Spatrick diag::err_invalid_digit)
1306ec727ea7Spatrick << StringRef(s, 1) << 2;
1307e5dd7070Spatrick hadError = true;
1308e5dd7070Spatrick }
1309e5dd7070Spatrick // Other suffixes will be diagnosed by the caller.
1310e5dd7070Spatrick return;
1311e5dd7070Spatrick }
1312e5dd7070Spatrick
1313e5dd7070Spatrick // For now, the radix is set to 8. If we discover that we have a
1314e5dd7070Spatrick // floating point constant, the radix will change to 10. Octal floating
1315e5dd7070Spatrick // point constants are not permitted (only decimal and hexadecimal).
1316e5dd7070Spatrick radix = 8;
1317*12c85518Srobert const char *PossibleNewDigitStart = s;
1318e5dd7070Spatrick s = SkipOctalDigits(s);
1319*12c85518Srobert // When the value is 0 followed by a suffix (like 0wb), we want to leave 0
1320*12c85518Srobert // as the start of the digits. So if skipping octal digits does not skip
1321*12c85518Srobert // anything, we leave the digit start where it was.
1322*12c85518Srobert if (s != PossibleNewDigitStart)
1323*12c85518Srobert DigitsBegin = PossibleNewDigitStart;
1324*12c85518Srobert
1325e5dd7070Spatrick if (s == ThisTokEnd)
1326e5dd7070Spatrick return; // Done, simple octal number like 01234
1327e5dd7070Spatrick
1328e5dd7070Spatrick // If we have some other non-octal digit that *is* a decimal digit, see if
1329e5dd7070Spatrick // this is part of a floating point number like 094.123 or 09e1.
1330e5dd7070Spatrick if (isDigit(*s)) {
1331e5dd7070Spatrick const char *EndDecimal = SkipDigits(s);
1332e5dd7070Spatrick if (EndDecimal[0] == '.' || EndDecimal[0] == 'e' || EndDecimal[0] == 'E') {
1333e5dd7070Spatrick s = EndDecimal;
1334e5dd7070Spatrick radix = 10;
1335e5dd7070Spatrick }
1336e5dd7070Spatrick }
1337e5dd7070Spatrick
1338e5dd7070Spatrick ParseDecimalOrOctalCommon(TokLoc);
1339e5dd7070Spatrick }
1340e5dd7070Spatrick
alwaysFitsInto64Bits(unsigned Radix,unsigned NumDigits)1341e5dd7070Spatrick static bool alwaysFitsInto64Bits(unsigned Radix, unsigned NumDigits) {
1342e5dd7070Spatrick switch (Radix) {
1343e5dd7070Spatrick case 2:
1344e5dd7070Spatrick return NumDigits <= 64;
1345e5dd7070Spatrick case 8:
1346e5dd7070Spatrick return NumDigits <= 64 / 3; // Digits are groups of 3 bits.
1347e5dd7070Spatrick case 10:
1348e5dd7070Spatrick return NumDigits <= 19; // floor(log10(2^64))
1349e5dd7070Spatrick case 16:
1350e5dd7070Spatrick return NumDigits <= 64 / 4; // Digits are groups of 4 bits.
1351e5dd7070Spatrick default:
1352e5dd7070Spatrick llvm_unreachable("impossible Radix");
1353e5dd7070Spatrick }
1354e5dd7070Spatrick }
1355e5dd7070Spatrick
1356e5dd7070Spatrick /// GetIntegerValue - Convert this numeric literal value to an APInt that
1357e5dd7070Spatrick /// matches Val's input width. If there is an overflow, set Val to the low bits
1358e5dd7070Spatrick /// of the result and return true. Otherwise, return false.
GetIntegerValue(llvm::APInt & Val)1359e5dd7070Spatrick bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) {
1360e5dd7070Spatrick // Fast path: Compute a conservative bound on the maximum number of
1361e5dd7070Spatrick // bits per digit in this radix. If we can't possibly overflow a
1362e5dd7070Spatrick // uint64 based on that bound then do the simple conversion to
1363e5dd7070Spatrick // integer. This avoids the expensive overflow checking below, and
1364e5dd7070Spatrick // handles the common cases that matter (small decimal integers and
1365e5dd7070Spatrick // hex/octal values which don't overflow).
1366e5dd7070Spatrick const unsigned NumDigits = SuffixBegin - DigitsBegin;
1367e5dd7070Spatrick if (alwaysFitsInto64Bits(radix, NumDigits)) {
1368e5dd7070Spatrick uint64_t N = 0;
1369e5dd7070Spatrick for (const char *Ptr = DigitsBegin; Ptr != SuffixBegin; ++Ptr)
1370e5dd7070Spatrick if (!isDigitSeparator(*Ptr))
1371e5dd7070Spatrick N = N * radix + llvm::hexDigitValue(*Ptr);
1372e5dd7070Spatrick
1373e5dd7070Spatrick // This will truncate the value to Val's input width. Simply check
1374e5dd7070Spatrick // for overflow by comparing.
1375e5dd7070Spatrick Val = N;
1376e5dd7070Spatrick return Val.getZExtValue() != N;
1377e5dd7070Spatrick }
1378e5dd7070Spatrick
1379e5dd7070Spatrick Val = 0;
1380e5dd7070Spatrick const char *Ptr = DigitsBegin;
1381e5dd7070Spatrick
1382e5dd7070Spatrick llvm::APInt RadixVal(Val.getBitWidth(), radix);
1383e5dd7070Spatrick llvm::APInt CharVal(Val.getBitWidth(), 0);
1384e5dd7070Spatrick llvm::APInt OldVal = Val;
1385e5dd7070Spatrick
1386e5dd7070Spatrick bool OverflowOccurred = false;
1387e5dd7070Spatrick while (Ptr < SuffixBegin) {
1388e5dd7070Spatrick if (isDigitSeparator(*Ptr)) {
1389e5dd7070Spatrick ++Ptr;
1390e5dd7070Spatrick continue;
1391e5dd7070Spatrick }
1392e5dd7070Spatrick
1393e5dd7070Spatrick unsigned C = llvm::hexDigitValue(*Ptr++);
1394e5dd7070Spatrick
1395e5dd7070Spatrick // If this letter is out of bound for this radix, reject it.
1396e5dd7070Spatrick assert(C < radix && "NumericLiteralParser ctor should have rejected this");
1397e5dd7070Spatrick
1398e5dd7070Spatrick CharVal = C;
1399e5dd7070Spatrick
1400e5dd7070Spatrick // Add the digit to the value in the appropriate radix. If adding in digits
1401e5dd7070Spatrick // made the value smaller, then this overflowed.
1402e5dd7070Spatrick OldVal = Val;
1403e5dd7070Spatrick
1404e5dd7070Spatrick // Multiply by radix, did overflow occur on the multiply?
1405e5dd7070Spatrick Val *= RadixVal;
1406e5dd7070Spatrick OverflowOccurred |= Val.udiv(RadixVal) != OldVal;
1407e5dd7070Spatrick
1408e5dd7070Spatrick // Add value, did overflow occur on the value?
1409e5dd7070Spatrick // (a + b) ult b <=> overflow
1410e5dd7070Spatrick Val += CharVal;
1411e5dd7070Spatrick OverflowOccurred |= Val.ult(CharVal);
1412e5dd7070Spatrick }
1413e5dd7070Spatrick return OverflowOccurred;
1414e5dd7070Spatrick }
1415e5dd7070Spatrick
1416e5dd7070Spatrick llvm::APFloat::opStatus
GetFloatValue(llvm::APFloat & Result)1417e5dd7070Spatrick NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) {
1418e5dd7070Spatrick using llvm::APFloat;
1419e5dd7070Spatrick
1420e5dd7070Spatrick unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin);
1421e5dd7070Spatrick
1422e5dd7070Spatrick llvm::SmallString<16> Buffer;
1423e5dd7070Spatrick StringRef Str(ThisTokBegin, n);
1424*12c85518Srobert if (Str.contains('\'')) {
1425e5dd7070Spatrick Buffer.reserve(n);
1426e5dd7070Spatrick std::remove_copy_if(Str.begin(), Str.end(), std::back_inserter(Buffer),
1427e5dd7070Spatrick &isDigitSeparator);
1428e5dd7070Spatrick Str = Buffer;
1429e5dd7070Spatrick }
1430e5dd7070Spatrick
1431e5dd7070Spatrick auto StatusOrErr =
1432e5dd7070Spatrick Result.convertFromString(Str, APFloat::rmNearestTiesToEven);
1433e5dd7070Spatrick assert(StatusOrErr && "Invalid floating point representation");
1434e5dd7070Spatrick return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr
1435e5dd7070Spatrick : APFloat::opInvalidOp;
1436e5dd7070Spatrick }
1437e5dd7070Spatrick
IsExponentPart(char c)1438e5dd7070Spatrick static inline bool IsExponentPart(char c) {
1439e5dd7070Spatrick return c == 'p' || c == 'P' || c == 'e' || c == 'E';
1440e5dd7070Spatrick }
1441e5dd7070Spatrick
GetFixedPointValue(llvm::APInt & StoreVal,unsigned Scale)1442e5dd7070Spatrick bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) {
1443e5dd7070Spatrick assert(radix == 16 || radix == 10);
1444e5dd7070Spatrick
1445e5dd7070Spatrick // Find how many digits are needed to store the whole literal.
1446e5dd7070Spatrick unsigned NumDigits = SuffixBegin - DigitsBegin;
1447e5dd7070Spatrick if (saw_period) --NumDigits;
1448e5dd7070Spatrick
1449e5dd7070Spatrick // Initial scan of the exponent if it exists
1450e5dd7070Spatrick bool ExpOverflowOccurred = false;
1451e5dd7070Spatrick bool NegativeExponent = false;
1452e5dd7070Spatrick const char *ExponentBegin;
1453e5dd7070Spatrick uint64_t Exponent = 0;
1454e5dd7070Spatrick int64_t BaseShift = 0;
1455e5dd7070Spatrick if (saw_exponent) {
1456e5dd7070Spatrick const char *Ptr = DigitsBegin;
1457e5dd7070Spatrick
1458e5dd7070Spatrick while (!IsExponentPart(*Ptr)) ++Ptr;
1459e5dd7070Spatrick ExponentBegin = Ptr;
1460e5dd7070Spatrick ++Ptr;
1461e5dd7070Spatrick NegativeExponent = *Ptr == '-';
1462e5dd7070Spatrick if (NegativeExponent) ++Ptr;
1463e5dd7070Spatrick
1464e5dd7070Spatrick unsigned NumExpDigits = SuffixBegin - Ptr;
1465e5dd7070Spatrick if (alwaysFitsInto64Bits(radix, NumExpDigits)) {
1466e5dd7070Spatrick llvm::StringRef ExpStr(Ptr, NumExpDigits);
1467e5dd7070Spatrick llvm::APInt ExpInt(/*numBits=*/64, ExpStr, /*radix=*/10);
1468e5dd7070Spatrick Exponent = ExpInt.getZExtValue();
1469e5dd7070Spatrick } else {
1470e5dd7070Spatrick ExpOverflowOccurred = true;
1471e5dd7070Spatrick }
1472e5dd7070Spatrick
1473e5dd7070Spatrick if (NegativeExponent) BaseShift -= Exponent;
1474e5dd7070Spatrick else BaseShift += Exponent;
1475e5dd7070Spatrick }
1476e5dd7070Spatrick
1477e5dd7070Spatrick // Number of bits needed for decimal literal is
1478e5dd7070Spatrick // ceil(NumDigits * log2(10)) Integral part
1479e5dd7070Spatrick // + Scale Fractional part
1480e5dd7070Spatrick // + ceil(Exponent * log2(10)) Exponent
1481e5dd7070Spatrick // --------------------------------------------------
1482e5dd7070Spatrick // ceil((NumDigits + Exponent) * log2(10)) + Scale
1483e5dd7070Spatrick //
1484e5dd7070Spatrick // But for simplicity in handling integers, we can round up log2(10) to 4,
1485e5dd7070Spatrick // making:
1486e5dd7070Spatrick // 4 * (NumDigits + Exponent) + Scale
1487e5dd7070Spatrick //
1488e5dd7070Spatrick // Number of digits needed for hexadecimal literal is
1489e5dd7070Spatrick // 4 * NumDigits Integral part
1490e5dd7070Spatrick // + Scale Fractional part
1491e5dd7070Spatrick // + Exponent Exponent
1492e5dd7070Spatrick // --------------------------------------------------
1493e5dd7070Spatrick // (4 * NumDigits) + Scale + Exponent
1494e5dd7070Spatrick uint64_t NumBitsNeeded;
1495e5dd7070Spatrick if (radix == 10)
1496e5dd7070Spatrick NumBitsNeeded = 4 * (NumDigits + Exponent) + Scale;
1497e5dd7070Spatrick else
1498e5dd7070Spatrick NumBitsNeeded = 4 * NumDigits + Exponent + Scale;
1499e5dd7070Spatrick
1500e5dd7070Spatrick if (NumBitsNeeded > std::numeric_limits<unsigned>::max())
1501e5dd7070Spatrick ExpOverflowOccurred = true;
1502e5dd7070Spatrick llvm::APInt Val(static_cast<unsigned>(NumBitsNeeded), 0, /*isSigned=*/false);
1503e5dd7070Spatrick
1504e5dd7070Spatrick bool FoundDecimal = false;
1505e5dd7070Spatrick
1506e5dd7070Spatrick int64_t FractBaseShift = 0;
1507e5dd7070Spatrick const char *End = saw_exponent ? ExponentBegin : SuffixBegin;
1508e5dd7070Spatrick for (const char *Ptr = DigitsBegin; Ptr < End; ++Ptr) {
1509e5dd7070Spatrick if (*Ptr == '.') {
1510e5dd7070Spatrick FoundDecimal = true;
1511e5dd7070Spatrick continue;
1512e5dd7070Spatrick }
1513e5dd7070Spatrick
1514e5dd7070Spatrick // Normal reading of an integer
1515e5dd7070Spatrick unsigned C = llvm::hexDigitValue(*Ptr);
1516e5dd7070Spatrick assert(C < radix && "NumericLiteralParser ctor should have rejected this");
1517e5dd7070Spatrick
1518e5dd7070Spatrick Val *= radix;
1519e5dd7070Spatrick Val += C;
1520e5dd7070Spatrick
1521e5dd7070Spatrick if (FoundDecimal)
1522e5dd7070Spatrick // Keep track of how much we will need to adjust this value by from the
1523e5dd7070Spatrick // number of digits past the radix point.
1524e5dd7070Spatrick --FractBaseShift;
1525e5dd7070Spatrick }
1526e5dd7070Spatrick
1527e5dd7070Spatrick // For a radix of 16, we will be multiplying by 2 instead of 16.
1528e5dd7070Spatrick if (radix == 16) FractBaseShift *= 4;
1529e5dd7070Spatrick BaseShift += FractBaseShift;
1530e5dd7070Spatrick
1531e5dd7070Spatrick Val <<= Scale;
1532e5dd7070Spatrick
1533e5dd7070Spatrick uint64_t Base = (radix == 16) ? 2 : 10;
1534e5dd7070Spatrick if (BaseShift > 0) {
1535e5dd7070Spatrick for (int64_t i = 0; i < BaseShift; ++i) {
1536e5dd7070Spatrick Val *= Base;
1537e5dd7070Spatrick }
1538e5dd7070Spatrick } else if (BaseShift < 0) {
1539*12c85518Srobert for (int64_t i = BaseShift; i < 0 && !Val.isZero(); ++i)
1540e5dd7070Spatrick Val = Val.udiv(Base);
1541e5dd7070Spatrick }
1542e5dd7070Spatrick
1543e5dd7070Spatrick bool IntOverflowOccurred = false;
1544e5dd7070Spatrick auto MaxVal = llvm::APInt::getMaxValue(StoreVal.getBitWidth());
1545e5dd7070Spatrick if (Val.getBitWidth() > StoreVal.getBitWidth()) {
1546e5dd7070Spatrick IntOverflowOccurred |= Val.ugt(MaxVal.zext(Val.getBitWidth()));
1547e5dd7070Spatrick StoreVal = Val.trunc(StoreVal.getBitWidth());
1548e5dd7070Spatrick } else if (Val.getBitWidth() < StoreVal.getBitWidth()) {
1549e5dd7070Spatrick IntOverflowOccurred |= Val.zext(MaxVal.getBitWidth()).ugt(MaxVal);
1550e5dd7070Spatrick StoreVal = Val.zext(StoreVal.getBitWidth());
1551e5dd7070Spatrick } else {
1552e5dd7070Spatrick StoreVal = Val;
1553e5dd7070Spatrick }
1554e5dd7070Spatrick
1555e5dd7070Spatrick return IntOverflowOccurred || ExpOverflowOccurred;
1556e5dd7070Spatrick }
1557e5dd7070Spatrick
1558e5dd7070Spatrick /// \verbatim
1559e5dd7070Spatrick /// user-defined-character-literal: [C++11 lex.ext]
1560e5dd7070Spatrick /// character-literal ud-suffix
1561e5dd7070Spatrick /// ud-suffix:
1562e5dd7070Spatrick /// identifier
1563e5dd7070Spatrick /// character-literal: [C++11 lex.ccon]
1564e5dd7070Spatrick /// ' c-char-sequence '
1565e5dd7070Spatrick /// u' c-char-sequence '
1566e5dd7070Spatrick /// U' c-char-sequence '
1567e5dd7070Spatrick /// L' c-char-sequence '
1568e5dd7070Spatrick /// u8' c-char-sequence ' [C++1z lex.ccon]
1569e5dd7070Spatrick /// c-char-sequence:
1570e5dd7070Spatrick /// c-char
1571e5dd7070Spatrick /// c-char-sequence c-char
1572e5dd7070Spatrick /// c-char:
1573e5dd7070Spatrick /// any member of the source character set except the single-quote ',
1574e5dd7070Spatrick /// backslash \, or new-line character
1575e5dd7070Spatrick /// escape-sequence
1576e5dd7070Spatrick /// universal-character-name
1577e5dd7070Spatrick /// escape-sequence:
1578e5dd7070Spatrick /// simple-escape-sequence
1579e5dd7070Spatrick /// octal-escape-sequence
1580e5dd7070Spatrick /// hexadecimal-escape-sequence
1581e5dd7070Spatrick /// simple-escape-sequence:
1582e5dd7070Spatrick /// one of \' \" \? \\ \a \b \f \n \r \t \v
1583e5dd7070Spatrick /// octal-escape-sequence:
1584e5dd7070Spatrick /// \ octal-digit
1585e5dd7070Spatrick /// \ octal-digit octal-digit
1586e5dd7070Spatrick /// \ octal-digit octal-digit octal-digit
1587e5dd7070Spatrick /// hexadecimal-escape-sequence:
1588e5dd7070Spatrick /// \x hexadecimal-digit
1589e5dd7070Spatrick /// hexadecimal-escape-sequence hexadecimal-digit
1590e5dd7070Spatrick /// universal-character-name: [C++11 lex.charset]
1591e5dd7070Spatrick /// \u hex-quad
1592e5dd7070Spatrick /// \U hex-quad hex-quad
1593e5dd7070Spatrick /// hex-quad:
1594e5dd7070Spatrick /// hex-digit hex-digit hex-digit hex-digit
1595e5dd7070Spatrick /// \endverbatim
1596e5dd7070Spatrick ///
CharLiteralParser(const char * begin,const char * end,SourceLocation Loc,Preprocessor & PP,tok::TokenKind kind)1597e5dd7070Spatrick CharLiteralParser::CharLiteralParser(const char *begin, const char *end,
1598e5dd7070Spatrick SourceLocation Loc, Preprocessor &PP,
1599e5dd7070Spatrick tok::TokenKind kind) {
1600e5dd7070Spatrick // At this point we know that the character matches the regex "(L|u|U)?'.*'".
1601e5dd7070Spatrick HadError = false;
1602e5dd7070Spatrick
1603e5dd7070Spatrick Kind = kind;
1604e5dd7070Spatrick
1605e5dd7070Spatrick const char *TokBegin = begin;
1606e5dd7070Spatrick
1607e5dd7070Spatrick // Skip over wide character determinant.
1608e5dd7070Spatrick if (Kind != tok::char_constant)
1609e5dd7070Spatrick ++begin;
1610e5dd7070Spatrick if (Kind == tok::utf8_char_constant)
1611e5dd7070Spatrick ++begin;
1612e5dd7070Spatrick
1613e5dd7070Spatrick // Skip over the entry quote.
1614*12c85518Srobert if (begin[0] != '\'') {
1615*12c85518Srobert PP.Diag(Loc, diag::err_lexing_char);
1616*12c85518Srobert HadError = true;
1617*12c85518Srobert return;
1618*12c85518Srobert }
1619*12c85518Srobert
1620e5dd7070Spatrick ++begin;
1621e5dd7070Spatrick
1622e5dd7070Spatrick // Remove an optional ud-suffix.
1623e5dd7070Spatrick if (end[-1] != '\'') {
1624e5dd7070Spatrick const char *UDSuffixEnd = end;
1625e5dd7070Spatrick do {
1626e5dd7070Spatrick --end;
1627e5dd7070Spatrick } while (end[-1] != '\'');
1628e5dd7070Spatrick // FIXME: Don't bother with this if !tok.hasUCN().
1629e5dd7070Spatrick expandUCNs(UDSuffixBuf, StringRef(end, UDSuffixEnd - end));
1630e5dd7070Spatrick UDSuffixOffset = end - TokBegin;
1631e5dd7070Spatrick }
1632e5dd7070Spatrick
1633e5dd7070Spatrick // Trim the ending quote.
1634e5dd7070Spatrick assert(end != begin && "Invalid token lexed");
1635e5dd7070Spatrick --end;
1636e5dd7070Spatrick
1637e5dd7070Spatrick // FIXME: The "Value" is an uint64_t so we can handle char literals of
1638e5dd7070Spatrick // up to 64-bits.
1639e5dd7070Spatrick // FIXME: This extensively assumes that 'char' is 8-bits.
1640e5dd7070Spatrick assert(PP.getTargetInfo().getCharWidth() == 8 &&
1641e5dd7070Spatrick "Assumes char is 8 bits");
1642e5dd7070Spatrick assert(PP.getTargetInfo().getIntWidth() <= 64 &&
1643e5dd7070Spatrick (PP.getTargetInfo().getIntWidth() & 7) == 0 &&
1644e5dd7070Spatrick "Assumes sizeof(int) on target is <= 64 and a multiple of char");
1645e5dd7070Spatrick assert(PP.getTargetInfo().getWCharWidth() <= 64 &&
1646e5dd7070Spatrick "Assumes sizeof(wchar) on target is <= 64");
1647e5dd7070Spatrick
1648e5dd7070Spatrick SmallVector<uint32_t, 4> codepoint_buffer;
1649e5dd7070Spatrick codepoint_buffer.resize(end - begin);
1650e5dd7070Spatrick uint32_t *buffer_begin = &codepoint_buffer.front();
1651e5dd7070Spatrick uint32_t *buffer_end = buffer_begin + codepoint_buffer.size();
1652e5dd7070Spatrick
1653e5dd7070Spatrick // Unicode escapes representing characters that cannot be correctly
1654e5dd7070Spatrick // represented in a single code unit are disallowed in character literals
1655e5dd7070Spatrick // by this implementation.
1656e5dd7070Spatrick uint32_t largest_character_for_kind;
1657e5dd7070Spatrick if (tok::wide_char_constant == Kind) {
1658e5dd7070Spatrick largest_character_for_kind =
1659e5dd7070Spatrick 0xFFFFFFFFu >> (32-PP.getTargetInfo().getWCharWidth());
1660e5dd7070Spatrick } else if (tok::utf8_char_constant == Kind) {
1661e5dd7070Spatrick largest_character_for_kind = 0x7F;
1662e5dd7070Spatrick } else if (tok::utf16_char_constant == Kind) {
1663e5dd7070Spatrick largest_character_for_kind = 0xFFFF;
1664e5dd7070Spatrick } else if (tok::utf32_char_constant == Kind) {
1665e5dd7070Spatrick largest_character_for_kind = 0x10FFFF;
1666e5dd7070Spatrick } else {
1667e5dd7070Spatrick largest_character_for_kind = 0x7Fu;
1668e5dd7070Spatrick }
1669e5dd7070Spatrick
1670e5dd7070Spatrick while (begin != end) {
1671e5dd7070Spatrick // Is this a span of non-escape characters?
1672e5dd7070Spatrick if (begin[0] != '\\') {
1673e5dd7070Spatrick char const *start = begin;
1674e5dd7070Spatrick do {
1675e5dd7070Spatrick ++begin;
1676e5dd7070Spatrick } while (begin != end && *begin != '\\');
1677e5dd7070Spatrick
1678e5dd7070Spatrick char const *tmp_in_start = start;
1679e5dd7070Spatrick uint32_t *tmp_out_start = buffer_begin;
1680e5dd7070Spatrick llvm::ConversionResult res =
1681e5dd7070Spatrick llvm::ConvertUTF8toUTF32(reinterpret_cast<llvm::UTF8 const **>(&start),
1682e5dd7070Spatrick reinterpret_cast<llvm::UTF8 const *>(begin),
1683e5dd7070Spatrick &buffer_begin, buffer_end, llvm::strictConversion);
1684e5dd7070Spatrick if (res != llvm::conversionOK) {
1685e5dd7070Spatrick // If we see bad encoding for unprefixed character literals, warn and
1686e5dd7070Spatrick // simply copy the byte values, for compatibility with gcc and
1687e5dd7070Spatrick // older versions of clang.
1688*12c85518Srobert bool NoErrorOnBadEncoding = isOrdinary();
1689e5dd7070Spatrick unsigned Msg = diag::err_bad_character_encoding;
1690e5dd7070Spatrick if (NoErrorOnBadEncoding)
1691e5dd7070Spatrick Msg = diag::warn_bad_character_encoding;
1692e5dd7070Spatrick PP.Diag(Loc, Msg);
1693e5dd7070Spatrick if (NoErrorOnBadEncoding) {
1694e5dd7070Spatrick start = tmp_in_start;
1695e5dd7070Spatrick buffer_begin = tmp_out_start;
1696e5dd7070Spatrick for (; start != begin; ++start, ++buffer_begin)
1697e5dd7070Spatrick *buffer_begin = static_cast<uint8_t>(*start);
1698e5dd7070Spatrick } else {
1699e5dd7070Spatrick HadError = true;
1700e5dd7070Spatrick }
1701e5dd7070Spatrick } else {
1702e5dd7070Spatrick for (; tmp_out_start < buffer_begin; ++tmp_out_start) {
1703e5dd7070Spatrick if (*tmp_out_start > largest_character_for_kind) {
1704e5dd7070Spatrick HadError = true;
1705e5dd7070Spatrick PP.Diag(Loc, diag::err_character_too_large);
1706e5dd7070Spatrick }
1707e5dd7070Spatrick }
1708e5dd7070Spatrick }
1709e5dd7070Spatrick
1710e5dd7070Spatrick continue;
1711e5dd7070Spatrick }
1712e5dd7070Spatrick // Is this a Universal Character Name escape?
1713*12c85518Srobert if (begin[1] == 'u' || begin[1] == 'U' || begin[1] == 'N') {
1714e5dd7070Spatrick unsigned short UcnLen = 0;
1715e5dd7070Spatrick if (!ProcessUCNEscape(TokBegin, begin, end, *buffer_begin, UcnLen,
1716e5dd7070Spatrick FullSourceLoc(Loc, PP.getSourceManager()),
1717e5dd7070Spatrick &PP.getDiagnostics(), PP.getLangOpts(), true)) {
1718e5dd7070Spatrick HadError = true;
1719e5dd7070Spatrick } else if (*buffer_begin > largest_character_for_kind) {
1720e5dd7070Spatrick HadError = true;
1721e5dd7070Spatrick PP.Diag(Loc, diag::err_character_too_large);
1722e5dd7070Spatrick }
1723e5dd7070Spatrick
1724e5dd7070Spatrick ++buffer_begin;
1725e5dd7070Spatrick continue;
1726e5dd7070Spatrick }
1727e5dd7070Spatrick unsigned CharWidth = getCharWidth(Kind, PP.getTargetInfo());
1728e5dd7070Spatrick uint64_t result =
1729e5dd7070Spatrick ProcessCharEscape(TokBegin, begin, end, HadError,
1730e5dd7070Spatrick FullSourceLoc(Loc,PP.getSourceManager()),
1731e5dd7070Spatrick CharWidth, &PP.getDiagnostics(), PP.getLangOpts());
1732e5dd7070Spatrick *buffer_begin++ = result;
1733e5dd7070Spatrick }
1734e5dd7070Spatrick
1735e5dd7070Spatrick unsigned NumCharsSoFar = buffer_begin - &codepoint_buffer.front();
1736e5dd7070Spatrick
1737e5dd7070Spatrick if (NumCharsSoFar > 1) {
1738*12c85518Srobert if (isOrdinary() && NumCharsSoFar == 4)
1739a9ac8606Spatrick PP.Diag(Loc, diag::warn_four_char_character_literal);
1740*12c85518Srobert else if (isOrdinary())
1741a9ac8606Spatrick PP.Diag(Loc, diag::warn_multichar_character_literal);
1742*12c85518Srobert else {
1743*12c85518Srobert PP.Diag(Loc, diag::err_multichar_character_literal) << (isWide() ? 0 : 1);
1744*12c85518Srobert HadError = true;
1745*12c85518Srobert }
1746e5dd7070Spatrick IsMultiChar = true;
1747e5dd7070Spatrick } else {
1748e5dd7070Spatrick IsMultiChar = false;
1749e5dd7070Spatrick }
1750e5dd7070Spatrick
1751e5dd7070Spatrick llvm::APInt LitVal(PP.getTargetInfo().getIntWidth(), 0);
1752e5dd7070Spatrick
1753e5dd7070Spatrick // Narrow character literals act as though their value is concatenated
1754e5dd7070Spatrick // in this implementation, but warn on overflow.
1755e5dd7070Spatrick bool multi_char_too_long = false;
1756*12c85518Srobert if (isOrdinary() && isMultiChar()) {
1757e5dd7070Spatrick LitVal = 0;
1758e5dd7070Spatrick for (size_t i = 0; i < NumCharsSoFar; ++i) {
1759e5dd7070Spatrick // check for enough leading zeros to shift into
1760e5dd7070Spatrick multi_char_too_long |= (LitVal.countLeadingZeros() < 8);
1761e5dd7070Spatrick LitVal <<= 8;
1762e5dd7070Spatrick LitVal = LitVal + (codepoint_buffer[i] & 0xFF);
1763e5dd7070Spatrick }
1764e5dd7070Spatrick } else if (NumCharsSoFar > 0) {
1765e5dd7070Spatrick // otherwise just take the last character
1766e5dd7070Spatrick LitVal = buffer_begin[-1];
1767e5dd7070Spatrick }
1768e5dd7070Spatrick
1769e5dd7070Spatrick if (!HadError && multi_char_too_long) {
1770e5dd7070Spatrick PP.Diag(Loc, diag::warn_char_constant_too_large);
1771e5dd7070Spatrick }
1772e5dd7070Spatrick
1773e5dd7070Spatrick // Transfer the value from APInt to uint64_t
1774e5dd7070Spatrick Value = LitVal.getZExtValue();
1775e5dd7070Spatrick
1776e5dd7070Spatrick // If this is a single narrow character, sign extend it (e.g. '\xFF' is "-1")
1777e5dd7070Spatrick // if 'char' is signed for this target (C99 6.4.4.4p10). Note that multiple
1778e5dd7070Spatrick // character constants are not sign extended in the this implementation:
1779e5dd7070Spatrick // '\xFF\xFF' = 65536 and '\x0\xFF' = 255, which matches GCC.
1780*12c85518Srobert if (isOrdinary() && NumCharsSoFar == 1 && (Value & 128) &&
1781e5dd7070Spatrick PP.getLangOpts().CharIsSigned)
1782e5dd7070Spatrick Value = (signed char)Value;
1783e5dd7070Spatrick }
1784e5dd7070Spatrick
1785e5dd7070Spatrick /// \verbatim
1786e5dd7070Spatrick /// string-literal: [C++0x lex.string]
1787e5dd7070Spatrick /// encoding-prefix " [s-char-sequence] "
1788e5dd7070Spatrick /// encoding-prefix R raw-string
1789e5dd7070Spatrick /// encoding-prefix:
1790e5dd7070Spatrick /// u8
1791e5dd7070Spatrick /// u
1792e5dd7070Spatrick /// U
1793e5dd7070Spatrick /// L
1794e5dd7070Spatrick /// s-char-sequence:
1795e5dd7070Spatrick /// s-char
1796e5dd7070Spatrick /// s-char-sequence s-char
1797e5dd7070Spatrick /// s-char:
1798e5dd7070Spatrick /// any member of the source character set except the double-quote ",
1799e5dd7070Spatrick /// backslash \, or new-line character
1800e5dd7070Spatrick /// escape-sequence
1801e5dd7070Spatrick /// universal-character-name
1802e5dd7070Spatrick /// raw-string:
1803e5dd7070Spatrick /// " d-char-sequence ( r-char-sequence ) d-char-sequence "
1804e5dd7070Spatrick /// r-char-sequence:
1805e5dd7070Spatrick /// r-char
1806e5dd7070Spatrick /// r-char-sequence r-char
1807e5dd7070Spatrick /// r-char:
1808e5dd7070Spatrick /// any member of the source character set, except a right parenthesis )
1809e5dd7070Spatrick /// followed by the initial d-char-sequence (which may be empty)
1810e5dd7070Spatrick /// followed by a double quote ".
1811e5dd7070Spatrick /// d-char-sequence:
1812e5dd7070Spatrick /// d-char
1813e5dd7070Spatrick /// d-char-sequence d-char
1814e5dd7070Spatrick /// d-char:
1815e5dd7070Spatrick /// any member of the basic source character set except:
1816e5dd7070Spatrick /// space, the left parenthesis (, the right parenthesis ),
1817e5dd7070Spatrick /// the backslash \, and the control characters representing horizontal
1818e5dd7070Spatrick /// tab, vertical tab, form feed, and newline.
1819e5dd7070Spatrick /// escape-sequence: [C++0x lex.ccon]
1820e5dd7070Spatrick /// simple-escape-sequence
1821e5dd7070Spatrick /// octal-escape-sequence
1822e5dd7070Spatrick /// hexadecimal-escape-sequence
1823e5dd7070Spatrick /// simple-escape-sequence:
1824e5dd7070Spatrick /// one of \' \" \? \\ \a \b \f \n \r \t \v
1825e5dd7070Spatrick /// octal-escape-sequence:
1826e5dd7070Spatrick /// \ octal-digit
1827e5dd7070Spatrick /// \ octal-digit octal-digit
1828e5dd7070Spatrick /// \ octal-digit octal-digit octal-digit
1829e5dd7070Spatrick /// hexadecimal-escape-sequence:
1830e5dd7070Spatrick /// \x hexadecimal-digit
1831e5dd7070Spatrick /// hexadecimal-escape-sequence hexadecimal-digit
1832e5dd7070Spatrick /// universal-character-name:
1833e5dd7070Spatrick /// \u hex-quad
1834e5dd7070Spatrick /// \U hex-quad hex-quad
1835e5dd7070Spatrick /// hex-quad:
1836e5dd7070Spatrick /// hex-digit hex-digit hex-digit hex-digit
1837e5dd7070Spatrick /// \endverbatim
1838e5dd7070Spatrick ///
1839e5dd7070Spatrick StringLiteralParser::
StringLiteralParser(ArrayRef<Token> StringToks,Preprocessor & PP)1840e5dd7070Spatrick StringLiteralParser(ArrayRef<Token> StringToks,
1841*12c85518Srobert Preprocessor &PP)
1842e5dd7070Spatrick : SM(PP.getSourceManager()), Features(PP.getLangOpts()),
1843*12c85518Srobert Target(PP.getTargetInfo()), Diags(&PP.getDiagnostics()),
1844e5dd7070Spatrick MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
1845e5dd7070Spatrick ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
1846e5dd7070Spatrick init(StringToks);
1847e5dd7070Spatrick }
1848e5dd7070Spatrick
init(ArrayRef<Token> StringToks)1849e5dd7070Spatrick void StringLiteralParser::init(ArrayRef<Token> StringToks){
1850e5dd7070Spatrick // The literal token may have come from an invalid source location (e.g. due
1851e5dd7070Spatrick // to a PCH error), in which case the token length will be 0.
1852e5dd7070Spatrick if (StringToks.empty() || StringToks[0].getLength() < 2)
1853e5dd7070Spatrick return DiagnoseLexingError(SourceLocation());
1854e5dd7070Spatrick
1855e5dd7070Spatrick // Scan all of the string portions, remember the max individual token length,
1856e5dd7070Spatrick // computing a bound on the concatenated string length, and see whether any
1857e5dd7070Spatrick // piece is a wide-string. If any of the string portions is a wide-string
1858e5dd7070Spatrick // literal, the result is a wide-string literal [C99 6.4.5p4].
1859e5dd7070Spatrick assert(!StringToks.empty() && "expected at least one token");
1860e5dd7070Spatrick MaxTokenLength = StringToks[0].getLength();
1861e5dd7070Spatrick assert(StringToks[0].getLength() >= 2 && "literal token is invalid!");
1862e5dd7070Spatrick SizeBound = StringToks[0].getLength()-2; // -2 for "".
1863e5dd7070Spatrick Kind = StringToks[0].getKind();
1864e5dd7070Spatrick
1865e5dd7070Spatrick hadError = false;
1866e5dd7070Spatrick
1867e5dd7070Spatrick // Implement Translation Phase #6: concatenation of string literals
1868e5dd7070Spatrick /// (C99 5.1.1.2p1). The common case is only one string fragment.
1869e5dd7070Spatrick for (unsigned i = 1; i != StringToks.size(); ++i) {
1870e5dd7070Spatrick if (StringToks[i].getLength() < 2)
1871e5dd7070Spatrick return DiagnoseLexingError(StringToks[i].getLocation());
1872e5dd7070Spatrick
1873e5dd7070Spatrick // The string could be shorter than this if it needs cleaning, but this is a
1874e5dd7070Spatrick // reasonable bound, which is all we need.
1875e5dd7070Spatrick assert(StringToks[i].getLength() >= 2 && "literal token is invalid!");
1876e5dd7070Spatrick SizeBound += StringToks[i].getLength()-2; // -2 for "".
1877e5dd7070Spatrick
1878e5dd7070Spatrick // Remember maximum string piece length.
1879e5dd7070Spatrick if (StringToks[i].getLength() > MaxTokenLength)
1880e5dd7070Spatrick MaxTokenLength = StringToks[i].getLength();
1881e5dd7070Spatrick
1882e5dd7070Spatrick // Remember if we see any wide or utf-8/16/32 strings.
1883e5dd7070Spatrick // Also check for illegal concatenations.
1884e5dd7070Spatrick if (StringToks[i].isNot(Kind) && StringToks[i].isNot(tok::string_literal)) {
1885*12c85518Srobert if (isOrdinary()) {
1886e5dd7070Spatrick Kind = StringToks[i].getKind();
1887e5dd7070Spatrick } else {
1888e5dd7070Spatrick if (Diags)
1889e5dd7070Spatrick Diags->Report(StringToks[i].getLocation(),
1890e5dd7070Spatrick diag::err_unsupported_string_concat);
1891e5dd7070Spatrick hadError = true;
1892e5dd7070Spatrick }
1893e5dd7070Spatrick }
1894e5dd7070Spatrick }
1895e5dd7070Spatrick
1896e5dd7070Spatrick // Include space for the null terminator.
1897e5dd7070Spatrick ++SizeBound;
1898e5dd7070Spatrick
1899e5dd7070Spatrick // TODO: K&R warning: "traditional C rejects string constant concatenation"
1900e5dd7070Spatrick
1901e5dd7070Spatrick // Get the width in bytes of char/wchar_t/char16_t/char32_t
1902e5dd7070Spatrick CharByteWidth = getCharWidth(Kind, Target);
1903e5dd7070Spatrick assert((CharByteWidth & 7) == 0 && "Assumes character size is byte multiple");
1904e5dd7070Spatrick CharByteWidth /= 8;
1905e5dd7070Spatrick
1906e5dd7070Spatrick // The output buffer size needs to be large enough to hold wide characters.
1907e5dd7070Spatrick // This is a worst-case assumption which basically corresponds to L"" "long".
1908e5dd7070Spatrick SizeBound *= CharByteWidth;
1909e5dd7070Spatrick
1910e5dd7070Spatrick // Size the temporary buffer to hold the result string data.
1911e5dd7070Spatrick ResultBuf.resize(SizeBound);
1912e5dd7070Spatrick
1913e5dd7070Spatrick // Likewise, but for each string piece.
1914e5dd7070Spatrick SmallString<512> TokenBuf;
1915e5dd7070Spatrick TokenBuf.resize(MaxTokenLength);
1916e5dd7070Spatrick
1917e5dd7070Spatrick // Loop over all the strings, getting their spelling, and expanding them to
1918e5dd7070Spatrick // wide strings as appropriate.
1919e5dd7070Spatrick ResultPtr = &ResultBuf[0]; // Next byte to fill in.
1920e5dd7070Spatrick
1921e5dd7070Spatrick Pascal = false;
1922e5dd7070Spatrick
1923e5dd7070Spatrick SourceLocation UDSuffixTokLoc;
1924e5dd7070Spatrick
1925e5dd7070Spatrick for (unsigned i = 0, e = StringToks.size(); i != e; ++i) {
1926e5dd7070Spatrick const char *ThisTokBuf = &TokenBuf[0];
1927e5dd7070Spatrick // Get the spelling of the token, which eliminates trigraphs, etc. We know
1928e5dd7070Spatrick // that ThisTokBuf points to a buffer that is big enough for the whole token
1929e5dd7070Spatrick // and 'spelled' tokens can only shrink.
1930e5dd7070Spatrick bool StringInvalid = false;
1931e5dd7070Spatrick unsigned ThisTokLen =
1932e5dd7070Spatrick Lexer::getSpelling(StringToks[i], ThisTokBuf, SM, Features,
1933e5dd7070Spatrick &StringInvalid);
1934e5dd7070Spatrick if (StringInvalid)
1935e5dd7070Spatrick return DiagnoseLexingError(StringToks[i].getLocation());
1936e5dd7070Spatrick
1937e5dd7070Spatrick const char *ThisTokBegin = ThisTokBuf;
1938e5dd7070Spatrick const char *ThisTokEnd = ThisTokBuf+ThisTokLen;
1939e5dd7070Spatrick
1940e5dd7070Spatrick // Remove an optional ud-suffix.
1941e5dd7070Spatrick if (ThisTokEnd[-1] != '"') {
1942e5dd7070Spatrick const char *UDSuffixEnd = ThisTokEnd;
1943e5dd7070Spatrick do {
1944e5dd7070Spatrick --ThisTokEnd;
1945e5dd7070Spatrick } while (ThisTokEnd[-1] != '"');
1946e5dd7070Spatrick
1947e5dd7070Spatrick StringRef UDSuffix(ThisTokEnd, UDSuffixEnd - ThisTokEnd);
1948e5dd7070Spatrick
1949e5dd7070Spatrick if (UDSuffixBuf.empty()) {
1950e5dd7070Spatrick if (StringToks[i].hasUCN())
1951e5dd7070Spatrick expandUCNs(UDSuffixBuf, UDSuffix);
1952e5dd7070Spatrick else
1953e5dd7070Spatrick UDSuffixBuf.assign(UDSuffix);
1954e5dd7070Spatrick UDSuffixToken = i;
1955e5dd7070Spatrick UDSuffixOffset = ThisTokEnd - ThisTokBuf;
1956e5dd7070Spatrick UDSuffixTokLoc = StringToks[i].getLocation();
1957e5dd7070Spatrick } else {
1958e5dd7070Spatrick SmallString<32> ExpandedUDSuffix;
1959e5dd7070Spatrick if (StringToks[i].hasUCN()) {
1960e5dd7070Spatrick expandUCNs(ExpandedUDSuffix, UDSuffix);
1961e5dd7070Spatrick UDSuffix = ExpandedUDSuffix;
1962e5dd7070Spatrick }
1963e5dd7070Spatrick
1964e5dd7070Spatrick // C++11 [lex.ext]p8: At the end of phase 6, if a string literal is the
1965e5dd7070Spatrick // result of a concatenation involving at least one user-defined-string-
1966e5dd7070Spatrick // literal, all the participating user-defined-string-literals shall
1967e5dd7070Spatrick // have the same ud-suffix.
1968e5dd7070Spatrick if (UDSuffixBuf != UDSuffix) {
1969e5dd7070Spatrick if (Diags) {
1970e5dd7070Spatrick SourceLocation TokLoc = StringToks[i].getLocation();
1971e5dd7070Spatrick Diags->Report(TokLoc, diag::err_string_concat_mixed_suffix)
1972e5dd7070Spatrick << UDSuffixBuf << UDSuffix
1973e5dd7070Spatrick << SourceRange(UDSuffixTokLoc, UDSuffixTokLoc)
1974e5dd7070Spatrick << SourceRange(TokLoc, TokLoc);
1975e5dd7070Spatrick }
1976e5dd7070Spatrick hadError = true;
1977e5dd7070Spatrick }
1978e5dd7070Spatrick }
1979e5dd7070Spatrick }
1980e5dd7070Spatrick
1981e5dd7070Spatrick // Strip the end quote.
1982e5dd7070Spatrick --ThisTokEnd;
1983e5dd7070Spatrick
1984e5dd7070Spatrick // TODO: Input character set mapping support.
1985e5dd7070Spatrick
1986e5dd7070Spatrick // Skip marker for wide or unicode strings.
1987e5dd7070Spatrick if (ThisTokBuf[0] == 'L' || ThisTokBuf[0] == 'u' || ThisTokBuf[0] == 'U') {
1988e5dd7070Spatrick ++ThisTokBuf;
1989e5dd7070Spatrick // Skip 8 of u8 marker for utf8 strings.
1990e5dd7070Spatrick if (ThisTokBuf[0] == '8')
1991e5dd7070Spatrick ++ThisTokBuf;
1992e5dd7070Spatrick }
1993e5dd7070Spatrick
1994e5dd7070Spatrick // Check for raw string
1995e5dd7070Spatrick if (ThisTokBuf[0] == 'R') {
1996a9ac8606Spatrick if (ThisTokBuf[1] != '"') {
1997a9ac8606Spatrick // The file may have come from PCH and then changed after loading the
1998a9ac8606Spatrick // PCH; Fail gracefully.
1999a9ac8606Spatrick return DiagnoseLexingError(StringToks[i].getLocation());
2000a9ac8606Spatrick }
2001e5dd7070Spatrick ThisTokBuf += 2; // skip R"
2002e5dd7070Spatrick
2003a9ac8606Spatrick // C++11 [lex.string]p2: A `d-char-sequence` shall consist of at most 16
2004a9ac8606Spatrick // characters.
2005a9ac8606Spatrick constexpr unsigned MaxRawStrDelimLen = 16;
2006a9ac8606Spatrick
2007e5dd7070Spatrick const char *Prefix = ThisTokBuf;
2008a9ac8606Spatrick while (static_cast<unsigned>(ThisTokBuf - Prefix) < MaxRawStrDelimLen &&
2009a9ac8606Spatrick ThisTokBuf[0] != '(')
2010e5dd7070Spatrick ++ThisTokBuf;
2011a9ac8606Spatrick if (ThisTokBuf[0] != '(')
2012a9ac8606Spatrick return DiagnoseLexingError(StringToks[i].getLocation());
2013e5dd7070Spatrick ++ThisTokBuf; // skip '('
2014e5dd7070Spatrick
2015e5dd7070Spatrick // Remove same number of characters from the end
2016e5dd7070Spatrick ThisTokEnd -= ThisTokBuf - Prefix;
2017a9ac8606Spatrick if (ThisTokEnd < ThisTokBuf)
2018a9ac8606Spatrick return DiagnoseLexingError(StringToks[i].getLocation());
2019e5dd7070Spatrick
2020e5dd7070Spatrick // C++14 [lex.string]p4: A source-file new-line in a raw string literal
2021e5dd7070Spatrick // results in a new-line in the resulting execution string-literal.
2022e5dd7070Spatrick StringRef RemainingTokenSpan(ThisTokBuf, ThisTokEnd - ThisTokBuf);
2023e5dd7070Spatrick while (!RemainingTokenSpan.empty()) {
2024e5dd7070Spatrick // Split the string literal on \r\n boundaries.
2025e5dd7070Spatrick size_t CRLFPos = RemainingTokenSpan.find("\r\n");
2026e5dd7070Spatrick StringRef BeforeCRLF = RemainingTokenSpan.substr(0, CRLFPos);
2027e5dd7070Spatrick StringRef AfterCRLF = RemainingTokenSpan.substr(CRLFPos);
2028e5dd7070Spatrick
2029e5dd7070Spatrick // Copy everything before the \r\n sequence into the string literal.
2030e5dd7070Spatrick if (CopyStringFragment(StringToks[i], ThisTokBegin, BeforeCRLF))
2031e5dd7070Spatrick hadError = true;
2032e5dd7070Spatrick
2033e5dd7070Spatrick // Point into the \n inside the \r\n sequence and operate on the
2034e5dd7070Spatrick // remaining portion of the literal.
2035e5dd7070Spatrick RemainingTokenSpan = AfterCRLF.substr(1);
2036e5dd7070Spatrick }
2037e5dd7070Spatrick } else {
2038e5dd7070Spatrick if (ThisTokBuf[0] != '"') {
2039e5dd7070Spatrick // The file may have come from PCH and then changed after loading the
2040e5dd7070Spatrick // PCH; Fail gracefully.
2041e5dd7070Spatrick return DiagnoseLexingError(StringToks[i].getLocation());
2042e5dd7070Spatrick }
2043e5dd7070Spatrick ++ThisTokBuf; // skip "
2044e5dd7070Spatrick
2045e5dd7070Spatrick // Check if this is a pascal string
2046e5dd7070Spatrick if (Features.PascalStrings && ThisTokBuf + 1 != ThisTokEnd &&
2047e5dd7070Spatrick ThisTokBuf[0] == '\\' && ThisTokBuf[1] == 'p') {
2048e5dd7070Spatrick
2049e5dd7070Spatrick // If the \p sequence is found in the first token, we have a pascal string
2050e5dd7070Spatrick // Otherwise, if we already have a pascal string, ignore the first \p
2051e5dd7070Spatrick if (i == 0) {
2052e5dd7070Spatrick ++ThisTokBuf;
2053e5dd7070Spatrick Pascal = true;
2054e5dd7070Spatrick } else if (Pascal)
2055e5dd7070Spatrick ThisTokBuf += 2;
2056e5dd7070Spatrick }
2057e5dd7070Spatrick
2058e5dd7070Spatrick while (ThisTokBuf != ThisTokEnd) {
2059e5dd7070Spatrick // Is this a span of non-escape characters?
2060e5dd7070Spatrick if (ThisTokBuf[0] != '\\') {
2061e5dd7070Spatrick const char *InStart = ThisTokBuf;
2062e5dd7070Spatrick do {
2063e5dd7070Spatrick ++ThisTokBuf;
2064e5dd7070Spatrick } while (ThisTokBuf != ThisTokEnd && ThisTokBuf[0] != '\\');
2065e5dd7070Spatrick
2066e5dd7070Spatrick // Copy the character span over.
2067e5dd7070Spatrick if (CopyStringFragment(StringToks[i], ThisTokBegin,
2068e5dd7070Spatrick StringRef(InStart, ThisTokBuf - InStart)))
2069e5dd7070Spatrick hadError = true;
2070e5dd7070Spatrick continue;
2071e5dd7070Spatrick }
2072e5dd7070Spatrick // Is this a Universal Character Name escape?
2073*12c85518Srobert if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U' ||
2074*12c85518Srobert ThisTokBuf[1] == 'N') {
2075e5dd7070Spatrick EncodeUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd,
2076e5dd7070Spatrick ResultPtr, hadError,
2077e5dd7070Spatrick FullSourceLoc(StringToks[i].getLocation(), SM),
2078e5dd7070Spatrick CharByteWidth, Diags, Features);
2079e5dd7070Spatrick continue;
2080e5dd7070Spatrick }
2081e5dd7070Spatrick // Otherwise, this is a non-UCN escape character. Process it.
2082e5dd7070Spatrick unsigned ResultChar =
2083e5dd7070Spatrick ProcessCharEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, hadError,
2084e5dd7070Spatrick FullSourceLoc(StringToks[i].getLocation(), SM),
2085e5dd7070Spatrick CharByteWidth*8, Diags, Features);
2086e5dd7070Spatrick
2087e5dd7070Spatrick if (CharByteWidth == 4) {
2088e5dd7070Spatrick // FIXME: Make the type of the result buffer correct instead of
2089e5dd7070Spatrick // using reinterpret_cast.
2090e5dd7070Spatrick llvm::UTF32 *ResultWidePtr = reinterpret_cast<llvm::UTF32*>(ResultPtr);
2091e5dd7070Spatrick *ResultWidePtr = ResultChar;
2092e5dd7070Spatrick ResultPtr += 4;
2093e5dd7070Spatrick } else if (CharByteWidth == 2) {
2094e5dd7070Spatrick // FIXME: Make the type of the result buffer correct instead of
2095e5dd7070Spatrick // using reinterpret_cast.
2096e5dd7070Spatrick llvm::UTF16 *ResultWidePtr = reinterpret_cast<llvm::UTF16*>(ResultPtr);
2097e5dd7070Spatrick *ResultWidePtr = ResultChar & 0xFFFF;
2098e5dd7070Spatrick ResultPtr += 2;
2099e5dd7070Spatrick } else {
2100e5dd7070Spatrick assert(CharByteWidth == 1 && "Unexpected char width");
2101e5dd7070Spatrick *ResultPtr++ = ResultChar & 0xFF;
2102e5dd7070Spatrick }
2103e5dd7070Spatrick }
2104e5dd7070Spatrick }
2105e5dd7070Spatrick }
2106e5dd7070Spatrick
2107e5dd7070Spatrick if (Pascal) {
2108e5dd7070Spatrick if (CharByteWidth == 4) {
2109e5dd7070Spatrick // FIXME: Make the type of the result buffer correct instead of
2110e5dd7070Spatrick // using reinterpret_cast.
2111e5dd7070Spatrick llvm::UTF32 *ResultWidePtr = reinterpret_cast<llvm::UTF32*>(ResultBuf.data());
2112e5dd7070Spatrick ResultWidePtr[0] = GetNumStringChars() - 1;
2113e5dd7070Spatrick } else if (CharByteWidth == 2) {
2114e5dd7070Spatrick // FIXME: Make the type of the result buffer correct instead of
2115e5dd7070Spatrick // using reinterpret_cast.
2116e5dd7070Spatrick llvm::UTF16 *ResultWidePtr = reinterpret_cast<llvm::UTF16*>(ResultBuf.data());
2117e5dd7070Spatrick ResultWidePtr[0] = GetNumStringChars() - 1;
2118e5dd7070Spatrick } else {
2119e5dd7070Spatrick assert(CharByteWidth == 1 && "Unexpected char width");
2120e5dd7070Spatrick ResultBuf[0] = GetNumStringChars() - 1;
2121e5dd7070Spatrick }
2122e5dd7070Spatrick
2123e5dd7070Spatrick // Verify that pascal strings aren't too large.
2124e5dd7070Spatrick if (GetStringLength() > 256) {
2125e5dd7070Spatrick if (Diags)
2126e5dd7070Spatrick Diags->Report(StringToks.front().getLocation(),
2127e5dd7070Spatrick diag::err_pascal_string_too_long)
2128e5dd7070Spatrick << SourceRange(StringToks.front().getLocation(),
2129e5dd7070Spatrick StringToks.back().getLocation());
2130e5dd7070Spatrick hadError = true;
2131e5dd7070Spatrick return;
2132e5dd7070Spatrick }
2133e5dd7070Spatrick } else if (Diags) {
2134e5dd7070Spatrick // Complain if this string literal has too many characters.
2135e5dd7070Spatrick unsigned MaxChars = Features.CPlusPlus? 65536 : Features.C99 ? 4095 : 509;
2136e5dd7070Spatrick
2137e5dd7070Spatrick if (GetNumStringChars() > MaxChars)
2138e5dd7070Spatrick Diags->Report(StringToks.front().getLocation(),
2139e5dd7070Spatrick diag::ext_string_too_long)
2140e5dd7070Spatrick << GetNumStringChars() << MaxChars
2141e5dd7070Spatrick << (Features.CPlusPlus ? 2 : Features.C99 ? 1 : 0)
2142e5dd7070Spatrick << SourceRange(StringToks.front().getLocation(),
2143e5dd7070Spatrick StringToks.back().getLocation());
2144e5dd7070Spatrick }
2145e5dd7070Spatrick }
2146e5dd7070Spatrick
resyncUTF8(const char * Err,const char * End)2147e5dd7070Spatrick static const char *resyncUTF8(const char *Err, const char *End) {
2148e5dd7070Spatrick if (Err == End)
2149e5dd7070Spatrick return End;
2150e5dd7070Spatrick End = Err + std::min<unsigned>(llvm::getNumBytesForUTF8(*Err), End-Err);
2151e5dd7070Spatrick while (++Err != End && (*Err & 0xC0) == 0x80)
2152e5dd7070Spatrick ;
2153e5dd7070Spatrick return Err;
2154e5dd7070Spatrick }
2155e5dd7070Spatrick
2156e5dd7070Spatrick /// This function copies from Fragment, which is a sequence of bytes
2157e5dd7070Spatrick /// within Tok's contents (which begin at TokBegin) into ResultPtr.
2158e5dd7070Spatrick /// Performs widening for multi-byte characters.
CopyStringFragment(const Token & Tok,const char * TokBegin,StringRef Fragment)2159e5dd7070Spatrick bool StringLiteralParser::CopyStringFragment(const Token &Tok,
2160e5dd7070Spatrick const char *TokBegin,
2161e5dd7070Spatrick StringRef Fragment) {
2162e5dd7070Spatrick const llvm::UTF8 *ErrorPtrTmp;
2163e5dd7070Spatrick if (ConvertUTF8toWide(CharByteWidth, Fragment, ResultPtr, ErrorPtrTmp))
2164e5dd7070Spatrick return false;
2165e5dd7070Spatrick
2166e5dd7070Spatrick // If we see bad encoding for unprefixed string literals, warn and
2167e5dd7070Spatrick // simply copy the byte values, for compatibility with gcc and older
2168e5dd7070Spatrick // versions of clang.
2169*12c85518Srobert bool NoErrorOnBadEncoding = isOrdinary();
2170e5dd7070Spatrick if (NoErrorOnBadEncoding) {
2171e5dd7070Spatrick memcpy(ResultPtr, Fragment.data(), Fragment.size());
2172e5dd7070Spatrick ResultPtr += Fragment.size();
2173e5dd7070Spatrick }
2174e5dd7070Spatrick
2175e5dd7070Spatrick if (Diags) {
2176e5dd7070Spatrick const char *ErrorPtr = reinterpret_cast<const char *>(ErrorPtrTmp);
2177e5dd7070Spatrick
2178e5dd7070Spatrick FullSourceLoc SourceLoc(Tok.getLocation(), SM);
2179e5dd7070Spatrick const DiagnosticBuilder &Builder =
2180e5dd7070Spatrick Diag(Diags, Features, SourceLoc, TokBegin,
2181e5dd7070Spatrick ErrorPtr, resyncUTF8(ErrorPtr, Fragment.end()),
2182e5dd7070Spatrick NoErrorOnBadEncoding ? diag::warn_bad_string_encoding
2183e5dd7070Spatrick : diag::err_bad_string_encoding);
2184e5dd7070Spatrick
2185e5dd7070Spatrick const char *NextStart = resyncUTF8(ErrorPtr, Fragment.end());
2186e5dd7070Spatrick StringRef NextFragment(NextStart, Fragment.end()-NextStart);
2187e5dd7070Spatrick
2188e5dd7070Spatrick // Decode into a dummy buffer.
2189e5dd7070Spatrick SmallString<512> Dummy;
2190e5dd7070Spatrick Dummy.reserve(Fragment.size() * CharByteWidth);
2191e5dd7070Spatrick char *Ptr = Dummy.data();
2192e5dd7070Spatrick
2193e5dd7070Spatrick while (!ConvertUTF8toWide(CharByteWidth, NextFragment, Ptr, ErrorPtrTmp)) {
2194e5dd7070Spatrick const char *ErrorPtr = reinterpret_cast<const char *>(ErrorPtrTmp);
2195e5dd7070Spatrick NextStart = resyncUTF8(ErrorPtr, Fragment.end());
2196e5dd7070Spatrick Builder << MakeCharSourceRange(Features, SourceLoc, TokBegin,
2197e5dd7070Spatrick ErrorPtr, NextStart);
2198e5dd7070Spatrick NextFragment = StringRef(NextStart, Fragment.end()-NextStart);
2199e5dd7070Spatrick }
2200e5dd7070Spatrick }
2201e5dd7070Spatrick return !NoErrorOnBadEncoding;
2202e5dd7070Spatrick }
2203e5dd7070Spatrick
DiagnoseLexingError(SourceLocation Loc)2204e5dd7070Spatrick void StringLiteralParser::DiagnoseLexingError(SourceLocation Loc) {
2205e5dd7070Spatrick hadError = true;
2206e5dd7070Spatrick if (Diags)
2207e5dd7070Spatrick Diags->Report(Loc, diag::err_lexing_string);
2208e5dd7070Spatrick }
2209e5dd7070Spatrick
2210e5dd7070Spatrick /// getOffsetOfStringByte - This function returns the offset of the
2211e5dd7070Spatrick /// specified byte of the string data represented by Token. This handles
2212e5dd7070Spatrick /// advancing over escape sequences in the string.
getOffsetOfStringByte(const Token & Tok,unsigned ByteNo) const2213e5dd7070Spatrick unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
2214e5dd7070Spatrick unsigned ByteNo) const {
2215e5dd7070Spatrick // Get the spelling of the token.
2216e5dd7070Spatrick SmallString<32> SpellingBuffer;
2217e5dd7070Spatrick SpellingBuffer.resize(Tok.getLength());
2218e5dd7070Spatrick
2219e5dd7070Spatrick bool StringInvalid = false;
2220e5dd7070Spatrick const char *SpellingPtr = &SpellingBuffer[0];
2221e5dd7070Spatrick unsigned TokLen = Lexer::getSpelling(Tok, SpellingPtr, SM, Features,
2222e5dd7070Spatrick &StringInvalid);
2223e5dd7070Spatrick if (StringInvalid)
2224e5dd7070Spatrick return 0;
2225e5dd7070Spatrick
2226e5dd7070Spatrick const char *SpellingStart = SpellingPtr;
2227e5dd7070Spatrick const char *SpellingEnd = SpellingPtr+TokLen;
2228e5dd7070Spatrick
2229e5dd7070Spatrick // Handle UTF-8 strings just like narrow strings.
2230e5dd7070Spatrick if (SpellingPtr[0] == 'u' && SpellingPtr[1] == '8')
2231e5dd7070Spatrick SpellingPtr += 2;
2232e5dd7070Spatrick
2233e5dd7070Spatrick assert(SpellingPtr[0] != 'L' && SpellingPtr[0] != 'u' &&
2234e5dd7070Spatrick SpellingPtr[0] != 'U' && "Doesn't handle wide or utf strings yet");
2235e5dd7070Spatrick
2236e5dd7070Spatrick // For raw string literals, this is easy.
2237e5dd7070Spatrick if (SpellingPtr[0] == 'R') {
2238e5dd7070Spatrick assert(SpellingPtr[1] == '"' && "Should be a raw string literal!");
2239e5dd7070Spatrick // Skip 'R"'.
2240e5dd7070Spatrick SpellingPtr += 2;
2241e5dd7070Spatrick while (*SpellingPtr != '(') {
2242e5dd7070Spatrick ++SpellingPtr;
2243e5dd7070Spatrick assert(SpellingPtr < SpellingEnd && "Missing ( for raw string literal");
2244e5dd7070Spatrick }
2245e5dd7070Spatrick // Skip '('.
2246e5dd7070Spatrick ++SpellingPtr;
2247e5dd7070Spatrick return SpellingPtr - SpellingStart + ByteNo;
2248e5dd7070Spatrick }
2249e5dd7070Spatrick
2250e5dd7070Spatrick // Skip over the leading quote
2251e5dd7070Spatrick assert(SpellingPtr[0] == '"' && "Should be a string literal!");
2252e5dd7070Spatrick ++SpellingPtr;
2253e5dd7070Spatrick
2254e5dd7070Spatrick // Skip over bytes until we find the offset we're looking for.
2255e5dd7070Spatrick while (ByteNo) {
2256e5dd7070Spatrick assert(SpellingPtr < SpellingEnd && "Didn't find byte offset!");
2257e5dd7070Spatrick
2258e5dd7070Spatrick // Step over non-escapes simply.
2259e5dd7070Spatrick if (*SpellingPtr != '\\') {
2260e5dd7070Spatrick ++SpellingPtr;
2261e5dd7070Spatrick --ByteNo;
2262e5dd7070Spatrick continue;
2263e5dd7070Spatrick }
2264e5dd7070Spatrick
2265e5dd7070Spatrick // Otherwise, this is an escape character. Advance over it.
2266e5dd7070Spatrick bool HadError = false;
2267*12c85518Srobert if (SpellingPtr[1] == 'u' || SpellingPtr[1] == 'U' ||
2268*12c85518Srobert SpellingPtr[1] == 'N') {
2269e5dd7070Spatrick const char *EscapePtr = SpellingPtr;
2270e5dd7070Spatrick unsigned Len = MeasureUCNEscape(SpellingStart, SpellingPtr, SpellingEnd,
2271e5dd7070Spatrick 1, Features, HadError);
2272e5dd7070Spatrick if (Len > ByteNo) {
2273e5dd7070Spatrick // ByteNo is somewhere within the escape sequence.
2274e5dd7070Spatrick SpellingPtr = EscapePtr;
2275e5dd7070Spatrick break;
2276e5dd7070Spatrick }
2277e5dd7070Spatrick ByteNo -= Len;
2278e5dd7070Spatrick } else {
2279e5dd7070Spatrick ProcessCharEscape(SpellingStart, SpellingPtr, SpellingEnd, HadError,
2280e5dd7070Spatrick FullSourceLoc(Tok.getLocation(), SM),
2281e5dd7070Spatrick CharByteWidth*8, Diags, Features);
2282e5dd7070Spatrick --ByteNo;
2283e5dd7070Spatrick }
2284e5dd7070Spatrick assert(!HadError && "This method isn't valid on erroneous strings");
2285e5dd7070Spatrick }
2286e5dd7070Spatrick
2287e5dd7070Spatrick return SpellingPtr-SpellingStart;
2288e5dd7070Spatrick }
2289e5dd7070Spatrick
2290e5dd7070Spatrick /// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved
2291e5dd7070Spatrick /// suffixes as ud-suffixes, because the diagnostic experience is better if we
2292e5dd7070Spatrick /// treat it as an invalid suffix.
isValidUDSuffix(const LangOptions & LangOpts,StringRef Suffix)2293e5dd7070Spatrick bool StringLiteralParser::isValidUDSuffix(const LangOptions &LangOpts,
2294e5dd7070Spatrick StringRef Suffix) {
2295e5dd7070Spatrick return NumericLiteralParser::isValidUDSuffix(LangOpts, Suffix) ||
2296e5dd7070Spatrick Suffix == "sv";
2297e5dd7070Spatrick }
2298