|
2 | 2 |
|
3 | 3 | #include "llvm-c/Analysis.h"
|
4 | 4 | #include "llvm-c/Core.h"
|
| 5 | +#include "llvm-c/DebugInfo.h" |
5 | 6 | #include "llvm/ADT/ArrayRef.h"
|
6 | 7 | #include "llvm/ADT/SmallVector.h"
|
7 | 8 | #include "llvm/ADT/Statistic.h"
|
@@ -676,120 +677,73 @@ template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
|
676 | 677 | #define DIArray DINodeArray
|
677 | 678 | #define unwrapDI unwrapDIPtr
|
678 | 679 |
|
679 |
| -// These values **must** match debuginfo::DIFlags! They also *happen* |
680 |
| -// to match LLVM, but that isn't required as we do giant sets of |
681 |
| -// matching below. The value shouldn't be directly passed to LLVM. |
682 |
| -enum class LLVMRustDIFlags : uint32_t { |
683 |
| - FlagZero = 0, |
684 |
| - FlagPrivate = 1, |
685 |
| - FlagProtected = 2, |
686 |
| - FlagPublic = 3, |
687 |
| - FlagFwdDecl = (1 << 2), |
688 |
| - FlagAppleBlock = (1 << 3), |
689 |
| - FlagBlockByrefStruct = (1 << 4), |
690 |
| - FlagVirtual = (1 << 5), |
691 |
| - FlagArtificial = (1 << 6), |
692 |
| - FlagExplicit = (1 << 7), |
693 |
| - FlagPrototyped = (1 << 8), |
694 |
| - FlagObjcClassComplete = (1 << 9), |
695 |
| - FlagObjectPointer = (1 << 10), |
696 |
| - FlagVector = (1 << 11), |
697 |
| - FlagStaticMember = (1 << 12), |
698 |
| - FlagLValueReference = (1 << 13), |
699 |
| - FlagRValueReference = (1 << 14), |
700 |
| - FlagExternalTypeRef = (1 << 15), |
701 |
| - FlagIntroducedVirtual = (1 << 18), |
702 |
| - FlagBitField = (1 << 19), |
703 |
| - FlagNoReturn = (1 << 20), |
704 |
| - // Do not add values that are not supported by the minimum LLVM |
705 |
| - // version we support! see llvm/include/llvm/IR/DebugInfoFlags.def |
706 |
| -}; |
707 |
| - |
708 |
| -inline LLVMRustDIFlags operator&(LLVMRustDIFlags A, LLVMRustDIFlags B) { |
709 |
| - return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) & |
710 |
| - static_cast<uint32_t>(B)); |
711 |
| -} |
712 |
| - |
713 |
| -inline LLVMRustDIFlags operator|(LLVMRustDIFlags A, LLVMRustDIFlags B) { |
714 |
| - return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(A) | |
715 |
| - static_cast<uint32_t>(B)); |
716 |
| -} |
717 |
| - |
718 |
| -inline LLVMRustDIFlags &operator|=(LLVMRustDIFlags &A, LLVMRustDIFlags B) { |
719 |
| - return A = A | B; |
720 |
| -} |
721 |
| - |
722 |
| -inline bool isSet(LLVMRustDIFlags F) { return F != LLVMRustDIFlags::FlagZero; } |
723 |
| - |
724 |
| -inline LLVMRustDIFlags visibility(LLVMRustDIFlags F) { |
725 |
| - return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(F) & 0x3); |
726 |
| -} |
727 |
| - |
728 |
| -static DINode::DIFlags fromRust(LLVMRustDIFlags Flags) { |
729 |
| - DINode::DIFlags Result = DINode::DIFlags::FlagZero; |
730 |
| - |
731 |
| - switch (visibility(Flags)) { |
732 |
| - case LLVMRustDIFlags::FlagPrivate: |
733 |
| - Result |= DINode::DIFlags::FlagPrivate; |
734 |
| - break; |
735 |
| - case LLVMRustDIFlags::FlagProtected: |
736 |
| - Result |= DINode::DIFlags::FlagProtected; |
737 |
| - break; |
738 |
| - case LLVMRustDIFlags::FlagPublic: |
739 |
| - Result |= DINode::DIFlags::FlagPublic; |
740 |
| - break; |
741 |
| - default: |
742 |
| - // The rest are handled below |
743 |
| - break; |
744 |
| - } |
745 |
| - |
746 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagFwdDecl)) { |
747 |
| - Result |= DINode::DIFlags::FlagFwdDecl; |
748 |
| - } |
749 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagAppleBlock)) { |
750 |
| - Result |= DINode::DIFlags::FlagAppleBlock; |
751 |
| - } |
752 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagVirtual)) { |
753 |
| - Result |= DINode::DIFlags::FlagVirtual; |
754 |
| - } |
755 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagArtificial)) { |
756 |
| - Result |= DINode::DIFlags::FlagArtificial; |
757 |
| - } |
758 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagExplicit)) { |
759 |
| - Result |= DINode::DIFlags::FlagExplicit; |
760 |
| - } |
761 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagPrototyped)) { |
762 |
| - Result |= DINode::DIFlags::FlagPrototyped; |
763 |
| - } |
764 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagObjcClassComplete)) { |
765 |
| - Result |= DINode::DIFlags::FlagObjcClassComplete; |
766 |
| - } |
767 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagObjectPointer)) { |
768 |
| - Result |= DINode::DIFlags::FlagObjectPointer; |
769 |
| - } |
770 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagVector)) { |
771 |
| - Result |= DINode::DIFlags::FlagVector; |
772 |
| - } |
773 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagStaticMember)) { |
774 |
| - Result |= DINode::DIFlags::FlagStaticMember; |
775 |
| - } |
776 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagLValueReference)) { |
777 |
| - Result |= DINode::DIFlags::FlagLValueReference; |
778 |
| - } |
779 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagRValueReference)) { |
780 |
| - Result |= DINode::DIFlags::FlagRValueReference; |
781 |
| - } |
782 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagIntroducedVirtual)) { |
783 |
| - Result |= DINode::DIFlags::FlagIntroducedVirtual; |
784 |
| - } |
785 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagBitField)) { |
786 |
| - Result |= DINode::DIFlags::FlagBitField; |
787 |
| - } |
788 |
| - if (isSet(Flags & LLVMRustDIFlags::FlagNoReturn)) { |
789 |
| - Result |= DINode::DIFlags::FlagNoReturn; |
790 |
| - } |
791 |
| - |
792 |
| - return Result; |
| 680 | +// FIXME(Zalathar): This is a temporary typedef to avoid churning dozens of |
| 681 | +// bindings that are going to be deleted and replaced with their LLVM-C |
| 682 | +// equivalents, as part of #134009. After that happens, the remaining bindings |
| 683 | +// can be adjusted to use `LLVMDIFlags` instead of relying on this typedef. |
| 684 | +typedef LLVMDIFlags LLVMRustDIFlags; |
| 685 | + |
| 686 | +// Statically assert that `LLVMDIFlags` (C) and `DIFlags` (C++) have the same |
| 687 | +// layout, at least for the flags we know about. This isn't guaranteed, but is |
| 688 | +// likely to remain true, and as long as it is true it makes conversions easy. |
| 689 | +#define ASSERT_DIFLAG_VALUE(FLAG, VALUE) \ |
| 690 | + static_assert((LLVMDI##FLAG == (VALUE)) && (DINode::DIFlags::FLAG == (VALUE))) |
| 691 | +ASSERT_DIFLAG_VALUE(FlagZero, 0); |
| 692 | +ASSERT_DIFLAG_VALUE(FlagPrivate, 1); |
| 693 | +ASSERT_DIFLAG_VALUE(FlagProtected, 2); |
| 694 | +ASSERT_DIFLAG_VALUE(FlagPublic, 3); |
| 695 | +// Bit (1 << 1) is part of the private/protected/public values above. |
| 696 | +ASSERT_DIFLAG_VALUE(FlagFwdDecl, 1 << 2); |
| 697 | +ASSERT_DIFLAG_VALUE(FlagAppleBlock, 1 << 3); |
| 698 | +ASSERT_DIFLAG_VALUE(FlagReservedBit4, 1 << 4); |
| 699 | +ASSERT_DIFLAG_VALUE(FlagVirtual, 1 << 5); |
| 700 | +ASSERT_DIFLAG_VALUE(FlagArtificial, 1 << 6); |
| 701 | +ASSERT_DIFLAG_VALUE(FlagExplicit, 1 << 7); |
| 702 | +ASSERT_DIFLAG_VALUE(FlagPrototyped, 1 << 8); |
| 703 | +ASSERT_DIFLAG_VALUE(FlagObjcClassComplete, 1 << 9); |
| 704 | +ASSERT_DIFLAG_VALUE(FlagObjectPointer, 1 << 10); |
| 705 | +ASSERT_DIFLAG_VALUE(FlagVector, 1 << 11); |
| 706 | +ASSERT_DIFLAG_VALUE(FlagStaticMember, 1 << 12); |
| 707 | +ASSERT_DIFLAG_VALUE(FlagLValueReference, 1 << 13); |
| 708 | +ASSERT_DIFLAG_VALUE(FlagRValueReference, 1 << 14); |
| 709 | +// Bit (1 << 15) has been recycled, but the C API value hasn't been renamed. |
| 710 | +static_assert((LLVMDIFlagReserved == (1 << 15)) && |
| 711 | + (DINode::DIFlags::FlagExportSymbols == (1 << 15))); |
| 712 | +ASSERT_DIFLAG_VALUE(FlagSingleInheritance, 1 << 16); |
| 713 | +ASSERT_DIFLAG_VALUE(FlagMultipleInheritance, 2 << 16); |
| 714 | +ASSERT_DIFLAG_VALUE(FlagVirtualInheritance, 3 << 16); |
| 715 | +// Bit (1 << 17) is part of the inheritance values above. |
| 716 | +ASSERT_DIFLAG_VALUE(FlagIntroducedVirtual, 1 << 18); |
| 717 | +ASSERT_DIFLAG_VALUE(FlagBitField, 1 << 19); |
| 718 | +ASSERT_DIFLAG_VALUE(FlagNoReturn, 1 << 20); |
| 719 | +// Bit (1 << 21) is unused, but was `LLVMDIFlagMainSubprogram`. |
| 720 | +ASSERT_DIFLAG_VALUE(FlagTypePassByValue, 1 << 22); |
| 721 | +ASSERT_DIFLAG_VALUE(FlagTypePassByReference, 1 << 23); |
| 722 | +ASSERT_DIFLAG_VALUE(FlagEnumClass, 1 << 24); |
| 723 | +ASSERT_DIFLAG_VALUE(FlagThunk, 1 << 25); |
| 724 | +ASSERT_DIFLAG_VALUE(FlagNonTrivial, 1 << 26); |
| 725 | +ASSERT_DIFLAG_VALUE(FlagBigEndian, 1 << 27); |
| 726 | +ASSERT_DIFLAG_VALUE(FlagLittleEndian, 1 << 28); |
| 727 | +ASSERT_DIFLAG_VALUE(FlagIndirectVirtualBase, (1 << 2) | (1 << 5)); |
| 728 | +#undef ASSERT_DIFLAG_VALUE |
| 729 | + |
| 730 | +// There are two potential ways to convert `LLVMDIFlags` to `DIFlags`: |
| 731 | +// - Check and copy every individual bit/subvalue from input to output. |
| 732 | +// - Statically assert that both have the same layout, and cast. |
| 733 | +// As long as the static assertions succeed, a cast is easier and faster. |
| 734 | +// In the (hopefully) unlikely event that the assertions do fail someday, and |
| 735 | +// LLVM doesn't expose its own conversion function, we'll have to switch over |
| 736 | +// to copying each bit/subvalue. |
| 737 | +static DINode::DIFlags fromRust(LLVMDIFlags Flags) { |
| 738 | + // Check that all set bits are covered by the static assertions above. |
| 739 | + const unsigned UNKNOWN_BITS = (1 << 31) | (1 << 30) | (1 << 29) | (1 << 21); |
| 740 | + if (Flags & UNKNOWN_BITS) { |
| 741 | + report_fatal_error("bad LLVMDIFlags"); |
| 742 | + } |
| 743 | + |
| 744 | + // As long as the static assertions are satisfied and no unknown bits are |
| 745 | + // present, we can convert from `LLVMDIFlags` to `DIFlags` with a cast. |
| 746 | + return static_cast<DINode::DIFlags>(Flags); |
793 | 747 | }
|
794 | 748 |
|
795 | 749 | // These values **must** match debuginfo::DISPFlags! They also *happen*
|
|
0 commit comments