Tell the string literal parser when it's not permitted to emit
diagnostics. That would be while we're parsing string literals for the
sole purpose of producing a diagnostic about them. Fixes
<rdar://problem/8026030>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104684 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index f425582..b73f236 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -34,7 +34,7 @@
static unsigned ProcessCharEscape(const char *&ThisTokBuf,
const char *ThisTokEnd, bool &HadError,
SourceLocation Loc, bool IsWide,
- Preprocessor &PP) {
+ Preprocessor &PP, bool Complain) {
// Skip the '\' char.
++ThisTokBuf;
@@ -54,11 +54,13 @@
ResultChar = 8;
break;
case 'e':
- PP.Diag(Loc, diag::ext_nonstandard_escape) << "e";
+ if (Complain)
+ PP.Diag(Loc, diag::ext_nonstandard_escape) << "e";
ResultChar = 27;
break;
case 'E':
- PP.Diag(Loc, diag::ext_nonstandard_escape) << "E";
+ if (Complain)
+ PP.Diag(Loc, diag::ext_nonstandard_escape) << "E";
ResultChar = 27;
break;
case 'f':
@@ -79,7 +81,8 @@
case 'x': { // Hex escape.
ResultChar = 0;
if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
- PP.Diag(Loc, diag::err_hex_escape_no_digits);
+ if (Complain)
+ PP.Diag(Loc, diag::err_hex_escape_no_digits);
HadError = 1;
break;
}
@@ -106,7 +109,7 @@
}
// Check for overflow.
- if (Overflow) // Too many digits to fit in
+ if (Overflow && Complain) // Too many digits to fit in
PP.Diag(Loc, diag::warn_hex_escape_too_large);
break;
}
@@ -132,7 +135,8 @@
: PP.getTargetInfo().getCharWidth();
if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
- PP.Diag(Loc, diag::warn_octal_escape_too_large);
+ if (Complain)
+ PP.Diag(Loc, diag::warn_octal_escape_too_large);
ResultChar &= ~0U >> (32-CharWidth);
}
break;
@@ -141,10 +145,14 @@
// Otherwise, these are not valid escapes.
case '(': case '{': case '[': case '%':
// GCC accepts these as extensions. We warn about them as such though.
- PP.Diag(Loc, diag::ext_nonstandard_escape)
- << std::string()+(char)ResultChar;
+ if (Complain)
+ PP.Diag(Loc, diag::ext_nonstandard_escape)
+ << std::string()+(char)ResultChar;
break;
default:
+ if (!Complain)
+ break;
+
if (isgraph(ThisTokBuf[0]))
PP.Diag(Loc, diag::ext_unknown_escape) << std::string()+(char)ResultChar;
else
@@ -161,7 +169,8 @@
/// we will likely rework our support for UCN's.
static void ProcessUCNEscape(const char *&ThisTokBuf, const char *ThisTokEnd,
char *&ResultBuf, bool &HadError,
- SourceLocation Loc, bool IsWide, Preprocessor &PP)
+ SourceLocation Loc, bool IsWide, Preprocessor &PP,
+ bool Complain)
{
// FIXME: Add a warning - UCN's are only valid in C++ & C99.
// FIXME: Handle wide strings.
@@ -173,7 +182,8 @@
ThisTokBuf += 2;
if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
- PP.Diag(Loc, diag::err_ucn_escape_no_digits);
+ if (Complain)
+ PP.Diag(Loc, diag::err_ucn_escape_no_digits);
HadError = 1;
return;
}
@@ -189,8 +199,9 @@
}
// If we didn't consume the proper number of digits, there is a problem.
if (UcnLen) {
- PP.Diag(PP.AdvanceToTokenCharacter(Loc, ThisTokBuf-ThisTokBegin),
- diag::err_ucn_escape_incomplete);
+ if (Complain)
+ PP.Diag(PP.AdvanceToTokenCharacter(Loc, ThisTokBuf-ThisTokBegin),
+ diag::err_ucn_escape_incomplete);
HadError = 1;
return;
}
@@ -199,7 +210,8 @@
(UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60 )) // $, @, `
|| (UcnVal >= 0xD800 && UcnVal <= 0xDFFF)
|| (UcnVal > 0x10FFFF)) /* the maximum legal UTF32 value */ {
- PP.Diag(Loc, diag::err_ucn_escape_invalid);
+ if (Complain)
+ PP.Diag(Loc, diag::err_ucn_escape_invalid);
HadError = 1;
return;
}
@@ -660,7 +672,8 @@
if (begin[0] != '\\') // If this is a normal character, consume it.
ResultChar = *begin++;
else // Otherwise, this is an escape character.
- ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP);
+ ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP,
+ /*Complain=*/true);
// If this is a multi-character constant (e.g. 'abc'), handle it. These are
// implementation defined (C99 6.4.4.4p10).
@@ -746,7 +759,7 @@
///
StringLiteralParser::
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
- Preprocessor &pp) : PP(pp) {
+ Preprocessor &pp, bool Complain) : PP(pp) {
// Scan all of the string portions, remember the max individual token length,
// computing a bound on the concatenated string length, and see whether any
// piece is a wide-string. If any of the string portions is a wide-string
@@ -871,13 +884,14 @@
// Is this a Universal Character Name escape?
if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U') {
ProcessUCNEscape(ThisTokBuf, ThisTokEnd, ResultPtr,
- hadError, StringToks[i].getLocation(), ThisIsWide, PP);
+ hadError, StringToks[i].getLocation(), ThisIsWide, PP,
+ Complain);
continue;
}
// Otherwise, this is a non-UCN escape character. Process it.
unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
StringToks[i].getLocation(),
- ThisIsWide, PP);
+ ThisIsWide, PP, Complain);
// Note: our internal rep of wide char tokens is always little-endian.
*ResultPtr++ = ResultChar & 0xFF;
@@ -893,7 +907,7 @@
ResultBuf[0] = ResultPtr-&ResultBuf[0]-1;
// Verify that pascal strings aren't too large.
- if (GetStringLength() > 256) {
+ if (GetStringLength() > 256 && Complain) {
PP.Diag(StringToks[0].getLocation(), diag::err_pascal_string_too_long)
<< SourceRange(StringToks[0].getLocation(),
StringToks[NumStringToks-1].getLocation());
@@ -909,7 +923,8 @@
/// advancing over escape sequences in the string.
unsigned StringLiteralParser::getOffsetOfStringByte(const Token &Tok,
unsigned ByteNo,
- Preprocessor &PP) {
+ Preprocessor &PP,
+ bool Complain) {
// Get the spelling of the token.
llvm::SmallString<16> SpellingBuffer;
SpellingBuffer.resize(Tok.getLength());
@@ -945,7 +960,7 @@
// Otherwise, this is an escape character. Advance over it.
bool HadError = false;
ProcessCharEscape(SpellingPtr, SpellingEnd, HadError,
- Tok.getLocation(), false, PP);
+ Tok.getLocation(), false, PP, Complain);
assert(!HadError && "This method isn't valid on erroneous strings");
--ByteNo;
}