[cfe-commits] r39350 - in /cfe/cfe/trunk: AST/SemaExpr.cpp Sema/SemaExpr.cpp include/clang/Basic/DiagnosticKinds.def

snaroff at cs.uiuc.edu snaroff at cs.uiuc.edu
Wed Jul 11 09:43:28 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:43:28 2007
New Revision: 39350

URL: http://llvm.org/viewvc/llvm-project?rev=39350&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Refactored ParseNumericConstant using SkipDigits and friends. This
cleaned up the code and removed many "breaks". In the process, I found
several bugs that needed to be fixed (proof that this refactoring had
real value, not simply aesthetics). Also simplified error handling logic
and removed an unused error condition from Diagnostics.def.

Modified:
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39350&r1=39349&r2=39350&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:28 2007
@@ -285,6 +285,30 @@
   }
 }
 
+/// SkipHexDigits - Read and skip over any hex digits, up to End.
+/// Return a pointer to the first non-hex digit or End.
+static const char *SkipHexDigits(const char *ptr, const char *end) {
+  while (ptr != end && isxdigit(*ptr))
+    ptr++;
+  return ptr;
+}
+
+/// SkipOctalDigits - Read and skip over any octal digits, up to End.
+/// Return a pointer to the first non-hex digit or End.
+static const char *SkipOctalDigits(const char *ptr, const char *end) {
+  while (ptr != end && ((*ptr >= '0') && (*ptr <= '7')))
+    ptr++;
+  return ptr;
+}
+
+/// SkipDigits - Read and skip over any digits, up to End.
+/// Return a pointer to the first non-hex digit or End.
+static const char *SkipDigits(const char *ptr, const char *end) {
+  while (ptr != end && isdigit(*ptr))
+    ptr++;
+  return ptr;
+}
+                
 ///       integer-constant: [C99 6.4.4.1]
 ///         decimal-constant integer-suffix
 ///         octal-constant integer-suffix
@@ -350,34 +374,30 @@
   
   if (*s == '0') { // parse radix
     s++;
-    if ((*s == 'x' || *s == 'X') && isxdigit(s[1])) { // need 1 digit
+    if ((*s == 'x' || *s == 'X') && (isxdigit(s[1]) || s[1] == '.')) {
       s++;
       radix = 16;
-      while (s < ThisTokEnd) {
-        if (isxdigit(*s)) {
-          s++;
-        } else if (*s == '.') {
-          s++;
-          if (saw_period) {
-            Diag(Tok, diag::err_too_many_decimal_points);
-            return ExprResult(true);
-          } else
-            saw_period = true;
-        } else if (*s == 'p' || *s == 'P') { // binary exponent
-          saw_exponent = true;
-          s++;
-          if (*s == '+' || *s == '-')  s++; // sign is optional
-          if (isdigit(*s)) { 
-            do { s++; } while (isdigit(*s)); // a decimal integer
-          } else {
-            Diag(Tok, diag::err_exponent_has_no_digits);
-            return ExprResult(true);
-          }
-          break;
-        } else
-          break;
+      s = SkipHexDigits(s, ThisTokEnd);
+      if (s == ThisTokEnd) {
+      } else if (*s == '.') {
+        s++;
+        saw_period = true;
+        s = SkipHexDigits(s, ThisTokEnd);
       }
-      if (saw_period && !saw_exponent) { 
+      // A binary exponent can appear with or with a '.'. If dotted, the
+      // binary exponent is required. 
+      if (*s == 'p' || *s == 'P') { 
+        s++;
+        saw_exponent = true;
+        if (*s == '+' || *s == '-')  s++; // sign
+        const char *first_non_digit = SkipDigits(s, ThisTokEnd);
+        if (first_non_digit == s) {
+          Diag(Tok, diag::err_exponent_has_no_digits);
+          return ExprResult(true);
+        } else {
+          s = first_non_digit;
+        }
+      } else if (saw_period) {
         Diag(Tok, diag::err_hexconstant_requires_exponent);
         return ExprResult(true);
       }
@@ -386,126 +406,95 @@
       // floating point constant, the radix will change to 10. Octal floating
       // point constants are not permitted (only decimal and hexadecimal). 
       radix = 8;
-      while (s < ThisTokEnd) {
-        if ((*s >= '0') && (*s <= '7')) {
-          s++;
-        } else if (*s == '.') {
-          s++;
-          if (saw_period) {
-            Diag(Tok, diag::err_too_many_decimal_points);
-            return ExprResult(true);
-          }
-          saw_period = true;
-          radix = 10;
-        } else if (*s == 'e' || *s == 'E') { // exponent
-          saw_exponent = true;
-          s++;
-          if (*s == '+' || *s == '-')  s++; // sign
-          if (isdigit(*s)) { 
-            do { s++; } while (isdigit(*s)); // a decimal integer
-          } else {
-            Diag(Tok, diag::err_exponent_has_no_digits);
-            return ExprResult(true);
-          }
-          radix = 10;
-          break;
-        } else
-          break;
-      }
-    }
-  } else { // the first digit is non-zero
-    radix = 10;
-    while (s < ThisTokEnd) {
-      if (isdigit(*s)) {
-        s++;
+      s = SkipOctalDigits(s, ThisTokEnd);
+      if (s == ThisTokEnd) {
       } else if (*s == '.') {
         s++;
-        if (saw_period) {
-          Diag(Tok, diag::err_too_many_decimal_points);
-          return ExprResult(true);
-        } else
-          saw_period = true;
-      } else if (*s == 'e' || *s == 'E') { // exponent
-        saw_exponent = true;
+        radix = 10;
+        saw_period = true;
+        s = SkipDigits(s, ThisTokEnd);
+      }
+      if (*s == 'e' || *s == 'E') { // exponent
         s++;
+        radix = 10;
+        saw_exponent = true;
         if (*s == '+' || *s == '-')  s++; // sign
-        if (isdigit(*s)) { 
-          do { s++; } while (isdigit(*s)); // a decimal integer
-        } else {
+        const char *first_non_digit = SkipDigits(s, ThisTokEnd);
+        if (first_non_digit == s) {
           Diag(Tok, diag::err_exponent_has_no_digits);
           return ExprResult(true);
+        } else {
+          s = first_non_digit;
         }
-        break;
-      } else
-        break;
+      }
+    }
+  } else { // the first digit is non-zero
+    radix = 10;
+    s = SkipDigits(s, ThisTokEnd);
+    if (s == ThisTokEnd) {
+    } else if (*s == '.') {
+      s++;
+      saw_period = true;
+      s = SkipDigits(s, ThisTokEnd);
+    } 
+    if (*s == 'e' || *s == 'E') { // exponent
+      s++;
+      saw_exponent = true;
+      if (*s == '+' || *s == '-')  s++; // sign
+      const char *first_non_digit = SkipDigits(s, ThisTokEnd);
+      if (first_non_digit == s) {
+        Diag(Tok, diag::err_exponent_has_no_digits);
+        return ExprResult(true);
+      } else {
+        s = first_non_digit;
+      }
     }
   }
 
   const char *suffix_start = s;
-  bool invalid_suffix = false;
   
   if (saw_period || saw_exponent) {
     bool saw_float_suffix = false, saw_long_suffix = false;
-        
-    while (s < ThisTokEnd) {
-      // parse float suffix - they can appear in any order.
+    
+    if (s < ThisTokEnd) { // parse size suffix (float, long double)
       if (*s == 'f' || *s == 'F') {
-        if (saw_float_suffix) {
-          invalid_suffix = true;
-          break;
-        } else {
-          saw_float_suffix = true;
-          s++;
-        }
+        saw_float_suffix = true;
+        s++;
       } else if (*s == 'l' || *s == 'L') {
-        if (saw_long_suffix) {
-          invalid_suffix = true;
-          break;
-        } else {
-          saw_long_suffix = true;
-          s++;
-        }
-      } else {
-        invalid_suffix = true;
-        break;
+        saw_long_suffix = true;
+        s++;
+      }
+      if (s != ThisTokEnd) {
+        Diag(Tok, diag::err_invalid_suffix_float_constant, 
+             std::string(suffix_start, ThisTokEnd));
+        return ExprResult(true);
       }
-    }
-    if (invalid_suffix) {
-      Diag(Tok, diag::err_invalid_suffix_float_constant, 
-           std::string(suffix_start, ThisTokEnd));
-      return ExprResult(true);
     }
     literal_expr = new FloatingLiteral();
   } else {
-    bool saw_unsigned = false;
-    int long_cnt = 0;
+    bool saw_unsigned = false, saw_long = false, saw_longlong = false;
 
     // if there is no suffix, this loop won't be executed (s == ThisTokEnd)
     while (s < ThisTokEnd) {
       // parse int suffix - they can appear in any order ("ul", "lu", "llu").
       if (*s == 'u' || *s == 'U') {
-        if (saw_unsigned) {
-          invalid_suffix = true;
-          break;
-        } else {
-          saw_unsigned = true;
-          s++;
-        }
+        if (saw_unsigned) break; // only allowed to have one 
+        saw_unsigned = true;
+        s++;
       } else if (*s == 'l' || *s == 'L') {
-        long_cnt++;
-        // l's need to be adjacent and the same case.
-        if ((long_cnt == 2 && (*s != *(s-1))) || long_cnt == 3) {
-          invalid_suffix = true;
-          break;
-        } else {
+        if (saw_long || saw_longlong) break; // only allowed to have one
+        s++;
+        if (s < ThisTokEnd && (*s == *(s-1))) {
+          saw_longlong = true; // l's need to be adjacent and same case.
           s++;
+        } else {
+          saw_long = true;
         }
       } else {
-        invalid_suffix = true;
         break;
       }
     }
-    if (invalid_suffix) {
+    if (s != ThisTokEnd) {
       Diag(Tok, diag::err_invalid_suffix_integer_constant, 
            std::string(suffix_start, ThisTokEnd));
       return ExprResult(true);

Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39350&r1=39349&r2=39350&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:28 2007
@@ -285,6 +285,30 @@
   }
 }
 
+/// SkipHexDigits - Read and skip over any hex digits, up to End.
+/// Return a pointer to the first non-hex digit or End.
+static const char *SkipHexDigits(const char *ptr, const char *end) {
+  while (ptr != end && isxdigit(*ptr))
+    ptr++;
+  return ptr;
+}
+
+/// SkipOctalDigits - Read and skip over any octal digits, up to End.
+/// Return a pointer to the first non-hex digit or End.
+static const char *SkipOctalDigits(const char *ptr, const char *end) {
+  while (ptr != end && ((*ptr >= '0') && (*ptr <= '7')))
+    ptr++;
+  return ptr;
+}
+
+/// SkipDigits - Read and skip over any digits, up to End.
+/// Return a pointer to the first non-hex digit or End.
+static const char *SkipDigits(const char *ptr, const char *end) {
+  while (ptr != end && isdigit(*ptr))
+    ptr++;
+  return ptr;
+}
+                
 ///       integer-constant: [C99 6.4.4.1]
 ///         decimal-constant integer-suffix
 ///         octal-constant integer-suffix
@@ -350,34 +374,30 @@
   
   if (*s == '0') { // parse radix
     s++;
-    if ((*s == 'x' || *s == 'X') && isxdigit(s[1])) { // need 1 digit
+    if ((*s == 'x' || *s == 'X') && (isxdigit(s[1]) || s[1] == '.')) {
       s++;
       radix = 16;
-      while (s < ThisTokEnd) {
-        if (isxdigit(*s)) {
-          s++;
-        } else if (*s == '.') {
-          s++;
-          if (saw_period) {
-            Diag(Tok, diag::err_too_many_decimal_points);
-            return ExprResult(true);
-          } else
-            saw_period = true;
-        } else if (*s == 'p' || *s == 'P') { // binary exponent
-          saw_exponent = true;
-          s++;
-          if (*s == '+' || *s == '-')  s++; // sign is optional
-          if (isdigit(*s)) { 
-            do { s++; } while (isdigit(*s)); // a decimal integer
-          } else {
-            Diag(Tok, diag::err_exponent_has_no_digits);
-            return ExprResult(true);
-          }
-          break;
-        } else
-          break;
+      s = SkipHexDigits(s, ThisTokEnd);
+      if (s == ThisTokEnd) {
+      } else if (*s == '.') {
+        s++;
+        saw_period = true;
+        s = SkipHexDigits(s, ThisTokEnd);
       }
-      if (saw_period && !saw_exponent) { 
+      // A binary exponent can appear with or with a '.'. If dotted, the
+      // binary exponent is required. 
+      if (*s == 'p' || *s == 'P') { 
+        s++;
+        saw_exponent = true;
+        if (*s == '+' || *s == '-')  s++; // sign
+        const char *first_non_digit = SkipDigits(s, ThisTokEnd);
+        if (first_non_digit == s) {
+          Diag(Tok, diag::err_exponent_has_no_digits);
+          return ExprResult(true);
+        } else {
+          s = first_non_digit;
+        }
+      } else if (saw_period) {
         Diag(Tok, diag::err_hexconstant_requires_exponent);
         return ExprResult(true);
       }
@@ -386,126 +406,95 @@
       // floating point constant, the radix will change to 10. Octal floating
       // point constants are not permitted (only decimal and hexadecimal). 
       radix = 8;
-      while (s < ThisTokEnd) {
-        if ((*s >= '0') && (*s <= '7')) {
-          s++;
-        } else if (*s == '.') {
-          s++;
-          if (saw_period) {
-            Diag(Tok, diag::err_too_many_decimal_points);
-            return ExprResult(true);
-          }
-          saw_period = true;
-          radix = 10;
-        } else if (*s == 'e' || *s == 'E') { // exponent
-          saw_exponent = true;
-          s++;
-          if (*s == '+' || *s == '-')  s++; // sign
-          if (isdigit(*s)) { 
-            do { s++; } while (isdigit(*s)); // a decimal integer
-          } else {
-            Diag(Tok, diag::err_exponent_has_no_digits);
-            return ExprResult(true);
-          }
-          radix = 10;
-          break;
-        } else
-          break;
-      }
-    }
-  } else { // the first digit is non-zero
-    radix = 10;
-    while (s < ThisTokEnd) {
-      if (isdigit(*s)) {
-        s++;
+      s = SkipOctalDigits(s, ThisTokEnd);
+      if (s == ThisTokEnd) {
       } else if (*s == '.') {
         s++;
-        if (saw_period) {
-          Diag(Tok, diag::err_too_many_decimal_points);
-          return ExprResult(true);
-        } else
-          saw_period = true;
-      } else if (*s == 'e' || *s == 'E') { // exponent
-        saw_exponent = true;
+        radix = 10;
+        saw_period = true;
+        s = SkipDigits(s, ThisTokEnd);
+      }
+      if (*s == 'e' || *s == 'E') { // exponent
         s++;
+        radix = 10;
+        saw_exponent = true;
         if (*s == '+' || *s == '-')  s++; // sign
-        if (isdigit(*s)) { 
-          do { s++; } while (isdigit(*s)); // a decimal integer
-        } else {
+        const char *first_non_digit = SkipDigits(s, ThisTokEnd);
+        if (first_non_digit == s) {
           Diag(Tok, diag::err_exponent_has_no_digits);
           return ExprResult(true);
+        } else {
+          s = first_non_digit;
         }
-        break;
-      } else
-        break;
+      }
+    }
+  } else { // the first digit is non-zero
+    radix = 10;
+    s = SkipDigits(s, ThisTokEnd);
+    if (s == ThisTokEnd) {
+    } else if (*s == '.') {
+      s++;
+      saw_period = true;
+      s = SkipDigits(s, ThisTokEnd);
+    } 
+    if (*s == 'e' || *s == 'E') { // exponent
+      s++;
+      saw_exponent = true;
+      if (*s == '+' || *s == '-')  s++; // sign
+      const char *first_non_digit = SkipDigits(s, ThisTokEnd);
+      if (first_non_digit == s) {
+        Diag(Tok, diag::err_exponent_has_no_digits);
+        return ExprResult(true);
+      } else {
+        s = first_non_digit;
+      }
     }
   }
 
   const char *suffix_start = s;
-  bool invalid_suffix = false;
   
   if (saw_period || saw_exponent) {
     bool saw_float_suffix = false, saw_long_suffix = false;
-        
-    while (s < ThisTokEnd) {
-      // parse float suffix - they can appear in any order.
+    
+    if (s < ThisTokEnd) { // parse size suffix (float, long double)
       if (*s == 'f' || *s == 'F') {
-        if (saw_float_suffix) {
-          invalid_suffix = true;
-          break;
-        } else {
-          saw_float_suffix = true;
-          s++;
-        }
+        saw_float_suffix = true;
+        s++;
       } else if (*s == 'l' || *s == 'L') {
-        if (saw_long_suffix) {
-          invalid_suffix = true;
-          break;
-        } else {
-          saw_long_suffix = true;
-          s++;
-        }
-      } else {
-        invalid_suffix = true;
-        break;
+        saw_long_suffix = true;
+        s++;
+      }
+      if (s != ThisTokEnd) {
+        Diag(Tok, diag::err_invalid_suffix_float_constant, 
+             std::string(suffix_start, ThisTokEnd));
+        return ExprResult(true);
       }
-    }
-    if (invalid_suffix) {
-      Diag(Tok, diag::err_invalid_suffix_float_constant, 
-           std::string(suffix_start, ThisTokEnd));
-      return ExprResult(true);
     }
     literal_expr = new FloatingLiteral();
   } else {
-    bool saw_unsigned = false;
-    int long_cnt = 0;
+    bool saw_unsigned = false, saw_long = false, saw_longlong = false;
 
     // if there is no suffix, this loop won't be executed (s == ThisTokEnd)
     while (s < ThisTokEnd) {
       // parse int suffix - they can appear in any order ("ul", "lu", "llu").
       if (*s == 'u' || *s == 'U') {
-        if (saw_unsigned) {
-          invalid_suffix = true;
-          break;
-        } else {
-          saw_unsigned = true;
-          s++;
-        }
+        if (saw_unsigned) break; // only allowed to have one 
+        saw_unsigned = true;
+        s++;
       } else if (*s == 'l' || *s == 'L') {
-        long_cnt++;
-        // l's need to be adjacent and the same case.
-        if ((long_cnt == 2 && (*s != *(s-1))) || long_cnt == 3) {
-          invalid_suffix = true;
-          break;
-        } else {
+        if (saw_long || saw_longlong) break; // only allowed to have one
+        s++;
+        if (s < ThisTokEnd && (*s == *(s-1))) {
+          saw_longlong = true; // l's need to be adjacent and same case.
           s++;
+        } else {
+          saw_long = true;
         }
       } else {
-        invalid_suffix = true;
         break;
       }
     }
-    if (invalid_suffix) {
+    if (s != ThisTokEnd) {
       Diag(Tok, diag::err_invalid_suffix_integer_constant, 
            std::string(suffix_start, ThisTokEnd));
       return ExprResult(true);

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39350&r1=39349&r2=39350&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:28 2007
@@ -476,8 +476,6 @@
      "invalid suffix '%s' on floating constant")
 DIAG(err_exponent_has_no_digits, ERROR,
      "exponent has no digits")
-DIAG(err_too_many_decimal_points, ERROR,
-     "too many decimal points in number")
 DIAG(err_hexconstant_requires_exponent, ERROR,
      "hexadecimal floating constants require an exponent")
 





More information about the cfe-commits mailing list