[cfe-commits] r39352 - in /cfe/cfe/trunk: AST/SemaExpr.cpp Lex/LiteralSupport.cpp Lex/PPExpressions.cpp Sema/SemaExpr.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Lex/LiteralSupport.h

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


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

URL: http://llvm.org/viewvc/llvm-project?rev=39352&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
-Converted the preprocessor to use NumericLiteralParser.
-Several minor changes to LiteralSupport interface/implementation.
-Added an error diagnostic for floating point usage in pp expr's.

Modified:
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/Lex/LiteralSupport.cpp
    cfe/cfe/trunk/Lex/PPExpressions.cpp
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:29 2007
@@ -305,11 +305,8 @@
     return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
     
   NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, 
-                               Tok.getLocation(), PP, Context.Target);
-  if (Literal.hadError) {
-    return ExprResult(true);
-  }
-  Expr *literal_expr;
+                               Tok.getLocation(), PP);
+  Expr *literal_expr = 0;
     
   if (Literal.isIntegerLiteral()) {
     TypeRef t;
@@ -323,13 +320,14 @@
     } else {
       t = Context.IntTy; // implicit type is "int"
     }
-    intmax_t val;
-    if (Literal.GetValue(val)) {
+    uintmax_t val;
+    if (Literal.GetIntegerValue(val)) {
       literal_expr = new IntegerLiteral(val, t);
     } 
   } else if (Literal.isFloatingLiteral()) {
     // TODO: add floating point processing...
   }
+  return literal_expr ? ExprResult(literal_expr) : ExprResult(true);
 }
 
 Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,

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

==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (original)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:43:29 2007
@@ -60,8 +60,8 @@
 
 NumericLiteralParser::
 NumericLiteralParser(const char *begin, const char *end,
-                     SourceLocation TokLoc, Preprocessor &pp, TargetInfo &t) :
-  PP(pp), Target(t), ThisTokBegin(begin), ThisTokEnd(end)
+                     SourceLocation TokLoc, Preprocessor &pp) :
+  PP(pp), ThisTokBegin(begin), ThisTokEnd(end)
 {
   s = DigitsBegin = begin;
   saw_exponent = false;
@@ -216,13 +216,38 @@
   }
 }
 
-bool NumericLiteralParser::GetValue(intmax_t &val) {
-  intmax_t cutoff = INTMAX_MAX;
-  int cutlim = cutoff % radix;
+bool NumericLiteralParser::GetIntegerValue(uintmax_t &val) {
+  uintmax_t cutoff = UINTMAX_MAX / radix;
+  int cutlim = UINTMAX_MAX % radix;
+  char c;
+  
+  val = 0;
+  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;
+}
+
+bool NumericLiteralParser::GetIntegerValue(int &val) {
+  intmax_t cutoff = INT_MAX / radix;
+  int cutlim = INT_MAX % radix;
   char c;
   
   val = 0;
-  cutoff /= radix;
   s = DigitsBegin;
   while (s < SuffixBegin) {
     c = *s++;

Modified: cfe/cfe/trunk/Lex/PPExpressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/PPExpressions.cpp?rev=39352&r1=39351&r2=39352&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/PPExpressions.cpp (original)
+++ cfe/cfe/trunk/Lex/PPExpressions.cpp Wed Jul 11 11:43:29 2007
@@ -13,7 +13,6 @@
 //===----------------------------------------------------------------------===//
 //
 // FIXME: implement testing for asserts.
-// FIXME: Parse integer constants correctly.  Reject 123.0, etc.
 // FIXME: Track signed/unsigned correctly.
 // FIXME: Track and report integer overflow correctly.
 //
@@ -21,9 +20,11 @@
 
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/LiteralSupport.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/SmallString.h"
 using namespace llvm;
 using namespace clang;
 
@@ -144,10 +145,18 @@
     PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
     return true;
   case tok::numeric_constant: {
-    // FIXME: faster.  FIXME: track signs.
-    std::string Spell = PP.getSpelling(PeekTok);
-    // FIXME: COMPUTE integer constants CORRECTLY.
-    Result = atoi(Spell.c_str());
+    // FIXME: track signs. ?? snaroff: talk to Chris...
+    SmallString<512> IntegerBuffer;
+    IntegerBuffer.resize(PeekTok.getLength());
+    const char *ThisTokBegin = &IntegerBuffer[0];
+    unsigned ActualLength = PP.getSpelling(PeekTok, ThisTokBegin);
+    NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, 
+                                 PeekTok.getLocation(), PP);
+    if (Literal.isIntegerLiteral()) {
+      Literal.GetIntegerValue(Result);
+    } else if (Literal.isFloatingLiteral()) {
+      PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
+    }
     PP.LexNonComment(PeekTok);
     return false;
   }

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:29 2007
@@ -305,11 +305,8 @@
     return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
     
   NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, 
-                               Tok.getLocation(), PP, Context.Target);
-  if (Literal.hadError) {
-    return ExprResult(true);
-  }
-  Expr *literal_expr;
+                               Tok.getLocation(), PP);
+  Expr *literal_expr = 0;
     
   if (Literal.isIntegerLiteral()) {
     TypeRef t;
@@ -323,13 +320,14 @@
     } else {
       t = Context.IntTy; // implicit type is "int"
     }
-    intmax_t val;
-    if (Literal.GetValue(val)) {
+    uintmax_t val;
+    if (Literal.GetIntegerValue(val)) {
       literal_expr = new IntegerLiteral(val, t);
     } 
   } else if (Literal.isFloatingLiteral()) {
     // TODO: add floating point processing...
   }
+  return literal_expr ? ExprResult(literal_expr) : ExprResult(true);
 }
 
 Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,

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=39352&r1=39351&r2=39352&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:43:29 2007
@@ -237,6 +237,8 @@
      "pasting formed \"%s\", an invalid preprocessing token")
 DIAG(err_pp_operator_used_as_macro_name, ERROR,
      "C++ operator \"%s\" cannot be used as a macro name")
+DIAG(err_pp_illegal_floating_literal, ERROR,
+     "floating point literal in preprocessor expression")
 
 // Should be a sorry?
 DIAG(err_pp_I_dash_not_supported, ERROR,

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h Wed Jul 11 11:43:29 2007
@@ -25,10 +25,9 @@
     
 struct NumericLiteralParser {
   NumericLiteralParser(const char *begin, const char *end,
-                       SourceLocation Loc, Preprocessor &PP, TargetInfo &T);
+                       SourceLocation Loc, Preprocessor &PP);
 private:
   Preprocessor &PP; // needed for diagnostics
-  TargetInfo &Target; // needed to compute the size
   
   const char *const ThisTokBegin;
   const char *const ThisTokEnd;
@@ -47,21 +46,22 @@
   bool isLongLong;
   
   bool isIntegerLiteral() { 
-    return !saw_period && !saw_exponent ? true : false;
+    return !saw_period && !saw_exponent && !hadError ? true : false;
   }
   bool isFloatingLiteral() {
-    return saw_period || saw_exponent ? true : false;
+    return saw_period || saw_exponent && !hadError ? 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);
+  /// getIntegerValue - 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. Sizing of the integer
+  /// type (int, unsigned, long, unsigned long, long long, unsigned long long) 
+  /// will be done elsewhere - the computation is target dependent. We return 
+  /// true if the value fit into uintmax_t, false otherwise. 
+  bool GetIntegerValue(uintmax_t &val);
+  bool GetIntegerValue(int &val);
 
 private:  
   void Diag(SourceLocation Loc, unsigned DiagID, 





More information about the cfe-commits mailing list