summaryrefslogtreecommitdiff
path: root/clang/lib/Lex/LiteralSupport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Lex/LiteralSupport.cpp')
-rw-r--r--clang/lib/Lex/LiteralSupport.cpp111
1 files changed, 64 insertions, 47 deletions
diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
index 9a852141c6eea..eb16bc8c7da2d 100644
--- a/clang/lib/Lex/LiteralSupport.cpp
+++ b/clang/lib/Lex/LiteralSupport.cpp
@@ -25,6 +25,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
@@ -524,8 +525,12 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
///
NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
SourceLocation TokLoc,
- Preprocessor &PP)
- : PP(PP), ThisTokBegin(TokSpelling.begin()), ThisTokEnd(TokSpelling.end()) {
+ const SourceManager &SM,
+ const LangOptions &LangOpts,
+ const TargetInfo &Target,
+ DiagnosticsEngine &Diags)
+ : SM(SM), LangOpts(LangOpts), Diags(Diags),
+ ThisTokBegin(TokSpelling.begin()), ThisTokEnd(TokSpelling.end()) {
// This routine assumes that the range begin/end matches the regex for integer
// and FP constants (specifically, the 'pp-number' regex), and assumes that
@@ -571,7 +576,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
checkSeparator(TokLoc, s, CSK_AfterDigits);
// Initial scan to lookahead for fixed point suffix.
- if (PP.getLangOpts().FixedPoint) {
+ if (LangOpts.FixedPoint) {
for (const char *c = s; c != ThisTokEnd; ++c) {
if (*c == 'r' || *c == 'k' || *c == 'R' || *c == 'K') {
saw_fixed_point_suffix = true;
@@ -582,6 +587,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
// Parse the suffix. At this point we can classify whether we have an FP or
// integer constant.
+ bool isFixedPointConstant = isFixedPointLiteral();
bool isFPConstant = isFloatingLiteral();
// Loop over all of the characters of the suffix. If we see something bad,
@@ -590,14 +596,16 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
switch (*s) {
case 'R':
case 'r':
- if (!PP.getLangOpts().FixedPoint) break;
+ if (!LangOpts.FixedPoint)
+ break;
if (isFract || isAccum) break;
if (!(saw_period || saw_exponent)) break;
isFract = true;
continue;
case 'K':
case 'k':
- if (!PP.getLangOpts().FixedPoint) break;
+ if (!LangOpts.FixedPoint)
+ break;
if (isFract || isAccum) break;
if (!(saw_period || saw_exponent)) break;
isAccum = true;
@@ -605,7 +613,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
case 'h': // FP Suffix for "half".
case 'H':
// OpenCL Extension v1.2 s9.5 - h or H suffix for half type.
- if (!(PP.getLangOpts().Half || PP.getLangOpts().FixedPoint)) break;
+ if (!(LangOpts.Half || LangOpts.FixedPoint))
+ break;
if (isIntegerLiteral()) break; // Error for integer constant.
if (isHalf || isFloat || isLong) break; // HH, FH, LH invalid.
isHalf = true;
@@ -619,8 +628,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
// CUDA host and device may have different _Float16 support, therefore
// allows f16 literals to avoid false alarm.
// ToDo: more precise check for CUDA.
- if ((PP.getTargetInfo().hasFloat16Type() || PP.getLangOpts().CUDA) &&
- s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') {
+ if ((Target.hasFloat16Type() || LangOpts.CUDA) && s + 2 < ThisTokEnd &&
+ s[1] == '1' && s[2] == '6') {
s += 2; // success, eat up 2 characters.
isFloat16 = true;
continue;
@@ -655,10 +664,10 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
} else {
isLong = true;
}
- continue; // Success.
+ continue; // Success.
case 'i':
case 'I':
- if (PP.getLangOpts().MicrosoftExt) {
+ if (LangOpts.MicrosoftExt) {
if (isLong || isLongLong || MicrosoftInteger)
break;
@@ -711,7 +720,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
if (s != ThisTokEnd || isImaginary) {
// FIXME: Don't bother expanding UCNs if !tok.hasUCN().
expandUCNs(UDSuffixBuf, StringRef(SuffixBegin, ThisTokEnd - SuffixBegin));
- if (isValidUDSuffix(PP.getLangOpts(), UDSuffixBuf)) {
+ if (isValidUDSuffix(LangOpts, UDSuffixBuf)) {
if (!isImaginary) {
// Any suffix pieces we might have parsed are actually part of the
// ud-suffix.
@@ -734,9 +743,11 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
if (s != ThisTokEnd) {
// Report an error if there are any.
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, SuffixBegin - ThisTokBegin),
- diag::err_invalid_suffix_constant)
- << StringRef(SuffixBegin, ThisTokEnd - SuffixBegin) << isFPConstant;
+ Diags.Report(Lexer::AdvanceToTokenCharacter(
+ TokLoc, SuffixBegin - ThisTokBegin, SM, LangOpts),
+ diag::err_invalid_suffix_constant)
+ << StringRef(SuffixBegin, ThisTokEnd - SuffixBegin)
+ << (isFixedPointConstant ? 2 : isFPConstant);
hadError = true;
}
}
@@ -755,9 +766,11 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){
// If we have a hex digit other than 'e' (which denotes a FP exponent) then
// the code is using an incorrect base.
if (isHexDigit(*s) && *s != 'e' && *s != 'E' &&
- !isValidUDSuffix(PP.getLangOpts(), StringRef(s, ThisTokEnd - s))) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
- diag::err_invalid_digit) << StringRef(s, 1) << (radix == 8 ? 1 : 0);
+ !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) {
+ Diags.Report(
+ Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM, LangOpts),
+ diag::err_invalid_digit)
+ << StringRef(s, 1) << (radix == 8 ? 1 : 0);
hadError = true;
return;
}
@@ -783,8 +796,9 @@ void NumericLiteralParser::ParseDecimalOrOctalCommon(SourceLocation TokLoc){
s = first_non_digit;
} else {
if (!hadError) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
- diag::err_exponent_has_no_digits);
+ Diags.Report(Lexer::AdvanceToTokenCharacter(
+ TokLoc, Exponent - ThisTokBegin, SM, LangOpts),
+ diag::err_exponent_has_no_digits);
hadError = true;
}
return;
@@ -815,7 +829,7 @@ bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts,
.Cases("h", "min", "s", true)
.Cases("ms", "us", "ns", true)
.Cases("il", "i", "if", true)
- .Cases("d", "y", LangOpts.CPlusPlus2a)
+ .Cases("d", "y", LangOpts.CPlusPlus20)
.Default(false);
}
@@ -830,9 +844,10 @@ void NumericLiteralParser::checkSeparator(SourceLocation TokLoc,
return;
if (isDigitSeparator(*Pos)) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin),
- diag::err_digit_separator_not_between_digits)
- << IsAfterDigits;
+ Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, Pos - ThisTokBegin, SM,
+ LangOpts),
+ diag::err_digit_separator_not_between_digits)
+ << IsAfterDigits;
hadError = true;
}
}
@@ -870,9 +885,10 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
}
if (!HasSignificandDigits) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin),
- diag::err_hex_constant_requires)
- << PP.getLangOpts().CPlusPlus << 1;
+ Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM,
+ LangOpts),
+ diag::err_hex_constant_requires)
+ << LangOpts.CPlusPlus << 1;
hadError = true;
return;
}
@@ -888,8 +904,9 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
const char *first_non_digit = SkipDigits(s);
if (!containsDigits(s, first_non_digit)) {
if (!hadError) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
- diag::err_exponent_has_no_digits);
+ Diags.Report(Lexer::AdvanceToTokenCharacter(
+ TokLoc, Exponent - ThisTokBegin, SM, LangOpts),
+ diag::err_exponent_has_no_digits);
hadError = true;
}
return;
@@ -897,16 +914,17 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
checkSeparator(TokLoc, s, CSK_BeforeDigits);
s = first_non_digit;
- if (!PP.getLangOpts().HexFloats)
- PP.Diag(TokLoc, PP.getLangOpts().CPlusPlus
- ? diag::ext_hex_literal_invalid
- : diag::ext_hex_constant_invalid);
- else if (PP.getLangOpts().CPlusPlus17)
- PP.Diag(TokLoc, diag::warn_cxx17_hex_literal);
+ if (!LangOpts.HexFloats)
+ Diags.Report(TokLoc, LangOpts.CPlusPlus
+ ? diag::ext_hex_literal_invalid
+ : diag::ext_hex_constant_invalid);
+ else if (LangOpts.CPlusPlus17)
+ Diags.Report(TokLoc, diag::warn_cxx17_hex_literal);
} else if (saw_period) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin),
- diag::err_hex_constant_requires)
- << PP.getLangOpts().CPlusPlus << 0;
+ Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM,
+ LangOpts),
+ diag::err_hex_constant_requires)
+ << LangOpts.CPlusPlus << 0;
hadError = true;
}
return;
@@ -915,12 +933,10 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
// Handle simple binary numbers 0b01010
if ((c1 == 'b' || c1 == 'B') && (s[1] == '0' || s[1] == '1')) {
// 0b101010 is a C++1y / GCC extension.
- PP.Diag(TokLoc,
- PP.getLangOpts().CPlusPlus14
- ? diag::warn_cxx11_compat_binary_literal
- : PP.getLangOpts().CPlusPlus
- ? diag::ext_binary_literal_cxx14
- : diag::ext_binary_literal);
+ Diags.Report(TokLoc, LangOpts.CPlusPlus14
+ ? diag::warn_cxx11_compat_binary_literal
+ : LangOpts.CPlusPlus ? diag::ext_binary_literal_cxx14
+ : diag::ext_binary_literal);
++s;
assert(s < ThisTokEnd && "didn't maximally munch?");
radix = 2;
@@ -929,10 +945,11 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
if (s == ThisTokEnd) {
// Done.
} else if (isHexDigit(*s) &&
- !isValidUDSuffix(PP.getLangOpts(),
- StringRef(s, ThisTokEnd - s))) {
- PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
- diag::err_invalid_digit) << StringRef(s, 1) << 2;
+ !isValidUDSuffix(LangOpts, StringRef(s, ThisTokEnd - s))) {
+ Diags.Report(Lexer::AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin, SM,
+ LangOpts),
+ diag::err_invalid_digit)
+ << StringRef(s, 1) << 2;
hadError = true;
}
// Other suffixes will be diagnosed by the caller.