[cfe-commits] r39349 - in /cfe/cfe/trunk: AST/Sema.cpp AST/Sema.h AST/SemaExpr.cpp Parse/ParseExpr.cpp Sema/Sema.cpp Sema/Sema.h Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Action.h include/clang/Parse/Parser.h

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


Author: snaroff
Date: Wed Jul 11 11:43:27 2007
New Revision: 39349

URL: http://llvm.org/viewvc/llvm-project?rev=39349&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
More code to parse numeric constants. This checkin includes:
- Feedback from Chris.
- Support for parsing floating point constants.
- Moved the code to "Sema". Changed API in Action.
- More/better error diagnostics.

At this point, the parsing support should be largely complete. Next step
is to work on filling in sensible values (in IntegerLiteral/FloatLiteral).

Modified:
    cfe/cfe/trunk/AST/Sema.cpp
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Parse/ParseExpr.cpp
    cfe/cfe/trunk/Sema/Sema.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Parse/Action.h
    cfe/cfe/trunk/include/clang/Parse/Parser.h

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

==============================================================================
--- cfe/cfe/trunk/AST/Sema.cpp (original)
+++ cfe/cfe/trunk/AST/Sema.cpp Wed Jul 11 11:43:27 2007
@@ -30,6 +30,10 @@
   PP.Diag(Loc, DiagID, Msg);
 }
 
+void Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
+  Diag(Tok.getLocation(), DiagID, M);
+}
+
 const LangOptions &Sema::getLangOptions() const {
   return PP.getLangOptions();
 }

Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39349&r1=39348&r2=39349&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:43:27 2007
@@ -30,6 +30,7 @@
   class TypeRef;
   class LangOptions;
   class DeclaratorChunk;
+  class LexerToken;
   
 /// Sema - This implements semantic analysis and AST building for C.
 class Sema : public Action {
@@ -53,6 +54,8 @@
   
   void Diag(SourceLocation Loc, unsigned DiagID,
             const std::string &Msg = std::string());
+  void Diag(const LexerToken &Tok, unsigned DiagID,
+            const std::string &M = std::string());
   
   //===--------------------------------------------------------------------===//
   // Type Analysis / Processing: SemaType.cpp.
@@ -155,8 +158,7 @@
                                          bool HasTrailingLParen);
   virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
                                             tok::TokenKind Kind);
-  virtual ExprResult ParseIntegerLiteral(SourceLocation Loc);
-  virtual ExprResult ParseFloatingLiteral(SourceLocation Loc);
+  virtual ExprResult ParseNumericConstant(const LexerToken &);
   virtual ExprResult ParseParenExpr(SourceLocation L, SourceLocation R,
                                     ExprTy *Val);
 

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:27 2007
@@ -285,11 +285,234 @@
   }
 }
 
-Sema::ExprResult Sema::ParseIntegerLiteral(SourceLocation Loc) {
-  return new IntegerLiteral();
-}
-Sema::ExprResult Sema::ParseFloatingLiteral(SourceLocation Loc) {
-  return new FloatingLiteral();
+///       integer-constant: [C99 6.4.4.1]
+///         decimal-constant integer-suffix
+///         octal-constant integer-suffix
+///         hexadecimal-constant integer-suffix
+///       decimal-constant: 
+///         nonzero-digit
+///         decimal-constant digit
+///       octal-constant: 
+///         0
+///         octal-constant octal-digit
+///       hexadecimal-constant: 
+///         hexadecimal-prefix hexadecimal-digit
+///         hexadecimal-constant hexadecimal-digit
+///       hexadecimal-prefix: one of
+///         0x 0X
+///       integer-suffix:
+///         unsigned-suffix [long-suffix]
+///         unsigned-suffix [long-long-suffix]
+///         long-suffix [unsigned-suffix]
+///         long-long-suffix [unsigned-sufix]
+///       nonzero-digit:
+///         1 2 3 4 5 6 7 8 9
+///       octal-digit:
+///         0 1 2 3 4 5 6 7
+///       hexadecimal-digit:
+///         0 1 2 3 4 5 6 7 8 9
+///         a b c d e f
+///         A B C D E F
+///       unsigned-suffix: one of
+///         u U
+///       long-suffix: one of
+///         l L
+///       long-long-suffix: one of 
+///         ll LL
+///
+///       floating-constant: [C99 6.4.4.2]
+///         TODO: add rules...
+///
+Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
+  SmallString<512> IntegerBuffer;
+  IntegerBuffer.resize(Tok.getLength());
+  const char *ThisTokBegin = &IntegerBuffer[0];
+  
+  // Get the spelling of the token, which eliminates trigraphs, etc.  Notes:
+  // - We know that ThisTokBuf points to a buffer that is big enough for the 
+  //   whole token and 'spelled' tokens can only shrink.
+  // - In practice, the local buffer is only used when the spelling doesn't
+  //   match the original token (which is rare). The common case simply returns
+  //   a pointer to a *constant* buffer (avoiding a copy). 
+  
+  unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
+  ExprResult Res;
+
+  // This is an optimization for single digits (which are very common).
+  if (ActualLength == 1) {
+    return ExprResult(new IntegerLiteral());
+  }
+  const char *ThisTokEnd = ThisTokBegin+ActualLength; 
+  const char *s = ThisTokBegin;
+  unsigned int radix;
+  bool saw_exponent = false, saw_period = false;
+  Expr *literal_expr = 0;
+  
+  if (*s == '0') { // parse radix
+    s++;
+    if ((*s == 'x' || *s == 'X') && isxdigit(s[1])) { // need 1 digit
+      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;
+      }
+      if (saw_period && !saw_exponent) { 
+        Diag(Tok, diag::err_hexconstant_requires_exponent);
+        return ExprResult(true);
+      }
+    } 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;
+      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++;
+      } 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;
+        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);
+        }
+        break;
+      } else
+        break;
+    }
+  }
+
+  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 == 'f' || *s == 'F') {
+        if (saw_float_suffix) {
+          invalid_suffix = true;
+          break;
+        } else {
+          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;
+      }
+    }
+    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;
+
+    // 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++;
+        }
+      } 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 {
+          s++;
+        }
+      } else {
+        invalid_suffix = true;
+        break;
+      }
+    }
+    if (invalid_suffix) {
+      Diag(Tok, diag::err_invalid_suffix_integer_constant, 
+           std::string(suffix_start, ThisTokEnd));
+      return ExprResult(true);
+    }
+    literal_expr = new IntegerLiteral();
+  }
+  return ExprResult(literal_expr);
 }
 
 Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,

Modified: cfe/cfe/trunk/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseExpr.cpp?rev=39349&r1=39348&r2=39349&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/ParseExpr.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseExpr.cpp Wed Jul 11 11:43:27 2007
@@ -473,7 +473,7 @@
     // constant: integer-constant
     // constant: floating-constant
     
-    ParseNumericConstant();
+    Actions.ParseNumericConstant(Tok);
     ConsumeToken();
     
     // These can be followed by postfix-expr pieces.
@@ -925,114 +925,3 @@
   // Pass the set of string tokens, ready for concatenation, to the actions.
   return Actions.ParseStringLiteral(&StringToks[0], StringToks.size());
 }
-
-///       integer-constant: [C99 6.4.4.1]
-///         decimal-constant integer-suffix
-///         octal-constant integer-suffix
-///         hexidecimal-constant integer-suffix
-///       decimal-constant: 
-///         nonzero-digit
-///         decimal-constant digit
-///       octal-constant: 
-///         0
-///         octal-constant octal-digit
-///       hexidecimal-constant: 
-///         hexidecimal-prefix hexidecimal-digit
-///         hexidecimal-constant hexidecimal-digit
-///       hexidecimal-prefix: one of
-///         0x 0X
-///       integer-suffix:
-///         unsigned-suffix [long-suffix]
-///         unsigned-suffix [long-long-suffix]
-///         long-suffix [unsigned-suffix]
-///         long-long-suffix [unsigned-sufix]
-///       nonzero-digit:
-///         1 2 3 4 5 6 7 8 9
-///       octal-digit:
-///         0 1 2 3 4 5 6 7
-///       hexadecimal-digit:
-///         0 1 2 3 4 5 6 7 8 9
-///         a b c d e f
-///         A B C D E F
-///       unsigned-suffix: one of
-///         u U
-///       long-suffix: one of
-///         l L
-///       long-long-suffix: one of 
-///         ll LL
-///
-///       floating-constant: [C99 6.4.4.2]
-///
-Parser::ExprResult Parser::ParseNumericConstant() {
-  SmallString<512> IntegerBuffer;
-  IntegerBuffer.resize(Tok.getLength());
-  const char *ThisTokBegin = &IntegerBuffer[0];
-  
-  // Get the spelling of the token, which eliminates trigraphs, etc.  Notes:
-  // - We know that ThisTokBuf points to a buffer that is big enough for the 
-  //   whole token and 'spelled' tokens can only shrink.
-  // - In practice, the local buffer is only used when the spelling doesn't
-  //   match the original token (which is rare). The common case simply returns
-  //   a pointer to a *constant* buffer (avoiding a copy). 
-  
-  unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
-  ExprResult Res;
-
-  if (ActualLength == 1) {
-	// need to change interface...just a placeholder
-    Res = Actions.ParseIntegerLiteral(Tok.getLocation()); 
-  } else if (ActualLength > 1) {
-    const char *ThisTokEnd = ThisTokBegin+ActualLength; 
-    const char *s = ThisTokBegin;
-    unsigned int radix;
-    
-    if (*s == '0') { // parse radix
-      s++;
-      if (*s == 'x' || *s == 'X') {
-        s++;
-        radix = 16;
-        while (s < ThisTokEnd && isxdigit(*s)) *s++;
-      } else {
-        radix = 8;
-        while (s < ThisTokEnd && ((*s >= '0') && (*s <= '7'))) *s++;
-      }
-    } else { // the first digit is non-zero
-      radix = 10;
-      while (s < ThisTokEnd && isdigit(*s)) *s++;
-    }
-    
-    if (*s == '.') { // TODO: Parse Floats...
-      Res = Actions.ParseFloatingLiteral(Tok.getLocation());
-    } else {
-      int unsigned_cnt = 0, long_cnt = 0, invalid_suffix = 0;
-
-      // if there is no suffix, this loop won't be executed (s == ThisTokEnd)
-      while (s < ThisTokEnd && !invalid_suffix) {
-        // parse type suffix - they can appear in any order "ul", "lu", "llu"
-        if (*s == 'u' || *s == 'U') {
-          unsigned_cnt++;
-          if (unsigned_cnt == 2)
-            invalid_suffix = 1;
-          else
-            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 = 1;
-          else
-            s++;
-        } else {
-          invalid_suffix = 1;
-        }
-      }
-      if (invalid_suffix) {
-        Diag(Tok, diag::err_invalid_suffix_integer_constant);
-        return ExprResult(true);
-      } else {
-        // need to change interface...just a placeholder
-        Res = Actions.ParseIntegerLiteral(Tok.getLocation()); 
-      }
-    }
-  }
-}

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

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.cpp (original)
+++ cfe/cfe/trunk/Sema/Sema.cpp Wed Jul 11 11:43:27 2007
@@ -30,6 +30,10 @@
   PP.Diag(Loc, DiagID, Msg);
 }
 
+void Sema::Diag(const LexerToken &Tok, unsigned DiagID, const std::string &M) {
+  Diag(Tok.getLocation(), DiagID, M);
+}
+
 const LangOptions &Sema::getLangOptions() const {
   return PP.getLangOptions();
 }

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

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:43:27 2007
@@ -30,6 +30,7 @@
   class TypeRef;
   class LangOptions;
   class DeclaratorChunk;
+  class LexerToken;
   
 /// Sema - This implements semantic analysis and AST building for C.
 class Sema : public Action {
@@ -53,6 +54,8 @@
   
   void Diag(SourceLocation Loc, unsigned DiagID,
             const std::string &Msg = std::string());
+  void Diag(const LexerToken &Tok, unsigned DiagID,
+            const std::string &M = std::string());
   
   //===--------------------------------------------------------------------===//
   // Type Analysis / Processing: SemaType.cpp.
@@ -155,8 +158,7 @@
                                          bool HasTrailingLParen);
   virtual ExprResult ParseSimplePrimaryExpr(SourceLocation Loc,
                                             tok::TokenKind Kind);
-  virtual ExprResult ParseIntegerLiteral(SourceLocation Loc);
-  virtual ExprResult ParseFloatingLiteral(SourceLocation Loc);
+  virtual ExprResult ParseNumericConstant(const LexerToken &);
   virtual ExprResult ParseParenExpr(SourceLocation L, SourceLocation R,
                                     ExprTy *Val);
 

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:27 2007
@@ -285,11 +285,234 @@
   }
 }
 
-Sema::ExprResult Sema::ParseIntegerLiteral(SourceLocation Loc) {
-  return new IntegerLiteral();
-}
-Sema::ExprResult Sema::ParseFloatingLiteral(SourceLocation Loc) {
-  return new FloatingLiteral();
+///       integer-constant: [C99 6.4.4.1]
+///         decimal-constant integer-suffix
+///         octal-constant integer-suffix
+///         hexadecimal-constant integer-suffix
+///       decimal-constant: 
+///         nonzero-digit
+///         decimal-constant digit
+///       octal-constant: 
+///         0
+///         octal-constant octal-digit
+///       hexadecimal-constant: 
+///         hexadecimal-prefix hexadecimal-digit
+///         hexadecimal-constant hexadecimal-digit
+///       hexadecimal-prefix: one of
+///         0x 0X
+///       integer-suffix:
+///         unsigned-suffix [long-suffix]
+///         unsigned-suffix [long-long-suffix]
+///         long-suffix [unsigned-suffix]
+///         long-long-suffix [unsigned-sufix]
+///       nonzero-digit:
+///         1 2 3 4 5 6 7 8 9
+///       octal-digit:
+///         0 1 2 3 4 5 6 7
+///       hexadecimal-digit:
+///         0 1 2 3 4 5 6 7 8 9
+///         a b c d e f
+///         A B C D E F
+///       unsigned-suffix: one of
+///         u U
+///       long-suffix: one of
+///         l L
+///       long-long-suffix: one of 
+///         ll LL
+///
+///       floating-constant: [C99 6.4.4.2]
+///         TODO: add rules...
+///
+Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
+  SmallString<512> IntegerBuffer;
+  IntegerBuffer.resize(Tok.getLength());
+  const char *ThisTokBegin = &IntegerBuffer[0];
+  
+  // Get the spelling of the token, which eliminates trigraphs, etc.  Notes:
+  // - We know that ThisTokBuf points to a buffer that is big enough for the 
+  //   whole token and 'spelled' tokens can only shrink.
+  // - In practice, the local buffer is only used when the spelling doesn't
+  //   match the original token (which is rare). The common case simply returns
+  //   a pointer to a *constant* buffer (avoiding a copy). 
+  
+  unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
+  ExprResult Res;
+
+  // This is an optimization for single digits (which are very common).
+  if (ActualLength == 1) {
+    return ExprResult(new IntegerLiteral());
+  }
+  const char *ThisTokEnd = ThisTokBegin+ActualLength; 
+  const char *s = ThisTokBegin;
+  unsigned int radix;
+  bool saw_exponent = false, saw_period = false;
+  Expr *literal_expr = 0;
+  
+  if (*s == '0') { // parse radix
+    s++;
+    if ((*s == 'x' || *s == 'X') && isxdigit(s[1])) { // need 1 digit
+      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;
+      }
+      if (saw_period && !saw_exponent) { 
+        Diag(Tok, diag::err_hexconstant_requires_exponent);
+        return ExprResult(true);
+      }
+    } 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;
+      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++;
+      } 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;
+        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);
+        }
+        break;
+      } else
+        break;
+    }
+  }
+
+  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 == 'f' || *s == 'F') {
+        if (saw_float_suffix) {
+          invalid_suffix = true;
+          break;
+        } else {
+          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;
+      }
+    }
+    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;
+
+    // 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++;
+        }
+      } 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 {
+          s++;
+        }
+      } else {
+        invalid_suffix = true;
+        break;
+      }
+    }
+    if (invalid_suffix) {
+      Diag(Tok, diag::err_invalid_suffix_integer_constant, 
+           std::string(suffix_start, ThisTokEnd));
+      return ExprResult(true);
+    }
+    literal_expr = new IntegerLiteral();
+  }
+  return ExprResult(literal_expr);
 }
 
 Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,

Modified: cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=39349&r1=39348&r2=39349&view=diff

==============================================================================
--- cfe/cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/cfe/trunk/clang.xcodeproj/project.pbxproj Wed Jul 11 11:43:27 2007
@@ -94,23 +94,6 @@
 		DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
 /* End PBXBuildFile section */
 
-/* Begin PBXBuildStyle section */
-		842065AF0B98D65200CA7A69 /* Development */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-				COPY_PHASE_STRIP = NO;
-			};
-			name = Development;
-		};
-		842065B00B98D65200CA7A69 /* Deployment */ = {
-			isa = PBXBuildStyle;
-			buildSettings = {
-				COPY_PHASE_STRIP = YES;
-			};
-			name = Deployment;
-		};
-/* End PBXBuildStyle section */
-
 /* Begin PBXCopyFilesBuildPhase section */
 		8DD76F690486A84900D96B5E /* CopyFiles */ = {
 			isa = PBXCopyFilesBuildPhase;
@@ -493,15 +476,12 @@
 		08FB7793FE84155DC02AAC07 /* Project object */ = {
 			isa = PBXProject;
 			buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
-			buildSettings = {
-			};
-			buildStyles = (
-				842065AF0B98D65200CA7A69 /* Development */,
-				842065B00B98D65200CA7A69 /* Deployment */,
-			);
+			compatibilityVersion = "Xcode 2.4";
 			hasScannedForEncodings = 1;
 			mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
 			projectDirPath = "";
+			projectRoot = "";
+			shouldCheckCompatibility = 1;
 			targets = (
 				8DD76F620486A84900D96B5E /* clang */,
 			);

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=39349&r1=39348&r2=39349&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:27 2007
@@ -471,7 +471,15 @@
 DIAG(err_alignof_incomplete_type, ERROR,
      "invalid application of '__alignof' to an incomplete type '%s'")
 DIAG(err_invalid_suffix_integer_constant, ERROR,
-     "invalid suffix on integer constant")
+     "invalid suffix '%s' on integer constant")
+DIAG(err_invalid_suffix_float_constant, ERROR,
+     "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")
 
 // Statements.
 DIAG(err_continue_not_in_loop, ERROR,

Modified: cfe/cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Action.h?rev=39349&r1=39348&r2=39349&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:43:27 2007
@@ -263,8 +263,7 @@
                                             tok::TokenKind Kind) {
     return 0;
   }
-  virtual ExprResult ParseIntegerLiteral(SourceLocation Loc) { return 0; }
-  virtual ExprResult ParseFloatingLiteral(SourceLocation Loc) { return 0; }
+  virtual ExprResult ParseNumericConstant(const LexerToken &) { return 0; }
   
   /// ParseStringLiteral - The specified tokens were lexed as pasted string
   /// fragments (e.g. "foo" "bar" L"baz").

Modified: cfe/cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/Parser.h?rev=39349&r1=39348&r2=39349&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:43:27 2007
@@ -291,7 +291,6 @@
     return ParseParenExpression(Op, CastTy, RParenLoc);
   }
   ExprResult ParseStringLiteralExpression();
-  ExprResult ParseNumericConstant();
   
   //===--------------------------------------------------------------------===//
   // C++ 5.2p1: C++ Casts





More information about the cfe-commits mailing list