https://github.com/beetrees updated https://github.com/llvm/llvm-project/pull/98369
>From b96a6a1b6ef96702461a6cf32b361847c318bf8a Mon Sep 17 00:00:00 2001 From: beetrees <b...@beetr.ee> Date: Wed, 10 Jul 2024 18:49:45 +0100 Subject: [PATCH] [lldb] Add support for displaying `__float128` variables --- lldb/bindings/python/python-extensions.swig | 1 + lldb/docs/python_api_enums.rst | 2 ++ lldb/include/lldb/Symbol/TypeSystem.h | 3 ++- lldb/include/lldb/lldb-enumerations.h | 7 +++++- lldb/source/Commands/CommandObjectMemory.cpp | 2 ++ lldb/source/Core/DumpDataExtractor.cpp | 14 ++++++++--- lldb/source/DataFormatters/FormatManager.cpp | 1 + lldb/source/DataFormatters/VectorType.cpp | 2 ++ .../TypeSystem/Clang/TypeSystemClang.cpp | 25 ++++++++++++++++++- .../TypeSystem/Clang/TypeSystemClang.h | 3 ++- lldb/source/ValueObject/ValueObject.cpp | 5 ++-- lldb/unittests/Core/DumpDataExtractorTest.cpp | 6 +++++ lldb/unittests/Symbol/TestTypeSystemClang.cpp | 2 ++ 13 files changed, 63 insertions(+), 10 deletions(-) diff --git a/lldb/bindings/python/python-extensions.swig b/lldb/bindings/python/python-extensions.swig index 4ba1607c70909..40fa76872ee96 100644 --- a/lldb/bindings/python/python-extensions.swig +++ b/lldb/bindings/python/python-extensions.swig @@ -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) diff --git a/lldb/docs/python_api_enums.rst b/lldb/docs/python_api_enums.rst index b6a2497ea878e..a43a47b8d6985 100644 --- a/lldb/docs/python_api_enums.rst +++ b/lldb/docs/python_api_enums.rst @@ -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: diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h index df87fea32b72a..636bea5adcf83 100644 --- a/lldb/include/lldb/Symbol/TypeSystem.h +++ b/lldb/include/lldb/Symbol/TypeSystem.h @@ -310,7 +310,8 @@ class TypeSystem : public PluginInterface, // Exploring the type - virtual const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) = 0; + virtual const llvm::fltSemantics & + GetFloatTypeSemantics(size_t byte_size, bool prefer_float128) = 0; virtual llvm::Expected<uint64_t> GetBitSize(lldb::opaque_compiler_type_t type, diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 6d10cc8bcffcb..311a18b850e0a 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -203,6 +203,10 @@ enum Format { 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 }; @@ -837,7 +841,8 @@ enum BasicType { eBasicTypeObjCClass, eBasicTypeObjCSel, eBasicTypeNullPtr, - eBasicTypeOther + eBasicTypeOther, + eBasicTypeFloat128 }; /// Deprecated diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index 7140333bb3cde..5ccd4be7741e6 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -156,6 +156,7 @@ class OptionGroupReadMemory : public OptionGroup { case eFormatBinary: case eFormatFloat: + case eFormatFloat128: case eFormatOctal: case eFormatDecimal: case eFormatEnum: @@ -1330,6 +1331,7 @@ class CommandObjectMemoryWrite : public CommandObjectParsed { switch (m_format_options.GetFormat()) { case kNumFormats: case eFormatFloat: // TODO: add support for floats soon + case eFormatFloat128: case eFormatCharPrintable: case eFormatBytesWithASCII: case eFormatComplex: diff --git a/lldb/source/Core/DumpDataExtractor.cpp b/lldb/source/Core/DumpDataExtractor.cpp index 72140736d8877..137a54d7aab29 100644 --- a/lldb/source/Core/DumpDataExtractor.cpp +++ b/lldb/source/Core/DumpDataExtractor.cpp @@ -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, + bool prefer_float128) { 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, prefer_float128); } // No target, just make a reasonable guess switch(byte_size) { @@ -335,6 +336,10 @@ static const llvm::fltSemantics &GetFloatSemantics(const TargetSP &target_sp, return llvm::APFloat::IEEEsingle(); case 8: return llvm::APFloat::IEEEdouble(); + case 16: + if (prefer_float128) { + return llvm::APFloat::IEEEquad(); + } } return llvm::APFloat::Bogus(); } @@ -653,6 +658,7 @@ lldb::offset_t lldb_private::DumpDataExtractor( } } break; + case eFormatFloat128: case eFormatFloat: { TargetSP target_sp; if (exe_scope) @@ -665,8 +671,8 @@ lldb::offset_t lldb_private::DumpDataExtractor( // Show full precision when printing float values const unsigned format_precision = 0; - const llvm::fltSemantics &semantics = - GetFloatSemantics(target_sp, item_byte_size); + const llvm::fltSemantics &semantics = GetFloatSemantics( + target_sp, item_byte_size, item_format == eFormatFloat128); // 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 diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp index 3b891cecb1c8b..6ff4948eec34a 100644 --- a/lldb/source/DataFormatters/FormatManager.cpp +++ b/lldb/source/DataFormatters/FormatManager.cpp @@ -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])) == diff --git a/lldb/source/DataFormatters/VectorType.cpp b/lldb/source/DataFormatters/VectorType.cpp index eab2612d1e941..2cea366c44adf 100644 --- a/lldb/source/DataFormatters/VectorType.cpp +++ b/lldb/source/DataFormatters/VectorType.cpp @@ -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: diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 1a2b3d4133e51..969c27a0abc18 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -809,6 +809,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: @@ -970,6 +972,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); @@ -979,6 +988,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: @@ -2068,6 +2079,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: @@ -4737,19 +4750,23 @@ CompilerType TypeSystemClang::CreateGenericFunctionPrototype() { // Exploring the type const llvm::fltSemantics & -TypeSystemClang::GetFloatTypeSemantics(size_t byte_size) { +TypeSystemClang::GetFloatTypeSemantics(size_t byte_size, bool prefer_float128) { 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 (prefer_float128 && 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(); } @@ -5222,6 +5239,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; } @@ -5545,6 +5564,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; @@ -6106,6 +6127,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: @@ -8837,6 +8859,7 @@ bool TypeSystemClang::DumpTypeValue( case eFormatHex: case eFormatHexUppercase: case eFormatFloat: + case eFormatFloat128: case eFormatOctal: case eFormatOSType: case eFormatUnsigned: diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h index 93933846d114d..23d86239b8d16 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -826,7 +826,8 @@ class TypeSystemClang : public TypeSystem { // Exploring the type - const llvm::fltSemantics &GetFloatTypeSemantics(size_t byte_size) override; + const llvm::fltSemantics & + GetFloatTypeSemantics(size_t byte_size, bool prefer_float128) override; llvm::Expected<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) { diff --git a/lldb/source/ValueObject/ValueObject.cpp b/lldb/source/ValueObject/ValueObject.cpp index e1c66763ff0b8..ddd95122aafa3 100644 --- a/lldb/source/ValueObject/ValueObject.cpp +++ b/lldb/source/ValueObject/ValueObject.cpp @@ -1468,8 +1468,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) || diff --git a/lldb/unittests/Core/DumpDataExtractorTest.cpp b/lldb/unittests/Core/DumpDataExtractorTest.cpp index 3d1e8bc5e4623..6302f1e1d31a6 100644 --- a/lldb/unittests/Core/DumpDataExtractorTest.cpp +++ b/lldb/unittests/Core/DumpDataExtractorTest.cpp @@ -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( diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp index a9b0c87c4fbce..a3a982ee596a9 100644 --- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp @@ -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), _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits