diff options
7 files changed, 188 insertions, 70 deletions
diff --git a/lldb/include/lldb/Symbol/ClangASTContext.h b/lldb/include/lldb/Symbol/ClangASTContext.h index 305775658f4..b3da283d610 100644 --- a/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/lldb/include/lldb/Symbol/ClangASTContext.h @@ -1003,7 +1003,16 @@ public: const char *s, uint8_t *dst, size_t dst_size); - + + lldb::clang_type_t + GetFloatTypeFromBitSize (size_t bit_size) + { + return GetFloatTypeFromBitSize (getASTContext(), bit_size); + } + + static lldb::clang_type_t + GetFloatTypeFromBitSize (clang::ASTContext *ast, + size_t bit_size); //------------------------------------------------------------------ // Qualifiers //------------------------------------------------------------------ diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp index 5b042ce37b6..02ff1e0a470 100644 --- a/lldb/source/Core/DataExtractor.cpp +++ b/lldb/source/Core/DataExtractor.cpp @@ -15,11 +15,15 @@ #include <sstream> #include <string> +#include "clang/AST/ASTContext.h" + #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/MathExtras.h" + #include "lldb/Core/DataBufferHeap.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/DataBuffer.h" @@ -30,6 +34,7 @@ #include "lldb/Core/UUID.h" #include "lldb/Core/dwarf.h" #include "lldb/Host/Endian.h" +#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Target.h" @@ -1234,8 +1239,8 @@ DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const return bytes_consumed; } -static lldb::offset_t -DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix) +static bool +GetAPInt (const DataExtractor &data, lldb::offset_t *offset_ptr, lldb::offset_t byte_size, llvm::APInt &result) { llvm::SmallVector<uint64_t, 2> uint64_array; lldb::offset_t bytes_left = byte_size; @@ -1247,20 +1252,22 @@ DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::of { if (bytes_left >= 8) { - u64 = data.GetU64(&offset); + u64 = data.GetU64(offset_ptr); bytes_left -= 8; } else { - u64 = data.GetMaxU64(&offset, (uint32_t)bytes_left); + u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left); bytes_left = 0; - } + } uint64_array.push_back(u64); } + result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); + return true; } else if (byte_order == lldb::eByteOrderBig) { - lldb::offset_t be_offset = offset + byte_size; + lldb::offset_t be_offset = *offset_ptr + byte_size; lldb::offset_t temp_offset; while (bytes_left > 0) { @@ -1277,28 +1284,36 @@ DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::of temp_offset = be_offset; u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left); bytes_left = 0; - } + } uint64_array.push_back(u64); } + *offset_ptr += byte_size; + result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); + return true; } - else - return offset; + return false; +} - llvm::APInt apint (byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array)); - - std::string apint_str(apint.toString(radix, is_signed)); - switch (radix) +static lldb::offset_t +DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix) +{ + llvm::APInt apint; + if (GetAPInt (data, &offset, byte_size, apint)) { - case 2: - s->Write ("0b", 2); - break; - case 8: - s->Write ("0", 1); - break; - case 10: - break; + std::string apint_str(apint.toString(radix, is_signed)); + switch (radix) + { + case 2: + s->Write ("0b", 2); + break; + case 8: + s->Write ("0", 1); + break; + case 10: + break; + } + s->Write(apint_str.c_str(), apint_str.size()); } - s->Write(apint_str.c_str(), apint_str.size()); return offset; } @@ -1702,39 +1717,117 @@ DataExtractor::Dump (Stream *s, case eFormatFloat: { - std::ostringstream ss; - if (item_byte_size == sizeof(float) || item_byte_size == 2) + TargetSP target_sp; + bool used_apfloat = false; + if (exe_scope) + target_sp = exe_scope->CalculateTarget(); + if (target_sp) + { + ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext(); + if (clang_ast) + { + clang::ASTContext *ast = clang_ast->getASTContext(); + if (ast) + { + llvm::SmallVector<char, 256> sv; + // Show full precision when printing float values + const unsigned format_precision = 0; + const unsigned format_max_padding = 100; + size_t item_bit_size = item_byte_size * 8; + + if (item_bit_size == ast->getTypeSize(ast->FloatTy)) + { + llvm::APInt apint(item_bit_size, this->GetMaxU64(&offset, item_byte_size)); + llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->FloatTy), apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) + { + llvm::APInt apint; + if (GetAPInt (*this, &offset, item_byte_size, apint)) + { + llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->DoubleTy), apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + } + else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) + { + llvm::APInt apint; + switch (target_sp->GetArchitecture().GetCore()) + { + case ArchSpec::eCore_x86_32_i386: + case ArchSpec::eCore_x86_32_i486: + case ArchSpec::eCore_x86_32_i486sx: + case ArchSpec::eCore_x86_64_x86_64: + // clang will assert when contructing the apfloat if we use a 16 byte integer value + if (GetAPInt (*this, &offset, 10, apint)) + { + llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->LongDoubleTy), apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + break; + + default: + if (GetAPInt (*this, &offset, item_byte_size, apint)) + { + llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->LongDoubleTy), apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + break; + } + } + else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) + { + llvm::APInt apint(item_bit_size, this->GetU16(&offset)); + llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->HalfTy), apint); + apfloat.toString(sv, format_precision, format_max_padding); + } + + if (!sv.empty()) + { + s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data()); + used_apfloat = true; + } + } + } + } + + if (!used_apfloat) { - float f; - if (item_byte_size == 2) + std::ostringstream ss; + if (item_byte_size == sizeof(float) || item_byte_size == 2) + { + float f; + if (item_byte_size == 2) + { + uint16_t half = this->GetU16(&offset); + f = half2float(half); + } + else + { + f = GetFloat (&offset); + } + ss.precision(std::numeric_limits<float>::digits10); + ss << f; + } + else if (item_byte_size == sizeof(double)) + { + ss.precision(std::numeric_limits<double>::digits10); + ss << GetDouble(&offset); + } + else if (item_byte_size == sizeof(long double)) { - uint16_t half = this->GetU16(&offset); - f = half2float(half); + ss.precision(std::numeric_limits<long double>::digits10); + ss << GetLongDouble(&offset); } else { - f = GetFloat (&offset); + s->Printf("error: unsupported byte size (%zu) for float format", item_byte_size); + return offset; } - ss.precision(std::numeric_limits<float>::digits10); - ss << f; - } - else if (item_byte_size == sizeof(double)) - { - ss.precision(std::numeric_limits<double>::digits10); - ss << GetDouble(&offset); - } - else if (item_byte_size == sizeof(long double)) - { - ss.precision(std::numeric_limits<long double>::digits10); - ss << GetLongDouble(&offset); - } - else - { - s->Printf("error: unsupported byte size (%zu) for float format", item_byte_size); - return offset; + ss.flush(); + s->Printf("%s", ss.str().c_str()); } - ss.flush(); - s->Printf("%s", ss.str().c_str()); } break; diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp index a69343b1fc7..73ed50931e1 100644 --- a/lldb/source/Symbol/ClangASTContext.cpp +++ b/lldb/source/Symbol/ClangASTContext.cpp @@ -6682,6 +6682,24 @@ ClangASTContext::ConvertStringToFloatValue (ASTContext *ast, clang_type_t clang_ return 0; } +lldb::clang_type_t +ClangASTContext::GetFloatTypeFromBitSize (clang::ASTContext *ast, + size_t bit_size) +{ + if (ast) + { + if (bit_size == ast->getTypeSize(ast->FloatTy)) + return ast->FloatTy.getAsOpaquePtr(); + else if (bit_size == ast->getTypeSize(ast->DoubleTy)) + return ast->DoubleTy.getAsOpaquePtr(); + else if (bit_size == ast->getTypeSize(ast->LongDoubleTy)) + return ast->LongDoubleTy.getAsOpaquePtr(); + else if (bit_size == ast->getTypeSize(ast->HalfTy)) + return ast->HalfTy.getAsOpaquePtr(); + } + return NULL; +} + unsigned ClangASTContext::GetTypeQualifiers(clang_type_t clang_type) { @@ -6704,7 +6722,7 @@ ClangASTContext::GetCompleteType (clang::ASTContext *ast, lldb::clang_type_t cla bool ClangASTContext::GetCompleteType (clang_type_t clang_type) -{ +{ return ClangASTContext::GetCompleteType (getASTContext(), clang_type); } diff --git a/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py b/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py index 1507ecefbee..6ab7f93067c 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/TestDataFormatterNamedSummaries.py @@ -81,7 +81,7 @@ class NamedSummariesDataFormatterTestCase(TestBase): self.expect("frame variable second --summary AllUseIt", substrs = ['AllUseIt: x=65', - 'y=43.21']) + 'y=43.25']) self.expect("frame variable third --summary AllUseIt", substrs = ['AllUseIt: x=96', diff --git a/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp index 77ff54dbcd5..fdec5fecd3a 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp +++ b/lldb/test/functionalities/data-formatter/data-formatter-named-summaries/main.cpp @@ -46,7 +46,7 @@ struct Third int main (int argc, const char * argv[]) { First first(12,34); - Second second(65,43.21); + Second second(65,43.25); Third *third = new Third(96,'E'); first.dummy = 1; // Set break point at this line. diff --git a/lldb/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py b/lldb/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py index 6d3103cda4b..27ca2e1361c 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py +++ b/lldb/test/functionalities/data-formatter/data-formatter-smart-array/TestDataFormatterSmartArray.py @@ -283,29 +283,29 @@ class SmartArrayDataFormatterTestCase(TestBase): self.expect("frame variable flarr", substrs = ['flarr = arr =', - '{78.5},{77.4},{78},{76.1},{76.7},{76.8},{77}']) + '{78.5},{77.25},{78},{76.125},{76.75},{76.875},{77}']) self.expect("frame variable other.flarr", substrs = ['flarr = arr = ', - '{25.5},{25.7},{25.9},{26.4},{27.1},{27.3},{26.9}']) + '{25.5},{25.25},{25.125},{26.75},{27.375},{27.5},{26.125}']) # printing full array as an array self.runCmd("type summary add --summary-string \"arr = ${var%float32[]}\" \"float [7]\"") self.expect("frame variable flarr", substrs = ['flarr = arr =', - '78.5,77.4,78,76.1,76.7,76.8,77']) + '78.5,77.25,78,76.125,76.75,76.875,77']) self.expect("frame variable other.flarr", substrs = ['flarr = arr =', - '25.5,25.7,25.9,26.4,27.1,27.3,26.9']) + '25.5,25.25,25.125,26.75,27.375,27.5,26.125']) # using array smart summary strings for pointers should make no sense self.runCmd("type summary add --summary-string \"arr = ${var%float32[]}\" \"float *\"") self.runCmd("type summary add --summary-string \"arr = ${var%int32_t[]}\" \"int *\"") self.expect("frame variable flptr", matching=False, - substrs = ['78.5,77.4,78,76.1,76.7,76.8,77']) + substrs = ['78.5,77.25,78,76.125,76.75,76.875,77']) self.expect("frame variable intptr", matching=False, substrs = ['1,1,2,3,5']) @@ -316,11 +316,11 @@ class SmartArrayDataFormatterTestCase(TestBase): self.expect("frame variable flarr", substrs = ['flarr = arr =', - '00 00 9d 42,cd cc 9a 42,00 00 9c 42,33 33 98 42,66 66 99 42,9a 99 99 42,00 00 9a 42']) + '00 00 9d 42,00 80 9a 42,00 00 9c 42,00 40 98 42,00 80 99 42,00 c0 99 42,00 00 9a 42']) self.expect("frame variable other.flarr", substrs = ['flarr = arr =', - '00 00 cc 41,9a 99 cd 41,33 33 cf 41,33 33 d3 41,cd cc d8 41,66 66 da 41,33 33 d7 41']) + '00 00 cc 41,00 00 ca 41,00 00 c9 41,00 00 d6 41,00 00 db 41,00 00 dc 41,00 00 d1 41']) self.expect("frame variable intarr", substrs = ['intarr = arr =', @@ -335,13 +335,11 @@ class SmartArrayDataFormatterTestCase(TestBase): self.expect("frame variable flarr", substrs = ['flarr = arr =', - '...B,cd cc 9a 42', - 'ff.B,9a 99 99 42']) + '00 00 9d 42 ...B,00 80 9a 42 ...B,00 00 9c 42 ...B,00 40 98 42 .@.B,00 80 99 42 ...B,00 c0 99 42 ...B,00 00 9a 42 ...B']) self.expect("frame variable other.flarr", substrs = ['flarr = arr =', - '...A,33 33 cf 41', - '33.A,cd cc d8 41']) + '00 00 cc 41 ...A,00 00 ca 41 ...A,00 00 c9 41 ...A,00 00 d6 41 ...A,00 00 db 41 ...A,00 00 dc 41 ...A,00 00 d1 41 ...A']) self.expect("frame variable intarr", substrs = ['intarr = arr =', diff --git a/lldb/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp index 24ee5be9e9c..9279e414be3 100644 --- a/lldb/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp +++ b/lldb/test/functionalities/data-formatter/data-formatter-smart-array/main.cpp @@ -36,12 +36,12 @@ struct SomeOtherData intarr[4] = 5; flarr[0] = 25.5; - flarr[1] = 25.7; - flarr[2] = 25.9; - flarr[3] = 26.4; - flarr[4] = 27.1; - flarr[5] = 27.3; - flarr[6] = 26.9; + flarr[1] = 25.25; + flarr[2] = 25.125; + flarr[3] = 26.75; + flarr[4] = 27.375; + flarr[5] = 27.5; + flarr[6] = 26.125; } }; @@ -51,7 +51,7 @@ int main (int argc, const char * argv[]) char *strptr = NULL; strptr = "Hello world!"; int intarr[5] = {1,1,2,3,5}; - float flarr[7] = {78.5,77.4,78.0,76.1,76.7,76.8,77.0}; + float flarr[7] = {78.5,77.25,78.0,76.125,76.75,76.875,77.0}; SomeData data; |

