[Lldb-commits] [lldb] [lldb][DWARFASTParserClang] Fix handle non-type template parameters in MakeAPValue (PR #186629)

via lldb-commits lldb-commits at lists.llvm.org
Sun Mar 15 14:18:20 PDT 2026


https://github.com/zyn-li updated https://github.com/llvm/llvm-project/pull/186629

>From 003e95ddad73efa3461361b60efd9cfb966b149c Mon Sep 17 00:00:00 2001
From: Zhiyuan Li <zynli at meta.com>
Date: Fri, 13 Mar 2026 18:05:10 -0700
Subject: [PATCH] [lldb][DWARFASTParserClang] Handle pointer-to-member non-type
 template parameters in MakeAPValue

---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 21 +++++++++----
 .../Makefile                                  |  3 ++
 .../TestCppNonTypeTemplateParamPtrToMember.py | 23 ++++++++++++++
 .../main.cpp                                  | 30 +++++++++++++++++++
 4 files changed, 72 insertions(+), 5 deletions(-)
 create mode 100644 lldb/test/API/lang/cpp/non-type-template-param-member-ptr/Makefile
 create mode 100644 lldb/test/API/lang/cpp/non-type-template-param-member-ptr/TestCppNonTypeTemplateParamPtrToMember.py
 create mode 100644 lldb/test/API/lang/cpp/non-type-template-param-member-ptr/main.cpp

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index cb33fc21bfba9..76628a38757f7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2015,7 +2015,10 @@ static std::optional<clang::APValue> MakeAPValue(const clang::ASTContext &ast,
     return std::nullopt;
 
   bool is_signed = false;
-  const bool is_integral = clang_type.IsIntegerOrEnumerationType(is_signed);
+  const bool is_integral = clang_type.IsIntegerOrEnumerationType(is_signed) ||
+                           clang_type.IsPointerOrReferenceType() ||
+                           clang_type.IsMemberFunctionPointerType() ||
+                           clang_type.IsNullPtrType();
 
   llvm::APSInt apint(*bit_width, !is_signed);
   apint = value;
@@ -2023,13 +2026,21 @@ static std::optional<clang::APValue> MakeAPValue(const clang::ASTContext &ast,
   if (is_integral)
     return clang::APValue(apint);
 
+  if (clang_type.IsRealFloatingPointType()) {
+    return clang::APValue(llvm::APFloat(
+        ast.getFloatTypeSemantics(ClangUtil::GetQualType(clang_type)), apint));
+  }
+
   // FIXME: we currently support a limited set of floating point types.
   // E.g., 16-bit floats are not supported.
-  if (!clang_type.IsRealFloatingPointType())
-    return std::nullopt;
 
-  return clang::APValue(llvm::APFloat(
-      ast.getFloatTypeSemantics(ClangUtil::GetQualType(clang_type)), apint));
+  LLDB_LOG(GetLog(LLDBLog::Types),
+           "MakeAPValue: Unsupported NTTP type class: {0}",
+           clang_type.GetTypeClass());
+
+  lldbassert(false && "Unsupported type for non-type template parameter");
+
+  return std::nullopt;
 }
 
 bool DWARFASTParserClang::ParseTemplateDIE(
diff --git a/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/Makefile b/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/Makefile
new file mode 100644
index 0000000000000..99998b20bcb05
--- /dev/null
+++ b/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
diff --git a/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/TestCppNonTypeTemplateParamPtrToMember.py b/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/TestCppNonTypeTemplateParamPtrToMember.py
new file mode 100644
index 0000000000000..7af6d9014b26d
--- /dev/null
+++ b/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/TestCppNonTypeTemplateParamPtrToMember.py
@@ -0,0 +1,23 @@
+"""
+Test that LLDB correctly distinguishes template specializations
+with different pointer-to-member non-type template parameter values.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+    @no_debug_info_test
+    def test(self):
+        self.build()
+        self.dbg.CreateTarget(self.getBuildArtifact("a.out"))
+
+        # Both Data<&S::x> and Data<&S::y> should be resolvable as
+        # distinct specializations. Without the fix, the second
+        # specialization is rejected as a duplicate and dy is
+        # unresolvable.
+        self.expect_expr("dx", result_type="Data<0>")
+        self.expect_expr("dy", result_type="Data<4>")
diff --git a/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/main.cpp b/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/main.cpp
new file mode 100644
index 0000000000000..0a236ce3604bb
--- /dev/null
+++ b/lldb/test/API/lang/cpp/non-type-template-param-member-ptr/main.cpp
@@ -0,0 +1,30 @@
+// Test that LLDB correctly distinguishes template specializations with
+// different pointer-to-member non-type template parameter values.
+//
+// When a template takes a pointer-to-member as a non-type parameter
+// (e.g., template <int S::*P>), DWARF encodes each instantiation's
+// member as a DW_AT_const_value (the byte offset of the member).
+// LLDB must treat these as distinct values so that each specialization
+// (e.g., Data<&S::x> vs Data<&S::y>) gets its own type in the AST.
+//
+// Without the fix, MakeAPValue rejects pointer-to-member types,
+// causing both specializations to produce identical TemplateArguments.
+// findSpecialization then treats the second as a duplicate, so only
+// one specialization exists and the other variable becomes unresolvable.
+
+struct S {
+  int x;
+  int y;
+};
+
+template <int S::*P> struct Data {
+  int get(S &s) { return s.*P; }
+};
+
+Data<&S::x> dx;
+Data<&S::y> dy;
+
+int main() {
+  S s{1, 2};
+  return dx.get(s) + dy.get(s);
+}



More information about the lldb-commits mailing list