[cfe-commits] r39351 - in /cfe/cfe/trunk: AST/SemaExpr.cpp Lex/LiteralSupport.cpp Sema/SemaExpr.cpp clang.xcodeproj/project.pbxproj include/clang/AST/Expr.h include/clang/Lex/LiteralSupport.h

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


Author: snaroff
Date: Wed Jul 11 11:43:29 2007
New Revision: 39351

URL: http://llvm.org/viewvc/llvm-project?rev=39351&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Moved numeric literal support from SemaExpr.cpp to LiteralSupport.[h,cpp]
in Lex. This will allow it to be used by both Sema and Preprocessor (and
should be the last major refactoring of this sub-system).. Over
time, it will be reused by anyone implementing an actions module (i.e.
any subclass of llvm::clang::Action. Minor changes to IntegerLiteral in Expr.h.
More to come...

Added:
    cfe/cfe/trunk/Lex/LiteralSupport.cpp   (with props)
    cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h   (with props)
Modified:
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/cfe/trunk/include/clang/AST/Expr.h

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:29 2007
@@ -16,6 +16,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
@@ -24,7 +25,7 @@
 using namespace llvm;
 using namespace clang;
 
-
+#include <iostream>
 
 /// HexDigitValue - Return the value of the specified hex digit, or -1 if it's
 /// not valid.
@@ -285,68 +286,6 @@
   }
 }
 
-/// 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
-///         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());
@@ -360,148 +299,37 @@
   //   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());
+  if (ActualLength == 1)
+    return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
+    
+  NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, 
+                               Tok.getLocation(), PP, Context.Target);
+  if (Literal.hadError) {
+    return ExprResult(true);
   }
-  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]) || s[1] == '.')) {
-      s++;
-      radix = 16;
-      s = SkipHexDigits(s, ThisTokEnd);
-      if (s == ThisTokEnd) {
-      } else if (*s == '.') {
-        s++;
-        saw_period = true;
-        s = SkipHexDigits(s, ThisTokEnd);
-      }
-      // 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);
-      }
+  Expr *literal_expr;
+    
+  if (Literal.isIntegerLiteral()) {
+    TypeRef t;
+    if (Literal.hasSuffix()) {
+      if (Literal.isLong) 
+        t = Literal.isUnsigned ? Context.UnsignedLongTy : Context.LongTy;
+      else if (Literal.isLongLong) 
+        t = Literal.isUnsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
+      else 
+        t = Context.UnsignedIntTy;
     } 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;
-      s = SkipOctalDigits(s, ThisTokEnd);
-      if (s == ThisTokEnd) {
-      } else if (*s == '.') {
-        s++;
-        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
-        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;
-        }
-      }
+      t = Context.IntTy; // implicit type is "int"
     }
-  } 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);
+    intmax_t val;
+    if (Literal.GetValue(val)) {
+      literal_expr = new IntegerLiteral(val, t);
     } 
-    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;
-  
-  if (saw_period || saw_exponent) {
-    bool saw_float_suffix = false, saw_long_suffix = false;
-    
-    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') {
-        saw_long_suffix = true;
-        s++;
-      }
-      if (s != ThisTokEnd) {
-        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, 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) break; // only allowed to have one 
-        saw_unsigned = true;
-        s++;
-      } else if (*s == 'l' || *s == 'L') {
-        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 {
-        break;
-      }
-    }
-    if (s != ThisTokEnd) {
-      Diag(Tok, diag::err_invalid_suffix_integer_constant, 
-           std::string(suffix_start, ThisTokEnd));
-      return ExprResult(true);
-    }
-    literal_expr = new IntegerLiteral();
+  } else if (Literal.isFloatingLiteral()) {
+    // TODO: add floating point processing...
   }
-  return ExprResult(literal_expr);
 }
 
 Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,

Added: cfe/cfe/trunk/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/LiteralSupport.cpp?rev=39351&view=auto

==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (added)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:43:29 2007
@@ -0,0 +1,244 @@
+//===--- LiteralSupport.cpp - Code to parse and process literals-*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Steve Naroff and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the NumericLiteralParser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Lex/LiteralSupport.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Diagnostic.h"
+
+using namespace llvm;
+using namespace clang;
+
+///       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...
+///
+
+NumericLiteralParser::
+NumericLiteralParser(const char *begin, const char *end,
+                     SourceLocation TokLoc, Preprocessor &pp, TargetInfo &t) :
+  PP(pp), Target(t), ThisTokBegin(begin), ThisTokEnd(end)
+{
+  s = DigitsBegin = begin;
+  saw_exponent = false;
+  saw_period = false;
+  saw_float_suffix = false;
+  isLong = false;
+  isUnsigned = false;
+  isLongLong = false;
+  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) {
+      } 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') { 
+        s++;
+        saw_exponent = true;
+        if (*s == '+' || *s == '-')  s++; // sign
+        const char *first_non_digit = SkipDigits(s);
+        if (first_non_digit == s) {
+          Diag(TokLoc, diag::err_exponent_has_no_digits);
+          return;
+        } else {
+          s = first_non_digit;
+        }
+      } else if (saw_period) {
+        Diag(TokLoc, diag::err_hexconstant_requires_exponent);
+        return;
+      }
+    } 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) {
+      } else if (*s == '.') {
+        s++;
+        radix = 10;
+        saw_period = true;
+        s = SkipDigits(s);
+      }
+      if (*s == 'e' || *s == 'E') { // exponent
+        s++;
+        radix = 10;
+        saw_exponent = true;
+        if (*s == '+' || *s == '-')  s++; // sign
+        const char *first_non_digit = SkipDigits(s);
+        if (first_non_digit == s) {
+          Diag(TokLoc, diag::err_exponent_has_no_digits);
+          return;
+        } else {
+          s = first_non_digit;
+        }
+      }
+    }
+  } else { // the first digit is non-zero
+    radix = 10;
+    s = SkipDigits(s);
+    if (s == ThisTokEnd) {
+    } else if (*s == '.') {
+      s++;
+      saw_period = true;
+      s = SkipDigits(s);
+    } 
+    if (*s == 'e' || *s == 'E') { // exponent
+      s++;
+      saw_exponent = true;
+      if (*s == '+' || *s == '-')  s++; // sign
+      const char *first_non_digit = SkipDigits(s);
+      if (first_non_digit == s) {
+        Diag(TokLoc, diag::err_exponent_has_no_digits);
+        return;
+      } else {
+        s = first_non_digit;
+      }
+    }
+  }
+
+  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') {
+        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;
+      }
+    }
+  }
+}
+
+bool NumericLiteralParser::GetValue(intmax_t &val) {
+  intmax_t cutoff = INTMAX_MAX;
+  int cutlim = cutoff % radix;
+  char c;
+  
+  val = 0;
+  cutoff /= radix;
+  s = DigitsBegin;
+  while (s < SuffixBegin) {
+    c = *s++;
+    if (c >= '0' && c <= '9')
+      c -= '0';
+    else if (c >= 'A' && c <= 'F') // 10...15
+      c -= 'A' - 10;
+    else if (c >= 'a' && c <= 'f') // 10...15
+      c -= 'a' - 10;
+    
+    if (val > cutoff || (val == cutoff && c > cutlim)) {
+      return false; // Overflow!
+    } else {
+      val *= radix;
+      val += c;
+    }
+  }
+  return true;
+}

Propchange: cfe/cfe/trunk/Lex/LiteralSupport.cpp

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/cfe/trunk/Lex/LiteralSupport.cpp

------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:29 2007
@@ -16,6 +16,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
@@ -24,7 +25,7 @@
 using namespace llvm;
 using namespace clang;
 
-
+#include <iostream>
 
 /// HexDigitValue - Return the value of the specified hex digit, or -1 if it's
 /// not valid.
@@ -285,68 +286,6 @@
   }
 }
 
-/// 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
-///         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());
@@ -360,148 +299,37 @@
   //   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());
+  if (ActualLength == 1)
+    return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
+    
+  NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, 
+                               Tok.getLocation(), PP, Context.Target);
+  if (Literal.hadError) {
+    return ExprResult(true);
   }
-  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]) || s[1] == '.')) {
-      s++;
-      radix = 16;
-      s = SkipHexDigits(s, ThisTokEnd);
-      if (s == ThisTokEnd) {
-      } else if (*s == '.') {
-        s++;
-        saw_period = true;
-        s = SkipHexDigits(s, ThisTokEnd);
-      }
-      // 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);
-      }
+  Expr *literal_expr;
+    
+  if (Literal.isIntegerLiteral()) {
+    TypeRef t;
+    if (Literal.hasSuffix()) {
+      if (Literal.isLong) 
+        t = Literal.isUnsigned ? Context.UnsignedLongTy : Context.LongTy;
+      else if (Literal.isLongLong) 
+        t = Literal.isUnsigned ? Context.UnsignedLongLongTy : Context.LongLongTy;
+      else 
+        t = Context.UnsignedIntTy;
     } 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;
-      s = SkipOctalDigits(s, ThisTokEnd);
-      if (s == ThisTokEnd) {
-      } else if (*s == '.') {
-        s++;
-        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
-        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;
-        }
-      }
+      t = Context.IntTy; // implicit type is "int"
     }
-  } 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);
+    intmax_t val;
+    if (Literal.GetValue(val)) {
+      literal_expr = new IntegerLiteral(val, t);
     } 
-    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;
-  
-  if (saw_period || saw_exponent) {
-    bool saw_float_suffix = false, saw_long_suffix = false;
-    
-    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') {
-        saw_long_suffix = true;
-        s++;
-      }
-      if (s != ThisTokEnd) {
-        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, 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) break; // only allowed to have one 
-        saw_unsigned = true;
-        s++;
-      } else if (*s == 'l' || *s == 'L') {
-        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 {
-        break;
-      }
-    }
-    if (s != ThisTokEnd) {
-      Diag(Tok, diag::err_invalid_suffix_integer_constant, 
-           std::string(suffix_start, ThisTokEnd));
-      return ExprResult(true);
-    }
-    literal_expr = new IntegerLiteral();
+  } else if (Literal.isFloatingLiteral()) {
+    // TODO: add floating point processing...
   }
-  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=39351&r1=39350&r2=39351&view=diff

==============================================================================
--- cfe/cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/cfe/trunk/clang.xcodeproj/project.pbxproj Wed Jul 11 11:43:29 2007
@@ -8,6 +8,8 @@
 
 /* Begin PBXBuildFile section */
 		1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; };
+		1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; };
+		1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; };
 		DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; };
 		DE06B73E0A8307640050E87E /* LangOptions.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06B73D0A8307640050E87E /* LangOptions.h */; };
 		DE06BECB0A854E4B0050E87E /* Scope.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06BECA0A854E4B0050E87E /* Scope.h */; };
@@ -145,6 +147,7 @@
 				DED67AEE0B6DB92A00AAD4A3 /* X86Builtins.def in CopyFiles */,
 				DED67AF00B6DB92F00AAD4A3 /* PPCBuiltins.def in CopyFiles */,
 				1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */,
+				1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */,
 			);
 			runOnlyForDeploymentPostprocessing = 1;
 		};
@@ -152,6 +155,8 @@
 
 /* Begin PBXFileReference section */
 		1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
+		1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
+		1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
 		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
 		DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
 		DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
@@ -415,6 +420,7 @@
 				DED7D73F0A524295003AD0FB /* Pragma.h */,
 				DED7D7400A524295003AD0FB /* Preprocessor.h */,
 				DED7D9170A52518C003AD0FB /* ScratchBuffer.h */,
+				1A869A6E0BA2164C008DA07A /* LiteralSupport.h */,
 			);
 			name = Lex;
 			path = clang/Lex;
@@ -436,6 +442,7 @@
 		DED7D78C0A5242E6003AD0FB /* Lex */ = {
 			isa = PBXGroup;
 			children = (
+				1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */,
 				DE344B530AE5E46C00DBC861 /* HeaderSearch.cpp */,
 				DED7D79D0A5242E6003AD0FB /* IdentifierTable.cpp */,
 				DED7D79E0A5242E6003AD0FB /* Lexer.cpp */,
@@ -534,6 +541,7 @@
 				DE17336E0B068DC20080B521 /* DeclSpec.cpp in Sources */,
 				DE1737A90B0847BC0080B521 /* SemaType.cpp in Sources */,
 				DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */,
+				1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: cfe/cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Expr.h?rev=39351&r1=39350&r2=39351&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:43:29 2007
@@ -60,9 +60,30 @@
   static bool classof(const DeclRefExpr *) { return true; }
 };
 
+
+// FIXME: The "type" will eventually be moved to Stmt.
 class IntegerLiteral : public Expr {
-public:
-  IntegerLiteral() : Expr(IntegerLiteralClass) {}
+  TypeRef Type; // IntTy, LongTy, LongLongTy
+                // UnsignedIntTy, UnsignedLongTy, UnsignedLongLongTy
+  intmax_t Value;
+public:
+  // FIXME: To satisfy some of the current adhoc usage...
+  IntegerLiteral() : Expr(IntegerLiteralClass),
+     Type(0), Value(0) {
+  }
+  // constructor for the single digit case
+  IntegerLiteral(intmax_t value) : Expr(IntegerLiteralClass), 
+     Type(0), Value(value) {
+  }
+  IntegerLiteral(intmax_t value, TypeRef type)
+    : Expr(IntegerLiteralClass), Type(type), Value(value) {
+#if 0
+      std::cout << "Value=" << Value;
+      std::cout << " Type= ";
+      std::cout << static_cast<BuiltinType *>(type.getTypePtr())->getName();
+      std::cout << "\n";
+#endif
+  }
   virtual void visit(StmtVisitor &Visitor);
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == IntegerLiteralClass; 

Added: cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h?rev=39351&view=auto

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h (added)
+++ cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h Wed Jul 11 11:43:29 2007
@@ -0,0 +1,101 @@
+//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Steve Naroff and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the NumericLiteralParser interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LITERALSUPPORT_H
+#define LLVM_CLANG_LITERALSUPPORT_H
+
+#include "clang/Lex/Preprocessor.h"
+
+namespace llvm {
+namespace clang {
+
+class Diagnostic;
+class Preprocessor;
+class TargetInfo;
+    
+struct NumericLiteralParser {
+  NumericLiteralParser(const char *begin, const char *end,
+                       SourceLocation Loc, Preprocessor &PP, TargetInfo &T);
+private:
+  Preprocessor &PP; // needed for diagnostics
+  TargetInfo &Target; // needed to compute the size
+  
+  const char *const ThisTokBegin;
+  const char *const ThisTokEnd;
+  const char *DigitsBegin, *SuffixBegin; // markers
+  const char *s; // cursor
+  
+  unsigned int radix;
+  
+  bool saw_exponent, saw_period;
+  bool saw_float_suffix;
+  
+public:
+  bool hadError;
+  bool isUnsigned;
+  bool isLong;
+  bool isLongLong;
+  
+  bool isIntegerLiteral() { 
+    return !saw_period && !saw_exponent ? true : false;
+  }
+  bool isFloatingLiteral() {
+    return saw_period || saw_exponent ? true : false;
+  }
+  bool hasSuffix() {
+    return SuffixBegin != ThisTokEnd;
+  }
+  /// getValue - Convert the string into a number. At this point, we know
+  /// the digit characters are valid (0...9, a...f, A...F). We don't know
+  /// how many bits are needed to store the number. We return true if the
+  /// value fit into intmax_t (typically 64-bit's), false otherwise. This
+  /// API will likely be replaced by sizing hooks and APInt. Nevertheless,
+  /// this provides basic conversion support for now.
+  bool GetValue(intmax_t &val);
+
+private:  
+  void Diag(SourceLocation Loc, unsigned DiagID, 
+            const std::string &M = std::string()) {
+    PP.Diag(Loc, DiagID, M);
+    hadError = true;
+  }
+  
+  /// 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) {
+    while (ptr != ThisTokEnd && 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.
+  const char *SkipOctalDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && ((*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.
+  const char *SkipDigits(const char *ptr) {
+    while (ptr != ThisTokEnd && isdigit(*ptr))
+      ptr++;
+    return ptr;
+  }
+};
+  
+}  // end namespace clang
+}  // end namespace llvm
+
+#endif
\ No newline at end of file

Propchange: cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h

------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h

------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision





More information about the cfe-commits mailing list