|
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"
|
@@ -672,117 +673,66 @@ template <typename DIT> DIT *unwrapDIPtr(LLVMMetadataRef Ref) {
|
672 | 673 | #define DIArray DINodeArray
|
673 | 674 | #define unwrapDI unwrapDIPtr
|
674 | 675 |
|
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; |
730 | 722 | break;
|
731 |
| - case LLVMRustDIFlags::FlagProtected: |
732 |
| - Result |= DINode::DIFlags::FlagProtected; |
| 723 | + case LLVMDIFlagProtected: |
| 724 | + Result |= DIFlags::FlagProtected; |
733 | 725 | break;
|
734 |
| - case LLVMRustDIFlags::FlagPublic: |
735 |
| - Result |= DINode::DIFlags::FlagPublic; |
| 726 | + case LLVMDIFlagPublic: |
| 727 | + Result |= DIFlags::FlagPublic; |
736 | 728 | break;
|
737 | 729 | default:
|
738 |
| - // The rest are handled below |
739 | 730 | break;
|
740 | 731 | }
|
741 | 732 |
|
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"); |
786 | 736 | }
|
787 | 737 |
|
788 | 738 | return Result;
|
|
0 commit comments