diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-07-23 08:14:48 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-07-23 08:14:48 +0000 |
commit | 4ac537b0f07f2efb9fcf081f60d54e6cfb1cf2d5 (patch) | |
tree | 46f5c8655939b0c184a2a907b2e4d391dfae3bc6 /lib/Lex/LiteralSupport.cpp | |
parent | fee16225a103ee1459af4f3ecb89fa2804e81ac3 (diff) | |
download | clang-4ac537b0f07f2efb9fcf081f60d54e6cfb1cf2d5.tar.gz clang-4ac537b0f07f2efb9fcf081f60d54e6cfb1cf2d5.tar.bz2 clang-4ac537b0f07f2efb9fcf081f60d54e6cfb1cf2d5.tar.xz |
C++1y literal suffix support:
* Allow ns, us, ms, s, min, h as numeric ud-suffixes
* Allow s as string ud-suffix
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@186933 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex/LiteralSupport.cpp')
-rw-r--r-- | lib/Lex/LiteralSupport.cpp | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp index 84882d0216..7641bfaa8b 100644 --- a/lib/Lex/LiteralSupport.cpp +++ b/lib/Lex/LiteralSupport.cpp @@ -413,10 +413,12 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, /// decimal-constant integer-suffix /// octal-constant integer-suffix /// hexadecimal-constant integer-suffix +/// binary-literal integer-suffix [GNU, C++1y] /// user-defined-integer-literal: [C++11 lex.ext] /// decimal-literal ud-suffix /// octal-literal ud-suffix /// hexadecimal-literal ud-suffix +/// binary-literal ud-suffix [GNU, C++1y] /// decimal-constant: /// nonzero-digit /// decimal-constant digit @@ -428,6 +430,10 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, /// hexadecimal-constant hexadecimal-digit /// hexadecimal-prefix: one of /// 0x 0X +/// binary-literal: +/// 0b binary-digit +/// 0B binary-digit +/// binary-literal binary-digit /// integer-suffix: /// unsigned-suffix [long-suffix] /// unsigned-suffix [long-long-suffix] @@ -441,6 +447,9 @@ static void EncodeUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf, /// 0 1 2 3 4 5 6 7 8 9 /// a b c d e f /// A B C D E F +/// binary-digit: +/// 0 +/// 1 /// unsigned-suffix: one of /// u U /// long-suffix: one of @@ -515,6 +524,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, // Parse the suffix. At this point we can classify whether we have an FP or // integer constant. bool isFPConstant = isFloatingLiteral(); + const char *ImaginarySuffixLoc = 0; // Loop over all of the characters of the suffix. If we see something bad, // we break out of the loop. @@ -598,9 +608,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, case 'j': case 'J': if (isImaginary) break; // Cannot be repeated. - PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s - ThisTokBegin), - diag::ext_imaginary_constant); isImaginary = true; + ImaginarySuffixLoc = s; continue; // Success. } // If we reached here, there was an error or a ud-suffix. @@ -608,9 +617,17 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, } if (s != ThisTokEnd) { - if (PP.getLangOpts().CPlusPlus11 && s == SuffixBegin && *s == '_') { - // We have a ud-suffix! By C++11 [lex.ext]p10, ud-suffixes not starting - // with an '_' are ill-formed. + if (isValidUDSuffix(PP.getLangOpts(), + StringRef(SuffixBegin, ThisTokEnd - SuffixBegin))) { + // Any suffix pieces we might have parsed are actually part of the + // ud-suffix. + isLong = false; + isUnsigned = false; + isLongLong = false; + isFloat = false; + isImaginary = false; + isMicrosoftInteger = false; + saw_ud_suffix = true; return; } @@ -623,6 +640,35 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, hadError = true; return; } + + if (isImaginary) { + PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, + ImaginarySuffixLoc - ThisTokBegin), + diag::ext_imaginary_constant); + } +} + +/// Determine whether a suffix is a valid ud-suffix. We avoid treating reserved +/// suffixes as ud-suffixes, because the diagnostic experience is better if we +/// treat it as an invalid suffix. +bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, + StringRef Suffix) { + if (!LangOpts.CPlusPlus11 || Suffix.empty()) + return false; + + // By C++11 [lex.ext]p10, ud-suffixes starting with an '_' are always valid. + if (Suffix[0] == '_') + return true; + + // In C++11, there are no library suffixes. + if (!LangOpts.CPlusPlus1y) + return false; + + // In C++1y, "s", "h", "min", "ms", "us", and "ns" are used in the library. + return llvm::StringSwitch<bool>(Suffix) + .Cases("h", "min", "s", true) + .Cases("ms", "us", "ns", true) + .Default(false); } /// ParseNumberStartingWithZero - This method is called when the first character |