#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"
#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"
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;
{
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)
{
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;
}
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;
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'])
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 =',
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 =',