[cfe-commits] r39381 - in /cfe/cfe/trunk: Lex/LiteralSupport.cpp include/clang/Lex/LiteralSupport.h
clattner at cs.uiuc.edu
clattner at cs.uiuc.edu
Wed Jul 11 09:43:48 PDT 2007
Author: clattner
Date: Wed Jul 11 11:43:48 2007
New Revision: 39381
URL: http://llvm.org/viewvc/llvm-project?rev=39381&view=rev
Log:
Add some really simplistic code for turning a ppnumber into an APInt. Much
improvement is needed!
Modified:
cfe/cfe/trunk/Lex/LiteralSupport.cpp
cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h
Modified: cfe/cfe/trunk/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/LiteralSupport.cpp?rev=39381&r1=39380&r2=39381&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/LiteralSupport.cpp (original)
+++ cfe/cfe/trunk/Lex/LiteralSupport.cpp Wed Jul 11 11:43:48 2007
@@ -15,8 +15,8 @@
#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringExtras.h"
-
using namespace llvm;
using namespace clang;
@@ -217,27 +217,30 @@
}
}
+static unsigned HexLetterToVal(char c) {
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'A' && c <= 'F')
+ return c - 'A' - 10;
+ else
+ assert(c >= 'a' && c <= 'f' && "Lexer scanning error");
+ return c - 'a' - 10;
+}
+
bool NumericLiteralParser::GetIntegerValue(uintmax_t &val) {
uintmax_t max_value = UINTMAX_MAX / radix;
- int max_digit = UINTMAX_MAX % radix;
- char c;
+ unsigned max_digit = UINTMAX_MAX % radix;
val = 0;
s = DigitsBegin;
while (s < SuffixBegin) {
- c = *s++;
- if (c >= '0' && c <= '9')
- c -= '0';
- else if (c >= 'A' && c <= 'F')
- c -= 'A' - 10;
- else if (c >= 'a' && c <= 'f')
- c -= 'a' - 10;
+ unsigned C = HexLetterToVal(*s++);
- if (val > max_value || (val == max_value && c > max_digit)) {
+ if (val > max_value || (val == max_value && C > max_digit)) {
return false; // Overflow!
} else {
val *= radix;
- val += c;
+ val += C;
}
}
return true;
@@ -245,30 +248,53 @@
bool NumericLiteralParser::GetIntegerValue(int &val) {
intmax_t max_value = INT_MAX / radix;
- int max_digit = INT_MAX % radix;
- char c;
+ unsigned max_digit = INT_MAX % radix;
val = 0;
s = DigitsBegin;
while (s < SuffixBegin) {
- c = *s++;
- if (c >= '0' && c <= '9')
- c -= '0';
- else if (c >= 'A' && c <= 'F')
- c -= 'A' - 10;
- else if (c >= 'a' && c <= 'f')
- c -= 'a' - 10;
+ unsigned C = HexLetterToVal(*s++);
- if (val > max_value || (val == max_value && c > max_digit)) {
+ if (val > max_value || (val == max_value && C > max_digit)) {
return false; // Overflow!
} else {
val *= radix;
- val += c;
+ val += C;
}
}
return true;
}
+/// GetIntegerValue - Convert this numeric literal value to an APInt that
+/// matches Val's input width. If there is an overflow, saturate Val to zero
+/// and return false. Otherwise, set Val and return true.
+bool NumericLiteralParser::GetIntegerValue(APInt &Val) {
+ Val = 0;
+ s = DigitsBegin;
+
+ // FIXME: This doesn't handle sign right, doesn't autopromote to wider
+ // integer, and is generally not conformant.
+ APInt RadixVal(Val.getBitWidth(), radix);
+ APInt CharVal(Val.getBitWidth(), 0);
+ APInt OldVal = Val;
+ while (s < SuffixBegin) {
+ unsigned C = HexLetterToVal(*s++);
+
+ // If this letter is out of bound for this radix, reject it.
+ if (C >= radix) { Val = 0; return false; }
+
+ CharVal = C;
+
+ OldVal = Val;
+ Val *= RadixVal;
+ Val += CharVal;
+ if (OldVal.ugt(Val))
+ return false; // Overflow!
+ }
+ return true;
+}
+
+
void NumericLiteralParser::Diag(SourceLocation Loc, unsigned DiagID,
const std::string &M) {
PP.Diag(Loc, DiagID, M);
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=39381&r1=39380&r2=39381&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/LiteralSupport.h Wed Jul 11 11:43:48 2007
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallString.h"
namespace llvm {
+ class APInt;
namespace clang {
class Diagnostic;
@@ -64,6 +65,7 @@
/// return true if the value fit into "val", false otherwise.
bool GetIntegerValue(uintmax_t &val);
bool GetIntegerValue(int &val);
+ bool GetIntegerValue(APInt &Val); //< Return the same width as Val.
private:
void Diag(SourceLocation Loc, unsigned DiagID,
More information about the cfe-commits
mailing list