[cfe-commits] r39462 - /cfe/cfe/trunk/Lex/LiteralSupport.cpp
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:44:41 PDT 2007
Author: clattner
Date: Wed Jul 11 11:44:41 2007
New Revision: 39462
URL: http://llvm.org/viewvc/llvm-project?rev=39462&view=rev
Log:
Implement hex escape sequences in string and character literals, e.g. L"\x12345"
Modified:
cfe/cfe/trunk/Lex/LiteralSupport.cpp
Modified: cfe/cfe/trunk/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/LiteralSupport.cpp?rev=39462&r1=39461&r2=39462&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (original)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:44:41 2007
@@ -34,7 +34,8 @@
/// either a character or a string literal.
static unsigned ProcessCharEscape(const char *&ThisTokBuf,
const char *ThisTokEnd, bool &HadError,
- SourceLocation Loc, Preprocessor &PP) {
+ SourceLocation Loc, bool IsWide,
+ Preprocessor &PP) {
// Skip the '\' char.
++ThisTokBuf;
@@ -74,19 +75,36 @@
break;
//case 'u': case 'U': // FIXME: UCNs.
- case 'x': // Hex escape.
- if (ThisTokBuf == ThisTokEnd ||
- (ResultChar = HexDigitValue(*ThisTokBuf)) == ~0U) {
+ case 'x': { // Hex escape.
+ ResultChar = 0;
+ if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
PP.Diag(Loc, diag::err_hex_escape_no_digits);
HadError = 1;
- ResultChar = 0;
break;
}
- ++ThisTokBuf; // Consumed one hex digit.
- // FIXME: warn_hex_escape_too_large. '\x12345'
- assert(0 && "hex escape: unimp!");
+ bool Overflow = false;
+ for (; ThisTokBuf != ThisTokEnd; ++ThisTokBuf) {
+ int CharVal = HexDigitValue(ThisTokBuf[0]);
+ if (CharVal == -1) break;
+ Overflow |= ResultChar & 0xF0000000; // About to shift out a digit?
+ ResultChar <<= 4;
+ ResultChar |= CharVal;
+ }
+
+ // See if any bits will be truncated when evaluated as a character.
+ unsigned CharWidth = IsWide ? PP.getTargetInfo().getWCharWidth(Loc)
+ : PP.getTargetInfo().getCharWidth(Loc);
+ if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
+ Overflow = true;
+ ResultChar &= ~0U >> (32-CharWidth);
+ }
+
+ // Check for overflow.
+ if (Overflow) // Too many digits to fit in
+ PP.Diag(Loc, diag::warn_hex_escape_too_large);
break;
+ }
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
// Octal escapes.
@@ -429,7 +447,7 @@
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, PP);
+ ResultChar = ProcessCharEscape(begin, end, HadError, Loc, IsWide, PP);
// If this is a multi-character constant (e.g. 'abc'), handle it. These are
// implementation defined (C99 6.4.4.4p10).
@@ -575,7 +593,11 @@
// TODO: Input character set mapping support.
// Skip L marker for wide strings.
- if (ThisTokBuf[0] == 'L') ++ThisTokBuf;
+ bool ThisIsWide = false;
+ if (ThisTokBuf[0] == 'L') {
+ ++ThisTokBuf;
+ ThisIsWide = true;
+ }
assert(ThisTokBuf[0] == '"' && "Expected quote, lexer broken?");
++ThisTokBuf;
@@ -607,7 +629,8 @@
// Otherwise, this is an escape character. Process it.
unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
- StringToks[i].getLocation(), PP);
+ StringToks[i].getLocation(),
+ ThisIsWide, PP);
// Note: our internal rep of wide char tokens is always little-endian.
*ResultPtr++ = ResultChar & 0xFF;
More information about the cfe-commits
mailing list