rnk updated this revision to Diff 361306. rnk added a comment. - add comments
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D106585/new/ https://reviews.llvm.org/D106585 Files: clang/lib/CodeGen/CGDebugInfo.cpp clang/test/CodeGenCXX/debug-info-enum-i128.cpp llvm/include/llvm/IR/DIBuilder.h llvm/lib/IR/DIBuilder.cpp Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -250,6 +250,11 @@ Name); } +DIEnumerator *DIBuilder::createEnumerator(StringRef Name, APSInt Value) { + assert(!Name.empty() && "Unable to create enumerator without name"); + return DIEnumerator::get(VMContext, APInt(Value), Value.isUnsigned(), Name); +} + DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) { assert(!Name.empty() && "Unable to create type without name"); return DIBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name); Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -181,7 +181,9 @@ DIFile *File); /// Create a single enumerator value. - DIEnumerator *createEnumerator(StringRef Name, int64_t Val, bool IsUnsigned = false); + DIEnumerator *createEnumerator(StringRef Name, APSInt Value); + DIEnumerator *createEnumerator(StringRef Name, int64_t Val, + bool IsUnsigned = false); /// Create a DWARF unspecified type. DIBasicType *createUnspecifiedType(StringRef Name); Index: clang/test/CodeGenCXX/debug-info-enum-i128.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/debug-info-enum-i128.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -debug-info-kind=limited -emit-llvm -o - | FileCheck %s + +enum class uns : __uint128_t { unsval = __uint128_t(1) << 64 }; +uns t1() { return uns::unsval; } + +enum class sig : __int128 { sigval = -(__int128(1) << 64) }; +sig t2() { return sig::sigval; } + + +// CHECK-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "uns", {{.*}}) +// CHECK: !DIEnumerator(name: "unsval", value: 18446744073709551616, isUnsigned: true) + +// CHECK-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "sig", {{.*}}) +// CHECK: !DIEnumerator(name: "sigval", value: -18446744073709551616) Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -3108,15 +3108,17 @@ SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU); - // Create elements for each enumerator. + // Create elements for each enumerator. Use the signed-ness of the enum type, + // not the signedness of the enumerator. This matches the DWARF produced by + // GCC for C enums with positive enumerators. SmallVector<llvm::Metadata *, 16> Enumerators; ED = ED->getDefinition(); bool IsSigned = ED->getIntegerType()->isSignedIntegerType(); for (const auto *Enum : ED->enumerators()) { - const auto &InitVal = Enum->getInitVal(); - auto Value = IsSigned ? InitVal.getSExtValue() : InitVal.getZExtValue(); + llvm::APSInt Value = Enum->getInitVal(); + Value.setIsSigned(IsSigned); Enumerators.push_back( - DBuilder.createEnumerator(Enum->getName(), Value, !IsSigned)); + DBuilder.createEnumerator(Enum->getName(), std::move(Value))); } // Return a CompositeType for the enum itself.
Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -250,6 +250,11 @@ Name); } +DIEnumerator *DIBuilder::createEnumerator(StringRef Name, APSInt Value) { + assert(!Name.empty() && "Unable to create enumerator without name"); + return DIEnumerator::get(VMContext, APInt(Value), Value.isUnsigned(), Name); +} + DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) { assert(!Name.empty() && "Unable to create type without name"); return DIBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name); Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -181,7 +181,9 @@ DIFile *File); /// Create a single enumerator value. - DIEnumerator *createEnumerator(StringRef Name, int64_t Val, bool IsUnsigned = false); + DIEnumerator *createEnumerator(StringRef Name, APSInt Value); + DIEnumerator *createEnumerator(StringRef Name, int64_t Val, + bool IsUnsigned = false); /// Create a DWARF unspecified type. DIBasicType *createUnspecifiedType(StringRef Name); Index: clang/test/CodeGenCXX/debug-info-enum-i128.cpp =================================================================== --- /dev/null +++ clang/test/CodeGenCXX/debug-info-enum-i128.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 %s -triple x86_64-windows-msvc -gcodeview -debug-info-kind=limited -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-linux-gnu -debug-info-kind=limited -emit-llvm -o - | FileCheck %s + +enum class uns : __uint128_t { unsval = __uint128_t(1) << 64 }; +uns t1() { return uns::unsval; } + +enum class sig : __int128 { sigval = -(__int128(1) << 64) }; +sig t2() { return sig::sigval; } + + +// CHECK-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "uns", {{.*}}) +// CHECK: !DIEnumerator(name: "unsval", value: 18446744073709551616, isUnsigned: true) + +// CHECK-LABEL: !DICompositeType(tag: DW_TAG_enumeration_type, name: "sig", {{.*}}) +// CHECK: !DIEnumerator(name: "sigval", value: -18446744073709551616) Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -3108,15 +3108,17 @@ SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU); - // Create elements for each enumerator. + // Create elements for each enumerator. Use the signed-ness of the enum type, + // not the signedness of the enumerator. This matches the DWARF produced by + // GCC for C enums with positive enumerators. SmallVector<llvm::Metadata *, 16> Enumerators; ED = ED->getDefinition(); bool IsSigned = ED->getIntegerType()->isSignedIntegerType(); for (const auto *Enum : ED->enumerators()) { - const auto &InitVal = Enum->getInitVal(); - auto Value = IsSigned ? InitVal.getSExtValue() : InitVal.getZExtValue(); + llvm::APSInt Value = Enum->getInitVal(); + Value.setIsSigned(IsSigned); Enumerators.push_back( - DBuilder.createEnumerator(Enum->getName(), Value, !IsSigned)); + DBuilder.createEnumerator(Enum->getName(), std::move(Value))); } // Return a CompositeType for the enum itself.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits