Skip to content

Commit c2b3f5a

Browse files
committed
Make our DIFlags match LLVMDIFlags in the LLVM-C API
1 parent 9c707a8 commit c2b3f5a

File tree

2 files changed

+61
-114
lines changed

2 files changed

+61
-114
lines changed

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,8 +748,8 @@ pub mod debuginfo {
748748
pub type DIEnumerator = DIDescriptor;
749749
pub type DITemplateTypeParameter = DIDescriptor;
750750

751-
// These values **must** match with LLVMRustDIFlags!!
752751
bitflags! {
752+
/// Must match the layout of `LLVMDIFlags` in the LLVM-C API.
753753
#[repr(transparent)]
754754
#[derive(Clone, Copy, Default)]
755755
pub struct DIFlags: u32 {
@@ -759,7 +759,7 @@ pub mod debuginfo {
759759
const FlagPublic = 3;
760760
const FlagFwdDecl = (1 << 2);
761761
const FlagAppleBlock = (1 << 3);
762-
const FlagBlockByrefStruct = (1 << 4);
762+
const FlagReservedBit4 = (1 << 4);
763763
const FlagVirtual = (1 << 5);
764764
const FlagArtificial = (1 << 6);
765765
const FlagExplicit = (1 << 7);
@@ -770,10 +770,20 @@ pub mod debuginfo {
770770
const FlagStaticMember = (1 << 12);
771771
const FlagLValueReference = (1 << 13);
772772
const FlagRValueReference = (1 << 14);
773-
const FlagExternalTypeRef = (1 << 15);
773+
const FlagReserved = (1 << 15);
774+
const FlagSingleInheritance = (1 << 16);
775+
const FlagMultipleInheritance = (2 << 16);
776+
const FlagVirtualInheritance = (3 << 16);
774777
const FlagIntroducedVirtual = (1 << 18);
775778
const FlagBitField = (1 << 19);
776779
const FlagNoReturn = (1 << 20);
780+
const FlagTypePassByValue = (1 << 22);
781+
const FlagTypePassByReference = (1 << 23);
782+
const FlagEnumClass = (1 << 24);
783+
const FlagThunk = (1 << 25);
784+
const FlagNonTrivial = (1 << 26);
785+
const FlagBigEndian = (1 << 27);
786+
const FlagLittleEndian = (1 << 28);
777787
}
778788
}
779789

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 48 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "LLVMWrapper.h"
22

33
#include "llvm-c/Core.h"
4+
#include "llvm-c/DebugInfo.h"
45
#include "llvm/ADT/ArrayRef.h"
56
#include "llvm/ADT/SmallVector.h"
67
#include "llvm/ADT/Statistic.h"
@@ -636,117 +637,53 @@ template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
636637
#define DIArray DINodeArray
637638
#define unwrapDI unwrapDIPtr
638639

639-
// These values **must** match debuginfo::DIFlags! They also *happen*
640-
// to match LLVM, but that isn't required as we do giant sets of
641-
// matching below. The value shouldn't be directly passed to LLVM.
642-
enum class LLVMRustDIFlags : uint32_t {
643-
FlagZero = 0,
644-
FlagPrivate = 1,
645-
FlagProtected = 2,
646-
FlagPublic = 3,
647-
FlagFwdDecl = (1 << 2),
648-
FlagAppleBlock = (1 << 3),
649-
FlagBlockByrefStruct = (1 << 4),
650-
FlagVirtual = (1 << 5),
651-
FlagArtificial = (1 << 6),
652-
FlagExplicit = (1 << 7),
653-
FlagPrototyped = (1 << 8),
654-
FlagObjcClassComplete = (1 << 9),
655-
FlagObjectPointer = (1 << 10),
656-
FlagVector = (1 << 11),
657-
FlagStaticMember = (1 << 12),
658-
FlagLValueReference = (1 << 13),
659-
FlagRValueReference = (1 << 14),
660-
FlagExternalTypeRef = (1 << 15),
661-
FlagIntroducedVirtual = (1 << 18),
662-
FlagBitField = (1 << 19),
663-
FlagNoReturn = (1 << 20),
664-
// Do not add values that are not supported by the minimum LLVM
665-
// version we support! see llvm/include/llvm/IR/DebugInfoFlags.def
666-
};
667-
668-
inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) {
669-
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) &
670-
static_cast<uint32_t>(B));
671-
}
672-
673-
inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) {
674-
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) |
675-
static_cast<uint32_t>(B));
676-
}
677-
678-
inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) {
679-
return A = A | B;
680-
}
681-
682-
inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; }
683-
684-
inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) {
685-
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3);
686-
}
687-
688-
static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) {
689-
DINode::DIFlags Result = DINode::DIFlags::FlagZero;
690-
691-
switch (visibility(Flags)) {
692-
case LLVMRustDIFlags::FlagPrivate:
693-
Result |= DINode::DIFlags::FlagPrivate;
694-
break;
695-
case LLVMRustDIFlags::FlagProtected:
696-
Result |= DINode::DIFlags::FlagProtected;
697-
break;
698-
case LLVMRustDIFlags::FlagPublic:
699-
Result |= DINode::DIFlags::FlagPublic;
700-
break;
701-
default:
702-
// The rest are handled below
703-
break;
704-
}
705-
706-
if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) {
707-
Result |= DINode::DIFlags::FlagFwdDecl;
708-
}
709-
if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) {
710-
Result |= DINode::DIFlags::FlagAppleBlock;
711-
}
712-
if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) {
713-
Result |= DINode::DIFlags::FlagVirtual;
714-
}
715-
if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) {
716-
Result |= DINode::DIFlags::FlagArtificial;
717-
}
718-
if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) {
719-
Result |= DINode::DIFlags::FlagExplicit;
720-
}
721-
if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) {
722-
Result |= DINode::DIFlags::FlagPrototyped;
723-
}
724-
if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) {
725-
Result |= DINode::DIFlags::FlagObjcClassComplete;
726-
}
727-
if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) {
728-
Result |= DINode::DIFlags::FlagObjectPointer;
729-
}
730-
if (isSet(Flags & LLVMRustDIFlags::FlagVector)) {
731-
Result |= DINode::DIFlags::FlagVector;
732-
}
733-
if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) {
734-
Result |= DINode::DIFlags::FlagStaticMember;
735-
}
736-
if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) {
737-
Result |= DINode::DIFlags::FlagLValueReference;
738-
}
739-
if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) {
740-
Result |= DINode::DIFlags::FlagRValueReference;
741-
}
742-
if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) {
743-
Result |= DINode::DIFlags::FlagIntroducedVirtual;
744-
}
745-
if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) {
746-
Result |= DINode::DIFlags::FlagBitField;
747-
}
748-
if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) {
749-
Result |= DINode::DIFlags::FlagNoReturn;
640+
// Temporary typedef to avoid churning functions that are about to be deleted.
641+
typedef LLVMDIFlags LLVMRustDIFlags;
642+
643+
static DINode::DIFlags fromRust(LLVMDIFlags Flags) {
644+
using DIFlags = DINode::DIFlags;
645+
646+
// Internally, LLVM does this conversion with a simple integer cast, but we
647+
// can't rely on that always being the case so we write this the long way.
648+
auto Result = DIFlags::FlagZero;
649+
650+
// clang-format off
651+
if (Flags & LLVMDIFlagPrivate) Result |= DIFlags::FlagPrivate;
652+
if (Flags & LLVMDIFlagProtected) Result |= DIFlags::FlagProtected;
653+
if (Flags & LLVMDIFlagPublic) Result |= DIFlags::FlagPublic;
654+
if (Flags & LLVMDIFlagFwdDecl) Result |= DIFlags::FlagFwdDecl;
655+
if (Flags & LLVMDIFlagAppleBlock) Result |= DIFlags::FlagAppleBlock;
656+
if (Flags & LLVMDIFlagReservedBit4) Result |= DIFlags::FlagReservedBit4;
657+
if (Flags & LLVMDIFlagVirtual) Result |= DIFlags::FlagVirtual;
658+
if (Flags & LLVMDIFlagArtificial) Result |= DIFlags::FlagArtificial;
659+
if (Flags & LLVMDIFlagExplicit) Result |= DIFlags::FlagExplicit;
660+
if (Flags & LLVMDIFlagPrototyped) Result |= DIFlags::FlagPrototyped;
661+
if (Flags & LLVMDIFlagObjcClassComplete) Result |= DIFlags::FlagObjcClassComplete;
662+
if (Flags & LLVMDIFlagObjectPointer) Result |= DIFlags::FlagObjectPointer;
663+
if (Flags & LLVMDIFlagVector) Result |= DIFlags::FlagVector;
664+
if (Flags & LLVMDIFlagStaticMember) Result |= DIFlags::FlagStaticMember;
665+
if (Flags & LLVMDIFlagLValueReference) Result |= DIFlags::FlagLValueReference;
666+
if (Flags & LLVMDIFlagRValueReference) Result |= DIFlags::FlagRValueReference;
667+
// This flag has been recycled, but the value in the C API hasn't been renamed yet.
668+
if (Flags & LLVMDIFlagReserved) Result |= DIFlags::FlagExportSymbols;
669+
if (Flags & LLVMDIFlagSingleInheritance) Result |= DIFlags::FlagSingleInheritance;
670+
if (Flags & LLVMDIFlagMultipleInheritance) Result |= DIFlags::FlagMultipleInheritance;
671+
if (Flags & LLVMDIFlagVirtualInheritance) Result |= DIFlags::FlagVirtualInheritance;
672+
if (Flags & LLVMDIFlagIntroducedVirtual) Result |= DIFlags::FlagIntroducedVirtual;
673+
if (Flags & LLVMDIFlagBitField) Result |= DIFlags::FlagBitField;
674+
if (Flags & LLVMDIFlagNoReturn) Result |= DIFlags::FlagNoReturn;
675+
if (Flags & LLVMDIFlagTypePassByValue) Result |= DIFlags::FlagTypePassByValue;
676+
if (Flags & LLVMDIFlagTypePassByReference) Result |= DIFlags::FlagTypePassByReference;
677+
if (Flags & LLVMDIFlagEnumClass) Result |= DIFlags::FlagEnumClass;
678+
if (Flags & LLVMDIFlagThunk) Result |= DIFlags::FlagThunk;
679+
if (Flags & LLVMDIFlagNonTrivial) Result |= DIFlags::FlagNonTrivial;
680+
if (Flags & LLVMDIFlagBigEndian) Result |= DIFlags::FlagLittleEndian;
681+
if (Flags & LLVMDIFlagLittleEndian) Result |= DIFlags::FlagLittleEndian;
682+
// clang-format on
683+
684+
// Reject anything beyond the highest known flag.
685+
if (static_cast<uint32_t>(Flags) >= (LLVMDIFlagLittleEndian << 1)) {
686+
report_fatal_error("bad LLVMDIFlags");
750687
}
751688

752689
return Result;

0 commit comments

Comments
 (0)