uweigand updated this revision to Diff 53622. uweigand added a comment. This adds some unit tests verifying correct operation of the GetBytes routine as well as the conversions (SChar, UChar, ...). Those tests actually exposed more problems in the original Scalar code: the SetValueFromData routine didn't work correctly for 128- and 256-bit data types, and the SChar routine should have an explicit "signed char" return type to work correctly on platforms where char defaults to unsigned.
Regression testing on Intel revealed a bug in my original patch: since Scalar only accepts APInt initializers with a bit size that is a power of 2, we may need to extend some values before converting them to Scalar. This occured for values representing 10-byte Intel long double data. Tested on System z and Intel. http://reviews.llvm.org/D18981 Files: include/lldb/Core/Scalar.h include/lldb/Symbol/Type.h source/Core/Scalar.cpp source/Expression/IRInterpreter.cpp source/Plugins/ExpressionParser/Clang/IRForTarget.cpp source/Symbol/ClangASTContext.cpp unittests/Core/ScalarTest.cpp
Index: unittests/Core/ScalarTest.cpp =================================================================== --- unittests/Core/ScalarTest.cpp +++ unittests/Core/ScalarTest.cpp @@ -15,7 +15,10 @@ #include "gtest/gtest.h" +#include "lldb/Core/Error.h" #include "lldb/Core/Scalar.h" +#include "lldb/Core/DataExtractor.h" +#include "lldb/Host/Endian.h" using namespace lldb_private; @@ -30,3 +33,49 @@ ASSERT_EQ(a >> c, a_scalar >> c_scalar); ASSERT_EQ(b >> c, b_scalar >> c_scalar); } + +TEST(ScalarTest, GetBytes) +{ + int a = 0x01020304; + long long b = 0x0102030405060708LL; + float c = 1234567.89e42; + double d = 1234567.89e42; + char e[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + char f[32] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }; + Scalar a_scalar(a); + Scalar b_scalar(b); + Scalar c_scalar(c); + Scalar d_scalar(d); + Scalar e_scalar; + Scalar f_scalar; + DataExtractor e_data(e, sizeof(e), endian::InlHostByteOrder(), sizeof(void *)); + Error e_error = e_scalar.SetValueFromData(e_data, lldb::eEncodingUint, sizeof(e)); + DataExtractor f_data(f, sizeof(f), endian::InlHostByteOrder(), sizeof(void *)); + Error f_error = f_scalar.SetValueFromData(f_data, lldb::eEncodingUint, sizeof(f)); + ASSERT_EQ(0, memcmp(&a, a_scalar.GetBytes(), sizeof(a))); + ASSERT_EQ(0, memcmp(&b, b_scalar.GetBytes(), sizeof(b))); + ASSERT_EQ(0, memcmp(&c, c_scalar.GetBytes(), sizeof(c))); + ASSERT_EQ(0, memcmp(&d, d_scalar.GetBytes(), sizeof(d))); + ASSERT_EQ(0, e_error.Fail()); + ASSERT_EQ(0, memcmp(e, e_scalar.GetBytes(), sizeof(e))); + ASSERT_EQ(0, f_error.Fail()); + ASSERT_EQ(0, memcmp(f, f_scalar.GetBytes(), sizeof(f))); +} + +TEST(ScalarTest, CastOperations) +{ + long long a = 0xf1f2f3f4f5f6f7f8LL; + Scalar a_scalar(a); + ASSERT_EQ((signed char)a, a_scalar.SChar()); + ASSERT_EQ((unsigned char)a, a_scalar.UChar()); + ASSERT_EQ((signed short)a, a_scalar.SShort()); + ASSERT_EQ((unsigned short)a, a_scalar.UShort()); + ASSERT_EQ((signed int)a, a_scalar.SInt()); + ASSERT_EQ((unsigned int)a, a_scalar.UInt()); + ASSERT_EQ((signed long)a, a_scalar.SLong()); + ASSERT_EQ((unsigned long)a, a_scalar.ULong()); + ASSERT_EQ((signed long long)a, a_scalar.SLongLong()); + ASSERT_EQ((unsigned long long)a, a_scalar.ULongLong()); +} + Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -72,6 +72,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegularExpression.h" +#include "lldb/Core/Scalar.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Core/UniqueCStringMap.h" @@ -8609,18 +8610,10 @@ const uint64_t byte_size = bit_size / 8; if (dst_size >= byte_size) { - if (bit_size == sizeof(float)*8) - { - float float32 = ap_float.convertToFloat(); - ::memcpy (dst, &float32, byte_size); + Scalar scalar = ap_float.bitcastToAPInt().zextOrTrunc(llvm::NextPowerOf2(byte_size) * 8); + lldb_private::Error get_data_error; + if (scalar.GetAsMemoryData(dst, byte_size, lldb_private::endian::InlHostByteOrder(), get_data_error)) return byte_size; - } - else if (bit_size >= 64) - { - llvm::APInt ap_int(ap_float.bitcastToAPInt()); - ::memcpy (dst, ap_int.getRawData(), byte_size); - return byte_size; - } } } } Index: source/Plugins/ExpressionParser/Clang/IRForTarget.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -1105,7 +1105,13 @@ if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) { - memcpy (data, int_initializer->getValue().getRawData(), m_target_data->getTypeStoreSize(initializer_type)); + size_t constant_size = m_target_data->getTypeStoreSize(initializer_type); + lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8); + + lldb_private::Error get_data_error; + if (!scalar.GetAsMemoryData(data, constant_size, lldb_private::endian::InlHostByteOrder(), get_data_error)) + return false; + return true; } else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer)) Index: source/Expression/IRInterpreter.cpp =================================================================== --- source/Expression/IRInterpreter.cpp +++ source/Expression/IRInterpreter.cpp @@ -231,7 +231,7 @@ lldb_private::Scalar cast_scalar; - if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType())) + if (!AssignToMatchType(cast_scalar, scalar.ULongLong(), value->getType())) return false; size_t value_byte_size = m_target_data.getTypeStoreSize(value->getType()); @@ -373,19 +373,18 @@ if (!ResolveConstantValue(resolved_value, constant)) return false; - lldb_private::StreamString buffer (lldb_private::Stream::eBinary, - m_execution_unit.GetAddressByteSize(), - m_execution_unit.GetByteOrder()); - size_t constant_size = m_target_data.getTypeStoreSize(constant->getType()); + lldb_private::DataBufferHeap buf(constant_size, 0); - const uint64_t *raw_data = resolved_value.getRawData(); + lldb_private::Error get_data_error; - buffer.PutRawBytes(raw_data, constant_size, lldb_private::endian::InlHostByteOrder()); + lldb_private::Scalar resolved_scalar(resolved_value.zextOrTrunc(llvm::NextPowerOf2(constant_size) * 8)); + if (!resolved_scalar.GetAsMemoryData(buf.GetBytes(), buf.GetByteSize(), m_byte_order, get_data_error)) + return false; lldb_private::Error write_error; - m_execution_unit.WriteMemory(process_address, (const uint8_t*)buffer.GetData(), constant_size, write_error); + m_execution_unit.WriteMemory(process_address, buf.GetBytes(), buf.GetByteSize(), write_error); return write_error.Success(); } @@ -819,15 +818,19 @@ result = L / R; break; case Instruction::UDiv: - result = L.GetRawBits64(0) / R.GetRawBits64(1); + L.MakeUnsigned(); + R.MakeUnsigned(); + result = L / R; break; case Instruction::SRem: L.MakeSigned(); R.MakeSigned(); result = L % R; break; case Instruction::URem: - result = L.GetRawBits64(0) % R.GetRawBits64(1); + L.MakeUnsigned(); + R.MakeUnsigned(); + result = L % R; break; case Instruction::Shl: result = L << R; @@ -1030,7 +1033,7 @@ return false; } - if (C.GetRawBits64(0)) + if (!C.IsZero()) frame.Jump(br_inst->getSuccessor(0)); else frame.Jump(br_inst->getSuccessor(1)); @@ -1181,16 +1184,24 @@ result = (L != R); break; case CmpInst::ICMP_UGT: - result = (L.GetRawBits64(0) > R.GetRawBits64(0)); + L.MakeUnsigned(); + R.MakeUnsigned(); + result = (L > R); break; case CmpInst::ICMP_UGE: - result = (L.GetRawBits64(0) >= R.GetRawBits64(0)); + L.MakeUnsigned(); + R.MakeUnsigned(); + result = (L >= R); break; case CmpInst::ICMP_ULT: - result = (L.GetRawBits64(0) < R.GetRawBits64(0)); + L.MakeUnsigned(); + R.MakeUnsigned(); + result = (L < R); break; case CmpInst::ICMP_ULE: - result = (L.GetRawBits64(0) <= R.GetRawBits64(0)); + L.MakeUnsigned(); + R.MakeUnsigned(); + result = (L <= R); break; case CmpInst::ICMP_SGT: L.MakeSigned(); Index: source/Core/Scalar.cpp =================================================================== --- source/Core/Scalar.cpp +++ source/Core/Scalar.cpp @@ -16,6 +16,8 @@ #include <cstdio> // Other libraries and framework includes +#include "llvm/ADT/SmallString.h" + // Project includes #include "lldb/Interpreter/Args.h" #include "lldb/Core/Error.h" @@ -134,116 +136,30 @@ Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const { size_t byte_size = GetByteSize(); - static float f_val; - static double d_val; if (byte_size > 0) { + const uint8_t *bytes = reinterpret_cast<const uint8_t *>(GetBytes()); + if (limit_byte_size < byte_size) { if (endian::InlHostByteOrder() == eByteOrderLittle) { // On little endian systems if we want fewer bytes from the // current type we just specify fewer bytes since the LSByte // is first... - switch(m_type) - { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - data.SetData((const uint8_t *)m_integer.getRawData(), limit_byte_size, endian::InlHostByteOrder()); - return true; - case e_float: - f_val = m_float.convertToFloat(); - data.SetData((uint8_t *)&f_val, limit_byte_size, endian::InlHostByteOrder()); - return true; - case e_double: - d_val = m_float.convertToDouble(); - data.SetData((uint8_t *)&d_val, limit_byte_size, endian::InlHostByteOrder()); - return true; - case e_long_double: - static llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - data.SetData((const uint8_t *)ldbl_val.getRawData(), limit_byte_size, endian::InlHostByteOrder()); - return true; - } + byte_size = limit_byte_size; } else if (endian::InlHostByteOrder() == eByteOrderBig) { // On big endian systems if we want fewer bytes from the // current type have to advance our initial byte pointer and // trim down the number of bytes since the MSByte is first - switch(m_type) - { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - data.SetData((const uint8_t *)m_integer.getRawData() + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); - return true; - case e_float: - f_val = m_float.convertToFloat(); - data.SetData((uint8_t *)&f_val + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); - return true; - case e_double: - d_val = m_float.convertToDouble(); - data.SetData((uint8_t *)&d_val + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); - return true; - case e_long_double: - static llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - data.SetData((const uint8_t *)ldbl_val.getRawData() + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); - return true; - } - } - } - else - { - // We want all of the data - switch(m_type) - { - case e_void: - break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - data.SetData((const uint8_t *)m_integer.getRawData(), byte_size, endian::InlHostByteOrder()); - return true; - case e_float: - f_val = m_float.convertToFloat(); - data.SetData((uint8_t *)&f_val, byte_size, endian::InlHostByteOrder()); - return true; - case e_double: - d_val = m_float.convertToDouble(); - data.SetData((uint8_t *)&d_val, byte_size, endian::InlHostByteOrder()); - return true; - case e_long_double: - static llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - data.SetData((const uint8_t *)ldbl_val.getRawData(), byte_size, endian::InlHostByteOrder()); - return true; + bytes += byte_size - limit_byte_size; + byte_size = limit_byte_size; } } + + data.SetData(bytes, byte_size, endian::InlHostByteOrder()); return true; } data.Clear(); @@ -253,8 +169,11 @@ const void * Scalar::GetBytes() const { + const uint64_t *apint_words; + const uint8_t *bytes; static float_t flt_val; static double_t dbl_val; + static uint64_t swapped_words[4]; switch (m_type) { case e_void: @@ -265,20 +184,63 @@ case e_ulong: case e_slonglong: case e_ulonglong: + bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData()); + // getRawData always returns a pointer to an uint64_t. If we have a smaller type, + // we need to update the pointer on big-endian systems. + if (endian::InlHostByteOrder() == eByteOrderBig) + { + size_t byte_size = m_integer.getBitWidth() / 8; + if (byte_size < 8) + bytes += 8 - byte_size; + } + return bytes; case e_sint128: case e_uint128: + apint_words = m_integer.getRawData(); + // getRawData always returns a pointer to an array of two uint64_t values, + // where the least-significant word always comes first. On big-endian + // systems we need to swap the two words. + if (endian::InlHostByteOrder() == eByteOrderBig) + { + swapped_words[0] = apint_words[1]; + swapped_words[1] = apint_words[0]; + apint_words = swapped_words; + } + return reinterpret_cast<const void *>(apint_words); case e_sint256: case e_uint256: - return reinterpret_cast<const void *>(m_integer.getRawData()); + apint_words = m_integer.getRawData(); + // getRawData always returns a pointer to an array of four uint64_t values, + // where the least-significant word always comes first. On big-endian + // systems we need to swap the four words. + if (endian::InlHostByteOrder() == eByteOrderBig) + { + swapped_words[0] = apint_words[3]; + swapped_words[1] = apint_words[2]; + swapped_words[2] = apint_words[1]; + swapped_words[3] = apint_words[0]; + apint_words = swapped_words; + } + return reinterpret_cast<const void *>(apint_words); case e_float: flt_val = m_float.convertToFloat(); return reinterpret_cast<const void *>(&flt_val); case e_double: dbl_val = m_float.convertToDouble(); return reinterpret_cast<const void *>(&dbl_val); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return reinterpret_cast<const void *>(ldbl_val.getRawData()); + apint_words = ldbl_val.getRawData(); + // getRawData always returns a pointer to an array of two uint64_t values, + // where the least-significant word always comes first. On big-endian + // systems we need to swap the two words. + if (endian::InlHostByteOrder() == eByteOrderBig) + { + swapped_words[0] = apint_words[1]; + swapped_words[1] = apint_words[0]; + apint_words = swapped_words; + } + return reinterpret_cast<const void *>(apint_words); } return nullptr; } @@ -338,36 +300,33 @@ void Scalar::GetValue (Stream *s, bool show_type) const { - const uint64_t *src; if (show_type) s->Printf("(%s) ", GetTypeAsCString()); switch (m_type) { case e_void: break; - case e_sint: s->Printf("%i", *(const sint_t *) m_integer.getRawData()); break; - case e_uint: s->Printf("0x%8.8x", *(const uint_t *) m_integer.getRawData()); break; - case e_slong: s->Printf("%li", *(const slong_t *) m_integer.getRawData()); break; - case e_ulong: s->Printf("0x%8.8lx", *(const ulong_t *) m_integer.getRawData()); break; - case e_slonglong: s->Printf("%lli", *(const slonglong_t *) m_integer.getRawData()); break; - case e_ulonglong: s->Printf("0x%16.16llx", *(const ulonglong_t *) m_integer.getRawData()); break; + case e_sint: + case e_ulong: + case e_slonglong: case e_sint128: case e_sint256: s->Printf("%s",m_integer.toString(10,true).c_str()); break; + case e_uint: + case e_slong: + case e_ulonglong: case e_uint128: - src = m_integer.getRawData(); - s->Printf("0x%16.16llx%16.16llx", *(const ulonglong_t *)src, *(const ulonglong_t *)(src + 1)); - break; case e_uint256: s->Printf("%s",m_integer.toString(16,false).c_str()); break; - case e_float: s->Printf("%f", m_float.convertToFloat()); break; - case e_double: s->Printf("%g", m_float.convertToDouble()); break; + case e_float: + case e_double: case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - s->Printf("%Lg", *(const long_double_t *)ldbl_val.getRawData()); + llvm::SmallString<24> string; + m_float.toString(string); + s->Printf("%s", string.c_str()); break; } } @@ -535,39 +494,47 @@ case e_void: break; case e_sint: success = true; break; case e_uint: - m_integer = llvm::APInt(sizeof(uint_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(uint_t) * 8); success = true; break; case e_slong: - m_integer = llvm::APInt(sizeof(slong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8); success = true; break; case e_ulong: - m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8); success = true; break; case e_slonglong: - m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); success = true; break; case e_ulonglong: - m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); success = true; break; case e_sint128: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + case e_uint128: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -598,34 +565,42 @@ case e_sint: break; case e_uint: success = true; break; case e_slong: - m_integer = llvm::APInt(sizeof(slong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8); success = true; break; case e_ulong: - m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8); success = true; break; case e_slonglong: - m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); success = true; break; case e_ulonglong: - m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); success = true; break; case e_sint128: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + case e_uint128: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -657,29 +632,37 @@ case e_uint: break; case e_slong: success = true; break; case e_ulong: - m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8); success = true; break; case e_slonglong: - m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); success = true; break; case e_ulonglong: - m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); success = true; break; case e_sint128: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + case e_uint128: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -712,24 +695,32 @@ case e_slong: break; case e_ulong: success = true; break; case e_slonglong: - m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); success = true; break; case e_ulonglong: - m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); success = true; break; case e_sint128: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + case e_uint128: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -763,19 +754,27 @@ case e_ulong: break; case e_slonglong: success = true; break; case e_ulonglong: - m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); success = true; break; case e_sint128: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + case e_uint128: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -810,14 +809,22 @@ case e_slonglong: break; case e_ulonglong: success = true; break; case e_sint128: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + case e_uint128: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -853,13 +860,17 @@ case e_ulonglong: break; case e_sint128: success = true; break; case e_uint128: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -896,8 +907,12 @@ case e_sint128: break; case e_uint128: success = true; break; case e_sint256: + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); + success = true; + break; + case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, ((const type256 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -935,7 +950,7 @@ case e_uint128: break; case e_sint256: success = true; break; case e_uint256: - m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); success = true; break; @@ -1369,18 +1384,44 @@ case e_slonglong: success = true; break; case e_ulonglong: m_type = e_slonglong; success = true; break; case e_sint128: success = true; break; - case e_uint128: m_type = e_sint; success = true; break; + case e_uint128: m_type = e_sint128; success = true; break; + case e_sint256: success = true; break; + case e_uint256: m_type = e_sint256; success = true; break; + case e_float: success = true; break; + case e_double: success = true; break; + case e_long_double: success = true; break; + } + + return success; +} + +bool +Scalar::MakeUnsigned () +{ + bool success = false; + + switch (m_type) + { + case e_void: break; + case e_sint: success = true; break; + case e_uint: m_type = e_uint; success = true; break; + case e_slong: success = true; break; + case e_ulong: m_type = e_ulong; success = true; break; + case e_slonglong: success = true; break; + case e_ulonglong: m_type = e_ulonglong; success = true; break; + case e_sint128: success = true; break; + case e_uint128: m_type = e_uint128; success = true; break; case e_sint256: success = true; break; - case e_uint256: m_type = e_sint; success = true; break; + case e_uint256: m_type = e_uint256; success = true; break; case e_float: success = true; break; case e_double: success = true; break; case e_long_double: success = true; break; } return success; } -char +signed char Scalar::SChar(char fail_value) const { switch (m_type) @@ -1396,14 +1437,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const schar_t *)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getRawData(); + return (schar_t)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue(); case e_float: return (schar_t)m_float.convertToFloat(); case e_double: return (schar_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return (schar_t)*ldbl_val.getRawData(); + return (schar_t)(ldbl_val.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue(); } return fail_value; } @@ -1424,14 +1465,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const uchar_t *)m_integer.getRawData(); + return (uchar_t)(m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue(); case e_float: return (uchar_t)m_float.convertToFloat(); case e_double: return (uchar_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return (uchar_t)*ldbl_val.getRawData(); + return (uchar_t)(ldbl_val.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue(); } return fail_value; } @@ -1452,14 +1493,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const sshort_t *)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getRawData(); + return (sshort_t)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue(); case e_float: return (sshort_t)m_float.convertToFloat(); case e_double: return (sshort_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const sshort_t *)ldbl_val.getRawData(); + return (sshort_t)(ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue(); } return fail_value; } @@ -1480,14 +1521,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const ushort_t *)m_integer.getRawData(); + return (ushort_t)(m_integer.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue(); case e_float: return (ushort_t)m_float.convertToFloat(); case e_double: return (ushort_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const ushort_t *)ldbl_val.getRawData();; + return (ushort_t)(ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue(); } return fail_value; } @@ -1508,14 +1549,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const sint_t *)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getRawData(); + return (sint_t)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue(); case e_float: return (sint_t)m_float.convertToFloat(); case e_double: return (sint_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const sint_t *)ldbl_val.getRawData(); + return (sint_t)(ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue(); } return fail_value; } @@ -1536,14 +1577,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const uint_t *)m_integer.getRawData(); + return (uint_t)(m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue(); case e_float: return (uint_t)m_float.convertToFloat(); case e_double: return (uint_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const uint_t *)ldbl_val.getRawData(); + return (uint_t)(ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue(); } return fail_value; } @@ -1564,14 +1605,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const slong_t *)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getRawData(); + return (slong_t)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue(); case e_float: return (slong_t)m_float.convertToFloat(); case e_double: return (slong_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const slong_t *)ldbl_val.getRawData(); + return (slong_t)(ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue(); } return fail_value; } @@ -1592,44 +1633,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const ulong_t *)m_integer.getRawData(); + return (ulong_t)(m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue(); case e_float: return (ulong_t)m_float.convertToFloat(); case e_double: return (ulong_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const ulong_t *)ldbl_val.getRawData(); - } - return fail_value; -} - -uint64_t -Scalar::GetRawBits64(uint64_t fail_value) const -{ - switch (m_type) - { - case e_void: - break; - - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - case e_uint128: - case e_sint256: - case e_uint256: - return *m_integer.getRawData(); - case e_float: - return (uint64_t)m_float.convertToFloat(); - case e_double: - return (uint64_t)m_float.convertToDouble(); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *ldbl_val.getRawData(); + return (ulong_t)(ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue(); } return fail_value; } @@ -1650,14 +1661,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const slonglong_t *)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getRawData(); + return (slonglong_t)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue(); case e_float: return (slonglong_t)m_float.convertToFloat(); case e_double: return (slonglong_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const slonglong_t *)ldbl_val.getRawData(); + return (slonglong_t)(ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue(); } return fail_value; } @@ -1678,14 +1689,14 @@ case e_uint128: case e_sint256: case e_uint256: - return *(const ulonglong_t *)m_integer.getRawData(); + return (ulonglong_t)(m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue(); case e_float: return (ulonglong_t)m_float.convertToFloat(); case e_double: return (ulonglong_t)m_float.convertToDouble(); case e_long_double: llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return *(const ulonglong_t *)ldbl_val.getRawData(); + return (ulonglong_t)(ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue(); } return fail_value; } @@ -1948,7 +1959,7 @@ case e_uint128: case e_sint256: case e_uint256: - m_integer <<= *rhs.m_integer.getRawData(); + m_integer = m_integer << rhs.m_integer; break; } break; @@ -1996,7 +2007,8 @@ case e_uint128: case e_sint256: case e_uint256: - m_integer = m_integer.lshr(*(const uint_t *) rhs.m_integer.getRawData()); break; + m_integer = m_integer.lshr(rhs.m_integer); + break; } break; } @@ -2043,7 +2055,7 @@ case e_uint128: case e_sint256: case e_uint256: - m_integer = m_integer.ashr(*(const uint_t *)rhs.m_integer.getRawData()); + m_integer = m_integer.ashr(rhs.m_integer); break; } break; @@ -2258,18 +2270,24 @@ { case Scalar::e_void: break; case Scalar::e_sint: - case Scalar::e_uint: case Scalar::e_slong: - case Scalar::e_ulong: case Scalar::e_slonglong: - case Scalar::e_ulonglong: case Scalar::e_sint128: - case Scalar::e_uint128: case Scalar::e_sint256: + if (b->m_integer != 0) + { + result.m_integer = a->m_integer.sdiv(b->m_integer); + return result; + } + break; + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: case Scalar::e_uint256: if (b->m_integer != 0) { - result.m_integer = *a->m_integer.getRawData() / *b->m_integer.getRawData(); + result.m_integer = a->m_integer.udiv(b->m_integer); return result; } break; @@ -2405,18 +2423,23 @@ default: break; case Scalar::e_void: break; case Scalar::e_sint: - case Scalar::e_uint: case Scalar::e_slong: - case Scalar::e_ulong: case Scalar::e_slonglong: - case Scalar::e_ulonglong: case Scalar::e_sint128: - case Scalar::e_uint128: case Scalar::e_sint256: + if (b->m_integer != 0) + { + result.m_integer = a->m_integer.srem(b->m_integer); + return result; + } + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: case Scalar::e_uint256: if (b->m_integer != 0) { - result.m_integer = *a->m_integer.getRawData() % *b->m_integer.getRawData(); + result.m_integer = a->m_integer.urem(b->m_integer); return result; } break; @@ -2477,27 +2500,6 @@ return result; } -// Return the raw unsigned integer without any casting or conversion -unsigned int -Scalar::RawUInt () const -{ - return *(const uint_t *) m_integer.getRawData(); -} - -// Return the raw unsigned long without any casting or conversion -unsigned long -Scalar::RawULong () const -{ - return *(const ulong_t *) m_integer.getRawData(); -} - -// Return the raw unsigned long long without any casting or conversion -unsigned long long -Scalar::RawULongLong () const -{ - return *(const ulonglong_t *) m_integer.getRawData(); -} - Error Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t byte_size) { @@ -2652,29 +2654,29 @@ if (data.GetByteOrder() == eByteOrderBig) { int128.x[1] = (uint64_t)data.GetU64 (&offset); - int128.x[0] = (uint64_t)data.GetU64 (&offset + 1); + int128.x[0] = (uint64_t)data.GetU64 (&offset); } else { int128.x[0] = (uint64_t)data.GetU64 (&offset); - int128.x[1] = (uint64_t)data.GetU64 (&offset + 1); + int128.x[1] = (uint64_t)data.GetU64 (&offset); } operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x)); break; case 32: if (data.GetByteOrder() == eByteOrderBig) { int256.x[3] = (uint64_t)data.GetU64 (&offset); - int256.x[2] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[1] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[0] = (uint64_t)data.GetU64 (&offset + 1); + int256.x[2] = (uint64_t)data.GetU64 (&offset); + int256.x[1] = (uint64_t)data.GetU64 (&offset); + int256.x[0] = (uint64_t)data.GetU64 (&offset); } else { int256.x[0] = (uint64_t)data.GetU64 (&offset); - int256.x[1] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[2] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[3] = (uint64_t)data.GetU64 (&offset + 1); + int256.x[1] = (uint64_t)data.GetU64 (&offset); + int256.x[2] = (uint64_t)data.GetU64 (&offset); + int256.x[3] = (uint64_t)data.GetU64 (&offset); } operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x)); break; @@ -2698,29 +2700,29 @@ if (data.GetByteOrder() == eByteOrderBig) { int128.x[1] = (uint64_t)data.GetU64 (&offset); - int128.x[0] = (uint64_t)data.GetU64 (&offset + 1); + int128.x[0] = (uint64_t)data.GetU64 (&offset); } else { int128.x[0] = (uint64_t)data.GetU64 (&offset); - int128.x[1] = (uint64_t)data.GetU64 (&offset + 1); + int128.x[1] = (uint64_t)data.GetU64 (&offset); } operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x)); break; case 32: if (data.GetByteOrder() == eByteOrderBig) { int256.x[3] = (uint64_t)data.GetU64 (&offset); - int256.x[2] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[1] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[0] = (uint64_t)data.GetU64 (&offset + 1); + int256.x[2] = (uint64_t)data.GetU64 (&offset); + int256.x[1] = (uint64_t)data.GetU64 (&offset); + int256.x[0] = (uint64_t)data.GetU64 (&offset); } else { int256.x[0] = (uint64_t)data.GetU64 (&offset); - int256.x[1] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[2] = (uint64_t)data.GetU64 (&offset + 1); - int256.x[3] = (uint64_t)data.GetU64 (&offset + 1); + int256.x[1] = (uint64_t)data.GetU64 (&offset); + int256.x[2] = (uint64_t)data.GetU64 (&offset); + int256.x[3] = (uint64_t)data.GetU64 (&offset); } operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x)); break; @@ -2828,45 +2830,28 @@ if (bit_size == 0) return true; - uint32_t msbit = bit_offset + bit_size - 1; - uint32_t lsbit = bit_offset; - uint64_t result; switch (m_type) { case Scalar::e_void: + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: break; - case e_float: - result = SignedBits ((uint64_t )m_float.convertToFloat(), msbit, lsbit); - m_float = llvm::APFloat((float_t)result); - return true; - case e_double: - result = SignedBits ((uint64_t )m_float.convertToDouble(), msbit, lsbit); - m_float = llvm::APFloat((double_t)result); - return true; - case e_long_double: - m_integer = m_float.bitcastToAPInt(); - result = SignedBits (*m_integer.getRawData(), msbit, lsbit); - if(m_ieee_quad) - m_float = llvm::APFloat(llvm::APFloat::IEEEquad, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&result)->x)); - else - m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&result)->x)); - return true; - case Scalar::e_sint: case Scalar::e_slong: case Scalar::e_slonglong: case Scalar::e_sint128: case Scalar::e_sint256: - m_integer = SignedBits (*m_integer.getRawData(), msbit, lsbit); + m_integer = m_integer.ashr(bit_offset).trunc(bit_size).sext(8 * GetByteSize()); return true; case Scalar::e_uint: case Scalar::e_ulong: case Scalar::e_ulonglong: case Scalar::e_uint128: case Scalar::e_uint256: - m_integer = UnsignedBits (*m_integer.getRawData(), msbit, lsbit); + m_integer = m_integer.lshr(bit_offset).trunc(bit_size).zext(8 * GetByteSize()); return true; } return false; Index: include/lldb/Symbol/Type.h =================================================================== --- include/lldb/Symbol/Type.h +++ include/lldb/Symbol/Type.h @@ -958,13 +958,13 @@ uint64_t GetValueAsUnsigned () const { - return *m_value.getRawData(); + return m_value.getZExtValue(); } int64_t GetValueAsSigned () const { - return (int64_t) *m_value.getRawData(); + return m_value.getSExtValue(); } protected: Index: include/lldb/Core/Scalar.h =================================================================== --- include/lldb/Core/Scalar.h +++ include/lldb/Core/Scalar.h @@ -162,6 +162,9 @@ bool MakeSigned (); + bool + MakeUnsigned (); + static const char * GetValueTypeAsCString (Scalar::Type value_type); @@ -242,22 +245,10 @@ int SInt(int fail_value = 0) const; - // Return the raw unsigned integer without any casting or conversion - unsigned int - RawUInt () const; - - // Return the raw unsigned long without any casting or conversion - unsigned long - RawULong () const; - - // Return the raw unsigned long long without any casting or conversion - unsigned long long - RawULongLong () const; - unsigned char UChar(unsigned char fail_value = 0) const; - char + signed char SChar(char fail_value = 0) const; unsigned short @@ -302,9 +293,6 @@ long double LongDouble(long double fail_value = 0.0) const; - uint64_t - GetRawBits64 (uint64_t fail_value) const; - Error SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size);
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits