[llvm] 3230493 - Fix clang debug info irgen of i128 enums
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 26 12:25:36 PDT 2021
Author: Reid Kleckner
Date: 2021-07-26T12:25:29-07:00
New Revision: 323049329939becf690adbeeff9f5f7e219075ec
URL: https://github.com/llvm/llvm-project/commit/323049329939becf690adbeeff9f5f7e219075ec
DIFF: https://github.com/llvm/llvm-project/commit/323049329939becf690adbeeff9f5f7e219075ec.diff
LOG: Fix clang debug info irgen of i128 enums
DIEnumerator stores an APInt as of April 2020, so now we don't need to
truncate the enumerator value to 64 bits. Fixes assertions during IRGen.
Split from D105320, thanks to Matheus Izvekov for the test case and
report.
Differential Revision: https://reviews.llvm.org/D106585
Added:
clang/test/CodeGenCXX/debug-info-enum-i128.cpp
Modified:
clang/lib/CodeGen/CGDebugInfo.cpp
llvm/include/llvm/IR/DIBuilder.h
llvm/lib/IR/DIBuilder.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 432e2400a4406..f96c5ef43ff02 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -3084,15 +3084,17 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
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.
diff --git a/clang/test/CodeGenCXX/debug-info-enum-i128.cpp b/clang/test/CodeGenCXX/debug-info-enum-i128.cpp
new file mode 100644
index 0000000000000..081f21875a04e
--- /dev/null
+++ b/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)
diff --git a/llvm/include/llvm/IR/DIBuilder.h b/llvm/include/llvm/IR/DIBuilder.h
index fc035de79bc0e..7c7a0ebe5d303 100644
--- a/llvm/include/llvm/IR/DIBuilder.h
+++ b/llvm/include/llvm/IR/DIBuilder.h
@@ -181,7 +181,9 @@ namespace llvm {
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);
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 1256749b74972..4eddf4737b70a 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -250,6 +250,11 @@ DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val,
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);
More information about the llvm-commits
mailing list