[cfe-commits] r52889 - in /cfe/trunk: include/clang/Lex/LiteralSupport.h lib/Lex/LiteralSupport.cpp
Chris Lattner
sabre at nondot.org
Sun Jun 29 23:39:55 PDT 2008
Author: lattner
Date: Mon Jun 30 01:39:54 2008
New Revision: 52889
URL: http://llvm.org/viewvc/llvm-project?rev=52889&view=rev
Log:
refactor some code out into a new method.
Modified:
cfe/trunk/include/clang/Lex/LiteralSupport.h
cfe/trunk/lib/Lex/LiteralSupport.cpp
Modified: cfe/trunk/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=52889&r1=52888&r2=52889&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/trunk/include/clang/Lex/LiteralSupport.h Mon Jun 30 01:39:54 2008
@@ -87,6 +87,8 @@
void Diag(SourceLocation Loc, unsigned DiagID,
const std::string &M = std::string());
+ void ParseNumberStartingWithZero(SourceLocation TokLoc);
+
/// SkipHexDigits - Read and skip over any hex digits, up to End.
/// Return a pointer to the first non-hex digit or End.
const char *SkipHexDigits(const char *ptr) {
Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=52889&r1=52888&r2=52889&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/trunk/lib/Lex/LiteralSupport.cpp Mon Jun 30 01:39:54 2008
@@ -193,7 +193,6 @@
/// floating-constant: [C99 6.4.4.2]
/// TODO: add rules...
///
-
NumericLiteralParser::
NumericLiteralParser(const char *begin, const char *end,
SourceLocation TokLoc, Preprocessor &pp)
@@ -209,88 +208,9 @@
hadError = false;
if (*s == '0') { // parse radix
- s++;
- if ((*s == 'x' || *s == 'X') && (isxdigit(s[1]) || s[1] == '.')) {
- s++;
- radix = 16;
- DigitsBegin = s;
- s = SkipHexDigits(s);
- if (s == ThisTokEnd) {
- // Done.
- } else if (*s == '.') {
- s++;
- saw_period = true;
- s = SkipHexDigits(s);
- }
- // A binary exponent can appear with or with a '.'. If dotted, the
- // binary exponent is required.
- if ((*s == 'p' || *s == 'P') && PP.getLangOptions().HexFloats) {
- const char *Exponent = s;
- s++;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s);
- if (first_non_digit != s) {
- s = first_non_digit;
- } else {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-begin),
- diag::err_exponent_has_no_digits);
- return;
- }
- } else if (saw_period) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::err_hexconstant_requires_exponent);
- return;
- }
- } else if (*s == 'b' || *s == 'B') {
- // 0b101010 is a GCC extension.
- ++s;
- radix = 2;
- DigitsBegin = s;
- s = SkipBinaryDigits(s);
- if (s == ThisTokEnd) {
- // Done.
- } else if (isxdigit(*s)) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::err_invalid_binary_digit, std::string(s, s+1));
- return;
- }
- PP.Diag(TokLoc, diag::ext_binary_literal);
- } else {
- // For now, the radix is set to 8. If we discover that we have a
- // floating point constant, the radix will change to 10. Octal floating
- // point constants are not permitted (only decimal and hexadecimal).
- radix = 8;
- DigitsBegin = s;
- s = SkipOctalDigits(s);
- if (s == ThisTokEnd) {
- // Done.
- } else if (isxdigit(*s) && !(*s == 'e' || *s == 'E')) {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
- diag::err_invalid_octal_digit, std::string(s, s+1));
- return;
- } else if (*s == '.') {
- s++;
- radix = 10;
- saw_period = true;
- s = SkipDigits(s);
- }
- if (*s == 'e' || *s == 'E') { // exponent
- const char *Exponent = s;
- s++;
- radix = 10;
- saw_exponent = true;
- if (*s == '+' || *s == '-') s++; // sign
- const char *first_non_digit = SkipDigits(s);
- if (first_non_digit != s) {
- s = first_non_digit;
- } else {
- Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-begin),
- diag::err_exponent_has_no_digits);
- return;
- }
- }
- }
+ ParseNumberStartingWithZero(TokLoc);
+ if (hadError)
+ return;
} else { // the first digit is non-zero
radix = 10;
s = SkipDigits(s);
@@ -410,6 +330,107 @@
}
}
+/// ParseNumberStartingWithZero - This method is called when the first character
+/// of the number is found to be a zero. This means it is either an octal
+/// number (like '04') or a hex number ('0x123a') a binary number ('0b1010') or
+/// a floating point number (01239.123e4). Eat the prefix, determining the
+/// radix etc.
+void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
+ assert(s[0] == '0' && "Invalid method call");
+ s++;
+
+ // Handle a hex number like 0x1234.
+ if ((*s == 'x' || *s == 'X') && (isxdigit(s[1]) || s[1] == '.')) {
+ s++;
+ radix = 16;
+ DigitsBegin = s;
+ s = SkipHexDigits(s);
+ if (s == ThisTokEnd) {
+ // Done.
+ } else if (*s == '.') {
+ s++;
+ saw_period = true;
+ s = SkipHexDigits(s);
+ }
+ // A binary exponent can appear with or with a '.'. If dotted, the
+ // binary exponent is required.
+ if ((*s == 'p' || *s == 'P') && PP.getLangOptions().HexFloats) {
+ const char *Exponent = s;
+ s++;
+ saw_exponent = true;
+ if (*s == '+' || *s == '-') s++; // sign
+ const char *first_non_digit = SkipDigits(s);
+ if (first_non_digit != s) {
+ s = first_non_digit;
+ } else {
+ Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
+ diag::err_exponent_has_no_digits);
+ }
+ } else if (saw_period) {
+ Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
+ diag::err_hexconstant_requires_exponent);
+ }
+ return;
+ }
+
+ // Handle simple binary numbers 0b01010
+ if (*s == 'b' || *s == 'B') {
+ // 0b101010 is a GCC extension.
+ ++s;
+ radix = 2;
+ DigitsBegin = s;
+ s = SkipBinaryDigits(s);
+ if (s == ThisTokEnd) {
+ // Done.
+ } else if (isxdigit(*s)) {
+ Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
+ diag::err_invalid_binary_digit, std::string(s, s+1));
+ return;
+ }
+ // Otherwise suffixes will be diagnosed by the caller.
+ PP.Diag(TokLoc, diag::ext_binary_literal);
+ return;
+ }
+
+ // For now, the radix is set to 8. If we discover that we have a
+ // floating point constant, the radix will change to 10. Octal floating
+ // point constants are not permitted (only decimal and hexadecimal).
+ radix = 8;
+ DigitsBegin = s;
+ s = SkipOctalDigits(s);
+ if (s == ThisTokEnd)
+ return; // Done, simple octal number like 01234
+
+ if (isxdigit(*s) && *s != 'e' && *s != 'E') {
+ Diag(PP.AdvanceToTokenCharacter(TokLoc, s-ThisTokBegin),
+ diag::err_invalid_octal_digit, std::string(s, s+1));
+ return;
+ }
+
+ if (*s == '.') {
+ s++;
+ radix = 10;
+ saw_period = true;
+ s = SkipDigits(s);
+ }
+ if (*s == 'e' || *s == 'E') { // exponent
+ const char *Exponent = s;
+ s++;
+ radix = 10;
+ saw_exponent = true;
+ if (*s == '+' || *s == '-') s++; // sign
+ const char *first_non_digit = SkipDigits(s);
+ if (first_non_digit != s) {
+ s = first_non_digit;
+ } else {
+ Diag(PP.AdvanceToTokenCharacter(TokLoc, Exponent-ThisTokBegin),
+ diag::err_exponent_has_no_digits);
+ return;
+ }
+ }
+}
+
+
/// GetIntegerValue - Convert this numeric literal value to an APInt that
/// matches Val's input width. If there is an overflow, set Val to the low bits
/// of the result and return true. Otherwise, return false.
More information about the cfe-commits
mailing list