Skip to content

Commit ff1c33d

Browse files
committed
Make our DIFlags match LLVMDIFlags in the LLVM-C API
1 parent 6c8347b commit ff1c33d

File tree

2 files changed

+67
-107
lines changed

2 files changed

+67
-107
lines changed

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -740,8 +740,8 @@ pub mod debuginfo {
740740
pub type DIEnumerator = DIDescriptor;
741741
pub type DITemplateTypeParameter = DIDescriptor;
742742

743-
// These values **must** match with LLVMRustDIFlags!!
744743
bitflags! {
744+
/// Must match the layout of `LLVMDIFlags` in the LLVM-C API.
745745
#[repr(transparent)]
746746
#[derive(Clone, Copy, Default)]
747747
pub struct DIFlags: u32 {
@@ -751,7 +751,7 @@ pub mod debuginfo {
751751
const FlagPublic = 3;
752752
const FlagFwdDecl = (1 << 2);
753753
const FlagAppleBlock = (1 << 3);
754-
const FlagBlockByrefStruct = (1 << 4);
754+
const FlagReservedBit4 = (1 << 4);
755755
const FlagVirtual = (1 << 5);
756756
const FlagArtificial = (1 << 6);
757757
const FlagExplicit = (1 << 7);
@@ -762,10 +762,20 @@ pub mod debuginfo {
762762
const FlagStaticMember = (1 << 12);
763763
const FlagLValueReference = (1 << 13);
764764
const FlagRValueReference = (1 << 14);
765-
const FlagExternalTypeRef = (1 << 15);
765+
const FlagReserved = (1 << 15);
766+
const FlagSingleInheritance = (1 << 16);
767+
const FlagMultipleInheritance = (2 << 16);
768+
const FlagVirtualInheritance = (3 << 16);
766769
const FlagIntroducedVirtual = (1 << 18);
767770
const FlagBitField = (1 << 19);
768771
const FlagNoReturn = (1 << 20);
772+
const FlagTypePassByValue = (1 << 22);
773+
const FlagTypePassByReference = (1 << 23);
774+
const FlagEnumClass = (1 << 24);
775+
const FlagThunk = (1 << 25);
776+
const FlagNonTrivial = (1 << 26);
777+
const FlagBigEndian = (1 << 27);
778+
const FlagLittleEndian = (1 << 28);
769779
}
770780
}
771781

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 54 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "llvm-c/Analysis.h"
44
#include "llvm-c/Core.h"
5+
#include "llvm-c/DebugInfo.h"
56
#include "llvm/ADT/ArrayRef.h"
67
#include "llvm/ADT/SmallVector.h"
78
#include "llvm/ADT/Statistic.h"
@@ -672,117 +673,66 @@ template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
672673
#define DIArray DINodeArray
673674
#define unwrapDI unwrapDIPtr
674675

675-
// These values **must** match debuginfo::DIFlags! They also *happen*
676-
// to match LLVM, but that isn't required as we do giant sets of
677-
// matching below. The value shouldn't be directly passed to LLVM.
678-
enum class LLVMRustDIFlags : uint32_t {
679-
FlagZero = 0,
680-
FlagPrivate = 1,
681-
FlagProtected = 2,
682-
FlagPublic = 3,
683-
FlagFwdDecl = (1 << 2),
684-
FlagAppleBlock = (1 << 3),
685-
FlagBlockByrefStruct = (1 << 4),
686-
FlagVirtual = (1 << 5),
687-
FlagArtificial = (1 << 6),
688-
FlagExplicit = (1 << 7),
689-
FlagPrototyped = (1 << 8),
690-
FlagObjcClassComplete = (1 << 9),
691-
FlagObjectPointer = (1 << 10),
692-
FlagVector = (1 << 11),
693-
FlagStaticMember = (1 << 12),
694-
FlagLValueReference = (1 << 13),
695-
FlagRValueReference = (1 << 14),
696-
FlagExternalTypeRef = (1 << 15),
697-
FlagIntroducedVirtual = (1 << 18),
698-
FlagBitField = (1 << 19),
699-
FlagNoReturn = (1 << 20),
700-
// Do not add values that are not supported by the minimum LLVM
701-
// version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
702-
};
703-
704-
inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
705-
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
706-
static_cast<uint32_t>(B));
707-
}
708-
709-
inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
710-
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
711-
static_cast<uint32_t>(B));
712-
}
713-
714-
inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
715-
return A = A | B;
716-
}
717-
718-
inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
719-
720-
inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
721-
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
722-
}
723-
724-
static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
725-
DINode::DIFlags Result = DINode::DIFlags::FlagZero;
726-
727-
switch (visibility(Flags)) {
728-
case LLVMRustDIFlags::FlagPrivate:
729-
Result |= DINode::DIFlags::FlagPrivate;
676+
// Temporary typedef to avoid churning functions that are about to be deleted.
677+
typedef LLVMDIFlags LLVMRustDIFlags;
678+
679+
static DINode::DIFlags fromRust(LLVMDIFlags Flags) {
680+
using DIFlags = DINode::DIFlags;
681+
682+
// Internally, LLVM does this conversion with a simple integer cast, but we
683+
// can't rely on that always being the case so we write this the long way.
684+
auto Result = DIFlags::FlagZero;
685+
686+
// clang-format off
687+
if (Flags & LLVMDIFlagFwdDecl) Result |= DIFlags::FlagFwdDecl;
688+
if (Flags & LLVMDIFlagAppleBlock) Result |= DIFlags::FlagAppleBlock;
689+
if (Flags & LLVMDIFlagReservedBit4) Result |= DIFlags::FlagReservedBit4;
690+
if (Flags & LLVMDIFlagVirtual) Result |= DIFlags::FlagVirtual;
691+
if (Flags & LLVMDIFlagArtificial) Result |= DIFlags::FlagArtificial;
692+
if (Flags & LLVMDIFlagExplicit) Result |= DIFlags::FlagExplicit;
693+
if (Flags & LLVMDIFlagPrototyped) Result |= DIFlags::FlagPrototyped;
694+
if (Flags & LLVMDIFlagObjcClassComplete) Result |= DIFlags::FlagObjcClassComplete;
695+
if (Flags & LLVMDIFlagObjectPointer) Result |= DIFlags::FlagObjectPointer;
696+
if (Flags & LLVMDIFlagVector) Result |= DIFlags::FlagVector;
697+
if (Flags & LLVMDIFlagStaticMember) Result |= DIFlags::FlagStaticMember;
698+
if (Flags & LLVMDIFlagLValueReference) Result |= DIFlags::FlagLValueReference;
699+
if (Flags & LLVMDIFlagRValueReference) Result |= DIFlags::FlagRValueReference;
700+
// This flag has been recycled, but the value in the C API hasn't been renamed yet.
701+
if (Flags & LLVMDIFlagReserved) Result |= DIFlags::FlagExportSymbols;
702+
if (Flags & LLVMDIFlagSingleInheritance) Result |= DIFlags::FlagSingleInheritance;
703+
if (Flags & LLVMDIFlagMultipleInheritance) Result |= DIFlags::FlagMultipleInheritance;
704+
if (Flags & LLVMDIFlagVirtualInheritance) Result |= DIFlags::FlagVirtualInheritance;
705+
if (Flags & LLVMDIFlagIntroducedVirtual) Result |= DIFlags::FlagIntroducedVirtual;
706+
if (Flags & LLVMDIFlagBitField) Result |= DIFlags::FlagBitField;
707+
if (Flags & LLVMDIFlagNoReturn) Result |= DIFlags::FlagNoReturn;
708+
if (Flags & LLVMDIFlagTypePassByValue) Result |= DIFlags::FlagTypePassByValue;
709+
if (Flags & LLVMDIFlagTypePassByReference) Result |= DIFlags::FlagTypePassByReference;
710+
if (Flags & LLVMDIFlagEnumClass) Result |= DIFlags::FlagEnumClass;
711+
if (Flags & LLVMDIFlagThunk) Result |= DIFlags::FlagThunk;
712+
if (Flags & LLVMDIFlagNonTrivial) Result |= DIFlags::FlagNonTrivial;
713+
if (Flags & LLVMDIFlagBigEndian) Result |= DIFlags::FlagLittleEndian;
714+
if (Flags & LLVMDIFlagLittleEndian) Result |= DIFlags::FlagLittleEndian;
715+
// clang-format on
716+
717+
// The private/protected/public values overlap, so processing them separately
718+
// (after other flags) seems to be easier for compilers to optimize.
719+
switch (Flags & LLVMDIFlagAccessibility) {
720+
case LLVMDIFlagPrivate:
721+
Result |= DIFlags::FlagPrivate;
730722
break;
731-
case LLVMRustDIFlags::FlagProtected:
732-
Result |= DINode::DIFlags::FlagProtected;
723+
case LLVMDIFlagProtected:
724+
Result |= DIFlags::FlagProtected;
733725
break;
734-
case LLVMRustDIFlags::FlagPublic:
735-
Result |= DINode::DIFlags::FlagPublic;
726+
case LLVMDIFlagPublic:
727+
Result |= DIFlags::FlagPublic;
736728
break;
737729
default:
738-
// The rest are handled below
739730
break;
740731
}
741732

742-
if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
743-
Result |= DINode::DIFlags::FlagFwdDecl;
744-
}
745-
if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
746-
Result |= DINode::DIFlags::FlagAppleBlock;
747-
}
748-
if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
749-
Result |= DINode::DIFlags::FlagVirtual;
750-
}
751-
if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
752-
Result |= DINode::DIFlags::FlagArtificial;
753-
}
754-
if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
755-
Result |= DINode::DIFlags::FlagExplicit;
756-
}
757-
if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
758-
Result |= DINode::DIFlags::FlagPrototyped;
759-
}
760-
if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
761-
Result |= DINode::DIFlags::FlagObjcClassComplete;
762-
}
763-
if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
764-
Result |= DINode::DIFlags::FlagObjectPointer;
765-
}
766-
if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
767-
Result |= DINode::DIFlags::FlagVector;
768-
}
769-
if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
770-
Result |= DINode::DIFlags::FlagStaticMember;
771-
}
772-
if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
773-
Result |= DINode::DIFlags::FlagLValueReference;
774-
}
775-
if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
776-
Result |= DINode::DIFlags::FlagRValueReference;
777-
}
778-
if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
779-
Result |= DINode::DIFlags::FlagIntroducedVirtual;
780-
}
781-
if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
782-
Result |= DINode::DIFlags::FlagBitField;
783-
}
784-
if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
785-
Result |= DINode::DIFlags::FlagNoReturn;
733+
// Reject anything beyond the highest known flag.
734+
if (static_cast<uint32_t>(Flags) >= (LLVMDIFlagLittleEndian << 1)) {
735+
report_fatal_error("bad LLVMDIFlags");
786736
}
787737

788738
return Result;

0 commit comments

Comments
 (0)