[Lldb-commits] [lldb] [lldb] Add support for displaying `__float128` variables (PR #98369)
via lldb-commits
lldb-commits at lists.llvm.org
Fri May 16 07:46:10 PDT 2025
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 at 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),
More information about the lldb-commits
mailing list