[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