[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