23#include "llvm/ADT/APInt.h"
24#include "llvm/ADT/ScopeExit.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringExtras.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/Support/ConvertUTF.h"
29#include "llvm/Support/Error.h"
30#include "llvm/Support/ErrorHandling.h"
31#include "llvm/Support/Unicode.h"
43 default: llvm_unreachable(
"Unknown token type!");
44 case tok::char_constant:
45 case tok::string_literal:
46 case tok::utf8_char_constant:
47 case tok::utf8_string_literal:
48 return Target.getCharWidth();
49 case tok::wide_char_constant:
50 case tok::wide_string_literal:
51 return Target.getWCharWidth();
52 case tok::utf16_char_constant:
53 case tok::utf16_string_literal:
54 return Target.getChar16Width();
55 case tok::utf32_char_constant:
56 case tok::utf32_string_literal:
57 return Target.getChar32Width();
64 llvm_unreachable(
"Unknown token type!");
65 case tok::char_constant:
66 case tok::string_literal:
68 case tok::utf8_char_constant:
69 case tok::utf8_string_literal:
71 case tok::wide_char_constant:
72 case tok::wide_string_literal:
73 case tok::utf16_char_constant:
74 case tok::utf16_string_literal:
75 case tok::utf32_char_constant:
76 case tok::utf32_string_literal:
84 const char *TokRangeBegin,
85 const char *TokRangeEnd) {
102 const char *TokBegin,
const char *TokRangeBegin,
103 const char *TokRangeEnd,
unsigned DiagID) {
107 return Diags->
Report(Begin, DiagID) <<
129static llvm::ErrorOr<char>
132 std::error_code EC = Converter.convert(Char, ResultCharConv);
135 else if (ResultCharConv.size() > 1)
136 return std::error_code(E2BIG, std::generic_category());
137 return ResultCharConv[0];
143 const char *&ThisTokBuf,
144 const char *ThisTokEnd,
bool &HadError,
149 llvm::TextEncodingConverter *Converter) {
150 const char *EscapeBegin = ThisTokBuf;
151 bool Delimited =
false;
152 bool EndDelimiterFound =
false;
159 unsigned ResultChar = *ThisTokBuf++;
160 char Escape = ResultChar;
161 bool Transcode =
true;
163 switch (ResultChar) {
165 case '\\':
case '\'':
case '"':
case '?':
break;
177 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
178 diag::ext_nonstandard_escape) <<
"e";
183 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
184 diag::ext_nonstandard_escape) <<
"E";
205 if (ThisTokBuf != ThisTokEnd && *ThisTokBuf ==
'{') {
208 if (*ThisTokBuf ==
'}') {
211 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
212 diag::err_delimited_escape_empty);
214 }
else if (ThisTokBuf == ThisTokEnd || !
isHexDigit(*ThisTokBuf)) {
216 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
217 diag::err_hex_escape_no_digits) <<
"x";
222 bool Overflow =
false;
223 for (; ThisTokBuf != ThisTokEnd; ++ThisTokBuf) {
224 if (Delimited && *ThisTokBuf ==
'}') {
226 EndDelimiterFound =
true;
229 int CharVal = llvm::hexDigitValue(*ThisTokBuf);
236 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
237 diag::err_delimited_escape_invalid)
238 << StringRef(ThisTokBuf, 1);
242 if (ResultChar & 0xF0000000)
245 ResultChar |= CharVal;
248 if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
250 ResultChar &= ~0
U >> (32-CharWidth);
254 if (!HadError && Overflow) {
257 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
258 diag::err_escape_too_large)
263 case '0':
case '1':
case '2':
case '3':
264 case '4':
case '5':
case '6':
case '7': {
272 unsigned NumDigits = 0;
275 ResultChar |= *ThisTokBuf++ -
'0';
277 }
while (ThisTokBuf != ThisTokEnd && NumDigits < 3 &&
278 ThisTokBuf[0] >=
'0' && ThisTokBuf[0] <=
'7');
281 if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
283 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
284 diag::err_escape_too_large) << 1;
285 ResultChar &= ~0
U >> (32-CharWidth);
290 bool Overflow =
false;
292 if (ThisTokBuf == ThisTokEnd || *ThisTokBuf !=
'{') {
295 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
296 diag::err_delimited_escape_missing_brace)
304 if (*ThisTokBuf ==
'}') {
307 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
308 diag::err_delimited_escape_empty);
311 while (ThisTokBuf != ThisTokEnd) {
312 if (*ThisTokBuf ==
'}') {
313 EndDelimiterFound =
true;
317 if (*ThisTokBuf <
'0' || *ThisTokBuf >
'7') {
320 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
321 diag::err_delimited_escape_invalid)
322 << StringRef(ThisTokBuf, 1);
327 if (ResultChar & 0xE0000000)
331 ResultChar |= *ThisTokBuf++ -
'0';
335 (Overflow || (CharWidth != 32 && (ResultChar >> CharWidth) != 0))) {
338 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
339 diag::err_escape_too_large)
341 ResultChar &= ~0
U >> (32 - CharWidth);
346 case '(':
case '{':
case '[':
case '%':
349 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
350 diag::ext_nonstandard_escape)
351 << std::string(1, ResultChar);
359 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
360 diag::ext_unknown_escape)
361 << std::string(1, ResultChar);
363 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
364 diag::ext_unknown_escape)
365 <<
"x" + llvm::utohexstr(ResultChar);
369 if (Delimited && Diags) {
370 if (!EndDelimiterFound)
371 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
374 else if (!HadError) {
382 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
383 diag::err_unevaluated_string_invalid_escape_sequence)
384 << StringRef(EscapeBegin, ThisTokBuf - EscapeBegin);
389 Transcode && Converter) {
392 static_cast<unsigned>(std::numeric_limits<char>::max()));
393 char ByteChar =
Invalid ?
'?' : ResultChar;
396 ResultChar = *ErrorOrChar;
398 Diag(Diags, Features, Loc, ThisTokBegin, EscapeBegin, ThisTokBuf,
399 diag::err_exec_charset_conversion_failed)
400 << ErrorOrChar.getError().message();
410 char *ResultPtr = ResultBuf;
411 if (llvm::ConvertCodePointToUTF8(Codepoint, ResultPtr))
412 Str.append(ResultBuf, ResultPtr);
416 for (StringRef::iterator I = Input.begin(), E = Input.end(); I != E; ++I) {
426 assert(Kind ==
'u' || Kind ==
'U' || Kind ==
'N');
427 uint32_t CodePoint = 0;
429 if (Kind ==
'u' && *I ==
'{') {
430 for (++I; *I !=
'}'; ++I) {
431 unsigned Value = llvm::hexDigitValue(*I);
432 assert(
Value != -1U);
443 auto Delim = std::find(I, Input.end(),
'}');
444 assert(Delim != Input.end());
445 StringRef Name(I, std::distance(I, Delim));
446 std::optional<llvm::sys::unicode::LooseMatchingResult> Res =
447 llvm::sys::unicode::nameToCodepointLooseMatching(Name);
448 assert(Res &&
"could not find a codepoint that was previously found");
449 CodePoint = Res->CodePoint;
450 assert(CodePoint != 0xFFFFFFFF);
456 unsigned NumHexDigits;
462 assert(I + NumHexDigits <= E);
464 for (; NumHexDigits != 0; ++I, --NumHexDigits) {
465 unsigned Value = llvm::hexDigitValue(*I);
466 assert(
Value != -1U);
479 return LO.MicrosoftExt &&
480 (K == tok::kw___FUNCTION__ || K == tok::kw_L__FUNCTION__ ||
481 K == tok::kw___FUNCSIG__ || K == tok::kw_L__FUNCSIG__ ||
482 K == tok::kw___FUNCDNAME__);
491 const char *&ThisTokBuf,
492 const char *ThisTokEnd,
uint32_t &UcnVal,
493 unsigned short &UcnLen,
bool &Delimited,
496 bool in_char_string_literal =
false) {
497 const char *UcnBegin = ThisTokBuf;
498 bool HasError =
false;
499 bool EndDelimiterFound =
false;
504 if (UcnBegin[1] ==
'u' && in_char_string_literal &&
505 ThisTokBuf != ThisTokEnd && *ThisTokBuf ==
'{') {
508 }
else if (ThisTokBuf == ThisTokEnd || !
isHexDigit(*ThisTokBuf)) {
510 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
511 diag::err_hex_escape_no_digits)
512 << StringRef(&ThisTokBuf[-1], 1);
515 UcnLen = (ThisTokBuf[-1] ==
'u' ? 4 : 8);
517 bool Overflow =
false;
518 unsigned short Count = 0;
519 for (; ThisTokBuf != ThisTokEnd && (Delimited || Count != UcnLen);
521 if (Delimited && *ThisTokBuf ==
'}') {
523 EndDelimiterFound =
true;
526 int CharVal = llvm::hexDigitValue(*ThisTokBuf);
532 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
533 diag::err_delimited_escape_invalid)
534 << StringRef(ThisTokBuf, 1);
539 if (UcnVal & 0xF0000000) {
550 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
551 diag::err_escape_too_large)
556 if (Delimited && !EndDelimiterFound) {
558 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
566 if (Count == 0 || (!Delimited && Count != UcnLen)) {
568 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
569 Delimited ? diag::err_delimited_escape_empty
570 : diag::err_ucn_escape_incomplete);
577 return (
C >=
'A' &&
C <=
'Z') || (
C >=
'0' &&
C <=
'9') ||
C ==
'-' ||
583 const char *TokBegin,
const char *TokRangeBegin,
const char *TokRangeEnd,
584 llvm::StringRef Name) {
586 Diag(Diags, Features, Loc, TokBegin, TokRangeBegin, TokRangeEnd,
587 diag::err_invalid_ucn_name)
590 namespace u = llvm::sys::unicode;
592 bool HasIllegalCharacter =
false;
593 for (
const char *P = Name.begin(), *E = Name.end(); P != E;) {
599 Loc, (TokRangeBegin - TokBegin) + (P - Name.begin()), Loc.
getManager(),
601 Diags->
Report(CharLoc, diag::note_invalid_ucn_name_character)
603 StringRef(P, std::distance(P, E)));
604 HasIllegalCharacter =
true;
608 std::optional<u::LooseMatchingResult> Res =
609 u::nameToCodepointLooseMatching(Name);
611 Diag(Diags, Features, Loc, TokBegin, TokRangeBegin, TokRangeEnd,
612 diag::note_invalid_ucn_name_loose_matching)
623 if (HasIllegalCharacter)
626 unsigned Distance = 0;
628 u::nearestMatchesForCodepointName(Name, 5);
629 assert(!Matches.empty() &&
"No unicode characters found");
631 for (
const auto &
Match : Matches) {
633 Distance =
Match.Distance;
634 if (std::max(Distance,
Match.Distance) -
635 std::min(Distance,
Match.Distance) >
638 Distance =
Match.Distance;
639 Diag(Diags, Features, Loc, TokBegin, TokRangeBegin, TokRangeEnd,
640 diag::note_invalid_ucn_name_candidate)
650 const char *&ThisTokBuf,
651 const char *ThisTokEnd,
uint32_t &UcnVal,
655 const char *UcnBegin = ThisTokBuf;
656 assert(UcnBegin[0] ==
'\\' && UcnBegin[1] ==
'N');
658 if (ThisTokBuf == ThisTokEnd || *ThisTokBuf !=
'{') {
660 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
661 diag::err_delimited_escape_missing_brace)
662 << StringRef(&ThisTokBuf[-1], 1);
667 const char *ClosingBrace = std::find_if(ThisTokBuf, ThisTokEnd, [](
char C) {
671 bool Empty = ClosingBrace == ThisTokBuf;
674 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
676 : diag::err_delimited_escape_empty)
677 << StringRef(&UcnBegin[1], 1);
679 ThisTokBuf = ClosingBrace == ThisTokEnd ? ClosingBrace : ClosingBrace + 1;
682 StringRef Name(ThisTokBuf, ClosingBrace - ThisTokBuf);
683 ThisTokBuf = ClosingBrace + 1;
684 std::optional<char32_t> Res = llvm::sys::unicode::nameToCodepointStrict(Name);
688 &UcnBegin[3], ClosingBrace, Name);
692 UcnLen = UcnVal > 0xFFFF ? 8 : 4;
699 const char *ThisTokEnd,
uint32_t &UcnVal,
703 bool in_char_string_literal =
false) {
706 const char *UcnBegin = ThisTokBuf;
707 bool IsDelimitedEscapeSequence =
false;
708 bool IsNamedEscapeSequence =
false;
709 if (ThisTokBuf[1] ==
'N') {
710 IsNamedEscapeSequence =
true;
712 UcnVal, UcnLen, Loc, Diags, Features);
716 UcnLen, IsDelimitedEscapeSequence, Loc, Diags,
717 Features, in_char_string_literal);
723 if ((0xD800 <= UcnVal && UcnVal <= 0xDFFF) ||
726 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
727 diag::err_ucn_escape_invalid);
735 (UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60)) {
737 (!(Features.CPlusPlus11 || Features.C23) || !in_char_string_literal);
739 char BasicSCSChar = UcnVal;
740 if (UcnVal >= 0x20 && UcnVal < 0x7f)
741 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
742 IsError ? diag::err_ucn_escape_basic_scs
744 ? diag::warn_cxx98_compat_literal_ucn_escape_basic_scs
745 : diag::warn_c23_compat_literal_ucn_escape_basic_scs)
746 << StringRef(&BasicSCSChar, 1);
748 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
749 IsError ? diag::err_ucn_control_character
751 ? diag::warn_cxx98_compat_literal_ucn_control_character
752 : diag::warn_c23_compat_literal_ucn_control_character);
758 if (!Features.CPlusPlus && !Features.C99 && Diags)
759 Diag(Diags, Features, Loc, ThisTokBegin, UcnBegin, ThisTokBuf,
760 diag::warn_ucn_not_valid_in_c89_literal);
762 if ((IsDelimitedEscapeSequence || IsNamedEscapeSequence) && Diags)
771 const char *ThisTokEnd,
unsigned CharByteWidth,
774 if (CharByteWidth == 4)
778 unsigned short UcnLen = 0;
782 UcnLen, Loc,
nullptr, Features,
true)) {
788 if (CharByteWidth == 2)
789 return UcnVal <= 0xFFFF ? 2 : 4;
796 if (UcnVal < 0x10000)
806 const char *ThisTokEnd,
char *&ResultBuf,
810 llvm::TextEncodingConverter *Converter) {
813 unsigned short UcnLen = 0;
815 Loc, Diags, Features,
true)) {
820 assert((CharByteWidth == 1 || CharByteWidth == 2 || CharByteWidth == 4) &&
821 "only character widths of 1, 2, or 4 bytes supported");
824 assert((UcnLen== 4 || UcnLen== 8) &&
"only ucn length of 4 or 8 supported");
826 if (CharByteWidth == 4) {
829 llvm::UTF32 *ResultPtr =
reinterpret_cast<llvm::UTF32*
>(ResultBuf);
835 if (CharByteWidth == 2) {
838 llvm::UTF16 *ResultPtr =
reinterpret_cast<llvm::UTF16*
>(ResultBuf);
840 if (UcnVal <= (
UTF32)0xFFFF) {
848 *ResultPtr = 0xD800 + (UcnVal >> 10);
849 *(ResultPtr+1) = 0xDC00 + (UcnVal & 0x3FF);
854 assert(CharByteWidth == 1 &&
"UTF-8 encoding is only for 1 byte characters");
862 unsigned short bytesToWrite = 0;
863 if (UcnVal < (
UTF32)0x80)
865 else if (UcnVal < (
UTF32)0x800)
867 else if (UcnVal < (
UTF32)0x10000)
872 const unsigned byteMask = 0xBF;
873 const unsigned byteMark = 0x80;
877 static const UTF8 firstByteMark[5] = {
878 0x00, 0x00, 0xC0, 0xE0, 0xF0
881 ResultBuf += bytesToWrite;
882 switch (bytesToWrite) {
884 *--ResultBuf = (
UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
887 *--ResultBuf = (
UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
890 *--ResultBuf = (
UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
893 *--ResultBuf = (
UTF8) (UcnVal | firstByteMark[bytesToWrite]);
896 ResultBuf += bytesToWrite;
900 char *Cp = ResultBuf - bytesToWrite;
901 auto EC = Converter->convert(StringRef(Cp, bytesToWrite), CpConv);
903 memcpy(Cp, CpConv.data(), CpConv.size());
904 ResultBuf = Cp + CpConv.size();
906 Diags->
Report(Loc, diag::err_exec_charset_conversion_failed)
970 : SM(SM), LangOpts(LangOpts), Diags(Diags),
971 ThisTokBegin(TokSpelling.begin()), ThisTokEnd(TokSpelling.end()) {
973 s = DigitsBegin = ThisTokBegin;
974 saw_exponent =
false;
976 saw_ud_suffix =
false;
977 saw_fixed_point_suffix =
false;
1001 !(LangOpts.HLSL && *ThisTokEnd ==
'.')) {
1002 Diags.Report(TokLoc, diag::err_lexing_numeric);
1008 ParseNumberStartingWithZero(TokLoc);
1014 if (s == ThisTokEnd) {
1017 ParseDecimalOrOctalCommon(TokLoc);
1024 checkSeparator(TokLoc, s, CSK_AfterDigits);
1027 if (LangOpts.FixedPoint) {
1028 for (
const char *c = s; c != ThisTokEnd; ++c) {
1029 if (*c ==
'r' || *c ==
'k' || *c ==
'R' || *c ==
'K') {
1030 saw_fixed_point_suffix =
true;
1040 bool HasSize =
false;
1041 bool DoubleUnderscore =
false;
1045 for (; s != ThisTokEnd; ++s) {
1049 if (!LangOpts.FixedPoint)
1052 if (!(saw_period || saw_exponent))
break;
1057 if (!LangOpts.FixedPoint)
1060 if (!(saw_period || saw_exponent))
break;
1066 if (!(LangOpts.Half || LangOpts.FixedPoint))
1076 if (!isFPConstant)
break;
1087 if ((
Target.hasFloat16Type() || LangOpts.CUDA ||
1088 (LangOpts.OpenMPIsTargetDevice &&
Target.getTriple().isNVPTX())) &&
1089 s + 2 < ThisTokEnd && s[1] ==
'1' && s[2] ==
'6') {
1099 if (!isFPConstant)
break;
1107 if (isFPConstant)
break;
1119 assert(s + 1 < ThisTokEnd &&
"didn't maximally munch?");
1120 if (isFPConstant)
break;
1138 if (LangOpts.MicrosoftExt && s + 1 < ThisTokEnd && !isFPConstant) {
1149 if (s + 2 < ThisTokEnd && s[2] ==
'6') {
1152 }
else if (s + 3 < ThisTokEnd && s[2] ==
'2' &&
1159 if (s + 2 < ThisTokEnd && s[2] ==
'2') {
1165 if (s + 2 < ThisTokEnd && s[2] ==
'4') {
1179 assert(s <= ThisTokEnd &&
"didn't maximally munch?");
1196 assert(!DoubleUnderscore &&
"unhandled double underscore case");
1197 if (LangOpts.CPlusPlus && s + 2 < ThisTokEnd &&
1200 DoubleUnderscore =
true;
1202 if (s + 1 < ThisTokEnd &&
1203 (*s ==
'u' || *s ==
'U')) {
1207 if (s + 1 < ThisTokEnd &&
1208 ((*s ==
'w' && *(++s) ==
'b') || (*s ==
'W' && *(++s) ==
'B'))) {
1226 if ((!LangOpts.CPlusPlus || DoubleUnderscore) && s + 1 < ThisTokEnd &&
1227 ((s[0] ==
'w' && s[1] ==
'b') || (s[0] ==
'W' && s[1] ==
'B'))) {
1241 expandUCNs(UDSuffixBuf, StringRef(SuffixBegin, ThisTokEnd - SuffixBegin));
1256 saw_fixed_point_suffix =
false;
1261 saw_ud_suffix =
true;
1265 if (s != ThisTokEnd) {
1268 TokLoc, SuffixBegin - ThisTokBegin, SM, LangOpts),
1269 diag::err_invalid_suffix_constant)
1270 << StringRef(SuffixBegin, ThisTokEnd - SuffixBegin)
1271 << (isFixedPointConstant ? 2 : isFPConstant);
1276 if (!
hadError && saw_fixed_point_suffix) {
1284void NumericLiteralParser::ParseDecimalOrOctalCommon(
SourceLocation TokLoc){
1285 assert((radix == 8 || radix == 10) &&
"Unexpected radix");
1289 if (
isHexDigit(*s) && *s !=
'e' && *s !=
'E' &&
1293 diag::err_invalid_digit)
1294 << StringRef(s, 1) << (radix == 8 ? 1 : 0);
1300 checkSeparator(TokLoc, s, CSK_AfterDigits);
1304 checkSeparator(TokLoc, s, CSK_BeforeDigits);
1307 if (*s ==
'e' || *s ==
'E') {
1308 checkSeparator(TokLoc, s, CSK_AfterDigits);
1309 const char *Exponent = s;
1312 saw_exponent =
true;
1313 if (s != ThisTokEnd && (*s ==
'+' || *s ==
'-')) s++;
1314 const char *first_non_digit = SkipDigits(s);
1315 if (containsDigits(s, first_non_digit)) {
1316 checkSeparator(TokLoc, s, CSK_BeforeDigits);
1317 s = first_non_digit;
1321 TokLoc, Exponent - ThisTokBegin, SM, LangOpts),
1322 diag::err_exponent_has_no_digits);
1335 if (!LangOpts.CPlusPlus11 || Suffix.empty())
1341 if (Suffix.starts_with(
"_") && !Suffix.starts_with(
"__"))
1345 if (!LangOpts.CPlusPlus14)
1351 return llvm::StringSwitch<bool>(Suffix)
1352 .Cases({
"h",
"min",
"s"},
true)
1353 .Cases({
"ms",
"us",
"ns"},
true)
1354 .Cases({
"il",
"i",
"if"},
true)
1355 .Cases({
"d",
"y"}, LangOpts.CPlusPlus20)
1361 CheckSeparatorKind IsAfterDigits) {
1362 if (IsAfterDigits == CSK_AfterDigits) {
1363 if (Pos == ThisTokBegin)
1366 }
else if (Pos == ThisTokEnd)
1369 if (isDigitSeparator(*Pos)) {
1372 diag::err_digit_separator_not_between_digits)
1383void NumericLiteralParser::ParseNumberStartingWithZero(
SourceLocation TokLoc) {
1384 assert(s[0] ==
'0' &&
"Invalid method call");
1390 if ((c1 ==
'x' || c1 ==
'X') && (
isHexDigit(s[1]) || s[1] ==
'.')) {
1392 assert(s < ThisTokEnd &&
"didn't maximally munch?");
1395 s = SkipHexDigits(s);
1396 bool HasSignificandDigits = containsDigits(DigitsBegin, s);
1397 if (s == ThisTokEnd) {
1399 }
else if (*s ==
'.') {
1402 const char *floatDigitsBegin = s;
1403 s = SkipHexDigits(s);
1404 if (containsDigits(floatDigitsBegin, s))
1405 HasSignificandDigits =
true;
1406 if (HasSignificandDigits)
1407 checkSeparator(TokLoc, floatDigitsBegin, CSK_BeforeDigits);
1410 if (!HasSignificandDigits) {
1413 diag::err_hex_constant_requires)
1414 << LangOpts.CPlusPlus << 1;
1421 if (*s ==
'p' || *s ==
'P') {
1422 checkSeparator(TokLoc, s, CSK_AfterDigits);
1423 const char *Exponent = s;
1425 saw_exponent =
true;
1426 if (s != ThisTokEnd && (*s ==
'+' || *s ==
'-')) s++;
1427 const char *first_non_digit = SkipDigits(s);
1428 if (!containsDigits(s, first_non_digit)) {
1431 TokLoc, Exponent - ThisTokBegin, SM, LangOpts),
1432 diag::err_exponent_has_no_digits);
1437 checkSeparator(TokLoc, s, CSK_BeforeDigits);
1438 s = first_non_digit;
1440 if (!LangOpts.HexFloats)
1441 Diags.Report(TokLoc, LangOpts.CPlusPlus
1442 ? diag::ext_hex_literal_invalid
1443 : diag::ext_hex_constant_invalid);
1444 else if (LangOpts.CPlusPlus17)
1445 Diags.Report(TokLoc, diag::warn_cxx17_hex_literal);
1446 }
else if (saw_period) {
1449 diag::err_hex_constant_requires)
1450 << LangOpts.CPlusPlus << 0;
1457 if ((c1 ==
'b' || c1 ==
'B') && (s[1] ==
'0' || s[1] ==
'1')) {
1460 if (LangOpts.CPlusPlus14)
1461 DiagId = diag::warn_cxx11_compat_binary_literal;
1462 else if (LangOpts.C23)
1463 DiagId = diag::warn_c23_compat_binary_literal;
1464 else if (LangOpts.CPlusPlus)
1465 DiagId = diag::ext_binary_literal_cxx14;
1467 DiagId = diag::ext_binary_literal;
1468 Diags.Report(TokLoc, DiagId);
1470 assert(s < ThisTokEnd &&
"didn't maximally munch?");
1473 s = SkipBinaryDigits(s);
1474 if (s == ThisTokEnd) {
1480 diag::err_invalid_digit)
1481 << StringRef(s, 1) << 2;
1489 bool IsSingleZero =
false;
1490 if ((c1 ==
'O' || c1 ==
'o') && (s[1] >=
'0' && s[1] <=
'7')) {
1493 DiagId = diag::warn_c2y_compat_octal_literal;
1494 else if (LangOpts.CPlusPlus)
1495 DiagId = diag::ext_cpp_octal_literal;
1497 DiagId = diag::ext_octal_literal;
1504 if (!SM.isInSystemMacro(TokLoc))
1505 Diags.Report(TokLoc, DiagId);
1510 s = SkipOctalDigits(s);
1511 if (s == ThisTokEnd) {
1513 }
else if ((
isHexDigit(*s) && *s !=
'e' && *s !=
'E' && *s !=
'.') &&
1516 TokLoc, s - ThisTokBegin, SM, LangOpts);
1517 Diags.Report(InvalidDigitLoc, diag::err_invalid_digit)
1518 << StringRef(s, 1) << 1;
1525 llvm::scope_exit _([&] {
1530 if (radix == 8 && LangOpts.C2y && !
hadError && !IsSingleZero &&
1531 !SM.isInSystemMacro(TokLoc))
1532 Diags.Report(TokLoc, diag::warn_unprefixed_octal_deprecated);
1539 const char *PossibleNewDigitStart = s;
1540 s = SkipOctalDigits(s);
1544 if (s != PossibleNewDigitStart)
1545 DigitsBegin = PossibleNewDigitStart;
1547 IsSingleZero = (s == ThisTokBegin + 1);
1549 if (s == ThisTokEnd)
1555 const char *EndDecimal = SkipDigits(s);
1556 if (EndDecimal[0] ==
'.' || EndDecimal[0] ==
'e' || EndDecimal[0] ==
'E') {
1562 ParseDecimalOrOctalCommon(TokLoc);
1568 return NumDigits <= 64;
1570 return NumDigits <= 64 / 3;
1572 return NumDigits <= 19;
1574 return NumDigits <= 64 / 4;
1576 llvm_unreachable(
"impossible Radix");
1590 const unsigned NumDigits = SuffixBegin - DigitsBegin;
1593 for (
const char *Ptr = DigitsBegin; Ptr != SuffixBegin; ++Ptr)
1594 if (!isDigitSeparator(*Ptr))
1595 N = N * radix + llvm::hexDigitValue(*Ptr);
1600 return Val.getZExtValue() != N;
1604 const char *Ptr = DigitsBegin;
1606 llvm::APInt RadixVal(Val.getBitWidth(), radix);
1607 llvm::APInt CharVal(Val.getBitWidth(), 0);
1608 llvm::APInt OldVal = Val;
1610 bool OverflowOccurred =
false;
1611 while (Ptr < SuffixBegin) {
1612 if (isDigitSeparator(*Ptr)) {
1617 unsigned C = llvm::hexDigitValue(*Ptr++);
1620 assert(
C < radix &&
"NumericLiteralParser ctor should have rejected this");
1630 OverflowOccurred |= Val.udiv(RadixVal) != OldVal;
1635 OverflowOccurred |= Val.ult(CharVal);
1637 return OverflowOccurred;
1640llvm::APFloat::opStatus
1642 llvm::RoundingMode RM) {
1643 using llvm::APFloat;
1645 unsigned n = std::min(SuffixBegin - ThisTokBegin, ThisTokEnd - ThisTokBegin);
1648 StringRef Str(ThisTokBegin, n);
1649 if (Str.contains(
'\'')) {
1651 std::remove_copy_if(Str.begin(), Str.end(), std::back_inserter(Buffer),
1656 auto StatusOrErr =
Result.convertFromString(Str, RM);
1657 assert(StatusOrErr &&
"Invalid floating point representation");
1658 return !errorToBool(StatusOrErr.takeError()) ? *StatusOrErr
1659 : APFloat::opInvalidOp;
1664 return c ==
'p' || c ==
'P';
1665 return c ==
'e' || c ==
'E';
1669 assert(radix == 16 || radix == 10);
1672 unsigned NumDigits = SuffixBegin - DigitsBegin;
1673 if (saw_period) --NumDigits;
1676 bool ExpOverflowOccurred =
false;
1677 bool NegativeExponent =
false;
1678 const char *ExponentBegin;
1679 uint64_t Exponent = 0;
1680 int64_t BaseShift = 0;
1682 const char *Ptr = DigitsBegin;
1686 ExponentBegin = Ptr;
1688 NegativeExponent = *Ptr ==
'-';
1689 if (NegativeExponent) ++Ptr;
1691 unsigned NumExpDigits = SuffixBegin - Ptr;
1693 llvm::StringRef ExpStr(Ptr, NumExpDigits);
1694 llvm::APInt ExpInt(64, ExpStr, 10);
1695 Exponent = ExpInt.getZExtValue();
1697 ExpOverflowOccurred =
true;
1700 if (NegativeExponent) BaseShift -= Exponent;
1701 else BaseShift += Exponent;
1721 uint64_t NumBitsNeeded;
1723 NumBitsNeeded = 4 * (NumDigits + Exponent) + Scale;
1725 NumBitsNeeded = 4 * NumDigits + Exponent + Scale;
1727 if (NumBitsNeeded > std::numeric_limits<unsigned>::max())
1728 ExpOverflowOccurred =
true;
1729 llvm::APInt Val(
static_cast<unsigned>(NumBitsNeeded), 0,
false);
1731 bool FoundDecimal =
false;
1733 int64_t FractBaseShift = 0;
1734 const char *End = saw_exponent ? ExponentBegin : SuffixBegin;
1735 for (
const char *Ptr = DigitsBegin; Ptr < End; ++Ptr) {
1737 FoundDecimal =
true;
1742 unsigned C = llvm::hexDigitValue(*Ptr);
1743 assert(
C < radix &&
"NumericLiteralParser ctor should have rejected this");
1755 if (radix == 16) FractBaseShift *= 4;
1756 BaseShift += FractBaseShift;
1760 uint64_t
Base = (radix == 16) ? 2 : 10;
1761 if (BaseShift > 0) {
1762 for (int64_t i = 0; i < BaseShift; ++i) {
1765 }
else if (BaseShift < 0) {
1766 for (int64_t i = BaseShift; i < 0 && !Val.isZero(); ++i)
1767 Val = Val.udiv(
Base);
1770 bool IntOverflowOccurred =
false;
1771 auto MaxVal = llvm::APInt::getMaxValue(StoreVal.getBitWidth());
1772 if (Val.getBitWidth() > StoreVal.getBitWidth()) {
1773 IntOverflowOccurred |= Val.ugt(MaxVal.zext(Val.getBitWidth()));
1774 StoreVal = Val.trunc(StoreVal.getBitWidth());
1775 }
else if (Val.getBitWidth() < StoreVal.getBitWidth()) {
1776 IntOverflowOccurred |= Val.zext(MaxVal.getBitWidth()).ugt(MaxVal);
1777 StoreVal = Val.zext(StoreVal.getBitWidth());
1779 StoreVal = std::move(Val);
1782 return IntOverflowOccurred || ExpOverflowOccurred;
1832 const char *TokBegin = begin;
1835 if (Kind != tok::char_constant)
1837 if (Kind == tok::utf8_char_constant)
1841 if (begin[0] !=
'\'') {
1842 PP.
Diag(Loc, diag::err_lexing_char);
1850 if (end[-1] !=
'\'') {
1851 const char *UDSuffixEnd = end;
1854 }
while (end[-1] !=
'\'');
1856 expandUCNs(UDSuffixBuf, StringRef(end, UDSuffixEnd - end));
1857 UDSuffixOffset = end - TokBegin;
1861 assert(end != begin &&
"Invalid token lexed");
1868 "Assumes char is 8 bits");
1871 "Assumes sizeof(int) on target is <= 64 and a multiple of char");
1873 "Assumes sizeof(wchar) on target is <= 64");
1876 codepoint_buffer.resize(end - begin);
1877 uint32_t *buffer_begin = &codepoint_buffer.front();
1878 uint32_t *buffer_end = buffer_begin + codepoint_buffer.size();
1881 llvm::TextEncodingConverter *Converter =
nullptr;
1888 uint32_t largest_character_for_kind;
1889 if (tok::wide_char_constant == Kind) {
1890 largest_character_for_kind =
1892 }
else if (tok::utf8_char_constant == Kind) {
1893 largest_character_for_kind = 0x7F;
1894 }
else if (tok::utf16_char_constant == Kind) {
1895 largest_character_for_kind = 0xFFFF;
1896 }
else if (tok::utf32_char_constant == Kind) {
1897 largest_character_for_kind = 0x10FFFF;
1899 largest_character_for_kind = (Converter ==
nullptr) ? 0x7Fu : 0xFFu;
1902 while (begin != end) {
1904 if (begin[0] !=
'\\') {
1905 char const *start = begin;
1908 }
while (begin != end && *begin !=
'\\');
1910 char const *tmp_in_start = start;
1911 uint32_t *tmp_out_start = buffer_begin;
1912 std::string UTF8String(start, begin);
1913 llvm::ConversionResult res =
1914 llvm::ConvertUTF8toUTF32(
reinterpret_cast<llvm::UTF8
const **
>(&start),
1915 reinterpret_cast<llvm::UTF8
const *
>(begin),
1916 &buffer_begin, buffer_end, llvm::strictConversion);
1917 if (res != llvm::conversionOK) {
1922 unsigned Msg = diag::err_bad_character_encoding;
1923 if (NoErrorOnBadEncoding)
1924 Msg = diag::warn_bad_character_encoding;
1926 if (NoErrorOnBadEncoding) {
1927 start = tmp_in_start;
1928 buffer_begin = tmp_out_start;
1929 for (; start != begin; ++start, ++buffer_begin)
1930 *buffer_begin =
static_cast<uint8_t
>(*start);
1935 uint32_t *validation_ptr = tmp_out_start;
1936 for (; validation_ptr < buffer_begin; ++validation_ptr) {
1937 if (*validation_ptr > largest_character_for_kind) {
1939 PP.
Diag(Loc, diag::err_character_too_large);
1944 if (!HadError && Converter) {
1945 assert(
isOrdinary() &&
"Only ordinary characters are supported");
1947 auto ErrorOrChar = Converter->convert(UTF8String, Converted);
1949 for (
int i = 0; tmp_out_start < buffer_begin;
1950 ++tmp_out_start, ++i) {
1951 *tmp_out_start = Converted[i];
1955 PP.
Diag(Loc, diag::err_exec_charset_conversion_failed)
1956 << ErrorOrChar.message();
1964 if (begin[1] ==
'u' || begin[1] ==
'U' || begin[1] ==
'N') {
1965 if (Converter ==
nullptr) {
1966 unsigned short UcnLen = 0;
1971 }
else if (*buffer_begin > largest_character_for_kind) {
1973 PP.
Diag(Loc, diag::err_character_too_large);
1977 char *ResultPtr = Cp;
1983 *buffer_begin = *Cp;
1994 *buffer_begin++ = result;
1997 unsigned NumCharsSoFar = buffer_begin - &codepoint_buffer.front();
1999 if (NumCharsSoFar > 1) {
2001 PP.
Diag(Loc, diag::warn_four_char_character_literal);
2003 PP.
Diag(Loc, diag::warn_multichar_character_literal);
2005 PP.
Diag(Loc, diag::err_multichar_character_literal) << (
isWide() ? 0 : 1);
2010 IsMultiChar =
false;
2017 bool multi_char_too_long =
false;
2020 for (
size_t i = 0; i < NumCharsSoFar; ++i) {
2022 multi_char_too_long |= (LitVal.countl_zero() < 8);
2024 LitVal = LitVal + (codepoint_buffer[i] & 0xFF);
2026 }
else if (NumCharsSoFar > 0) {
2028 LitVal = buffer_begin[-1];
2031 if (!HadError && multi_char_too_long) {
2032 PP.
Diag(Loc, diag::warn_char_constant_too_large);
2036 Value = LitVal.getZExtValue();
2042 if (
isOrdinary() && NumCharsSoFar == 1 && (Value & 128) &&
2044 Value = (
signed char)Value;
2105 : SM(PP.getSourceManager()), Features(PP.getLangOpts()),
2106 Target(PP.getTargetInfo()), Diags(&PP.getDiagnostics()),
2107 TE(&PP.getTextEncoding()), MaxTokenLength(0), SizeBound(0),
2108 CharByteWidth(0), Kind(
tok::unknown), ResultPtr(ResultBuf.data()),
2110 init(StringToks, Action);
2117 if (StringToks.empty() || StringToks[0].getLength() < 2)
2124 assert(!StringToks.empty() &&
"expected at least one token");
2125 MaxTokenLength = StringToks[0].getLength();
2126 assert(StringToks[0].getLength() >= 2 &&
"literal token is invalid!");
2127 SizeBound = StringToks[0].getLength() - 2;
2131 Kind = tok::string_literal;
2134 for (
const Token &
Tok : StringToks) {
2135 if (
Tok.getLength() < 2)
2136 return DiagnoseLexingError(
Tok.getLocation());
2140 assert(
Tok.getLength() >= 2 &&
"literal token is invalid!");
2141 SizeBound +=
Tok.getLength() - 2;
2144 if (
Tok.getLength() > MaxTokenLength)
2145 MaxTokenLength =
Tok.getLength();
2156 StringRef Prefix(
SM.getCharacterData(
Tok.getLocation()),
2159 Features.CPlusPlus26
2160 ? diag::err_unevaluated_string_prefix
2161 : diag::warn_unevaluated_string_prefix)
2164 if (Features.CPlusPlus26)
2171 Diags->Report(
Tok.
getLocation(), diag::err_unsupported_string_concat);
2184 assert((CharByteWidth & 7) == 0 &&
"Assumes character size is byte multiple");
2189 SizeBound *= CharByteWidth;
2192 ResultBuf.resize(SizeBound);
2195 SmallString<512> TokenBuf;
2196 TokenBuf.resize(MaxTokenLength);
2200 ResultPtr = &ResultBuf[0];
2204 SourceLocation UDSuffixTokLoc;
2206 llvm::TextEncodingConverter *Converter =
nullptr;
2208 Converter = TE->getConverter(Action);
2210 for (
unsigned i = 0, e = StringToks.size(); i != e; ++i) {
2211 const char *ThisTokBuf = &TokenBuf[0];
2215 bool StringInvalid =
false;
2216 unsigned ThisTokLen =
2220 return DiagnoseLexingError(StringToks[i].getLocation());
2222 const char *ThisTokBegin = ThisTokBuf;
2223 const char *ThisTokEnd = ThisTokBuf+ThisTokLen;
2226 if (ThisTokEnd[-1] !=
'"') {
2227 const char *UDSuffixEnd = ThisTokEnd;
2230 }
while (ThisTokEnd[-1] !=
'"');
2232 StringRef UDSuffix(ThisTokEnd, UDSuffixEnd - ThisTokEnd);
2234 if (UDSuffixBuf.empty()) {
2235 if (StringToks[i].hasUCN())
2238 UDSuffixBuf.assign(UDSuffix);
2240 UDSuffixOffset = ThisTokEnd - ThisTokBuf;
2241 UDSuffixTokLoc = StringToks[i].getLocation();
2243 SmallString<32> ExpandedUDSuffix;
2244 if (StringToks[i].hasUCN()) {
2246 UDSuffix = ExpandedUDSuffix;
2253 bool UnevaluatedStringHasUDL =
isUnevaluated() && !UDSuffix.empty();
2254 if (UDSuffixBuf != UDSuffix || UnevaluatedStringHasUDL) {
2256 SourceLocation TokLoc = StringToks[i].getLocation();
2257 if (UnevaluatedStringHasUDL) {
2258 Diags->Report(TokLoc, diag::err_unevaluated_string_udl)
2259 << SourceRange(TokLoc, TokLoc);
2261 Diags->Report(TokLoc, diag::err_string_concat_mixed_suffix)
2262 << UDSuffixBuf << UDSuffix
2263 << SourceRange(UDSuffixTokLoc, UDSuffixTokLoc);
2277 if (ThisTokBuf[0] ==
'L' || ThisTokBuf[0] ==
'u' || ThisTokBuf[0] ==
'U') {
2280 if (ThisTokBuf[0] ==
'8')
2285 if (ThisTokBuf[0] ==
'R') {
2286 if (ThisTokBuf[1] !=
'"') {
2289 return DiagnoseLexingError(StringToks[i].getLocation());
2295 constexpr unsigned MaxRawStrDelimLen = 16;
2297 const char *Prefix = ThisTokBuf;
2298 while (
static_cast<unsigned>(ThisTokBuf - Prefix) < MaxRawStrDelimLen &&
2299 ThisTokBuf[0] !=
'(')
2301 if (ThisTokBuf[0] !=
'(')
2302 return DiagnoseLexingError(StringToks[i].getLocation());
2306 ThisTokEnd -= ThisTokBuf - Prefix;
2307 if (ThisTokEnd < ThisTokBuf)
2308 return DiagnoseLexingError(StringToks[i].getLocation());
2312 StringRef RemainingTokenSpan(ThisTokBuf, ThisTokEnd - ThisTokBuf);
2313 while (!RemainingTokenSpan.empty()) {
2315 size_t CRLFPos = RemainingTokenSpan.find(
"\r\n");
2316 StringRef BeforeCRLF = RemainingTokenSpan.substr(0, CRLFPos);
2317 StringRef AfterCRLF = RemainingTokenSpan.substr(CRLFPos);
2320 if (CopyStringFragment(StringToks[i], ThisTokBegin, BeforeCRLF,
2326 RemainingTokenSpan = AfterCRLF.substr(1);
2329 if (ThisTokBuf[0] !=
'"') {
2332 return DiagnoseLexingError(StringToks[i].getLocation());
2338 ThisTokBuf + 1 != ThisTokEnd && ThisTokBuf[0] ==
'\\' &&
2339 ThisTokBuf[1] ==
'p') {
2350 while (ThisTokBuf != ThisTokEnd) {
2352 if (ThisTokBuf[0] !=
'\\') {
2353 const char *InStart = ThisTokBuf;
2356 }
while (ThisTokBuf != ThisTokEnd && ThisTokBuf[0] !=
'\\');
2359 if (CopyStringFragment(StringToks[i], ThisTokBegin,
2360 StringRef(InStart, ThisTokBuf - InStart),
2366 if (ThisTokBuf[1] ==
'u' || ThisTokBuf[1] ==
'U' ||
2367 ThisTokBuf[1] ==
'N') {
2370 FullSourceLoc(StringToks[i].getLocation(), SM),
2371 CharByteWidth, Diags, Features, Converter);
2376 ThisTokBegin, ThisTokBuf, ThisTokEnd,
hadError,
2377 FullSourceLoc(StringToks[i].getLocation(), SM), CharByteWidth * 8,
2378 Diags, Features, EvalMethod, Converter);
2380 if (CharByteWidth == 4) {
2383 llvm::UTF32 *ResultWidePtr =
reinterpret_cast<llvm::UTF32*
>(ResultPtr);
2384 *ResultWidePtr = ResultChar;
2386 }
else if (CharByteWidth == 2) {
2389 llvm::UTF16 *ResultWidePtr =
reinterpret_cast<llvm::UTF16*
>(ResultPtr);
2390 *ResultWidePtr = ResultChar & 0xFFFF;
2393 assert(CharByteWidth == 1 &&
"Unexpected char width");
2394 *ResultPtr++ = ResultChar & 0xFF;
2401 "Pascal string in unevaluated context");
2403 if (CharByteWidth == 4) {
2406 llvm::UTF32 *ResultWidePtr =
reinterpret_cast<llvm::UTF32*
>(ResultBuf.data());
2408 }
else if (CharByteWidth == 2) {
2411 llvm::UTF16 *ResultWidePtr =
reinterpret_cast<llvm::UTF16*
>(ResultBuf.data());
2414 assert(CharByteWidth == 1 &&
"Unexpected char width");
2421 Diags->Report(StringToks.front().getLocation(),
2422 diag::err_pascal_string_too_long)
2423 << SourceRange(StringToks.front().getLocation(),
2424 StringToks.back().getLocation());
2430 unsigned MaxChars = Features.CPlusPlus? 65536 : Features.C99 ? 4095 : 509;
2433 Diags->Report(StringToks.front().getLocation(),
2434 diag::ext_string_too_long)
2436 << (Features.CPlusPlus ? 2 : Features.C99 ? 1 : 0)
2437 << SourceRange(StringToks.front().getLocation(),
2438 StringToks.back().getLocation());
2445 End = Err + std::min<unsigned>(llvm::getNumBytesForUTF8(*Err), End-Err);
2446 while (++Err != End && (*Err & 0xC0) == 0x80)
2454bool StringLiteralParser::CopyStringFragment(
2455 const Token &
Tok,
const char *TokBegin, StringRef Fragment,
2456 llvm::TextEncodingConverter *Converter) {
2458 const llvm::UTF8 *ErrorPtrTmp;
2459 if (ConvertUTF8toWide(CharByteWidth, Fragment, ResultPtr, ErrorPtrTmp)) {
2461 assert(
isOrdinary() &&
"Only ordinary literals are supported");
2462 SmallString<64> CpConv;
2463 char *Cp = ResultPtr - Fragment.size();
2464 auto EC = Converter->convert(Fragment, CpConv);
2466 memcpy(Cp, CpConv.data(), CpConv.size());
2467 ResultPtr = Cp + CpConv.size();
2471 diag::err_exec_charset_conversion_failed)
2483 if (NoErrorOnBadEncoding) {
2484 memcpy(ResultPtr, Fragment.data(), Fragment.size());
2485 ResultPtr += Fragment.size();
2489 const char *ErrorPtr =
reinterpret_cast<const char *
>(ErrorPtrTmp);
2492 const DiagnosticBuilder &Builder =
2493 Diag(Diags, Features, SourceLoc, TokBegin,
2494 ErrorPtr,
resyncUTF8(ErrorPtr, Fragment.end()),
2495 NoErrorOnBadEncoding ? diag::warn_bad_string_encoding
2496 : diag::err_bad_string_encoding);
2498 const char *NextStart =
resyncUTF8(ErrorPtr, Fragment.end());
2499 StringRef NextFragment(NextStart, Fragment.end()-NextStart);
2502 SmallString<512> Dummy;
2503 Dummy.reserve(Fragment.size() * CharByteWidth);
2504 char *Ptr = Dummy.data();
2506 while (!ConvertUTF8toWide(CharByteWidth, NextFragment, Ptr, ErrorPtrTmp)) {
2507 const char *ErrorPtr =
reinterpret_cast<const char *
>(ErrorPtrTmp);
2508 NextStart =
resyncUTF8(ErrorPtr, Fragment.end());
2510 ErrorPtr, NextStart);
2511 NextFragment = StringRef(NextStart, Fragment.end()-NextStart);
2514 return !NoErrorOnBadEncoding;
2517void StringLiteralParser::DiagnoseLexingError(
SourceLocation Loc) {
2520 Diags->Report(Loc, diag::err_lexing_string);
2527 unsigned ByteNo)
const {
2530 SpellingBuffer.resize(
Tok.getLength());
2532 bool StringInvalid =
false;
2533 const char *SpellingPtr = &SpellingBuffer[0];
2539 const char *SpellingStart = SpellingPtr;
2540 const char *SpellingEnd = SpellingPtr+TokLen;
2543 if (SpellingPtr[0] ==
'u' && SpellingPtr[1] ==
'8')
2546 assert(SpellingPtr[0] !=
'L' && SpellingPtr[0] !=
'u' &&
2547 SpellingPtr[0] !=
'U' &&
"Doesn't handle wide or utf strings yet");
2550 if (SpellingPtr[0] ==
'R') {
2551 assert(SpellingPtr[1] ==
'"' &&
"Should be a raw string literal!");
2554 while (*SpellingPtr !=
'(') {
2556 assert(SpellingPtr < SpellingEnd &&
"Missing ( for raw string literal");
2560 return SpellingPtr - SpellingStart + ByteNo;
2564 assert(SpellingPtr[0] ==
'"' &&
"Should be a string literal!");
2569 assert(SpellingPtr < SpellingEnd &&
"Didn't find byte offset!");
2572 if (*SpellingPtr !=
'\\') {
2579 bool HadError =
false;
2580 if (SpellingPtr[1] ==
'u' || SpellingPtr[1] ==
'U' ||
2581 SpellingPtr[1] ==
'N') {
2582 const char *EscapePtr = SpellingPtr;
2584 1, Features, HadError);
2587 SpellingPtr = EscapePtr;
2598 assert(!HadError &&
"This method isn't valid on erroneous strings");
2601 return SpellingPtr-SpellingStart;
Defines the clang::LangOptions interface.
static bool 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)
ProcessUCNEscape - Read the Universal Character Name, check constraints and return the UTF32.
static CharSourceRange MakeCharSourceRange(const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd)
static const char * resyncUTF8(const char *Err, const char *End)
static int MeasureUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, const char *ThisTokEnd, unsigned CharByteWidth, const LangOptions &Features, bool &HadError)
MeasureUCNEscape - Determine the number of bytes within the resulting string which this UCN will occu...
static void appendCodePoint(unsigned Codepoint, llvm::SmallVectorImpl< char > &Str)
static unsigned getEncodingPrefixLen(tok::TokenKind kind)
static void DiagnoseInvalidUnicodeCharacterName(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc Loc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, llvm::StringRef Name)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool IsEscapeValidInUnevaluatedStringLiteral(char Escape)
static bool 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)
static bool allowedInCharacterName(char C)
static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, const char *ThisTokEnd, char *&ResultBuf, bool &HadError, FullSourceLoc Loc, unsigned CharByteWidth, DiagnosticsEngine *Diags, const LangOptions &Features, llvm::TextEncodingConverter *Converter)
EncodeUCNEscape - Read the Universal Character Name, check constraints and convert the UTF32 to UTF8 ...
static bool ProcessNamedUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, const char *ThisTokEnd, uint32_t &UcnVal, unsigned short &UcnLen, FullSourceLoc Loc, DiagnosticsEngine *Diags, const LangOptions &Features)
static llvm::ErrorOr< char > convertCharacter(StringRef Char, const llvm::TextEncodingConverter &Converter)
static unsigned ProcessCharEscape(const char *ThisTokBegin, const char *&ThisTokBuf, const char *ThisTokEnd, bool &HadError, FullSourceLoc Loc, unsigned CharWidth, DiagnosticsEngine *Diags, const LangOptions &Features, StringLiteralEvalMethod EvalMethod, llvm::TextEncodingConverter *Converter)
ProcessCharEscape - Parse a standard C escape sequence, which can occur in either a character or a st...
static bool IsExponentPart(char c, bool isHex)
static bool alwaysFitsInto64Bits(unsigned Radix, unsigned NumDigits)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Target Target
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
CharLiteralParser(const char *begin, const char *end, SourceLocation Loc, Preprocessor &PP, tok::TokenKind kind)
Represents a byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
A little helper class used to produce diagnostics.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
A SourceLocation and its associated SourceManager.
const SourceManager & getManager() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart, unsigned Characters, const SourceManager &SM, const LangOptions &LangOpts)
AdvanceToTokenCharacter - If the current SourceLocation specifies a location at the start of a token,...
static void DiagnoseDelimitedOrNamedEscapeSequence(SourceLocation Loc, bool Named, const LangOptions &Opts, DiagnosticsEngine &Diags)
Diagnose use of a delimited or named escape sequence.
static unsigned getSpelling(const Token &Tok, const char *&Buffer, const SourceManager &SourceMgr, const LangOptions &LangOpts, bool *Invalid=nullptr)
getSpelling - This method is used to get the spelling of a token into a preallocated buffer,...
NumericLiteralParser(StringRef TokSpelling, SourceLocation TokLoc, const SourceManager &SM, const LangOptions &LangOpts, const TargetInfo &Target, DiagnosticsEngine &Diags)
integer-constant: [C99 6.4.4.1] decimal-constant integer-suffix octal-constant integer-suffix hexadec...
bool isFixedPointLiteral() const
bool isFloatingLiteral() const
bool isIntegerLiteral() const
llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result, llvm::RoundingMode RM)
Convert this numeric literal to a floating value, using the specified APFloat fltSemantics (specifyin...
static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix)
Determine whether a suffix is a valid ud-suffix.
bool GetIntegerValue(llvm::APInt &Val)
GetIntegerValue - Convert this numeric literal value to an APInt that matches Val's input width.
bool GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale)
GetFixedPointValue - Convert this numeric literal value into a scaled integer that represents this va...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
SourceManager & getSourceManager() const
const TargetInfo & getTargetInfo() const
const LangOptions & getLangOpts() const
TextEncoding & getTextEncoding()
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const
getOffsetOfStringByte - This function returns the offset of the specified byte of the string data rep...
bool isUnevaluated() const
StringLiteralParser(ArrayRef< Token > StringToks, Preprocessor &PP, StringLiteralEvalMethod StringMethod=StringLiteralEvalMethod::Evaluated, ConversionAction Action=CA_NoConversion)
unsigned GetStringLength() const
static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix)
Determine whether a suffix is a valid ud-suffix.
unsigned GetNumStringChars() const
Exposes information about the current target.
unsigned getIntWidth() const
getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...
unsigned getWCharWidth() const
getWCharWidth/Align - Return the size of 'wchar_t' for this target, in bits.
unsigned getCharWidth() const
llvm::TextEncodingConverter * getConverter(ConversionAction Action) const
Token - This structure provides full information about a lexed token.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
tok::TokenKind getKind() const
bool isNot(tok::TokenKind K) const
Defines the clang::TargetInfo interface.
bool isStringLiteral(TokenKind K)
Return true if this is a C or C++ string-literal (or C++11 user-defined-string-literal) token.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
LLVM_READONLY bool isVerticalWhitespace(unsigned char c)
Returns true if this character is vertical ASCII whitespace: '\n', '\r'.
LLVM_READONLY bool isPrintable(unsigned char c)
Return true if this character is an ASCII printable character; that is, a character that should take ...
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
void expandUCNs(SmallVectorImpl< char > &Buf, StringRef Input)
Copy characters from Input to Buf, expanding any UCNs.
bool tokenIsLikeStringLiteral(const Token &Tok, const LangOptions &LO)
Return true if the token is a string literal, or a function local predefined macro,...
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
LLVM_READONLY bool isDigit(unsigned char c)
Return true if this character is an ASCII digit: [0-9].
bool isFunctionLocalStringLiteralMacro(tok::TokenKind K, const LangOptions &LO)
Return true if the token corresponds to a function local predefined macro, which expands to a string ...
LLVM_READONLY bool isPreprocessingNumberBody(unsigned char c)
Return true if this is the body character of a C preprocessing number, which is [a-zA-Z0-9_.
LLVM_READONLY bool isHexDigit(unsigned char c)
Return true if this character is an ASCII hex digit: [0-9a-fA-F].
SmallString< 16 > EscapeSingleCodepointForDiagnostic(StringRef Str)
Displays a single Unicode codepoint in U+NNNN notation, optionally prepending the quoted codepoint it...
@ Incomplete
Template argument deduction did not deduce a value for every template parameter.
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 uint32_t