[cfe-commits] r41411 - in /cfe/trunk: Lex/LiteralSupport.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Lex/LiteralSupport.h

Chris Lattner sabre at nondot.org
Sat Aug 25 18:58:14 PDT 2007


Author: lattner
Date: Sat Aug 25 20:58:14 2007
New Revision: 41411

URL: http://llvm.org/viewvc/llvm-project?rev=41411&view=rev
Log:
1) refactor some code.
2) Add support for lexing imaginary constants (a GCC extension):

t.c:5:10: warning: imaginary constants are an extension
  A = 1.0iF;
         ^

3) Make the 'invalid suffix' diagnostic pointer more accurate:

t.c:6:10: error: invalid suffix 'qF' on floating constant
  A = 1.0qF;
         ^

instead of:

t.c:6:10: error: invalid suffix 'qF' on floating constant
  A = 1.0qF;
      ^


Modified:
    cfe/trunk/Lex/LiteralSupport.cpp
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/include/clang/Lex/LiteralSupport.h

Modified: cfe/trunk/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Lex/LiteralSupport.cpp?rev=41411&r1=41410&r2=41411&view=diff

==============================================================================
--- cfe/trunk/Lex/LiteralSupport.cpp (original)
+++ cfe/trunk/Lex/LiteralSupport.cpp Sat Aug 25 20:58:14 2007
@@ -206,6 +206,7 @@
   isLong = false;
   isUnsigned = false;
   isLongLong = false;
+  isImaginary = false;
   hadError = false;
   
   if (*s == '0') { // parse radix
@@ -313,65 +314,62 @@
   }
 
   SuffixBegin = s;
-
-  if (saw_period || saw_exponent) {    
-    if (s < ThisTokEnd) { // parse size suffix (float, long double)
-      if (*s == 'f' || *s == 'F') {
-        saw_float_suffix = true;
-        s++;
-      } else if (*s == 'l' || *s == 'L') {
+  
+  // Parse the suffix.  At this point we can classify whether we have an FP or
+  // integer constant.
+  bool isFPConstant = isFloatingLiteral();
+  
+  // Loop over all of the characters of the suffix.  If we see something bad,
+  // we break out of the loop.
+  for (; s != ThisTokEnd; ++s) {
+    switch (*s) {
+    case 'f':      // FP Suffix for "float"
+    case 'F':
+      if (!isFPConstant) break;  // Error for integer constant.
+      if (saw_float_suffix || isLong) break; // FF, LF invalid.
+      saw_float_suffix = true;
+      continue;  // Success.
+    case 'u':
+    case 'U':
+      if (isFPConstant) break;  // Error for floating constant.
+      if (isUnsigned) break;    // Cannot be repeated.
+      isUnsigned = true;
+      continue;  // Success.
+    case 'l':
+    case 'L':
+      if (isLong || isLongLong) break;  // Cannot be repeated.
+      if (saw_float_suffix) break;      // LF invalid.
+      
+      // Check for long long.  The L's need to be adjacent and the same case.
+      if (s+1 != ThisTokEnd && s[1] == s[0]) {
+        if (isFPConstant) break;        // long long invalid for floats.
+        isLongLong = true;
+        ++s;  // Eat both of them.
+      } else {
         isLong = true;
-        s++;
-      }
-      if (s != ThisTokEnd) {
-        Diag(TokLoc, diag::err_invalid_suffix_float_constant, 
-             std::string(SuffixBegin, ThisTokEnd));
-        return;
-      }
-    }
-  } else {    
-    if (s < ThisTokEnd) {
-      // parse int suffix - they can appear in any order ("ul", "lu", "llu").
-      if (*s == 'u' || *s == 'U') {
-        s++;
-        isUnsigned = true; // unsigned
-
-        if ((s < ThisTokEnd) && (*s == 'l' || *s == 'L')) {
-          s++;
-          // handle "long long" type - l's need to be adjacent and same case.
-          if ((s < ThisTokEnd) && (*s == *(s-1))) {
-            isLongLong = true; // unsigned long long
-            s++;
-          } else {
-            isLong = true; // unsigned long 
-          }
-        }
-      } else if (*s == 'l' || *s == 'L') {
-        s++;
-        // handle "long long" types - l's need to be adjacent and same case.
-        if ((s < ThisTokEnd) && (*s == *(s-1))) {
-          s++;
-          if ((s < ThisTokEnd) && (*s == 'u' || *s == 'U')) {
-            isUnsigned = true; // unsigned long long
-            s++;
-          } else {
-            isLongLong = true; // long long
-          }
-        } else { // handle "long" types
-          if ((s < ThisTokEnd) && (*s == 'u' || *s == 'U')) {
-            isUnsigned = true; // unsigned  long
-            s++;
-          } else {
-            isLong = true; // long 
-          }
-        }
-      } 
-      if (s != ThisTokEnd) {
-        Diag(TokLoc, diag::err_invalid_suffix_integer_constant, 
-             std::string(SuffixBegin, ThisTokEnd));
-        return;
       }
+      continue;  // Success.
+    case 'i':
+    case 'I':
+    case 'j':
+    case 'J':
+      if (isImaginary) break;   // Cannot be repeated.
+      PP.Diag(PP.AdvanceToTokenCharacter(TokLoc, s-begin),
+              diag::ext_imaginary_constant);
+      isImaginary = true;
+      continue;  // Success.
     }
+    // If we reached here, there was an error.
+    break;
+  }
+  
+  // Report an error if there are any.
+  if (s != ThisTokEnd) {
+    TokLoc = PP.AdvanceToTokenCharacter(TokLoc, s-begin);
+    Diag(TokLoc, isFPConstant ? diag::err_invalid_suffix_float_constant :
+                                diag::err_invalid_suffix_integer_constant, 
+         std::string(SuffixBegin, ThisTokEnd));
+    return;
   }
 }
 

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

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Sat Aug 25 20:58:14 2007
@@ -570,6 +570,8 @@
      "invalid suffix '%0' on integer constant")
 DIAG(err_invalid_suffix_float_constant, ERROR,
      "invalid suffix '%0' on floating constant")
+DIAG(ext_imaginary_constant, EXTENSION,
+     "imaginary constants are an extension")
 DIAG(warn_integer_too_large, WARNING,
      "integer constant is too large for its type")
 DIAG(warn_integer_too_large_for_signed, WARNING,

Modified: cfe/trunk/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=41411&r1=41410&r2=41411&view=diff

==============================================================================
--- cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/trunk/include/clang/Lex/LiteralSupport.h Sat Aug 25 20:58:14 2007
@@ -44,21 +44,22 @@
   unsigned radix;
   
   bool saw_exponent, saw_period;
-  bool saw_float_suffix;
+  bool saw_float_suffix;    // 1.0f
   
 public:
   NumericLiteralParser(const char *begin, const char *end,
                        SourceLocation Loc, Preprocessor &PP);
   bool hadError;
   bool isUnsigned;
-  bool isLong;       // This is also set for long long.
+  bool isLong;        // This is *not* set for long long.
   bool isLongLong;
+  bool isImaginary;   // 1.0i
   
   bool isIntegerLiteral() const { 
-    return !saw_period && !saw_exponent ? true : false;
+    return !saw_period && !saw_exponent;
   }
   bool isFloatingLiteral() const {
-    return saw_period || saw_exponent ? true : false;
+    return saw_period || saw_exponent;
   }
   bool hasSuffix() const {
     return SuffixBegin != ThisTokEnd;





More information about the cfe-commits mailing list