forked from OSchip/llvm-project
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. llvm-svn: 39352
This commit is contained in:
parent
09ef474197
commit
451d8f1626
|
@ -305,11 +305,8 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
|
|||
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 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
|
|||
} 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,
|
||||
|
|
|
@ -60,8 +60,8 @@ using namespace clang;
|
|||
|
||||
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 @@ NumericLiteralParser(const char *begin, const char *end,
|
|||
}
|
||||
}
|
||||
|
||||
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++;
|
||||
|
|
|
@ -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 @@ static bool EvaluateValue(int &Result, LexerToken &PeekTok, DefinedTracker &DT,
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -305,11 +305,8 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
|
|||
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 @@ Action::ExprResult Sema::ParseNumericConstant(const LexerToken &Tok) {
|
|||
} 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,
|
||||
|
|
|
@ -237,6 +237,8 @@ DIAG(err_pp_bad_paste, ERROR,
|
|||
"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,
|
||||
|
|
|
@ -25,10 +25,9 @@ class TargetInfo;
|
|||
|
||||
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 @@ public:
|
|||
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,
|
||||
|
|
Loading…
Reference in New Issue