[lldb] Add support for displaying __float128
variables (#98369)
This commit is contained in:
parent
03bb10bea6
commit
e15b3ef704
@ -594,6 +594,7 @@ def is_numeric_type(basic_type):
|
||||
if basic_type == eBasicTypeFloat: return (True,True)
|
||||
if basic_type == eBasicTypeDouble: return (True,True)
|
||||
if basic_type == eBasicTypeLongDouble: return (True,True)
|
||||
if basic_type == eBasicTypeFloat128: return (True,True)
|
||||
if basic_type == eBasicTypeFloatComplex: return (True,True)
|
||||
if basic_type == eBasicTypeDoubleComplex: return (True,True)
|
||||
if basic_type == eBasicTypeLongDoubleComplex: return (True,True)
|
||||
|
@ -321,6 +321,7 @@ Format
|
||||
.. py:data:: eFormatInstruction
|
||||
.. py:data:: eFormatVoid
|
||||
.. py:data:: eFormatUnicode8
|
||||
.. py:data:: eFormatFloat128
|
||||
|
||||
|
||||
.. _DescriptionLevel:
|
||||
@ -1045,6 +1046,7 @@ BasicType
|
||||
.. py:data:: eBasicTypeObjCSel
|
||||
.. py:data:: eBasicTypeNullPtr
|
||||
.. py:data:: eBasicTypeOther
|
||||
.. py:data:: eBasicTypeFloat128
|
||||
|
||||
|
||||
.. _TraceType:
|
||||
|
@ -310,7 +310,8 @@ public:
|
||||
|
||||
// Exploring the type
|
||||
|
||||
virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0;
|
||||
virtual const llvm::fltSemantics &
|
||||
GetFloatTypeSemantics(size_t byte_size, lldb::Format format) = 0;
|
||||
|
||||
virtual llvm::Expected<uint64_t>
|
||||
GetBitSize(lldb::opaque_compiler_type_t type,
|
||||
|
@ -198,11 +198,15 @@ enum Format {
|
||||
///< character arrays that can contain non printable
|
||||
///< characters
|
||||
eFormatAddressInfo, ///< Describe what an address points to (func + offset
|
||||
///< with file/line, symbol + offset, data, etc)
|
||||
eFormatHexFloat, ///< ISO C99 hex float string
|
||||
eFormatInstruction, ///< Disassemble an opcode
|
||||
eFormatVoid, ///< Do not print this
|
||||
///< with file/line, symbol + offset, data, etc)
|
||||
eFormatHexFloat, ///< ISO C99 hex float string
|
||||
eFormatInstruction, ///< Disassemble an opcode
|
||||
eFormatVoid, ///< Do not print this
|
||||
eFormatUnicode8,
|
||||
eFormatFloat128, ///< Disambiguate between 128-bit `long double` (which uses
|
||||
///< `eFormatFloat`) and `__float128` (which uses
|
||||
///< `eFormatFloat128`). If the value being formatted is not
|
||||
///< 128 bits, then this is identical to `eFormatFloat`.
|
||||
kNumFormats
|
||||
};
|
||||
|
||||
@ -838,7 +842,8 @@ enum BasicType {
|
||||
eBasicTypeObjCClass,
|
||||
eBasicTypeObjCSel,
|
||||
eBasicTypeNullPtr,
|
||||
eBasicTypeOther
|
||||
eBasicTypeOther,
|
||||
eBasicTypeFloat128
|
||||
};
|
||||
|
||||
/// Deprecated
|
||||
|
@ -156,6 +156,7 @@ public:
|
||||
|
||||
case eFormatBinary:
|
||||
case eFormatFloat:
|
||||
case eFormatFloat128:
|
||||
case eFormatOctal:
|
||||
case eFormatDecimal:
|
||||
case eFormatEnum:
|
||||
@ -1356,6 +1357,7 @@ protected:
|
||||
switch (m_format_options.GetFormat()) {
|
||||
case kNumFormats:
|
||||
case eFormatFloat: // TODO: add support for floats soon
|
||||
case eFormatFloat128:
|
||||
case eFormatCharPrintable:
|
||||
case eFormatBytesWithASCII:
|
||||
case eFormatComplex:
|
||||
|
@ -318,14 +318,15 @@ static void printMemoryTags(const DataExtractor &DE, Stream *s,
|
||||
}
|
||||
|
||||
static const llvm::fltSemantics &GetFloatSemantics(const TargetSP &target_sp,
|
||||
size_t byte_size) {
|
||||
size_t byte_size,
|
||||
lldb::Format format) {
|
||||
if (target_sp) {
|
||||
auto type_system_or_err =
|
||||
target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
|
||||
if (!type_system_or_err)
|
||||
llvm::consumeError(type_system_or_err.takeError());
|
||||
else if (auto ts = *type_system_or_err)
|
||||
return ts->GetFloatTypeSemantics(byte_size);
|
||||
return ts->GetFloatTypeSemantics(byte_size, format);
|
||||
}
|
||||
// No target, just make a reasonable guess
|
||||
switch(byte_size) {
|
||||
@ -335,7 +336,13 @@ static const llvm::fltSemantics &GetFloatSemantics(const TargetSP &target_sp,
|
||||
return llvm::APFloat::IEEEsingle();
|
||||
case 8:
|
||||
return llvm::APFloat::IEEEdouble();
|
||||
}
|
||||
case 16:
|
||||
if (format == eFormatFloat128) {
|
||||
return llvm::APFloat::IEEEquad();
|
||||
}
|
||||
// Otherwise it's ambigious whether a 16-byte float is a float128 or a
|
||||
// target-specific long double.
|
||||
}
|
||||
return llvm::APFloat::Bogus();
|
||||
}
|
||||
|
||||
@ -653,6 +660,7 @@ lldb::offset_t lldb_private::DumpDataExtractor(
|
||||
}
|
||||
} break;
|
||||
|
||||
case eFormatFloat128:
|
||||
case eFormatFloat: {
|
||||
TargetSP target_sp;
|
||||
if (exe_scope)
|
||||
@ -666,7 +674,7 @@ lldb::offset_t lldb_private::DumpDataExtractor(
|
||||
const unsigned format_precision = 0;
|
||||
|
||||
const llvm::fltSemantics &semantics =
|
||||
GetFloatSemantics(target_sp, item_byte_size);
|
||||
GetFloatSemantics(target_sp, item_byte_size, item_format);
|
||||
|
||||
// Recalculate the byte size in case of a difference. This is possible
|
||||
// when item_byte_size is 16 (128-bit), because you could get back the
|
||||
|
@ -72,6 +72,7 @@ static constexpr FormatInfo g_format_infos[] = {
|
||||
{eFormatInstruction, 'i', "instruction"},
|
||||
{eFormatVoid, 'v', "void"},
|
||||
{eFormatUnicode8, 'u', "unicode8"},
|
||||
{eFormatFloat128, '\0', "float128"},
|
||||
};
|
||||
|
||||
static_assert((sizeof(g_format_infos) / sizeof(g_format_infos[0])) ==
|
||||
|
@ -55,6 +55,8 @@ static CompilerType GetCompilerTypeForFormat(lldb::Format format,
|
||||
|
||||
case lldb::eFormatFloat:
|
||||
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat);
|
||||
case lldb::eFormatFloat128:
|
||||
return type_system->GetBasicTypeFromAST(lldb::eBasicTypeFloat128);
|
||||
|
||||
case lldb::eFormatHex:
|
||||
case lldb::eFormatHexUppercase:
|
||||
|
@ -795,6 +795,8 @@ TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding,
|
||||
return GetType(ast.LongDoubleTy);
|
||||
if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy))
|
||||
return GetType(ast.HalfTy);
|
||||
if (QualTypeMatchesBitSize(bit_size, ast, ast.Float128Ty))
|
||||
return GetType(ast.Float128Ty);
|
||||
break;
|
||||
|
||||
case eEncodingVector:
|
||||
@ -956,6 +958,13 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize(
|
||||
if (type_name == "long double" &&
|
||||
QualTypeMatchesBitSize(bit_size, ast, ast.LongDoubleTy))
|
||||
return GetType(ast.LongDoubleTy);
|
||||
// As Rust currently uses `TypeSystemClang`, match `f128` here as well so it
|
||||
// doesn't get misinterpreted as `long double` on targets where they are
|
||||
// the same size but different formats.
|
||||
if ((type_name == "__float128" || type_name == "_Float128" ||
|
||||
type_name == "f128") &&
|
||||
QualTypeMatchesBitSize(bit_size, ast, ast.Float128Ty))
|
||||
return GetType(ast.Float128Ty);
|
||||
// Fall back to not requiring a name match
|
||||
if (QualTypeMatchesBitSize(bit_size, ast, ast.FloatTy))
|
||||
return GetType(ast.FloatTy);
|
||||
@ -965,6 +974,8 @@ CompilerType TypeSystemClang::GetBuiltinTypeForDWARFEncodingAndBitSize(
|
||||
return GetType(ast.LongDoubleTy);
|
||||
if (QualTypeMatchesBitSize(bit_size, ast, ast.HalfTy))
|
||||
return GetType(ast.HalfTy);
|
||||
if (QualTypeMatchesBitSize(bit_size, ast, ast.Float128Ty))
|
||||
return GetType(ast.Float128Ty);
|
||||
break;
|
||||
|
||||
case DW_ATE_signed:
|
||||
@ -2054,6 +2065,8 @@ TypeSystemClang::GetOpaqueCompilerType(clang::ASTContext *ast,
|
||||
return ast->DoubleTy.getAsOpaquePtr();
|
||||
case eBasicTypeLongDouble:
|
||||
return ast->LongDoubleTy.getAsOpaquePtr();
|
||||
case eBasicTypeFloat128:
|
||||
return ast->Float128Ty.getAsOpaquePtr();
|
||||
case eBasicTypeFloatComplex:
|
||||
return ast->getComplexType(ast->FloatTy).getAsOpaquePtr();
|
||||
case eBasicTypeDoubleComplex:
|
||||
@ -4742,19 +4755,24 @@ CompilerType TypeSystemClang::CreateGenericFunctionPrototype() {
|
||||
// Exploring the type
|
||||
|
||||
const llvm::fltSemantics &
|
||||
TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) {
|
||||
TypeSystemClang::GetFloatTypeSemantics(size_t byte_size, lldb::Format format) {
|
||||
clang::ASTContext &ast = getASTContext();
|
||||
const size_t bit_size = byte_size * 8;
|
||||
if (bit_size == ast.getTypeSize(ast.FloatTy))
|
||||
return ast.getFloatTypeSemantics(ast.FloatTy);
|
||||
else if (bit_size == ast.getTypeSize(ast.DoubleTy))
|
||||
return ast.getFloatTypeSemantics(ast.DoubleTy);
|
||||
else if (format == eFormatFloat128 &&
|
||||
bit_size == ast.getTypeSize(ast.Float128Ty))
|
||||
return ast.getFloatTypeSemantics(ast.Float128Ty);
|
||||
else if (bit_size == ast.getTypeSize(ast.LongDoubleTy) ||
|
||||
bit_size == llvm::APFloat::semanticsSizeInBits(
|
||||
ast.getFloatTypeSemantics(ast.LongDoubleTy)))
|
||||
return ast.getFloatTypeSemantics(ast.LongDoubleTy);
|
||||
else if (bit_size == ast.getTypeSize(ast.HalfTy))
|
||||
return ast.getFloatTypeSemantics(ast.HalfTy);
|
||||
else if (bit_size == ast.getTypeSize(ast.Float128Ty))
|
||||
return ast.getFloatTypeSemantics(ast.Float128Ty);
|
||||
return llvm::APFloatBase::Bogus();
|
||||
}
|
||||
|
||||
@ -5232,6 +5250,8 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) {
|
||||
case clang::BuiltinType::Double:
|
||||
case clang::BuiltinType::LongDouble:
|
||||
return lldb::eFormatFloat;
|
||||
case clang::BuiltinType::Float128:
|
||||
return lldb::eFormatFloat128;
|
||||
default:
|
||||
return lldb::eFormatHex;
|
||||
}
|
||||
@ -5529,6 +5549,8 @@ TypeSystemClang::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
|
||||
return eBasicTypeDouble;
|
||||
case clang::BuiltinType::LongDouble:
|
||||
return eBasicTypeLongDouble;
|
||||
case clang::BuiltinType::Float128:
|
||||
return eBasicTypeFloat128;
|
||||
|
||||
case clang::BuiltinType::NullPtr:
|
||||
return eBasicTypeNullPtr;
|
||||
@ -6090,6 +6112,7 @@ uint32_t TypeSystemClang::GetNumPointeeChildren(clang::QualType type) {
|
||||
case clang::BuiltinType::Float:
|
||||
case clang::BuiltinType::Double:
|
||||
case clang::BuiltinType::LongDouble:
|
||||
case clang::BuiltinType::Float128:
|
||||
case clang::BuiltinType::Dependent:
|
||||
case clang::BuiltinType::Overload:
|
||||
case clang::BuiltinType::ObjCId:
|
||||
@ -8733,6 +8756,7 @@ bool TypeSystemClang::DumpTypeValue(
|
||||
case eFormatHex:
|
||||
case eFormatHexUppercase:
|
||||
case eFormatFloat:
|
||||
case eFormatFloat128:
|
||||
case eFormatOctal:
|
||||
case eFormatOSType:
|
||||
case eFormatUnsigned:
|
||||
|
@ -823,7 +823,8 @@ public:
|
||||
|
||||
// Exploring the type
|
||||
|
||||
const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override;
|
||||
const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size,
|
||||
lldb::Format format) override;
|
||||
|
||||
llvm::Expected<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type,
|
||||
ExecutionContextScope *exe_scope) {
|
||||
|
@ -1466,8 +1466,9 @@ bool ValueObject::DumpPrintableRepresentation(
|
||||
(custom_format == eFormatComplexFloat) ||
|
||||
(custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
|
||||
(custom_format == eFormatHexUppercase) ||
|
||||
(custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
|
||||
(custom_format == eFormatOSType) ||
|
||||
(custom_format == eFormatFloat) ||
|
||||
(custom_format == eFormatFloat128) ||
|
||||
(custom_format == eFormatOctal) || (custom_format == eFormatOSType) ||
|
||||
(custom_format == eFormatUnicode16) ||
|
||||
(custom_format == eFormatUnicode32) ||
|
||||
(custom_format == eFormatUnsigned) ||
|
||||
|
@ -163,6 +163,9 @@ TEST_F(DumpDataExtractorTest, Formats) {
|
||||
TestDump(0xcafef00d, lldb::Format::eFormatHex, "0xcafef00d");
|
||||
TestDump(0xcafef00d, lldb::Format::eFormatHexUppercase, "0xCAFEF00D");
|
||||
TestDump(0.456, lldb::Format::eFormatFloat, "0.45600000000000002");
|
||||
TestDump(std::vector<uint64_t>{0x47ae147ae147ae14, 0x40011147ae147ae1},
|
||||
lldb::Format::eFormatFloat128,
|
||||
"4.26999999999999999999999999999999963");
|
||||
TestDump(9, lldb::Format::eFormatOctal, "011");
|
||||
// Chars packed into an integer.
|
||||
TestDump<uint32_t>(0x4C4C4442, lldb::Format::eFormatOSType, "'LLDB'");
|
||||
@ -388,6 +391,9 @@ TEST_F(DumpDataExtractorTest, ItemByteSizeErrors) {
|
||||
TestDumpWithItemByteSize(
|
||||
18, lldb::Format::eFormatFloat,
|
||||
"error: unsupported byte size (18) for float format");
|
||||
TestDumpWithItemByteSize(
|
||||
17, lldb::Format::eFormatFloat128,
|
||||
"error: unsupported byte size (17) for float format");
|
||||
|
||||
// We want sizes to exactly match one of float/double.
|
||||
TestDumpWithItemByteSize(
|
||||
|
@ -76,6 +76,8 @@ TEST_F(TestTypeSystemClang, TestGetBasicTypeFromEnum) {
|
||||
context.getComplexType(context.FloatTy)));
|
||||
EXPECT_TRUE(
|
||||
context.hasSameType(GetBasicQualType(eBasicTypeHalf), context.HalfTy));
|
||||
EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeFloat128),
|
||||
context.Float128Ty));
|
||||
EXPECT_TRUE(
|
||||
context.hasSameType(GetBasicQualType(eBasicTypeInt), context.IntTy));
|
||||
EXPECT_TRUE(context.hasSameType(GetBasicQualType(eBasicTypeInt128),
|
||||
|
Loading…
x
Reference in New Issue
Block a user