Make our DIFlags
match LLVMDIFlags
in the LLVM-C API
This commit is contained in:
parent
a42d5ecf34
commit
32f1c1d85e
2 changed files with 81 additions and 113 deletions
|
@ -741,8 +741,11 @@ pub mod debuginfo {
|
||||||
pub type DIEnumerator = DIDescriptor;
|
pub type DIEnumerator = DIDescriptor;
|
||||||
pub type DITemplateTypeParameter = DIDescriptor;
|
pub type DITemplateTypeParameter = DIDescriptor;
|
||||||
|
|
||||||
// These values **must** match with LLVMRustDIFlags!!
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
/// Must match the layout of `LLVMDIFlags` in the LLVM-C API.
|
||||||
|
///
|
||||||
|
/// Each value declared here must also be covered by the static
|
||||||
|
/// assertions in `RustWrapper.cpp` used by `fromRust(LLVMDIFlags)`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(Clone, Copy, Default)]
|
#[derive(Clone, Copy, Default)]
|
||||||
pub struct DIFlags: u32 {
|
pub struct DIFlags: u32 {
|
||||||
|
@ -752,7 +755,7 @@ pub mod debuginfo {
|
||||||
const FlagPublic = 3;
|
const FlagPublic = 3;
|
||||||
const FlagFwdDecl = (1 << 2);
|
const FlagFwdDecl = (1 << 2);
|
||||||
const FlagAppleBlock = (1 << 3);
|
const FlagAppleBlock = (1 << 3);
|
||||||
const FlagBlockByrefStruct = (1 << 4);
|
const FlagReservedBit4 = (1 << 4);
|
||||||
const FlagVirtual = (1 << 5);
|
const FlagVirtual = (1 << 5);
|
||||||
const FlagArtificial = (1 << 6);
|
const FlagArtificial = (1 << 6);
|
||||||
const FlagExplicit = (1 << 7);
|
const FlagExplicit = (1 << 7);
|
||||||
|
@ -763,10 +766,21 @@ pub mod debuginfo {
|
||||||
const FlagStaticMember = (1 << 12);
|
const FlagStaticMember = (1 << 12);
|
||||||
const FlagLValueReference = (1 << 13);
|
const FlagLValueReference = (1 << 13);
|
||||||
const FlagRValueReference = (1 << 14);
|
const FlagRValueReference = (1 << 14);
|
||||||
const FlagExternalTypeRef = (1 << 15);
|
const FlagReserved = (1 << 15);
|
||||||
|
const FlagSingleInheritance = (1 << 16);
|
||||||
|
const FlagMultipleInheritance = (2 << 16);
|
||||||
|
const FlagVirtualInheritance = (3 << 16);
|
||||||
const FlagIntroducedVirtual = (1 << 18);
|
const FlagIntroducedVirtual = (1 << 18);
|
||||||
const FlagBitField = (1 << 19);
|
const FlagBitField = (1 << 19);
|
||||||
const FlagNoReturn = (1 << 20);
|
const FlagNoReturn = (1 << 20);
|
||||||
|
// The bit at (1 << 21) is unused, but was `LLVMDIFlagMainSubprogram`.
|
||||||
|
const FlagTypePassByValue = (1 << 22);
|
||||||
|
const FlagTypePassByReference = (1 << 23);
|
||||||
|
const FlagEnumClass = (1 << 24);
|
||||||
|
const FlagThunk = (1 << 25);
|
||||||
|
const FlagNonTrivial = (1 << 26);
|
||||||
|
const FlagBigEndian = (1 << 27);
|
||||||
|
const FlagLittleEndian = (1 << 28);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "llvm-c/Analysis.h"
|
#include "llvm-c/Analysis.h"
|
||||||
#include "llvm-c/Core.h"
|
#include "llvm-c/Core.h"
|
||||||
|
#include "llvm-c/DebugInfo.h"
|
||||||
#include "llvm/ADT/ArrayRef.h"
|
#include "llvm/ADT/ArrayRef.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
@ -676,120 +677,73 @@ template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
|
||||||
#define DIArray DINodeArray
|
#define DIArray DINodeArray
|
||||||
#define unwrapDI unwrapDIPtr
|
#define unwrapDI unwrapDIPtr
|
||||||
|
|
||||||
// These values **must** match debuginfo::DIFlags! They also *happen*
|
// FIXME(Zalathar): This is a temporary typedef to avoid churning dozens of
|
||||||
// to match LLVM, but that isn't required as we do giant sets of
|
// bindings that are going to be deleted and replaced with their LLVM-C
|
||||||
// matching below. The value shouldn't be directly passed to LLVM.
|
// equivalents, as part of #134009. After that happens, the remaining bindings
|
||||||
enum class LLVMRustDIFlags : uint32_t {
|
// can be adjusted to use `LLVMDIFlags` instead of relying on this typedef.
|
||||||
FlagZero = 0,
|
typedef LLVMDIFlags LLVMRustDIFlags;
|
||||||
FlagPrivate = 1,
|
|
||||||
FlagProtected = 2,
|
|
||||||
FlagPublic = 3,
|
|
||||||
FlagFwdDecl = (1 << 2),
|
|
||||||
FlagAppleBlock = (1 << 3),
|
|
||||||
FlagBlockByrefStruct = (1 << 4),
|
|
||||||
FlagVirtual = (1 << 5),
|
|
||||||
FlagArtificial = (1 << 6),
|
|
||||||
FlagExplicit = (1 << 7),
|
|
||||||
FlagPrototyped = (1 << 8),
|
|
||||||
FlagObjcClassComplete = (1 << 9),
|
|
||||||
FlagObjectPointer = (1 << 10),
|
|
||||||
FlagVector = (1 << 11),
|
|
||||||
FlagStaticMember = (1 << 12),
|
|
||||||
FlagLValueReference = (1 << 13),
|
|
||||||
FlagRValueReference = (1 << 14),
|
|
||||||
FlagExternalTypeRef = (1 << 15),
|
|
||||||
FlagIntroducedVirtual = (1 << 18),
|
|
||||||
FlagBitField = (1 << 19),
|
|
||||||
FlagNoReturn = (1 << 20),
|
|
||||||
// Do not add values that are not supported by the minimum LLVM
|
|
||||||
// version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
|
|
||||||
};
|
|
||||||
|
|
||||||
inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
|
// Statically assert that `LLVMDIFlags` (C) and `DIFlags` (C++) have the same
|
||||||
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
|
// layout, at least for the flags we know about. This isn't guaranteed, but is
|
||||||
static_cast<uint32_t>(B));
|
// likely to remain true, and as long as it is true it makes conversions easy.
|
||||||
}
|
#define ASSERT_DIFLAG_VALUE(FLAG, VALUE) \
|
||||||
|
static_assert((LLVMDI##FLAG == (VALUE)) && (DINode::DIFlags::FLAG == (VALUE)))
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagZero, 0);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagPrivate, 1);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagProtected, 2);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagPublic, 3);
|
||||||
|
// Bit (1 << 1) is part of the private/protected/public values above.
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagFwdDecl, 1 << 2);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagAppleBlock, 1 << 3);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagReservedBit4, 1 << 4);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagVirtual, 1 << 5);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagArtificial, 1 << 6);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagExplicit, 1 << 7);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagPrototyped, 1 << 8);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagObjcClassComplete, 1 << 9);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagObjectPointer, 1 << 10);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagVector, 1 << 11);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagStaticMember, 1 << 12);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagLValueReference, 1 << 13);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagRValueReference, 1 << 14);
|
||||||
|
// Bit (1 << 15) has been recycled, but the C API value hasn't been renamed.
|
||||||
|
static_assert((LLVMDIFlagReserved == (1 << 15)) &&
|
||||||
|
(DINode::DIFlags::FlagExportSymbols == (1 << 15)));
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagSingleInheritance, 1 << 16);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagMultipleInheritance, 2 << 16);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagVirtualInheritance, 3 << 16);
|
||||||
|
// Bit (1 << 17) is part of the inheritance values above.
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagIntroducedVirtual, 1 << 18);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagBitField, 1 << 19);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagNoReturn, 1 << 20);
|
||||||
|
// Bit (1 << 21) is unused, but was `LLVMDIFlagMainSubprogram`.
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagTypePassByValue, 1 << 22);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagTypePassByReference, 1 << 23);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagEnumClass, 1 << 24);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagThunk, 1 << 25);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagNonTrivial, 1 << 26);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagBigEndian, 1 << 27);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagLittleEndian, 1 << 28);
|
||||||
|
ASSERT_DIFLAG_VALUE(FlagIndirectVirtualBase, (1 << 2) | (1 << 5));
|
||||||
|
#undef ASSERT_DIFLAG_VALUE
|
||||||
|
|
||||||
inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
|
// There are two potential ways to convert `LLVMDIFlags` to `DIFlags`:
|
||||||
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
|
// - Check and copy every individual bit/subvalue from input to output.
|
||||||
static_cast<uint32_t>(B));
|
// - Statically assert that both have the same layout, and cast.
|
||||||
}
|
// As long as the static assertions succeed, a cast is easier and faster.
|
||||||
|
// In the (hopefully) unlikely event that the assertions do fail someday, and
|
||||||
inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
|
// LLVM doesn't expose its own conversion function, we'll have to switch over
|
||||||
return A = A | B;
|
// to copying each bit/subvalue.
|
||||||
}
|
static DINode::DIFlags fromRust(LLVMDIFlags Flags) {
|
||||||
|
// Check that all set bits are covered by the static assertions above.
|
||||||
inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
|
const unsigned UNKNOWN_BITS = (1 << 31) | (1 << 30) | (1 << 29) | (1 << 21);
|
||||||
|
if (Flags & UNKNOWN_BITS) {
|
||||||
inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
|
report_fatal_error("bad LLVMDIFlags");
|
||||||
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
|
|
||||||
DINode::DIFlags Result = DINode::DIFlags::FlagZero;
|
|
||||||
|
|
||||||
switch (visibility(Flags)) {
|
|
||||||
case LLVMRustDIFlags::FlagPrivate:
|
|
||||||
Result |= DINode::DIFlags::FlagPrivate;
|
|
||||||
break;
|
|
||||||
case LLVMRustDIFlags::FlagProtected:
|
|
||||||
Result |= DINode::DIFlags::FlagProtected;
|
|
||||||
break;
|
|
||||||
case LLVMRustDIFlags::FlagPublic:
|
|
||||||
Result |= DINode::DIFlags::FlagPublic;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// The rest are handled below
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
|
// As long as the static assertions are satisfied and no unknown bits are
|
||||||
Result |= DINode::DIFlags::FlagFwdDecl;
|
// present, we can convert from `LLVMDIFlags` to `DIFlags` with a cast.
|
||||||
}
|
return static_cast<DINode::DIFlags>(Flags);
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
|
|
||||||
Result |= DINode::DIFlags::FlagAppleBlock;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
|
|
||||||
Result |= DINode::DIFlags::FlagVirtual;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
|
|
||||||
Result |= DINode::DIFlags::FlagArtificial;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
|
|
||||||
Result |= DINode::DIFlags::FlagExplicit;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
|
|
||||||
Result |= DINode::DIFlags::FlagPrototyped;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
|
|
||||||
Result |= DINode::DIFlags::FlagObjcClassComplete;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
|
|
||||||
Result |= DINode::DIFlags::FlagObjectPointer;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
|
|
||||||
Result |= DINode::DIFlags::FlagVector;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
|
|
||||||
Result |= DINode::DIFlags::FlagStaticMember;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
|
|
||||||
Result |= DINode::DIFlags::FlagLValueReference;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
|
|
||||||
Result |= DINode::DIFlags::FlagRValueReference;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
|
|
||||||
Result |= DINode::DIFlags::FlagIntroducedVirtual;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
|
|
||||||
Result |= DINode::DIFlags::FlagBitField;
|
|
||||||
}
|
|
||||||
if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
|
|
||||||
Result |= DINode::DIFlags::FlagNoReturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These values **must** match debuginfo::DISPFlags! They also *happen*
|
// These values **must** match debuginfo::DISPFlags! They also *happen*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue