diff --git a/llvm/lib/TableGen/TGLexer.cpp b/llvm/lib/TableGen/TGLexer.cpp --- a/llvm/lib/TableGen/TGLexer.cpp +++ b/llvm/lib/TableGen/TGLexer.cpp @@ -462,56 +462,62 @@ /// 0x[0-9a-fA-F]+ /// 0b[01]+ tgtok::TokKind TGLexer::LexNumber() { + unsigned Base = 0; + const char *NumStart; + + // Check if it's a hex or a binary value if (CurPtr[-1] == '0') { + NumStart = CurPtr + 1; if (CurPtr[0] == 'x') { - ++CurPtr; - const char *NumStart = CurPtr; - while (isxdigit(CurPtr[0])) + Base = 16; + do ++CurPtr; - - // Requires at least one hex digit. - if (CurPtr == NumStart) - return ReturnError(TokStart, "Invalid hexadecimal number"); - - errno = 0; - CurIntVal = strtoll(NumStart, nullptr, 16); - if (errno == EINVAL) - return ReturnError(TokStart, "Invalid hexadecimal number"); - if (errno == ERANGE) { - errno = 0; - CurIntVal = (int64_t)strtoull(NumStart, nullptr, 16); - if (errno == EINVAL) - return ReturnError(TokStart, "Invalid hexadecimal number"); - if (errno == ERANGE) - return ReturnError(TokStart, "Hexadecimal number out of range"); - } - return tgtok::IntVal; + while (isxdigit(CurPtr[0])); } else if (CurPtr[0] == 'b') { - ++CurPtr; - const char *NumStart = CurPtr; - while (CurPtr[0] == '0' || CurPtr[0] == '1') + Base = 2; + do ++CurPtr; - - // Requires at least one binary digit. - if (CurPtr == NumStart) - return ReturnError(CurPtr-2, "Invalid binary number"); - CurIntVal = strtoll(NumStart, nullptr, 2); - return tgtok::BinaryIntVal; + while (CurPtr[0] == '0' || CurPtr[0] == '1'); } } - // Check for a sign without a digit. - if (!isdigit(CurPtr[0])) { - if (CurPtr[-1] == '-') - return tgtok::minus; - else if (CurPtr[-1] == '+') - return tgtok::plus; + // For a hex or binary value, we always convert it to an unsigned value + bool IsMinus = false; + + // Check if it's a decimal value + if (Base == 0) { + // Check for a sign without a digit. + if (!isdigit(CurPtr[0])) { + if (CurPtr[-1] == '-') + return tgtok::minus; + else if (CurPtr[-1] == '+') + return tgtok::plus; + } + + Base = 10; + NumStart = TokStart; + IsMinus = CurPtr[-1] == '-'; + + while (isdigit(CurPtr[0])) + ++CurPtr; } - while (isdigit(CurPtr[0])) - ++CurPtr; - CurIntVal = strtoll(TokStart, nullptr, 10); - return tgtok::IntVal; + // Requires at least one digit. + if (CurPtr == NumStart) + return ReturnError(TokStart, "Invalid number"); + + errno = 0; + if (IsMinus) + CurIntVal = strtoll(NumStart, nullptr, Base); + else + CurIntVal = strtoull(NumStart, nullptr, Base); + + if (errno == EINVAL) + return ReturnError(TokStart, "Invalid number"); + if (errno == ERANGE) + return ReturnError(TokStart, "Number out of range"); + + return Base == 2 ? tgtok::BinaryIntVal : tgtok::IntVal; } /// LexBracket - We just read '['. If this is a code block, return it, diff --git a/llvm/test/TableGen/64-bit-int.td b/llvm/test/TableGen/64-bit-int.td new file mode 100644 --- /dev/null +++ b/llvm/test/TableGen/64-bit-int.td @@ -0,0 +1,33 @@ +// RUN: llvm-tblgen -DVALID -print-records %s | FileCheck %s +// RUN: not llvm-tblgen -DOOR1 -print-records %s 2>&1 | FileCheck %s --check-prefix=CHECK-OOR +// RUN: not llvm-tblgen -DOOR2 -print-records %s 2>&1 | FileCheck %s --check-prefix=CHECK-OOR +// RUN: not llvm-tblgen -DOOR3 -print-records %s 2>&1 | FileCheck %s --check-prefix=CHECK-OOR + +def { + +#ifdef OOR1 + bits<64> Val = -9223372036854775809; +#endif + +#ifdef OOR2 + bits<64> Val = 0b10000000000000000000000000000000000000000000000000000000000000000; +#endif + +#ifdef OOR3 + bits<64> Val = 0x10000000000000000; +#endif +// CHECK-OOR: error: Number out of range + +#ifdef VALID + bits<64> BinVal = 0x8000000000000000; + bits<64> HexVal = 0b1000000000000000000000000000000000000000000000000000000000000000; + bits<64> DecVal1 = 9223372036854775808; + bits<64> DecVal2 = 9223372036854775809; + bits<64> DecVal3 = -9223372036854775808; +#endif +// CHECK: bits<64> BinVal = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +// CHECK: bits<64> HexVal = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +// CHECK: bits<64> DecVal1 = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +// CHECK: bits<64> DecVal2 = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; +// CHECK: bits<64> DecVal3 = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +}