Use llvm::APFloat for formatting if a target is available. Each target when debugging has a "ASTContext" that helps us to use the correct floating point semantics. Now that APFloat supports toString we now use that. If we don't have a target, we still fall back on the old display methodology, but the important formatting should always have a target available and thus use the compiler floating point code.
Modified the test programs to use floating point constants that always will display correctly. We had some numbers that were being rounded, and now that we are using clang, we no longer round them and we get more correct results. llvm-svn: 183792
This commit is contained in:
parent
1f16b743d9
commit
bc8fc0f5e0
|
@ -1004,6 +1004,15 @@ public:
|
|||
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
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -1280,12 +1287,19 @@ DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::of
|
|||
}
|
||||
uint64_array.push_back(u64);
|
||||
}
|
||||
*offset_ptr += byte_size;
|
||||
result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return offset;
|
||||
|
||||
llvm::APInt apint (byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
|
||||
|
||||
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))
|
||||
{
|
||||
std::string apint_str(apint.toString(radix, is_signed));
|
||||
switch (radix)
|
||||
{
|
||||
|
@ -1299,6 +1313,7 @@ DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::of
|
|||
break;
|
||||
}
|
||||
s->Write(apint_str.c_str(), apint_str.size());
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
@ -1701,6 +1716,83 @@ DataExtractor::Dump (Stream *s,
|
|||
break;
|
||||
|
||||
case eFormatFloat:
|
||||
{
|
||||
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)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
if (item_byte_size == sizeof(float) || item_byte_size == 2)
|
||||
|
@ -1736,6 +1828,7 @@ DataExtractor::Dump (Stream *s,
|
|||
ss.flush();
|
||||
s->Printf("%s", ss.str().c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case eFormatUnicode16:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 =',
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue