Author: Ilia Kuklin Date: 2025-02-13T22:08:31+05:00 New Revision: f30c891464debb4e0d47d27ea77dc2220d7cdf29
URL: https://github.com/llvm/llvm-project/commit/f30c891464debb4e0d47d27ea77dc2220d7cdf29 DIFF: https://github.com/llvm/llvm-project/commit/f30c891464debb4e0d47d27ea77dc2220d7cdf29.diff LOG: [lldb] Analyze enum promotion type during parsing (#115005) The information about an enum's best promotion type is discarded after compilation and is not present in debug info. This patch repeats the same analysis of each enum value as in the front-end to determine the best promotion type during DWARF info parsing. Fixes #86989 Added: lldb/test/API/lang/cpp/enum_promotion/Makefile lldb/test/API/lang/cpp/enum_promotion/TestCPPEnumPromotion.py lldb/test/API/lang/cpp/enum_promotion/main.cpp Modified: lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp index 4901b6029d9ce..bcb63f719de10 100644 --- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8474,29 +8474,22 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition( if (enum_decl->isCompleteDefinition()) return true; - clang::ASTContext &ast = lldb_ast->getASTContext(); - - /// TODO This really needs to be fixed. - QualType integer_type(enum_decl->getIntegerType()); if (!integer_type.isNull()) { - unsigned NumPositiveBits = 1; + clang::ASTContext &ast = lldb_ast->getASTContext(); + unsigned NumNegativeBits = 0; + unsigned NumPositiveBits = 0; + ast.computeEnumBits(enum_decl->enumerators(), NumNegativeBits, + NumPositiveBits); - clang::QualType promotion_qual_type; - // If the enum integer type is less than an integer in bit width, - // then we must promote it to an integer size. - if (ast.getTypeSize(enum_decl->getIntegerType()) < - ast.getTypeSize(ast.IntTy)) { - if (enum_decl->getIntegerType()->isSignedIntegerType()) - promotion_qual_type = ast.IntTy; - else - promotion_qual_type = ast.UnsignedIntTy; - } else - promotion_qual_type = enum_decl->getIntegerType(); + clang::QualType BestPromotionType; + clang::QualType BestType; + ast.computeBestEnumTypes(/*IsPacked=*/false, NumNegativeBits, + NumPositiveBits, BestType, BestPromotionType); enum_decl->completeDefinition(enum_decl->getIntegerType(), - promotion_qual_type, NumPositiveBits, + BestPromotionType, NumPositiveBits, NumNegativeBits); } return true; diff --git a/lldb/test/API/lang/cpp/enum_promotion/Makefile b/lldb/test/API/lang/cpp/enum_promotion/Makefile new file mode 100644 index 0000000000000..99998b20bcb05 --- /dev/null +++ b/lldb/test/API/lang/cpp/enum_promotion/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/lang/cpp/enum_promotion/TestCPPEnumPromotion.py b/lldb/test/API/lang/cpp/enum_promotion/TestCPPEnumPromotion.py new file mode 100644 index 0000000000000..2a73dc5357fe7 --- /dev/null +++ b/lldb/test/API/lang/cpp/enum_promotion/TestCPPEnumPromotion.py @@ -0,0 +1,36 @@ +""" +Test LLDB type promotion of unscoped enums. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class TestCPPEnumPromotion(TestBase): + def test(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, "// break here", lldb.SBFileSpec("main.cpp") + ) + UChar_promoted = self.frame().FindVariable("UChar_promoted") + UShort_promoted = self.frame().FindVariable("UShort_promoted") + UInt_promoted = self.frame().FindVariable("UInt_promoted") + SLong_promoted = self.frame().FindVariable("SLong_promoted") + ULong_promoted = self.frame().FindVariable("ULong_promoted") + NChar_promoted = self.frame().FindVariable("NChar_promoted") + NShort_promoted = self.frame().FindVariable("NShort_promoted") + NInt_promoted = self.frame().FindVariable("NInt_promoted") + NLong_promoted = self.frame().FindVariable("NLong_promoted") + + # Check that LLDB's promoted type is the same as the compiler's + self.expect_expr("+EnumUChar::UChar", result_type=UChar_promoted.type.name) + self.expect_expr("+EnumUShort::UShort", result_type=UShort_promoted.type.name) + self.expect_expr("+EnumUInt::UInt", result_type=UInt_promoted.type.name) + self.expect_expr("+EnumSLong::SLong", result_type=SLong_promoted.type.name) + self.expect_expr("+EnumULong::ULong", result_type=ULong_promoted.type.name) + self.expect_expr("+EnumNChar::NChar", result_type=NChar_promoted.type.name) + self.expect_expr("+EnumNShort::NShort", result_type=NShort_promoted.type.name) + self.expect_expr("+EnumNInt::NInt", result_type=NInt_promoted.type.name) + self.expect_expr("+EnumNLong::NLong", result_type=NLong_promoted.type.name) diff --git a/lldb/test/API/lang/cpp/enum_promotion/main.cpp b/lldb/test/API/lang/cpp/enum_promotion/main.cpp new file mode 100644 index 0000000000000..bcdb0adff5d40 --- /dev/null +++ b/lldb/test/API/lang/cpp/enum_promotion/main.cpp @@ -0,0 +1,22 @@ +enum EnumUChar { UChar = 1 }; +enum EnumUShort { UShort = 0x101 }; +enum EnumUInt { UInt = 0x10001 }; +enum EnumSLong { SLong = 0x100000001 }; +enum EnumULong { ULong = 0xFFFFFFFFFFFFFFF0 }; +enum EnumNChar { NChar = -1 }; +enum EnumNShort { NShort = -0x101 }; +enum EnumNInt { NInt = -0x10001 }; +enum EnumNLong { NLong = -0x100000001 }; + +int main() { + auto UChar_promoted = +EnumUChar::UChar; + auto UShort_promoted = +EnumUShort::UShort; + auto UInt_promoted = +EnumUInt::UInt; + auto SLong_promoted = +EnumSLong::SLong; + auto ULong_promoted = +EnumULong::ULong; + auto NChar_promoted = +EnumNChar::NChar; + auto NShort_promoted = +EnumNShort::NShort; + auto NInt_promoted = +EnumNInt::NInt; + auto NLong_promoted = +EnumNLong::NLong; + return 0; // break here +} _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits