diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-09-24 04:06:10 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2013-09-24 04:06:10 +0000 |
commit | 2a98862be2ed03a418e5d684636d527bb2f2dc90 (patch) | |
tree | d7349d71500a013ceac558cb048144f6ac90ddd0 /clang/lib/Lex | |
parent | 0e08d7757b96e19908c774c08750cfc8994c970f (diff) | |
download | bcm5719-llvm-2a98862be2ed03a418e5d684636d527bb2f2dc90.tar.gz bcm5719-llvm-2a98862be2ed03a418e5d684636d527bb2f2dc90.zip |
Handle standard libraries that miss out the space when defining the standard
literal operators. Also, for now, allow the proposed C++1y "il", "i", and "if"
suffixes too. (Will revert the latter if LWG decides not to go ahead with that
change after all.)
llvm-svn: 191274
Diffstat (limited to 'clang/lib/Lex')
-rw-r--r-- | clang/lib/Lex/Lexer.cpp | 34 | ||||
-rw-r--r-- | clang/lib/Lex/LiteralSupport.cpp | 5 |
2 files changed, 33 insertions, 6 deletions
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index e6b6b1fe1c1..d8a5160e95d 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -29,6 +29,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Lex/CodeCompletionHandler.h" #include "clang/Lex/LexDiagnostic.h" +#include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" @@ -1638,12 +1639,33 @@ const char *Lexer::LexUDSuffix(Token &Result, const char *CurPtr, bool IsUDSuffix = false; if (C == '_') IsUDSuffix = true; - else if (IsStringLiteral && C == 's' && getLangOpts().CPlusPlus1y) { - // In C++1y, "s" is a valid ud-suffix for a string literal. - unsigned NextSize; - if (!isIdentifierBody(getCharAndSizeNoWarn(CurPtr + Size, NextSize, - getLangOpts()))) - IsUDSuffix = true; + else if (IsStringLiteral && getLangOpts().CPlusPlus1y) { + // In C++1y, we need to look ahead a few characters to see if this is a + // valid suffix for a string literal or a numeric literal (this could be + // the 'operator""if' defining a numeric literal operator). + const int MaxStandardSuffixLength = 3; + char Buffer[MaxStandardSuffixLength] = { C }; + unsigned Consumed = Size; + unsigned Chars = 1; + while (true) { + unsigned NextSize; + char Next = getCharAndSizeNoWarn(CurPtr + Consumed, NextSize, + getLangOpts()); + if (!isIdentifierBody(Next)) { + // End of suffix. Check whether this is on the whitelist. + IsUDSuffix = (Chars == 1 && Buffer[0] == 's') || + NumericLiteralParser::isValidUDSuffix( + getLangOpts(), StringRef(Buffer, Chars)); + break; + } + + if (Chars == MaxStandardSuffixLength) + // Too long: can't be a standard suffix. + break; + + Buffer[Chars++] = Next; + Consumed += NextSize; + } } if (!IsUDSuffix) { diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index c637c388192..893141d5957 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -604,6 +604,9 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling, break; } } + // "i", "if", and "il" are user-defined suffixes in C++1y. + if (PP.getLangOpts().CPlusPlus1y && *s == 'i') + break; // fall through. case 'j': case 'J': @@ -665,9 +668,11 @@ bool NumericLiteralParser::isValidUDSuffix(const LangOptions &LangOpts, return false; // In C++1y, "s", "h", "min", "ms", "us", and "ns" are used in the library. + // Per tweaked N3660, "il", "i", and "if" are also used in the library. return llvm::StringSwitch<bool>(Suffix) .Cases("h", "min", "s", true) .Cases("ms", "us", "ns", true) + .Cases("il", "i", "if", true) .Default(false); } |