[Lldb-commits] [lldb] 1847f4d - [lldb/Utility] Rewrite Scalar::SetValueFromCString
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Mon Jul 13 07:44:53 PDT 2020
Author: Pavel Labath
Date: 2020-07-13T16:44:42+02:00
New Revision: 1847f4dd7570f01f70646cd5067dd0c34257cd21
URL: https://github.com/llvm/llvm-project/commit/1847f4dd7570f01f70646cd5067dd0c34257cd21
DIFF: https://github.com/llvm/llvm-project/commit/1847f4dd7570f01f70646cd5067dd0c34257cd21.diff
LOG: [lldb/Utility] Rewrite Scalar::SetValueFromCString
The function's reliance on host types meant that it was needlessly
complicated, and did not handle the newer (wider) types. Rewrite it in
terms of APInt/APFloat functions to save code and improve functionality.
Added:
Modified:
lldb/source/Utility/Scalar.cpp
lldb/unittests/Utility/ScalarTest.cpp
Removed:
################################################################################
diff --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp
index 87ac6c23892d..6c48bbde532f 100644
--- a/lldb/source/Utility/Scalar.cpp
+++ b/lldb/source/Utility/Scalar.cpp
@@ -24,6 +24,7 @@ using namespace lldb;
using namespace lldb_private;
using llvm::APFloat;
+using llvm::APInt;
namespace {
enum class Category { Void, Integral, Float };
@@ -1002,116 +1003,60 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
error.SetErrorString("Invalid encoding.");
break;
- case eEncodingUint:
- if (byte_size <= sizeof(uint64_t)) {
- uint64_t uval64;
- if (!llvm::to_integer(value_str, uval64))
- error.SetErrorStringWithFormat(
- "'%s' is not a valid unsigned integer string value", value_str);
- else if (!UIntValueIsValidForSize(uval64, byte_size))
- error.SetErrorStringWithFormat(
- "value 0x%" PRIx64 " is too large to fit in a %" PRIu64
- " byte unsigned integer value",
- uval64, static_cast<uint64_t>(byte_size));
- else {
- m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize(byte_size);
- switch (m_type) {
- case e_uint:
- m_integer = llvm::APInt(sizeof(uint_t) * 8, uval64, false);
- break;
- case e_ulong:
- m_integer = llvm::APInt(sizeof(ulong_t) * 8, uval64, false);
- break;
- case e_ulonglong:
- m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, uval64, false);
- break;
- default:
- error.SetErrorStringWithFormat(
- "unsupported unsigned integer byte size: %" PRIu64 "",
- static_cast<uint64_t>(byte_size));
- break;
- }
- }
- } else {
- error.SetErrorStringWithFormat(
- "unsupported unsigned integer byte size: %" PRIu64 "",
- static_cast<uint64_t>(byte_size));
- return error;
- }
- break;
-
case eEncodingSint:
- if (byte_size <= sizeof(int64_t)) {
- int64_t sval64;
- if (!llvm::to_integer(value_str, sval64))
- error.SetErrorStringWithFormat(
- "'%s' is not a valid signed integer string value", value_str);
- else if (!SIntValueIsValidForSize(sval64, byte_size))
- error.SetErrorStringWithFormat(
- "value 0x%" PRIx64 " is too large to fit in a %" PRIu64
- " byte signed integer value",
- sval64, static_cast<uint64_t>(byte_size));
- else {
- m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize(byte_size);
- switch (m_type) {
- case e_sint:
- m_integer = llvm::APInt(sizeof(sint_t) * 8, sval64, true);
- break;
- case e_slong:
- m_integer = llvm::APInt(sizeof(slong_t) * 8, sval64, true);
- break;
- case e_slonglong:
- m_integer = llvm::APInt(sizeof(slonglong_t) * 8, sval64, true);
- break;
- default:
- error.SetErrorStringWithFormat(
- "unsupported signed integer byte size: %" PRIu64 "",
- static_cast<uint64_t>(byte_size));
- break;
- }
- }
- } else {
- error.SetErrorStringWithFormat(
- "unsupported signed integer byte size: %" PRIu64 "",
- static_cast<uint64_t>(byte_size));
- return error;
+ case eEncodingUint: {
+ llvm::StringRef str = value_str;
+ bool is_signed = encoding == eEncodingSint;
+ bool is_negative = is_signed && str.consume_front("-");
+ APInt integer;
+ if (str.getAsInteger(0, integer)) {
+ error.SetErrorStringWithFormatv(
+ "'{0}' is not a valid integer string value", value_str);
+ break;
+ }
+ bool fits;
+ if (is_signed) {
+ integer = integer.zext(integer.getBitWidth() + 1);
+ if (is_negative)
+ integer.negate();
+ fits = integer.isSignedIntN(byte_size * 8);
+ } else
+ fits = integer.isIntN(byte_size * 8);
+ if (!fits) {
+ error.SetErrorStringWithFormatv(
+ "value {0} is too large to fit in a {1} byte integer value",
+ value_str, byte_size);
+ break;
+ }
+ m_type = GetBestTypeForBitSize(8 * byte_size, is_signed);
+ if (m_type == e_void) {
+ error.SetErrorStringWithFormatv("unsupported integer byte size: {0}",
+ byte_size);
+ break;
}
+ if (is_signed)
+ m_integer = integer.sextOrTrunc(GetBitSize(m_type));
+ else
+ m_integer = integer.zextOrTrunc(GetBitSize(m_type));
break;
+ }
- case eEncodingIEEE754:
- static float f_val;
- static double d_val;
- static long double l_val;
- if (byte_size == sizeof(float)) {
- if (::sscanf(value_str, "%f", &f_val) == 1) {
- m_float = llvm::APFloat(f_val);
- m_type = e_float;
- } else
- error.SetErrorStringWithFormat("'%s' is not a valid float string value",
- value_str);
- } else if (byte_size == sizeof(double)) {
- if (::sscanf(value_str, "%lf", &d_val) == 1) {
- m_float = llvm::APFloat(d_val);
- m_type = e_double;
- } else
- error.SetErrorStringWithFormat("'%s' is not a valid float string value",
- value_str);
- } else if (byte_size == sizeof(long double)) {
- if (::sscanf(value_str, "%Lf", &l_val) == 1) {
- m_float = llvm::APFloat(
- llvm::APFloat::x87DoubleExtended(),
- llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
- (reinterpret_cast<type128 *>(&l_val))->x));
- m_type = e_long_double;
- } else
- error.SetErrorStringWithFormat("'%s' is not a valid float string value",
- value_str);
- } else {
- error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",
- static_cast<uint64_t>(byte_size));
- return error;
+ case eEncodingIEEE754: {
+ Type type = GetValueTypeForFloatWithByteSize(byte_size);
+ if (type == e_void) {
+ error.SetErrorStringWithFormatv("unsupported float byte size: {0}",
+ byte_size);
+ break;
}
+ APFloat f(GetFltSemantics(type));
+ if (llvm::Expected<APFloat::opStatus> op =
+ f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) {
+ m_type = type;
+ m_float = std::move(f);
+ } else
+ error = op.takeError();
break;
+ }
case eEncodingVector:
error.SetErrorString("vector encoding unsupported.");
diff --git a/lldb/unittests/Utility/ScalarTest.cpp b/lldb/unittests/Utility/ScalarTest.cpp
index 42a2f2aaebf2..dd4683145b96 100644
--- a/lldb/unittests/Utility/ScalarTest.cpp
+++ b/lldb/unittests/Utility/ScalarTest.cpp
@@ -334,6 +334,20 @@ TEST(ScalarTest, SetValueFromCString) {
EXPECT_THAT_ERROR(
a.SetValueFromCString("-123", lldb::eEncodingUint, 8).ToError(),
Failed());
+ EXPECT_THAT_ERROR(
+ a.SetValueFromCString("-2147483648", lldb::eEncodingSint, 4).ToError(),
+ Succeeded());
+ EXPECT_EQ(-2147483648, a);
+ EXPECT_THAT_ERROR(
+ a.SetValueFromCString("-2147483649", lldb::eEncodingSint, 4).ToError(),
+ Failed());
+ EXPECT_THAT_ERROR(
+ a.SetValueFromCString("47.25", lldb::eEncodingIEEE754, 4).ToError(),
+ Succeeded());
+ EXPECT_EQ(47.25f, a);
+ EXPECT_THAT_ERROR(
+ a.SetValueFromCString("asdf", lldb::eEncodingIEEE754, 4).ToError(),
+ Failed());
}
TEST(ScalarTest, APIntConstructor) {
More information about the lldb-commits
mailing list