[Lldb-commits] [lldb] [lldb][TypeSystemClang] Add support for floating point template argument constants (PR #127206)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Fri Feb 14 05:47:40 PST 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/127206
>From 759f0569807d00a059a78aeb3bd1eddeffcbdf36 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 14 Feb 2025 11:43:20 +0000
Subject: [PATCH 1/4] Init
---
lldb/include/lldb/Symbol/CompilerType.h | 3 +-
lldb/source/API/SBType.cpp | 8 +++-
.../Language/CPlusPlus/GenericBitset.cpp | 2 +-
.../Plugins/Language/CPlusPlus/LibCxxSpan.cpp | 2 +-
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 33 ++++++++++---
.../TypeSystem/Clang/TypeSystemClang.cpp | 47 +++++++++++++------
.../TestCppTemplateArguments.py | 31 ++++++++++--
.../API/lang/cpp/template-arguments/main.cpp | 6 +++
lldb/unittests/Symbol/TestTypeSystemClang.cpp | 42 ++++++++++++++++-
9 files changed, 143 insertions(+), 31 deletions(-)
diff --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index 096a8f1ab68e8..f7e3e552f3e45 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -15,6 +15,7 @@
#include <vector>
#include "lldb/lldb-private.h"
+#include "clang/AST/APValue.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/Support/Casting.h"
@@ -544,7 +545,7 @@ bool operator==(const CompilerType &lhs, const CompilerType &rhs);
bool operator!=(const CompilerType &lhs, const CompilerType &rhs);
struct CompilerType::IntegralTemplateArgument {
- llvm::APSInt value;
+ clang::APValue value;
CompilerType type;
};
diff --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index 6401d32c85795..72f590947dff6 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -697,6 +697,7 @@ lldb::SBValue SBType::GetTemplateArgumentValue(lldb::SBTarget target,
std::optional<CompilerType::IntegralTemplateArgument> arg;
const bool expand_pack = true;
switch (GetTemplateArgumentKind(idx)) {
+ case eTemplateArgumentKindStructuralValue:
case eTemplateArgumentKindIntegral:
arg = m_opaque_sp->GetCompilerType(false).GetIntegralTemplateArgument(
idx, expand_pack);
@@ -708,7 +709,12 @@ lldb::SBValue SBType::GetTemplateArgumentValue(lldb::SBTarget target,
if (!arg)
return {};
- Scalar value{arg->value};
+ Scalar value;
+ if (arg->value.isFloat())
+ value = arg->value.getFloat();
+ else
+ value = arg->value.getInt();
+
DataExtractor data;
value.GetData(data);
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index 33955dccb6ccc..99ff975825c71 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -91,7 +91,7 @@ lldb::ChildCacheState GenericBitsetFrontEnd::Update() {
size_t size = 0;
if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
- size = arg->value.getLimitedValue();
+ size = arg->value.getInt().getLimitedValue();
m_elements.assign(size, ValueObjectSP());
m_first =
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp
index 15040295efe6d..687ef1739ad11 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxSpan.cpp
@@ -119,7 +119,7 @@ lldb_private::formatters::LibcxxStdSpanSyntheticFrontEnd::Update() {
} else if (auto arg =
m_backend.GetCompilerType().GetIntegralTemplateArgument(1)) {
- m_num_elements = arg->value.getLimitedValue();
+ m_num_elements = arg->value.getInt().getLimitedValue();
}
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index ec0004c70c6da..70af283ab7443 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1973,6 +1973,27 @@ class DWARFASTParserClang::DelayedAddObjCClassProperty {
ClangASTMetadata m_metadata;
};
+static clang::APValue MakeAPValue(CompilerType clang_type, uint64_t bit_width,
+ uint64_t value) {
+ bool is_signed = false;
+ const bool is_integral = clang_type.IsIntegerOrEnumerationType(is_signed);
+
+ llvm::APSInt apint(bit_width, !is_signed);
+ apint = value;
+
+ if (is_integral)
+ return clang::APValue(apint);
+
+ uint32_t count;
+ bool is_complex;
+ assert(clang_type.IsFloatingPointType(count, is_complex));
+
+ if (bit_width == 32)
+ return clang::APValue(llvm::APFloat(apint.bitsToFloat()));
+
+ return clang::APValue(llvm::APFloat(apint.bitsToDouble()));
+}
+
bool DWARFASTParserClang::ParseTemplateDIE(
const DWARFDIE &die,
TypeSystemClang::TemplateParameterInfos &template_param_infos) {
@@ -2050,9 +2071,6 @@ bool DWARFASTParserClang::ParseTemplateDIE(
clang_type = m_ast.GetBasicType(eBasicTypeVoid);
if (!is_template_template_argument) {
- bool is_signed = false;
- // Get the signed value for any integer or enumeration if available
- clang_type.IsIntegerOrEnumerationType(is_signed);
if (name && !name[0])
name = nullptr;
@@ -2061,11 +2079,12 @@ bool DWARFASTParserClang::ParseTemplateDIE(
std::optional<uint64_t> size = clang_type.GetBitSize(nullptr);
if (!size)
return false;
- llvm::APInt apint(*size, uval64, is_signed);
+
template_param_infos.InsertArg(
- name, clang::TemplateArgument(ast, llvm::APSInt(apint, !is_signed),
- ClangUtil::GetQualType(clang_type),
- is_default_template_arg));
+ name,
+ clang::TemplateArgument(ast, ClangUtil::GetQualType(clang_type),
+ MakeAPValue(clang_type, *size, uval64),
+ is_default_template_arg));
} else {
template_param_infos.InsertArg(
name, clang::TemplateArgument(ClangUtil::GetQualType(clang_type),
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index bcb63f719de10..567819fc2572c 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1311,10 +1311,18 @@ CompilerType TypeSystemClang::CreateRecordType(
}
namespace {
-/// Returns true iff the given TemplateArgument should be represented as an
-/// NonTypeTemplateParmDecl in the AST.
-bool IsValueParam(const clang::TemplateArgument &argument) {
- return argument.getKind() == TemplateArgument::Integral;
+/// Returns the type of the template argument iff the given TemplateArgument
+/// should be represented as an NonTypeTemplateParmDecl in the AST. Returns
+/// a null QualType otherwise.
+QualType GetValueParamType(const clang::TemplateArgument &argument) {
+ switch (argument.getKind()) {
+ case TemplateArgument::Integral:
+ return argument.getIntegralType();
+ case TemplateArgument::StructuralValue:
+ return argument.getStructuralValueType();
+ default:
+ return {};
+ }
}
void AddAccessSpecifierDecl(clang::CXXRecordDecl *cxx_record_decl,
@@ -1361,8 +1369,8 @@ static TemplateParameterList *CreateTemplateParameterList(
if (name && name[0])
identifier_info = &ast.Idents.get(name);
TemplateArgument const &targ = args[i];
- if (IsValueParam(targ)) {
- QualType template_param_type = targ.getIntegralType();
+ QualType template_param_type = GetValueParamType(targ);
+ if (!template_param_type.isNull()) {
template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
ast, decl_context, SourceLocation(), SourceLocation(), depth, i,
identifier_info, template_param_type, parameter_pack,
@@ -1380,10 +1388,11 @@ static TemplateParameterList *CreateTemplateParameterList(
identifier_info = &ast.Idents.get(template_param_infos.GetPackName());
const bool parameter_pack_true = true;
- if (!template_param_infos.GetParameterPack().IsEmpty() &&
- IsValueParam(template_param_infos.GetParameterPack().Front())) {
- QualType template_param_type =
- template_param_infos.GetParameterPack().Front().getIntegralType();
+ QualType template_param_type =
+ !template_param_infos.GetParameterPack().IsEmpty()
+ ? GetValueParamType(template_param_infos.GetParameterPack().Front())
+ : QualType();
+ if (!template_param_type.isNull()) {
template_param_decls.push_back(NonTypeTemplateParmDecl::Create(
ast, decl_context, SourceLocation(), SourceLocation(), depth,
num_template_params, identifier_info, template_param_type,
@@ -1458,10 +1467,9 @@ static bool TemplateParameterAllowsValue(NamedDecl *param,
} else if (auto *type_param =
llvm::dyn_cast<NonTypeTemplateParmDecl>(param)) {
// Compare the argument kind, i.e. ensure that <typename> != <int>.
- if (!IsValueParam(value))
- return false;
+ QualType value_param_type = GetValueParamType(value);
// Compare the integral type, i.e. ensure that <int> != <char>.
- if (type_param->getType() != value.getIntegralType())
+ if (type_param->getType() != value_param_type)
return false;
} else {
// There is no way to create other parameter decls at the moment, so we
@@ -7351,10 +7359,19 @@ TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
return std::nullopt;
const auto *arg = GetNthTemplateArgument(template_decl, idx, expand_pack);
- if (!arg || arg->getKind() != clang::TemplateArgument::Integral)
+ if (!arg)
return std::nullopt;
- return {{arg->getAsIntegral(), GetType(arg->getIntegralType())}};
+ switch (arg->getKind()) {
+ case clang::TemplateArgument::Integral:
+ return {{clang::APValue(arg->getAsIntegral()),
+ GetType(arg->getIntegralType())}};
+ case clang::TemplateArgument::StructuralValue:
+ return {
+ {arg->getAsStructuralValue(), GetType(arg->getStructuralValueType())}};
+ default:
+ return std::nullopt;
+ }
}
CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
diff --git a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
index db5388b8bcc6d..fbfc7d1ca9868 100644
--- a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
+++ b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
@@ -62,10 +62,35 @@ def test(self):
self.assertEqual(template_param_value.GetTypeName(), "char")
self.assertEqual(chr(template_param_value.GetValueAsSigned()), "v")
- # FIXME: type should be Foo<float, 2.0f>
- # FIXME: double/float NTTP parameter values currently not supported.
- value = self.expect_expr("temp4", result_type="Foo<float, 1073741824>")
+ value = self.expect_expr("temp4", result_type="Foo<float, 2.000000e+00>")
template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
self.assertEqual(template_param_value.GetTypeName(), "float")
# FIXME: this should return a float
self.assertEqual(template_param_value.GetValueAsSigned(), 2)
+
+ value = self.expect_expr("temp5", result_type="Foo<double, -2.505000e+02>")
+ template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
+ self.assertEqual(template_param_value.GetTypeName(), "double")
+ # FIXME: this should return a float
+ self.assertEqual(template_param_value.GetValueAsSigned(), -250)
+
+ # FIXME: type should be Foo<int *, &temp1.member>
+ value = self.expect_expr("temp6", result_type="Foo<int *, int *>")
+ self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1))
+
+ value = self.expect_expr("temp7", result_type="Bar<double, 1.200000e+00>")
+ template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
+ self.assertEqual(template_param_value.GetTypeName(), "double")
+ # FIXME: this should return a float
+ self.assertEqual(template_param_value.GetValueAsSigned(), 1)
+
+ value = self.expect_expr("temp8", result_type="Bar<float, 1.000000e+00, 2.000000e+00>")
+ template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
+ self.assertEqual(template_param_value.GetTypeName(), "float")
+ # FIXME: this should return a float
+ self.assertEqual(template_param_value.GetValueAsSigned(), 1)
+
+ template_param_value = value.GetType().GetTemplateArgumentValue(target, 2)
+ self.assertEqual(template_param_value.GetTypeName(), "float")
+ # FIXME: this should return a float
+ self.assertEqual(template_param_value.GetValueAsSigned(), 2)
diff --git a/lldb/test/API/lang/cpp/template-arguments/main.cpp b/lldb/test/API/lang/cpp/template-arguments/main.cpp
index 0c0eb97cbc858..e1add12170b54 100644
--- a/lldb/test/API/lang/cpp/template-arguments/main.cpp
+++ b/lldb/test/API/lang/cpp/template-arguments/main.cpp
@@ -9,5 +9,11 @@ template <typename T, T value> struct Foo {};
Foo<short, -2> temp2;
Foo<char, 'v'> temp3;
Foo<float, 2.0f> temp4;
+Foo<double, -250.5> temp5;
+Foo<int *, &temp1.member> temp6;
+
+template <typename T, T... values> struct Bar {};
+Bar<double, 1.2> temp7;
+Bar<float, 1.0f, 2.0f> temp8;
int main() {}
diff --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
index 23374062127e0..446d1976481db 100644
--- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -525,7 +525,17 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
infos.InsertArg("I", TemplateArgument(m_ast->getASTContext(), arg,
m_ast->getASTContext().IntTy));
- // template<typename T, int I> struct foo;
+ llvm::APFloat float_arg(5.5f);
+ infos.InsertArg("F", TemplateArgument(m_ast->getASTContext(),
+ m_ast->getASTContext().FloatTy,
+ clang::APValue(float_arg)));
+
+ llvm::APFloat double_arg(-15.2);
+ infos.InsertArg("D", TemplateArgument(m_ast->getASTContext(),
+ m_ast->getASTContext().DoubleTy,
+ clang::APValue(double_arg)));
+
+ // template<typename T, int I, float F, double D> struct foo;
ClassTemplateDecl *decl = m_ast->CreateClassTemplateDecl(
m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), eAccessPublic,
"foo", llvm::to_underlying(clang::TagTypeKind::Struct), infos);
@@ -555,6 +565,10 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
CompilerType int_type(m_ast->weak_from_this(),
m_ast->getASTContext().IntTy.getAsOpaquePtr());
+ CompilerType float_type(m_ast->weak_from_this(),
+ m_ast->getASTContext().FloatTy.getAsOpaquePtr());
+ CompilerType double_type(m_ast->weak_from_this(),
+ m_ast->getASTContext().DoubleTy.getAsOpaquePtr());
for (CompilerType t : {type, typedef_type, auto_type}) {
SCOPED_TRACE(t.GetTypeName().AsCString());
@@ -577,8 +591,32 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1,
expand_pack);
ASSERT_NE(std::nullopt, result);
- EXPECT_EQ(arg, result->value);
+ EXPECT_EQ(arg, result->value.getInt());
EXPECT_EQ(int_type, result->type);
+
+ EXPECT_EQ(
+ m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 2, expand_pack),
+ eTemplateArgumentKindStructuralValue);
+ EXPECT_EQ(
+ m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 2, expand_pack),
+ CompilerType());
+ auto float_result = m_ast->GetIntegralTemplateArgument(
+ t.GetOpaqueQualType(), 2, expand_pack);
+ ASSERT_NE(std::nullopt, float_result);
+ EXPECT_EQ(float_arg, float_result->value.getFloat());
+ EXPECT_EQ(float_type, float_result->type);
+
+ EXPECT_EQ(
+ m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 3, expand_pack),
+ eTemplateArgumentKindStructuralValue);
+ EXPECT_EQ(
+ m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 3, expand_pack),
+ CompilerType());
+ auto double_result = m_ast->GetIntegralTemplateArgument(
+ t.GetOpaqueQualType(), 3, expand_pack);
+ ASSERT_NE(std::nullopt, double_result);
+ EXPECT_EQ(double_arg, double_result->value.getFloat());
+ EXPECT_EQ(double_type, double_result->type);
}
}
>From e78624df45c439e3fb513a990568d7225161d527 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 14 Feb 2025 12:22:53 +0000
Subject: [PATCH 2/4] fixup! python format
---
.../lang/cpp/template-arguments/TestCppTemplateArguments.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
index fbfc7d1ca9868..1d66cb5aefa82 100644
--- a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
+++ b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
@@ -84,7 +84,9 @@ def test(self):
# FIXME: this should return a float
self.assertEqual(template_param_value.GetValueAsSigned(), 1)
- value = self.expect_expr("temp8", result_type="Bar<float, 1.000000e+00, 2.000000e+00>")
+ value = self.expect_expr(
+ "temp8", result_type="Bar<float, 1.000000e+00, 2.000000e+00>"
+ )
template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
self.assertEqual(template_param_value.GetTypeName(), "float")
# FIXME: this should return a float
>From 00233b90030faac68e64ed7ae6ef46ef77fb4941 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 14 Feb 2025 12:25:32 +0000
Subject: [PATCH 3/4] fixup! put back condition in TemplateParameterAllowsValue
---
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 567819fc2572c..76d98c99b402b 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1468,6 +1468,9 @@ static bool TemplateParameterAllowsValue(NamedDecl *param,
llvm::dyn_cast<NonTypeTemplateParmDecl>(param)) {
// Compare the argument kind, i.e. ensure that <typename> != <int>.
QualType value_param_type = GetValueParamType(value);
+ if (value_param_type.isNull())
+ return false;
+
// Compare the integral type, i.e. ensure that <int> != <char>.
if (type_param->getType() != value_param_type)
return false;
>From c9ad8b5eebcecb3c6b821e21933954972fed0f6d Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 14 Feb 2025 13:46:59 +0000
Subject: [PATCH 4/4] fixup! create APFloat from fltSemantics; add more float
test-cases; add defensive check in GenericBitset
---
.../Language/CPlusPlus/GenericBitset.cpp | 3 +-
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 41 +++++++++++--------
.../TestCppTemplateArguments.py | 11 ++++-
.../API/lang/cpp/template-arguments/main.cpp | 6 ++-
4 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
index 99ff975825c71..5e8cdf4b90d56 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp
@@ -91,7 +91,8 @@ lldb::ChildCacheState GenericBitsetFrontEnd::Update() {
size_t size = 0;
if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
- size = arg->value.getInt().getLimitedValue();
+ if (arg->type.IsInteger())
+ size = arg->value.getInt().getLimitedValue();
m_elements.assign(size, ValueObjectSP());
m_first =
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 70af283ab7443..d9abc0722e6b2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1973,8 +1973,10 @@ class DWARFASTParserClang::DelayedAddObjCClassProperty {
ClangASTMetadata m_metadata;
};
-static clang::APValue MakeAPValue(CompilerType clang_type, uint64_t bit_width,
- uint64_t value) {
+static std::optional<clang::APValue> MakeAPValue(const clang::ASTContext &ast,
+ CompilerType clang_type,
+ uint64_t bit_width,
+ uint64_t value) {
bool is_signed = false;
const bool is_integral = clang_type.IsIntegerOrEnumerationType(is_signed);
@@ -1986,12 +1988,13 @@ static clang::APValue MakeAPValue(CompilerType clang_type, uint64_t bit_width,
uint32_t count;
bool is_complex;
- assert(clang_type.IsFloatingPointType(count, is_complex));
+ // FIXME: we currently support a limited set of floating point types.
+ // E.g., 16-bit floats are not supported.
+ if (!clang_type.IsFloatingPointType(count, is_complex))
+ return std::nullopt;
- if (bit_width == 32)
- return clang::APValue(llvm::APFloat(apint.bitsToFloat()));
-
- return clang::APValue(llvm::APFloat(apint.bitsToDouble()));
+ return clang::APValue(llvm::APFloat(
+ ast.getFloatTypeSemantics(ClangUtil::GetQualType(clang_type)), apint));
}
bool DWARFASTParserClang::ParseTemplateDIE(
@@ -2080,17 +2083,21 @@ bool DWARFASTParserClang::ParseTemplateDIE(
if (!size)
return false;
- template_param_infos.InsertArg(
- name,
- clang::TemplateArgument(ast, ClangUtil::GetQualType(clang_type),
- MakeAPValue(clang_type, *size, uval64),
- is_default_template_arg));
- } else {
- template_param_infos.InsertArg(
- name, clang::TemplateArgument(ClangUtil::GetQualType(clang_type),
- /*isNullPtr*/ false,
- is_default_template_arg));
+ if (auto value = MakeAPValue(ast, clang_type, *size, uval64)) {
+ template_param_infos.InsertArg(
+ name, clang::TemplateArgument(
+ ast, ClangUtil::GetQualType(clang_type),
+ std::move(*value), is_default_template_arg));
+ return true;
+ }
}
+
+ // We get here if this is a type-template parameter or we couldn't create
+ // a non-type template parameter.
+ template_param_infos.InsertArg(
+ name, clang::TemplateArgument(ClangUtil::GetQualType(clang_type),
+ /*isNullPtr*/ false,
+ is_default_template_arg));
} else {
auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name);
template_param_infos.InsertArg(
diff --git a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
index 1d66cb5aefa82..eac7b5ef1099a 100644
--- a/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
+++ b/lldb/test/API/lang/cpp/template-arguments/TestCppTemplateArguments.py
@@ -78,14 +78,21 @@ def test(self):
value = self.expect_expr("temp6", result_type="Foo<int *, int *>")
self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1))
- value = self.expect_expr("temp7", result_type="Bar<double, 1.200000e+00>")
+ # FIXME: support wider range of floating point types
+ value = self.expect_expr("temp7", result_type="Foo<__fp16, __fp16>")
+ self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1))
+
+ value = self.expect_expr("temp8", result_type="Foo<__fp16, __fp16>")
+ self.assertFalse(value.GetType().GetTemplateArgumentValue(target, 1))
+
+ value = self.expect_expr("temp9", result_type="Bar<double, 1.200000e+00>")
template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
self.assertEqual(template_param_value.GetTypeName(), "double")
# FIXME: this should return a float
self.assertEqual(template_param_value.GetValueAsSigned(), 1)
value = self.expect_expr(
- "temp8", result_type="Bar<float, 1.000000e+00, 2.000000e+00>"
+ "temp10", result_type="Bar<float, 1.000000e+00, 2.000000e+00>"
)
template_param_value = value.GetType().GetTemplateArgumentValue(target, 1)
self.assertEqual(template_param_value.GetTypeName(), "float")
diff --git a/lldb/test/API/lang/cpp/template-arguments/main.cpp b/lldb/test/API/lang/cpp/template-arguments/main.cpp
index e1add12170b54..c08679aa0e166 100644
--- a/lldb/test/API/lang/cpp/template-arguments/main.cpp
+++ b/lldb/test/API/lang/cpp/template-arguments/main.cpp
@@ -11,9 +11,11 @@ Foo<char, 'v'> temp3;
Foo<float, 2.0f> temp4;
Foo<double, -250.5> temp5;
Foo<int *, &temp1.member> temp6;
+Foo<_Float16, _Float16(1.0)> temp7;
+Foo<__bf16, __bf16(1.0)> temp8;
template <typename T, T... values> struct Bar {};
-Bar<double, 1.2> temp7;
-Bar<float, 1.0f, 2.0f> temp8;
+Bar<double, 1.2> temp9;
+Bar<float, 1.0f, 2.0f> temp10;
int main() {}
More information about the lldb-commits
mailing list