https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/210338
>From e1f62acc74b75014580361e58a7709a4689d7985 Mon Sep 17 00:00:00 2001 From: Nerixyz <[email protected]> Date: Fri, 17 Jul 2026 15:37:48 +0200 Subject: [PATCH 1/3] [lldb][NativePDB] Fix width and signedness of enum constants --- .../NativePDB/UdtRecordCompleter.cpp | 18 +++- lldb/test/API/lang/cpp/enum-limits/Makefile | 3 + .../lang/cpp/enum-limits/TestCPPEnumLimits.py | 91 +++++++++++++++++++ lldb/test/API/lang/cpp/enum-limits/main.cpp | 48 ++++++++++ 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 lldb/test/API/lang/cpp/enum-limits/Makefile create mode 100644 lldb/test/API/lang/cpp/enum-limits/TestCPPEnumLimits.py create mode 100644 lldb/test/API/lang/cpp/enum-limits/main.cpp diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index 9840b976d2713..871b053151c61 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -331,8 +331,24 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, Declaration decl; llvm::StringRef name = DropNameScope(enumerator.getName()); + clang::EnumDecl *enum_decl = TypeSystemClang::GetAsEnumDecl(m_derived_ct); + if (!enum_decl) + return Error::success(); + + llvm::APSInt val = enumerator.Value; + clang::QualType int_ty = enum_decl->getIntegerType(); + uint64_t n_bits = m_ast_builder.clang().getASTContext().getTypeSize(int_ty); + if (n_bits == 0) + return Error::success(); + + // MSVC encodes 64 Bit unsigned enum values as signed integers. For example, + // ULONGLONG_MAX will be encoded as -1. LLVM encodes all values as unsigned. + // Fix this by explicitly setting the bit width and signedness. + val = val.extOrTrunc(n_bits); + val.setIsSigned(int_ty->isSignedIntegerType()); + m_ast_builder.clang().AddEnumerationValueToEnumerationType( - m_derived_ct, decl, name.str().c_str(), enumerator.Value); + m_derived_ct, decl, name.str().c_str(), val); return Error::success(); } diff --git a/lldb/test/API/lang/cpp/enum-limits/Makefile b/lldb/test/API/lang/cpp/enum-limits/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/lang/cpp/enum-limits/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/enum-limits/TestCPPEnumLimits.py b/lldb/test/API/lang/cpp/enum-limits/TestCPPEnumLimits.py new file mode 100644 index 0000000000000..4e0c0a088c909 --- /dev/null +++ b/lldb/test/API/lang/cpp/enum-limits/TestCPPEnumLimits.py @@ -0,0 +1,91 @@ +"""Check that enumerator values are correct when they're near the limits of the underlying type.""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbsuite.test.lldbutil as lldbutil + + +class CPPEnumLimitsTestCase(TestBase): + SHARED_BUILD_TESTCASE = False + TEST_WITH_PDB_DEBUG_INFO = True + + def check_signed(self, ty: lldb.SBType, expected): + self.assertEqual( + {i.GetName(): i.GetValueAsSigned() for i in ty.GetEnumMembers()}, expected + ) + + def check_unsigned(self, ty: lldb.SBType, expected): + self.assertEqual( + {i.GetName(): i.GetValueAsUnsigned() for i in ty.GetEnumMembers()}, expected + ) + + def check_all(self, target: lldb.SBTarget): + self.check_unsigned(target.FindFirstType("U8Enum"), {"Min": 0, "Max": 255}) + self.check_signed(target.FindFirstType("I8Enum"), {"Min": -128, "Max": 127}) + self.check_unsigned(target.FindFirstType("U16Enum"), {"Min": 0, "Max": 65535}) + self.check_signed( + target.FindFirstType("I16Enum"), {"Min": -32768, "Max": 32767} + ) + self.check_unsigned( + target.FindFirstType("U32Enum"), + {"Min": 0, "MaxMinusOne": 4294967294, "Max": 4294967295}, + ) + self.check_signed( + target.FindFirstType("I32Enum"), {"Min": -2147483648, "Max": 2147483647} + ) + self.check_unsigned( + target.FindFirstType("U64Enum"), + { + "Min": 0, + "MaxMinusOne": 18446744073709551614, + "Max": 18446744073709551615, + }, + ) + self.check_signed( + target.FindFirstType("I64Enum"), + { + "Min": -9223372036854775808, + "MinPlusOne": -9223372036854775807, + "MaxMinusOne": 9223372036854775806, + "Max": 9223372036854775807, + }, + ) + + def test(self): + self.build() + self.check_all(self.dbg.CreateTarget(self.getBuildArtifact("a.out"))) + + @skipUnlessPlatform(["windows"]) + @skipUnlessMSVC + @no_debug_info_test # We only test MSVC + def test_msvc(self): + """Test that the limits work on MSVC.""" + + src = os.path.join(self.getSourceDir(), "main.cpp") + exe = os.path.join(self.getBuildDir(), "a.exe") + + # FIXME: Allow MSVC to be used with the Makefile. + result = subprocess.run( + [ + "cl.exe", + "/nologo", + "/Od", + "/Zi", + "/Fe" + exe, + src, + "/link", + "/nodefaultlib", + "/entry:main", + ], + cwd=self.getBuildDir(), + capture_output=True, + text=True, + ) + self.assertEqual( + result.returncode, + 0, + "Compilation failed:\n" + result.stdout + result.stderr, + ) + + self.check_all(self.dbg.CreateTarget(exe)) diff --git a/lldb/test/API/lang/cpp/enum-limits/main.cpp b/lldb/test/API/lang/cpp/enum-limits/main.cpp new file mode 100644 index 0000000000000..3aeef3fd03e01 --- /dev/null +++ b/lldb/test/API/lang/cpp/enum-limits/main.cpp @@ -0,0 +1,48 @@ +enum class U8Enum : unsigned char { + Min = 0, + Max = 255, +}; +enum class I8Enum : char { + Min = -128, + Max = 127, +}; +enum class U16Enum : unsigned short { + Min = 0, + Max = 65535, +}; +enum class I16Enum : short { + Min = -32768, + Max = 32767, +}; +enum class U32Enum : unsigned { + Min = 0, + MaxMinusOne = 4294967294, + Max = 4294967295, +}; +enum class I32Enum : int { + Min = -2147483648, + Max = 2147483647, +}; +enum class U64Enum : unsigned long long { + Min = 0, + MaxMinusOne = 18446744073709551614ULL, + Max = 18446744073709551615ULL, +}; +enum class I64Enum : long long { + Min = -9223372036854775807LL - 1, + MinPlusOne = -9223372036854775807LL, + MaxMinusOne = 9223372036854775806LL, + Max = 9223372036854775807LL, +}; + +int main(){ + auto u8 = U8Enum::Max; + auto i8 = I8Enum::Max; + auto u16 = U16Enum::Max; + auto i16 = I16Enum::Max; + auto u32 = U32Enum::Max; + auto i32 = I32Enum::Max; + auto u64 = U64Enum::Max; + auto i64 = I64Enum::Max; + return 0; +} >From 5ed10b2826735de4c8e8e3d4aa297c4d5920441d Mon Sep 17 00:00:00 2001 From: Nerixyz <[email protected]> Date: Fri, 17 Jul 2026 15:52:12 +0200 Subject: [PATCH 2/3] fix: formatting --- lldb/test/API/lang/cpp/enum-limits/main.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lldb/test/API/lang/cpp/enum-limits/main.cpp b/lldb/test/API/lang/cpp/enum-limits/main.cpp index 3aeef3fd03e01..b8855b5920e21 100644 --- a/lldb/test/API/lang/cpp/enum-limits/main.cpp +++ b/lldb/test/API/lang/cpp/enum-limits/main.cpp @@ -35,14 +35,14 @@ enum class I64Enum : long long { Max = 9223372036854775807LL, }; -int main(){ - auto u8 = U8Enum::Max; - auto i8 = I8Enum::Max; - auto u16 = U16Enum::Max; - auto i16 = I16Enum::Max; - auto u32 = U32Enum::Max; - auto i32 = I32Enum::Max; - auto u64 = U64Enum::Max; - auto i64 = I64Enum::Max; - return 0; +int main() { + auto u8 = U8Enum::Max; + auto i8 = I8Enum::Max; + auto u16 = U16Enum::Max; + auto i16 = I16Enum::Max; + auto u32 = U32Enum::Max; + auto i32 = I32Enum::Max; + auto u64 = U64Enum::Max; + auto i64 = I64Enum::Max; + return 0; } >From 9f1fcf5d28a4765f9c3037ecbba4b024ee8f09f8 Mon Sep 17 00:00:00 2001 From: Nerixyz <[email protected]> Date: Fri, 17 Jul 2026 16:06:31 +0200 Subject: [PATCH 3/3] fix: use signed char --- lldb/test/API/lang/cpp/enum-limits/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/lang/cpp/enum-limits/main.cpp b/lldb/test/API/lang/cpp/enum-limits/main.cpp index b8855b5920e21..ea7036f7f7c0e 100644 --- a/lldb/test/API/lang/cpp/enum-limits/main.cpp +++ b/lldb/test/API/lang/cpp/enum-limits/main.cpp @@ -2,7 +2,7 @@ enum class U8Enum : unsigned char { Min = 0, Max = 255, }; -enum class I8Enum : char { +enum class I8Enum : signed char { Min = -128, Max = 127, }; _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
