Support 64-bit integer constants in parser. Partial fix to issue #21.

This commit is contained in:
Matt Pharr
2011-07-06 16:54:14 +01:00
parent af70718eca
commit a1d5ea69b9
2 changed files with 44 additions and 37 deletions

59
lex.ll
View File

@@ -39,8 +39,9 @@
#include "sym.h" #include "sym.h"
#include "util.h" #include "util.h"
#include "module.h" #include "module.h"
#include <stdlib.h>
static uint32_t lParseBinary(const char *ptr, SourcePos pos); static uint64_t lParseBinary(const char *ptr, SourcePos pos);
static void lCComment(SourcePos *); static void lCComment(SourcePos *);
static void lCppComment(SourcePos *); static void lCppComment(SourcePos *);
static void lHandleCppHash(SourcePos *); static void lHandleCppHash(SourcePos *);
@@ -136,51 +137,54 @@ L?\"(\\.|[^\\"])*\" { lStringConst(yylval, yylloc); return TOKEN_STRING_LITERAL;
{INT_NUMBER} { {INT_NUMBER} {
char *endPtr = NULL; char *endPtr = NULL;
#ifdef ISPC_IS_WINDOWS int64_t val;
unsigned long val;
#else
unsigned long long val;
#endif
if (yytext[0] == '0' && yytext[1] == 'b') if (yytext[0] == '0' && yytext[1] == 'b')
val = lParseBinary(yytext+2, *yylloc); val = lParseBinary(yytext+2, *yylloc);
else { else {
#ifdef ISPC_IS_WINDOWS #ifdef ISPC_IS_WINDOWS
val = strtoul(yytext, &endPtr, 0); val = _strtoi64(yytext, &endPtr, 0);
#else #else
// FIXME: should use strtouq and then issue an error if we can't
// fit into 64 bits...
val = strtoull(yytext, &endPtr, 0); val = strtoull(yytext, &endPtr, 0);
#endif #endif
} }
yylval->int32Val = (int32_t)val;
if (val != (unsigned int)yylval->int32Val) // See if we can fit this into a 32-bit integer...
Warning(*yylloc, "32-bit integer has insufficient bits to represent value %s (%x %llx)", if ((val & 0xffffffff) == val) {
yytext, yylval->int32Val, (unsigned long long)val); yylval->int32Val = (int32_t)val;
return TOKEN_INT_CONSTANT; return TOKEN_INT32_CONSTANT;
}
else {
yylval->int64Val = val;
return TOKEN_INT64_CONSTANT;
}
} }
{INT_NUMBER}[uU] { {INT_NUMBER}[uU] {
char *endPtr = NULL; char *endPtr = NULL;
#ifdef ISPC_IS_WINDOWS uint64_t val;
unsigned long val;
#else
unsigned long long val;
#endif
if (yytext[0] == '0' && yytext[1] == 'b') if (yytext[0] == '0' && yytext[1] == 'b')
val = lParseBinary(yytext+2, *yylloc); val = lParseBinary(yytext+2, *yylloc);
else { else {
#ifdef ISPC_IS_WINDOWS #ifdef ISPC_IS_WINDOWS
val = strtoul(yytext, &endPtr, 0); val = _strtoui64(yytext, &endPtr, 0);
#else #else
val = strtoull(yytext, &endPtr, 0); val = strtoull(yytext, &endPtr, 0);
#endif #endif
} }
yylval->int32Val = (int32_t)val; if ((val & 0xffffffff) == val) {
if (val != (unsigned int)yylval->int32Val) // we can represent it in a 32-bit value
Warning(*yylloc, "32-bit integer has insufficient bits to represent value %s (%x %llx)", yylval->int32Val = (int32_t)val;
yytext, yylval->int32Val, (unsigned long long)val); return TOKEN_UINT32_CONSTANT;
return TOKEN_UINT_CONSTANT; }
else {
yylval->int64Val = val;
return TOKEN_UINT64_CONSTANT;
}
} }
{FLOAT_NUMBER} { {FLOAT_NUMBER} {
@@ -268,19 +272,18 @@ L?\"(\\.|[^\\"])*\" { lStringConst(yylval, yylloc); return TOKEN_STRING_LITERAL;
/** Return the integer version of a binary constant from a string. /** Return the integer version of a binary constant from a string.
*/ */
static uint32_t static uint64_t
lParseBinary(const char *ptr, SourcePos pos) { lParseBinary(const char *ptr, SourcePos pos) {
uint32_t val = 0; uint64_t val = 0;
bool warned = false; bool warned = false;
while (*ptr != '\0') { while (*ptr != '\0') {
/* if this hits, the regexp for 0b... constants is broken */ /* if this hits, the regexp for 0b... constants is broken */
assert(*ptr == '0' || *ptr == '1'); assert(*ptr == '0' || *ptr == '1');
if ((val & (1<<31)) && warned == false) { if ((val & (((int64_t)1)<<63)) && warned == false) {
// We're about to shift out a set bit // We're about to shift out a set bit
// FIXME: 64-bit int constants... Warning(pos, "Can't represent binary constant with a 64-bit integer type");
Warning(pos, "Can't represent binary constant with 32-bit integer type");
warned = true; warned = true;
} }

View File

@@ -129,17 +129,16 @@ static const char *lParamListTokens[] = {
StructDeclaration *structDeclaration; StructDeclaration *structDeclaration;
std::vector<StructDeclaration *> *structDeclarationList; std::vector<StructDeclaration *> *structDeclarationList;
int32_t int32Val; int32_t int32Val;
uint32_t uint32Val;
double floatVal; double floatVal;
int64_t int64Val; int64_t int64Val;
uint64_t uint64Val;
std::string *stringVal; std::string *stringVal;
const char *constCharPtr; const char *constCharPtr;
} }
%token TOKEN_IDENTIFIER TOKEN_INT_CONSTANT TOKEN_UINT_CONSTANT TOKEN_FLOAT_CONSTANT %token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT TOKEN_INT64_CONSTANT
%token TOKEN_STRING_LITERAL TOKEN_TYPE_NAME %token TOKEN_UINT64_CONSTANT TOKEN_FLOAT_CONSTANT
%token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP %token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP %token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
%token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN %token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN
@@ -220,12 +219,17 @@ primary_expression
Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str()); Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
} }
} }
| TOKEN_INT_CONSTANT { | TOKEN_INT32_CONSTANT {
/* FIXME: should support 64 bit constants (and doubles...) */
$$ = new ConstExpr(AtomicType::UniformConstInt32, yylval.int32Val, @1); $$ = new ConstExpr(AtomicType::UniformConstInt32, yylval.int32Val, @1);
} }
| TOKEN_UINT_CONSTANT { | TOKEN_UINT32_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstUInt32, yylval.uint32Val, @1); $$ = new ConstExpr(AtomicType::UniformConstUInt32, (uint32_t)yylval.int32Val, @1);
}
| TOKEN_INT64_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstInt64, yylval.int64Val, @1);
}
| TOKEN_UINT64_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstUInt64, (uint64_t)yylval.int64Val, @1);
} }
| TOKEN_FLOAT_CONSTANT { | TOKEN_FLOAT_CONSTANT {
$$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1); $$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1);
@@ -740,7 +744,7 @@ declarator
; ;
int_constant int_constant
: TOKEN_INT_CONSTANT { $$ = yylval.int32Val; } : TOKEN_INT32_CONSTANT { $$ = yylval.int32Val; }
; ;
direct_declarator direct_declarator