[cfe-commits] r39353 - in /cfe/cfe/trunk: AST/SemaExpr.cpp Lex/LiteralSupport.cpp Lex/PPExpressions.cpp Sema/SemaExpr.cpp 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:30 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:43:30 2007
New Revision: 39353

URL: http://llvm.org/viewvc/llvm-project?rev=39353&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
Misc. cleanup/polish of NumericLiteralParser and it's two clients, the
C preprocessor and AST builder...

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/AST/Expr.h
    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=39353&r1=39352&r2=39353&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:43:30 2007
@@ -17,6 +17,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/LiteralSupport.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
@@ -287,6 +288,12 @@
 }
 
 Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
+  // fast path for a single digit (which is quite common). A single digit 
+  // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
+  if (Tok.getLength() == 1) {
+    const char *t = PP.getSourceManager().getCharacterData(Tok.getLocation());
+    return ExprResult(new IntegerLiteral(*t-'0', Context.IntTy));
+  }
   SmallString<512> IntegerBuffer;
   IntegerBuffer.resize(Tok.getLength());
   const char *ThisTokBegin = &IntegerBuffer[0];
@@ -299,15 +306,11 @@
   //   a pointer to a *constant* buffer (avoiding a copy). 
   
   unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
-
-  // This is an optimization for single digits (which are very common).
-  if (ActualLength == 1)
-    return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
-    
   NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, 
                                Tok.getLocation(), PP);
-  Expr *literal_expr = 0;
-    
+  if (Literal.hadError)
+    return ExprResult(true);
+
   if (Literal.isIntegerLiteral()) {
     TypeRef t;
     if (Literal.hasSuffix()) {
@@ -322,12 +325,12 @@
     }
     uintmax_t val;
     if (Literal.GetIntegerValue(val)) {
-      literal_expr = new IntegerLiteral(val, t);
+      return new IntegerLiteral(val, t);
     } 
   } else if (Literal.isFloatingLiteral()) {
     // TODO: add floating point processing...
   }
-  return literal_expr ? ExprResult(literal_expr) : ExprResult(true);
+  return 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=39353&r1=39352&r2=39353&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (original)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:43:30 2007
@@ -217,8 +217,8 @@
 }
 
 bool NumericLiteralParser::GetIntegerValue(uintmax_t &val) {
-  uintmax_t cutoff = UINTMAX_MAX / radix;
-  int cutlim = UINTMAX_MAX % radix;
+  uintmax_t max_value = UINTMAX_MAX / radix;
+  int max_digit = UINTMAX_MAX % radix;
   char c;
   
   val = 0;
@@ -227,12 +227,12 @@
     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
+    else if (c >= 'A' && c <= 'F') 
+      c -= 'A' - 10; 
+    else if (c >= 'a' && c <= 'f') 
       c -= 'a' - 10;
     
-    if (val > cutoff || (val == cutoff && c > cutlim)) {
+    if (val > max_value || (val == max_value && c > max_digit)) {
       return false; // Overflow!
     } else {
       val *= radix;
@@ -243,8 +243,8 @@
 }
 
 bool NumericLiteralParser::GetIntegerValue(int &val) {
-  intmax_t cutoff = INT_MAX / radix;
-  int cutlim = INT_MAX % radix;
+  intmax_t max_value = INT_MAX / radix;
+  int max_digit = INT_MAX % radix;
   char c;
   
   val = 0;
@@ -253,12 +253,12 @@
     c = *s++;
     if (c >= '0' && c <= '9')
       c -= '0';
-    else if (c >= 'A' && c <= 'F') // 10...15
+    else if (c >= 'A' && c <= 'F') 
       c -= 'A' - 10;
-    else if (c >= 'a' && c <= 'f') // 10...15
+    else if (c >= 'a' && c <= 'f')
       c -= 'a' - 10;
     
-    if (val > cutoff || (val == cutoff && c > cutlim)) {
+    if (val > max_value || (val == max_value && c > max_digit)) {
       return false; // Overflow!
     } else {
       val *= radix;
@@ -267,3 +267,9 @@
   }
   return true;
 }
+
+void NumericLiteralParser::Diag(SourceLocation Loc, unsigned DiagID, 
+          const std::string &M) {
+  PP.Diag(Loc, DiagID, M);
+  hadError = true;
+}

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

==============================================================================
--- cfe/cfe/trunk/Lex/PPExpressions.cpp (original)
+++ cfe/cfe/trunk/Lex/PPExpressions.cpp Wed Jul 11 11:43:30 2007
@@ -145,20 +145,33 @@
     PP.Diag(PeekTok, diag::err_pp_expected_value_in_expr);
     return true;
   case tok::numeric_constant: {
-    // 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()) {
+    if (Literal.hadError) 
+      return true; // a diagnostic was already reported.
+    else if (Literal.isIntegerLiteral()) {
+      if (!Literal.GetIntegerValue(Result)) {
+        // FIXME: C99 (6.10.1) dictates that all preprocessor arithmetic be
+        // performed using the largest integer type found on the target 
+        // computer, which is intmax_t (the default) or uintmax_t (if the 
+        // literal contains an unsigned suffix) defined in stdint.h.
+        // Since "Result" is typed as "int", the maximum legal integer 
+        // literal is currently INT32_MAX (or 2147483647). If the literal
+        // value is larger, we will overflow and trigger this assert.
+        assert(0 && "Integer Overflow in preprocessor expression"); 
+        return true;
+      }
+      PP.LexNonComment(PeekTok);
+      return false;
+    } else {
+      assert(Literal.isFloatingLiteral() && "Unknown ppnumber");
       PP.Diag(PeekTok, diag::err_pp_illegal_floating_literal);
+      return true;
     }
-    PP.LexNonComment(PeekTok);
-    return false;
   }
   case tok::l_paren:
     PP.LexNonComment(PeekTok);  // Eat the (.

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:43:30 2007
@@ -17,6 +17,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/LiteralSupport.h"
+#include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
@@ -287,6 +288,12 @@
 }
 
 Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
+  // fast path for a single digit (which is quite common). A single digit 
+  // cannot have a trigraph, escaped newline, radix prefix, or type suffix.
+  if (Tok.getLength() == 1) {
+    const char *t = PP.getSourceManager().getCharacterData(Tok.getLocation());
+    return ExprResult(new IntegerLiteral(*t-'0', Context.IntTy));
+  }
   SmallString<512> IntegerBuffer;
   IntegerBuffer.resize(Tok.getLength());
   const char *ThisTokBegin = &IntegerBuffer[0];
@@ -299,15 +306,11 @@
   //   a pointer to a *constant* buffer (avoiding a copy). 
   
   unsigned ActualLength = PP.getSpelling(Tok, ThisTokBegin);
-
-  // This is an optimization for single digits (which are very common).
-  if (ActualLength == 1)
-    return ExprResult(new IntegerLiteral(atoi(ThisTokBegin)));
-    
   NumericLiteralParser Literal(ThisTokBegin, ThisTokBegin+ActualLength, 
                                Tok.getLocation(), PP);
-  Expr *literal_expr = 0;
-    
+  if (Literal.hadError)
+    return ExprResult(true);
+
   if (Literal.isIntegerLiteral()) {
     TypeRef t;
     if (Literal.hasSuffix()) {
@@ -322,12 +325,12 @@
     }
     uintmax_t val;
     if (Literal.GetIntegerValue(val)) {
-      literal_expr = new IntegerLiteral(val, t);
+      return new IntegerLiteral(val, t);
     } 
   } else if (Literal.isFloatingLiteral()) {
     // TODO: add floating point processing...
   }
-  return literal_expr ? ExprResult(literal_expr) : ExprResult(true);
+  return ExprResult(true);
 }
 
 Action::ExprResult Sema::ParseParenExpr(SourceLocation L, SourceLocation R,

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Expr.h Wed Jul 11 11:43:30 2007
@@ -71,10 +71,6 @@
   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

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h Wed Jul 11 11:43:30 2007
@@ -14,19 +14,17 @@
 #ifndef LLVM_CLANG_LITERALSUPPORT_H
 #define LLVM_CLANG_LITERALSUPPORT_H
 
-#include "clang/Lex/Preprocessor.h"
+#include <string>
 
 namespace llvm {
 namespace clang {
 
 class Diagnostic;
 class Preprocessor;
+class SourceLocation;
 class TargetInfo;
     
-struct NumericLiteralParser {
-  NumericLiteralParser(const char *begin, const char *end,
-                       SourceLocation Loc, Preprocessor &PP);
-private:
+class NumericLiteralParser {
   Preprocessor &PP; // needed for diagnostics
   
   const char *const ThisTokBegin;
@@ -40,35 +38,34 @@
   bool saw_float_suffix;
   
 public:
+  NumericLiteralParser(const char *begin, const char *end,
+                       SourceLocation Loc, Preprocessor &PP);
   bool hadError;
   bool isUnsigned;
   bool isLong;
   bool isLongLong;
   
-  bool isIntegerLiteral() { 
-    return !saw_period && !saw_exponent && !hadError ? true : false;
+  bool isIntegerLiteral() const { 
+    return !saw_period && !saw_exponent ? true : false;
   }
-  bool isFloatingLiteral() {
-    return saw_period || saw_exponent && !hadError ? true : false;
+  bool isFloatingLiteral() const {
+    return saw_period || saw_exponent ? true : false;
   }
-  bool hasSuffix() {
+  bool hasSuffix() const {
     return SuffixBegin != ThisTokEnd;
   }
   /// 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. 
+  /// will be done elsewhere - the size computation is target dependent. We  
+  /// return true if the value fit into "val", false otherwise. 
   bool GetIntegerValue(uintmax_t &val);
   bool GetIntegerValue(int &val);
 
 private:  
   void Diag(SourceLocation Loc, unsigned DiagID, 
-            const std::string &M = std::string()) {
-    PP.Diag(Loc, DiagID, M);
-    hadError = true;
-  }
+            const std::string &M = std::string());
   
   /// SkipHexDigits - Read and skip over any hex digits, up to End.
   /// Return a pointer to the first non-hex digit or End.





More information about the cfe-commits mailing list