xref: /openbsd-src/gnu/llvm/clang/lib/Lex/LiteralSupport.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
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