|
1 | 1 | use crate::CUint;
|
2 |
| -use llvm_sys::{core, LLVMIntPredicate, LLVMOpcode, LLVMRealPredicate}; |
| 2 | +use llvm_sys::{ |
| 3 | + core, LLVMDLLStorageClass, LLVMIntPredicate, LLVMLinkage, LLVMOpcode, LLVMRealPredicate, |
| 4 | + LLVMUnnamedAddr, LLVMVisibility, |
| 5 | +}; |
3 | 6 | use std::fmt::Display;
|
4 | 7 | use std::ops::Deref;
|
5 | 8 |
|
@@ -42,10 +45,16 @@ impl AddressSpace {
|
42 | 45 | }
|
43 | 46 |
|
44 | 47 | /// Dispose LLVM message
|
45 |
| -/// ## Safety |
46 |
| -/// Common function to dispose allocated message |
47 |
| -pub unsafe fn dispose_message(message: *mut libc::c_char) { |
48 |
| - unsafe { core::LLVMDisposeMessage(message) } |
| 48 | +/// |
| 49 | +/// ## Panics |
| 50 | +/// This function is purely informative and panics with a message about the call |
| 51 | +/// being unavailable. Since there are no cases in which it can be called in |
| 52 | +/// safe code. For raw access, if there is such a need, must be called |
| 53 | +/// `LLVMDisposeMessage` directly. |
| 54 | +pub fn dispose_message(_message: libc::c_char) { |
| 55 | + unreachable!( |
| 56 | + "LLVMDisposeMessage is unsafe adn restricted to operated to operate directly for safe code" |
| 57 | + ); |
49 | 58 | }
|
50 | 59 |
|
51 | 60 | /// LLVM version representation
|
@@ -559,3 +568,209 @@ impl From<RealPredicate> for LLVMRealPredicate {
|
559 | 568 | }
|
560 | 569 | }
|
561 | 570 | }
|
| 571 | + |
| 572 | +/// Represents the linkage types in LLVM for global values. |
| 573 | +/// Linkage types determine the visibility and behavior of symbols across different modules and within the same module. |
| 574 | +#[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| 575 | +pub enum Linkage { |
| 576 | + /// Externally visible function or variable. Can be linked from another module. |
| 577 | + ExternalLinkage, |
| 578 | + /// Similar to `ExternalLinkage`, but the symbol may be discarded if not used. |
| 579 | + AvailableExternallyLinkage, |
| 580 | + /// Keeps one copy of the function or variable when linking, discarding others. |
| 581 | + LinkOnceAnyLinkage, |
| 582 | + /// Similar to `LinkOnceAnyLinkage`, but the symbol cannot be discarded. |
| 583 | + LinkOnceODRLinkage, |
| 584 | + /// Same as `LinkOnceODRLinkage`, but with hidden visibility. |
| 585 | + LinkOnceODRAutoHideLinkage, |
| 586 | + /// Keeps one copy, discarding others, but prefer the local copy. |
| 587 | + WeakAnyLinkage, |
| 588 | + /// Similar to `WeakAnyLinkage`, but ensures that the symbol is unique and is emitted only once. |
| 589 | + WeakODRLinkage, |
| 590 | + /// Appending linkage: when linked, multiple definitions of the same variable are concatenated. |
| 591 | + AppendingLinkage, |
| 592 | + /// Local to the translation unit, not visible outside of it. |
| 593 | + InternalLinkage, |
| 594 | + /// Similar to `InternalLinkage`, but prevents inlining and other optimizations. |
| 595 | + PrivateLinkage, |
| 596 | + /// Indicates that the global value should be imported from a DLL. |
| 597 | + DLLImportLinkage, |
| 598 | + /// Indicates that the global value should be exported to a DLL. |
| 599 | + DLLExportLinkage, |
| 600 | + /// The global variable or function is merged into the program only if it is used. |
| 601 | + ExternalWeakLinkage, |
| 602 | + /// A special linkage type used internally by the linker. |
| 603 | + GhostLinkage, |
| 604 | + /// Common linkage for uninitialized global variables. |
| 605 | + CommonLinkage, |
| 606 | + /// Linker private linkage, used to indicate a symbol that is internal to the module. |
| 607 | + LinkerPrivateLinkage, |
| 608 | + /// Weak version of `LinkerPrivateLinkage`. |
| 609 | + LinkerPrivateWeakLinkage, |
| 610 | +} |
| 611 | + |
| 612 | +impl From<LLVMLinkage> for Linkage { |
| 613 | + fn from(linkage: LLVMLinkage) -> Self { |
| 614 | + match linkage { |
| 615 | + LLVMLinkage::LLVMExternalLinkage => Self::ExternalLinkage, |
| 616 | + LLVMLinkage::LLVMAvailableExternallyLinkage => Self::AvailableExternallyLinkage, |
| 617 | + LLVMLinkage::LLVMLinkOnceAnyLinkage => Self::LinkOnceAnyLinkage, |
| 618 | + LLVMLinkage::LLVMLinkOnceODRLinkage => Self::LinkOnceODRLinkage, |
| 619 | + LLVMLinkage::LLVMLinkOnceODRAutoHideLinkage => Self::LinkOnceODRAutoHideLinkage, |
| 620 | + LLVMLinkage::LLVMWeakAnyLinkage => Self::WeakAnyLinkage, |
| 621 | + LLVMLinkage::LLVMWeakODRLinkage => Self::WeakODRLinkage, |
| 622 | + LLVMLinkage::LLVMAppendingLinkage => Self::AppendingLinkage, |
| 623 | + LLVMLinkage::LLVMInternalLinkage => Self::InternalLinkage, |
| 624 | + LLVMLinkage::LLVMPrivateLinkage => Self::PrivateLinkage, |
| 625 | + LLVMLinkage::LLVMDLLImportLinkage => Self::DLLImportLinkage, |
| 626 | + LLVMLinkage::LLVMDLLExportLinkage => Self::DLLExportLinkage, |
| 627 | + LLVMLinkage::LLVMExternalWeakLinkage => Self::ExternalWeakLinkage, |
| 628 | + LLVMLinkage::LLVMGhostLinkage => Self::GhostLinkage, |
| 629 | + LLVMLinkage::LLVMCommonLinkage => Self::CommonLinkage, |
| 630 | + LLVMLinkage::LLVMLinkerPrivateLinkage => Self::LinkerPrivateLinkage, |
| 631 | + LLVMLinkage::LLVMLinkerPrivateWeakLinkage => Self::LinkerPrivateWeakLinkage, |
| 632 | + } |
| 633 | + } |
| 634 | +} |
| 635 | + |
| 636 | +impl From<Linkage> for LLVMLinkage { |
| 637 | + fn from(linkage: Linkage) -> Self { |
| 638 | + match linkage { |
| 639 | + Linkage::ExternalLinkage => Self::LLVMExternalLinkage, |
| 640 | + Linkage::AvailableExternallyLinkage => Self::LLVMAvailableExternallyLinkage, |
| 641 | + Linkage::LinkOnceAnyLinkage => Self::LLVMLinkOnceAnyLinkage, |
| 642 | + Linkage::LinkOnceODRLinkage => Self::LLVMLinkOnceODRLinkage, |
| 643 | + Linkage::LinkOnceODRAutoHideLinkage => Self::LLVMLinkOnceODRAutoHideLinkage, |
| 644 | + Linkage::WeakAnyLinkage => Self::LLVMWeakAnyLinkage, |
| 645 | + Linkage::WeakODRLinkage => Self::LLVMWeakODRLinkage, |
| 646 | + Linkage::AppendingLinkage => Self::LLVMAppendingLinkage, |
| 647 | + Linkage::InternalLinkage => Self::LLVMInternalLinkage, |
| 648 | + Linkage::PrivateLinkage => Self::LLVMPrivateLinkage, |
| 649 | + Linkage::DLLImportLinkage => Self::LLVMDLLImportLinkage, |
| 650 | + Linkage::DLLExportLinkage => Self::LLVMDLLExportLinkage, |
| 651 | + Linkage::ExternalWeakLinkage => Self::LLVMExternalWeakLinkage, |
| 652 | + Linkage::GhostLinkage => Self::LLVMGhostLinkage, |
| 653 | + Linkage::CommonLinkage => Self::LLVMCommonLinkage, |
| 654 | + Linkage::LinkerPrivateLinkage => Self::LLVMLinkerPrivateLinkage, |
| 655 | + Linkage::LinkerPrivateWeakLinkage => Self::LLVMLinkerPrivateWeakLinkage, |
| 656 | + } |
| 657 | + } |
| 658 | +} |
| 659 | + |
| 660 | +/// `Visibility` is an enumeration in LLVM that represents the |
| 661 | +/// visibility of global values such as functions and global |
| 662 | +/// variables. Visibility determines how symbols are treated by |
| 663 | +/// the linker and whether they can be seen by other modules or |
| 664 | +/// shared libraries. |
| 665 | +/// Generally `Visibility` represent access to the symbol after `Linkage`. |
| 666 | +/// Useful to compose `Linkage` and `Visibility` to define the symbol behavior. |
| 667 | +#[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| 668 | +pub enum Visibility { |
| 669 | + /// Default visibility. The symbol is visible to other modules. |
| 670 | + DefaultVisibility, |
| 671 | + /// Hidden visibility. The symbol is not visible to other modules or shared libraries. |
| 672 | + HiddenVisibility, |
| 673 | + /// Protected visibility. The symbol is visible to other modules but cannot be overridden. |
| 674 | + ProtectedVisibility, |
| 675 | +} |
| 676 | + |
| 677 | +impl From<LLVMVisibility> for Visibility { |
| 678 | + fn from(visibility: LLVMVisibility) -> Self { |
| 679 | + match visibility { |
| 680 | + LLVMVisibility::LLVMDefaultVisibility => Self::DefaultVisibility, |
| 681 | + LLVMVisibility::LLVMHiddenVisibility => Self::HiddenVisibility, |
| 682 | + LLVMVisibility::LLVMProtectedVisibility => Self::ProtectedVisibility, |
| 683 | + } |
| 684 | + } |
| 685 | +} |
| 686 | + |
| 687 | +impl From<Visibility> for LLVMVisibility { |
| 688 | + fn from(visibility: Visibility) -> Self { |
| 689 | + match visibility { |
| 690 | + Visibility::DefaultVisibility => Self::LLVMDefaultVisibility, |
| 691 | + Visibility::HiddenVisibility => Self::LLVMHiddenVisibility, |
| 692 | + Visibility::ProtectedVisibility => Self::LLVMProtectedVisibility, |
| 693 | + } |
| 694 | + } |
| 695 | +} |
| 696 | + |
| 697 | +/// Represents the DLL storage classes in LLVM, that specifies how a global value, |
| 698 | +/// such as a function or global variable, should be treated with respect to |
| 699 | +/// dynamic link libraries (DLLs) on platforms like Windows. The `DLLStorageClass` |
| 700 | +/// controls whether a symbol should be imported from a DLL, exported to a DLL, or |
| 701 | +/// treated as a normal global symbol. |
| 702 | +#[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| 703 | +pub enum DLLStorageClass { |
| 704 | + /// `DefaultStorageClass`: The default storage class. The symbol is not specifically marked for import or export |
| 705 | + /// from a DLL. It is treated as a normal global symbol. |
| 706 | + DefaultStorageClass, |
| 707 | + /// `DLLImportStorageClass`: Specifies that the symbol should be imported from a DLL. This is used when you want |
| 708 | + /// to use a function or variable that is defined in another DLL. The linker will ensure that the symbol is correctly |
| 709 | + /// imported at runtime. |
| 710 | + DLLImportStorageClass, |
| 711 | + /// `DLLExportStorageClass`: Specifies that the symbol should be exported to a DLL. This is used when you want to make |
| 712 | + /// a function or variable available for use by other modules or executables. The linker will ensure that the symbol is |
| 713 | + /// correctly exported and accessible to other programs. |
| 714 | + DLLExportStorageClass, |
| 715 | +} |
| 716 | + |
| 717 | +impl From<DLLStorageClass> for LLVMDLLStorageClass { |
| 718 | + fn from(storage_class: DLLStorageClass) -> Self { |
| 719 | + match storage_class { |
| 720 | + DLLStorageClass::DefaultStorageClass => Self::LLVMDefaultStorageClass, |
| 721 | + DLLStorageClass::DLLImportStorageClass => Self::LLVMDLLImportStorageClass, |
| 722 | + DLLStorageClass::DLLExportStorageClass => Self::LLVMDLLExportStorageClass, |
| 723 | + } |
| 724 | + } |
| 725 | +} |
| 726 | + |
| 727 | +impl From<LLVMDLLStorageClass> for DLLStorageClass { |
| 728 | + fn from(storage_class: LLVMDLLStorageClass) -> Self { |
| 729 | + match storage_class { |
| 730 | + LLVMDLLStorageClass::LLVMDefaultStorageClass => Self::DefaultStorageClass, |
| 731 | + LLVMDLLStorageClass::LLVMDLLImportStorageClass => Self::DLLImportStorageClass, |
| 732 | + LLVMDLLStorageClass::LLVMDLLExportStorageClass => Self::DLLExportStorageClass, |
| 733 | + } |
| 734 | + } |
| 735 | +} |
| 736 | + |
| 737 | +/// Represents the unnamed address attribute for global values in LLVM. |
| 738 | +/// |
| 739 | +/// `UnnamedAddr` is an enumeration that specifies whether a global variable or function's address is significant. |
| 740 | +/// This can help LLVM's optimizer determine whether it can merge or duplicate global values with identical content, |
| 741 | +/// potentially reducing code size or improving performance. |
| 742 | +#[derive(Clone, Copy, Debug, PartialEq, Eq)] |
| 743 | +pub enum UnnamedAddr { |
| 744 | + /// `NoUnnamedAddr`: The address of the global value is significant, and it must be unique. |
| 745 | + /// The global variable or function cannot be merged with others, even if they have the same content. |
| 746 | + /// This is the default behavior for most global values. |
| 747 | + NoUnnamedAddr, |
| 748 | + /// `LocalUnnamedAddr`: The address of the global value is not significant within the module, allowing the optimizer |
| 749 | + /// to merge or duplicate global values with the same content. However, the address is still unique within the module. |
| 750 | + /// This is useful for variables or functions that are only accessed within the same module and do not need a unique address. |
| 751 | + LocalUnnamedAddr, |
| 752 | + /// `GlobalUnnamedAddr`: The address of the global value is not significant across the entire program, allowing the optimizer |
| 753 | + /// to freely merge or duplicate global values with identical content across different modules. |
| 754 | + /// This can lead to more aggressive optimizations and is useful for constants or functions that do not rely on having a unique address. |
| 755 | + GlobalUnnamedAddr, |
| 756 | +} |
| 757 | + |
| 758 | +impl From<UnnamedAddr> for LLVMUnnamedAddr { |
| 759 | + fn from(unnamed_addr: UnnamedAddr) -> Self { |
| 760 | + match unnamed_addr { |
| 761 | + UnnamedAddr::NoUnnamedAddr => Self::LLVMNoUnnamedAddr, |
| 762 | + UnnamedAddr::LocalUnnamedAddr => Self::LLVMLocalUnnamedAddr, |
| 763 | + UnnamedAddr::GlobalUnnamedAddr => Self::LLVMGlobalUnnamedAddr, |
| 764 | + } |
| 765 | + } |
| 766 | +} |
| 767 | + |
| 768 | +impl From<LLVMUnnamedAddr> for UnnamedAddr { |
| 769 | + fn from(unnamed_addr: LLVMUnnamedAddr) -> Self { |
| 770 | + match unnamed_addr { |
| 771 | + LLVMUnnamedAddr::LLVMNoUnnamedAddr => Self::NoUnnamedAddr, |
| 772 | + LLVMUnnamedAddr::LLVMLocalUnnamedAddr => Self::LocalUnnamedAddr, |
| 773 | + LLVMUnnamedAddr::LLVMGlobalUnnamedAddr => Self::GlobalUnnamedAddr, |
| 774 | + } |
| 775 | + } |
| 776 | +} |
0 commit comments