llvm_lib/core/
mod.rs

1use crate::CUint;
2use llvm_sys::{
3    core, LLVMDLLStorageClass, LLVMIntPredicate, LLVMLinkage, LLVMOpcode, LLVMRealPredicate,
4    LLVMUnnamedAddr, LLVMVisibility,
5};
6use std::fmt::Display;
7use std::ops::Deref;
8
9pub mod context;
10pub mod module;
11pub mod types;
12pub mod values;
13
14/// Represents an LLVM address space.
15///
16/// The `AddressSpace` struct encapsulates a numeric value that indicates a specific address space
17/// in LLVM. Address spaces are used in LLVM to distinguish between different regions of memory, such as
18/// global memory, local memory, and private memory, especially in contexts like GPUs or other specialized
19/// hardware where different memory regions have different characteristics.
20///
21/// # Attributes
22///
23/// - Wrapped address value - the underlying numeric value representing the address space.
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct AddressSpace(CUint);
26
27impl From<u32> for AddressSpace {
28    fn from(value: u32) -> Self {
29        Self(CUint::from(value))
30    }
31}
32
33impl Deref for AddressSpace {
34    type Target = CUint;
35    fn deref(&self) -> &Self::Target {
36        &self.0
37    }
38}
39
40impl AddressSpace {
41    #[must_use]
42    pub const fn new(value: CUint) -> Self {
43        Self(value)
44    }
45}
46
47/// Dispose LLVM 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.
54pub fn dispose_message(_message: libc::c_char) {
55    unreachable!(
56        "LLVMDisposeMessage is unsafe adn restricted to operated to operate directly for safe code"
57    );
58}
59
60/// LLVM version representation
61///
62/// The `Version` struct encapsulates the major, minor, and patch components of the LLVM version.
63/// This struct provides methods to initialize and retrieve the version information.
64pub struct Version {
65    major: u32,
66    minor: u32,
67    patch: u32,
68}
69
70impl Version {
71    /// Init and return current LLVM version
72    ///
73    /// # Details
74    ///
75    /// Initializes and returns the current LLVM version.
76    ///
77    /// This method queries the LLVM library for its version information and returns a `Version` instance
78    /// containing the major, minor, and patch components of the LLVM version.
79    ///
80    /// # Returns
81    ///
82    /// A `Version` instance with the current LLVM version.
83    ///
84    /// # Example
85    ///
86    /// ```rust
87    /// let llvm_version = Version::new();
88    /// ```
89    #[must_use]
90    pub fn new() -> Self {
91        let mut major = CUint::from(0_u32);
92        let mut minor = CUint::from(0_u32);
93        let mut patch = CUint::from(0_u32);
94        unsafe {
95            core::LLVMGetVersion(&mut *major, &mut *minor, &mut *patch);
96        }
97        Self {
98            major: major.into(),
99            minor: minor.into(),
100            patch: patch.into(),
101        }
102    }
103
104    /// Return LLVM version data: (major, minor, patch)
105    ///
106    /// # Details
107    ///
108    ///  Returns the LLVM version as a tuple `(major, minor, patch)`.
109    ///
110    /// This method provides access to the individual components of the LLVM version stored in this `Version` instance.
111    ///
112    /// # Returns
113    ///
114    /// A tuple `(u32, u32, u32)` representing the major, minor, and patch components of the LLVM version.
115    ///
116    /// # Example
117    ///
118    /// ```rust
119    /// let llvm_version = Version::new();
120    /// let (major, minor, patch) = llvm_version.get();
121    /// ```
122    #[must_use]
123    pub const fn get(&self) -> (u32, u32, u32) {
124        (self.minor, self.minor, self.patch)
125    }
126}
127
128impl Display for Version {
129    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130        write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
131    }
132}
133
134/// Represents the various opcodes in LLVM IR.
135#[derive(Clone, Copy, Debug, PartialEq, Eq)]
136pub enum Opcode {
137    /// Return instruction.
138    Ret,
139    /// Branch instruction.
140    Br,
141    /// Switch instruction.
142    Switch,
143    /// Indirect branch instruction.
144    IndirectBr,
145    /// Invoke instruction.
146    Invoke,
147    /// Unreachable instruction.
148    Unreachable,
149    /// `CallBr` instruction.
150    CallBr,
151    /// Floating-point negation instruction.
152    FNeg,
153    /// Integer addition instruction.
154    Add,
155    /// Floating-point addition instruction.
156    FAdd,
157    /// Integer subtraction instruction.
158    Sub,
159    /// Floating-point subtraction instruction.
160    FSub,
161    /// Integer multiplication instruction
162    Mul,
163    /// Floating-point multiplication instruction.
164    FMul,
165    /// Unsigned integer division instruction.
166    UDiv,
167    /// Signed integer division instruction.
168    SDiv,
169    /// Floating-point division instruction.
170    FDiv,
171    /// Unsigned integer remainder instruction.
172    URem,
173    /// Signed integer remainder instruction.
174    SRem,
175    /// Floating-point remainder instruction.
176    FRem,
177    /// Logical shift left instruction.
178    Shl,
179    /// Logical shift right instruction.
180    LShr,
181    /// Arithmetic shift right instruction.
182    AShr,
183    /// Bitwise AND instruction.
184    And,
185    /// Bitwise OR instruction.
186    Or,
187    /// Bitwise XOR instruction.
188    Xor,
189    /// Alloca instruction.
190    Alloca,
191    /// Load instruction.
192    Load,
193    /// Store instruction.
194    Store,
195    /// `GetElementPtr` instruction.
196    GetElementPtr,
197    /// Truncate instruction.
198    Trunc,
199    /// Zero extend instruction.
200    ZExt,
201    /// Sign extend instruction.
202    SExt,
203    /// Floating-point to unsigned integer instruction.
204    FPToUI,
205    /// Floating-point to signed integer instruction.
206    FPToSI,
207    /// Unsigned integer to floating-point instruction.
208    UIToFP,
209    /// Signed integer to floating-point instruction.
210    SIToFP,
211    /// Floating-point truncate instruction.
212    FPTrunc,
213    /// Floating-point extend instruction
214    FPExt,
215    /// Pointer to integer instruction
216    PtrToInt,
217    /// Integer to pointer instruction
218    IntToPtr,
219    /// Bit-cast instruction
220    BitCast,
221    /// Address space cast instruction
222    AddrSpaceCast,
223    /// Integer comparison instruction
224    ICmp,
225    /// Floating-point comparison instruction
226    FCmp,
227    /// PHI node instruction
228    PHI,
229    /// Call instruction
230    Call,
231    /// Select instruction
232    Select,
233
234    /// User-defined operation 1
235    UserOp1,
236    /// User-defined operation 2
237    UserOp2,
238    /// Variable argument instruction
239    VAArg,
240    /// Extract element from vector instruction
241    ExtractElement,
242    /// Insert element into vector instruction
243    InsertElement,
244    /// Shuffle vector instruction
245    ShuffleVector,
246    /// Extract value from aggregate instruction
247    ExtractValue,
248    /// Insert value into aggregate instruction
249    InsertValue,
250    /// Freeze instruction
251    Freeze,
252    /// Fence instruction
253    Fence,
254    /// Atomic compare and exchange instruction
255    AtomicCmpXchg,
256    /// Atomic read-modify-write instruction
257    AtomicRMW,
258    /// Resume instruction
259    Resume,
260    /// Landing pad instruction
261    LandingPad,
262    /// Cleanup return instruction.
263    CleanupRet,
264    /// Catch return instruction
265    CatchRet,
266    /// Catch pad instruction
267    CatchPad,
268    /// Cleanup pad instruction
269    CleanupPad,
270    /// Catch switch instruction
271    CatchSwitch,
272}
273
274impl From<LLVMOpcode> for Opcode {
275    fn from(opcode: LLVMOpcode) -> Self {
276        match opcode {
277            LLVMOpcode::LLVMRet => Self::Ret,
278            LLVMOpcode::LLVMBr => Self::Br,
279            LLVMOpcode::LLVMSwitch => Self::Switch,
280            LLVMOpcode::LLVMIndirectBr => Self::IndirectBr,
281            LLVMOpcode::LLVMInvoke => Self::Invoke,
282            LLVMOpcode::LLVMUnreachable => Self::Unreachable,
283            LLVMOpcode::LLVMCallBr => Self::CallBr,
284            LLVMOpcode::LLVMFNeg => Self::FNeg,
285            LLVMOpcode::LLVMAdd => Self::Add,
286            LLVMOpcode::LLVMFAdd => Self::FAdd,
287            LLVMOpcode::LLVMSub => Self::Sub,
288            LLVMOpcode::LLVMFSub => Self::FSub,
289            LLVMOpcode::LLVMMul => Self::Mul,
290            LLVMOpcode::LLVMFMul => Self::FMul,
291            LLVMOpcode::LLVMUDiv => Self::UDiv,
292            LLVMOpcode::LLVMSDiv => Self::SDiv,
293            LLVMOpcode::LLVMFDiv => Self::FDiv,
294            LLVMOpcode::LLVMURem => Self::URem,
295            LLVMOpcode::LLVMSRem => Self::SRem,
296            LLVMOpcode::LLVMFRem => Self::FRem,
297            LLVMOpcode::LLVMShl => Self::Shl,
298            LLVMOpcode::LLVMLShr => Self::LShr,
299            LLVMOpcode::LLVMAShr => Self::AShr,
300            LLVMOpcode::LLVMAnd => Self::And,
301            LLVMOpcode::LLVMOr => Self::Or,
302            LLVMOpcode::LLVMXor => Self::Xor,
303            LLVMOpcode::LLVMAlloca => Self::Alloca,
304            LLVMOpcode::LLVMLoad => Self::Load,
305            LLVMOpcode::LLVMStore => Self::Store,
306            LLVMOpcode::LLVMGetElementPtr => Self::GetElementPtr,
307            LLVMOpcode::LLVMTrunc => Self::Trunc,
308            LLVMOpcode::LLVMZExt => Self::ZExt,
309            LLVMOpcode::LLVMSExt => Self::SExt,
310            LLVMOpcode::LLVMFPToUI => Self::FPToUI,
311            LLVMOpcode::LLVMFPToSI => Self::FPToSI,
312            LLVMOpcode::LLVMUIToFP => Self::UIToFP,
313            LLVMOpcode::LLVMSIToFP => Self::SIToFP,
314            LLVMOpcode::LLVMFPTrunc => Self::FPTrunc,
315            LLVMOpcode::LLVMFPExt => Self::FPExt,
316            LLVMOpcode::LLVMPtrToInt => Self::PtrToInt,
317            LLVMOpcode::LLVMIntToPtr => Self::IntToPtr,
318            LLVMOpcode::LLVMBitCast => Self::BitCast,
319            LLVMOpcode::LLVMAddrSpaceCast => Self::AddrSpaceCast,
320            LLVMOpcode::LLVMICmp => Self::ICmp,
321            LLVMOpcode::LLVMFCmp => Self::FCmp,
322            LLVMOpcode::LLVMPHI => Self::PHI,
323            LLVMOpcode::LLVMCall => Self::Call,
324            LLVMOpcode::LLVMSelect => Self::Select,
325            LLVMOpcode::LLVMUserOp1 => Self::UserOp1,
326            LLVMOpcode::LLVMUserOp2 => Self::UserOp2,
327            LLVMOpcode::LLVMVAArg => Self::VAArg,
328            LLVMOpcode::LLVMExtractElement => Self::ExtractElement,
329            LLVMOpcode::LLVMInsertElement => Self::InsertElement,
330            LLVMOpcode::LLVMShuffleVector => Self::ShuffleVector,
331            LLVMOpcode::LLVMExtractValue => Self::ExtractValue,
332            LLVMOpcode::LLVMInsertValue => Self::InsertValue,
333            LLVMOpcode::LLVMFreeze => Self::Freeze,
334            LLVMOpcode::LLVMFence => Self::Fence,
335            LLVMOpcode::LLVMAtomicCmpXchg => Self::AtomicCmpXchg,
336            LLVMOpcode::LLVMAtomicRMW => Self::AtomicRMW,
337            LLVMOpcode::LLVMResume => Self::Resume,
338            LLVMOpcode::LLVMLandingPad => Self::LandingPad,
339            LLVMOpcode::LLVMCleanupRet => Self::CleanupRet,
340            LLVMOpcode::LLVMCatchRet => Self::CatchRet,
341            LLVMOpcode::LLVMCatchPad => Self::CatchPad,
342            LLVMOpcode::LLVMCleanupPad => Self::CleanupPad,
343            LLVMOpcode::LLVMCatchSwitch => Self::CatchSwitch,
344        }
345    }
346}
347
348impl From<Opcode> for LLVMOpcode {
349    fn from(opcode: Opcode) -> Self {
350        match opcode {
351            Opcode::Ret => Self::LLVMRet,
352            Opcode::Br => Self::LLVMBr,
353            Opcode::Switch => Self::LLVMSwitch,
354            Opcode::IndirectBr => Self::LLVMIndirectBr,
355            Opcode::Invoke => Self::LLVMInvoke,
356            Opcode::Unreachable => Self::LLVMUnreachable,
357            Opcode::CallBr => Self::LLVMCallBr,
358            Opcode::FNeg => Self::LLVMFNeg,
359            Opcode::Add => Self::LLVMAdd,
360            Opcode::FAdd => Self::LLVMFAdd,
361            Opcode::Sub => Self::LLVMSub,
362            Opcode::FSub => Self::LLVMFSub,
363            Opcode::Mul => Self::LLVMMul,
364            Opcode::FMul => Self::LLVMFMul,
365            Opcode::UDiv => Self::LLVMUDiv,
366            Opcode::SDiv => Self::LLVMSDiv,
367            Opcode::FDiv => Self::LLVMFDiv,
368            Opcode::URem => Self::LLVMURem,
369            Opcode::SRem => Self::LLVMSRem,
370            Opcode::FRem => Self::LLVMFRem,
371            Opcode::Shl => Self::LLVMShl,
372            Opcode::LShr => Self::LLVMLShr,
373            Opcode::AShr => Self::LLVMAShr,
374            Opcode::And => Self::LLVMAnd,
375            Opcode::Or => Self::LLVMOr,
376            Opcode::Xor => Self::LLVMXor,
377            Opcode::Alloca => Self::LLVMAlloca,
378            Opcode::Load => Self::LLVMLoad,
379            Opcode::Store => Self::LLVMStore,
380            Opcode::GetElementPtr => Self::LLVMGetElementPtr,
381            Opcode::Trunc => Self::LLVMTrunc,
382            Opcode::ZExt => Self::LLVMZExt,
383            Opcode::SExt => Self::LLVMSExt,
384            Opcode::FPToUI => Self::LLVMFPToUI,
385            Opcode::FPToSI => Self::LLVMFPToSI,
386            Opcode::UIToFP => Self::LLVMUIToFP,
387            Opcode::SIToFP => Self::LLVMSIToFP,
388            Opcode::FPTrunc => Self::LLVMFPTrunc,
389            Opcode::FPExt => Self::LLVMFPExt,
390            Opcode::PtrToInt => Self::LLVMPtrToInt,
391            Opcode::IntToPtr => Self::LLVMIntToPtr,
392            Opcode::BitCast => Self::LLVMBitCast,
393            Opcode::AddrSpaceCast => Self::LLVMAddrSpaceCast,
394            Opcode::ICmp => Self::LLVMICmp,
395            Opcode::FCmp => Self::LLVMFCmp,
396            Opcode::PHI => Self::LLVMPHI,
397            Opcode::Call => Self::LLVMCall,
398            Opcode::Select => Self::LLVMSelect,
399            Opcode::UserOp1 => Self::LLVMUserOp1,
400            Opcode::UserOp2 => Self::LLVMUserOp2,
401            Opcode::VAArg => Self::LLVMVAArg,
402            Opcode::ExtractElement => Self::LLVMExtractElement,
403            Opcode::InsertElement => Self::LLVMInsertElement,
404            Opcode::ShuffleVector => Self::LLVMShuffleVector,
405            Opcode::ExtractValue => Self::LLVMExtractValue,
406            Opcode::InsertValue => Self::LLVMInsertValue,
407            Opcode::Freeze => Self::LLVMFreeze,
408            Opcode::Fence => Self::LLVMFence,
409            Opcode::AtomicCmpXchg => Self::LLVMAtomicCmpXchg,
410            Opcode::AtomicRMW => Self::LLVMAtomicRMW,
411            Opcode::Resume => Self::LLVMResume,
412            Opcode::LandingPad => Self::LLVMLandingPad,
413            Opcode::CleanupRet => Self::LLVMCleanupRet,
414            Opcode::CatchRet => Self::LLVMCatchRet,
415            Opcode::CatchPad => Self::LLVMCatchPad,
416            Opcode::CleanupPad => Self::LLVMCleanupPad,
417            Opcode::CatchSwitch => Self::LLVMCatchSwitch,
418        }
419    }
420}
421
422/// Represents the various integer comparison predicates in LLVM IR.
423///
424/// The `IntPredicate` enum defines the possible predicates that can be used for integer comparisons
425/// in LLVM IR. These predicates specify the condition under which an integer comparison is considered true.
426/// The predicates cover both signed and unsigned comparisons, as well as equality checks.
427#[derive(Clone, Copy, Debug, PartialEq, Eq)]
428pub enum IntPredicate {
429    /// Represents an equality comparison (`==`). This predicate is true if the two integers are equal.
430    IntEQ,
431    /// Represents an inequality comparison (`!=`). This predicate is true if the two integers are not equal.
432    IntNE,
433    /// Represents an unsigned greater than comparison (`>`). This predicate is true if the first integer is greater than the second, treating both as unsigned values.
434    IntUGT,
435    /// Represents an unsigned greater than or equal comparison (`>=`). This predicate is true if the first integer is greater than or equal to the second, treating both as unsigned values.
436    IntUGE,
437    /// Represents an unsigned less than comparison (`<`). This predicate is true if the first integer is less than the second, treating both as unsigned values.
438    IntULT,
439    /// Represents an unsigned less than or equal comparison (`<=`). This predicate is true if the first integer is less than or equal to the second, treating both as unsigned values.
440    IntULE,
441    /// Represents a signed greater than comparison (`>`). This predicate is true if the first integer is greater than the second, treating both as signed values.
442    IntSGT,
443    /// Represents a signed greater than or equal comparison (`>=`). This predicate is true if the first integer is greater than or equal to the second, treating both as signed values.
444    IntSGE,
445    /// Represents a signed less than comparison (`<`). This predicate is true if the first integer is less than the second, treating both as signed values.
446    IntSLT,
447    /// Represents a signed less than or equal comparison (`<=`). This predicate is true if the first integer is less than or equal to the second, treating both as signed values.
448    IntSLE,
449}
450
451impl From<LLVMIntPredicate> for IntPredicate {
452    fn from(predicate: LLVMIntPredicate) -> Self {
453        match predicate {
454            LLVMIntPredicate::LLVMIntEQ => Self::IntEQ,
455            LLVMIntPredicate::LLVMIntNE => Self::IntNE,
456            LLVMIntPredicate::LLVMIntUGT => Self::IntUGT,
457            LLVMIntPredicate::LLVMIntUGE => Self::IntUGE,
458            LLVMIntPredicate::LLVMIntULT => Self::IntULT,
459            LLVMIntPredicate::LLVMIntULE => Self::IntULE,
460            LLVMIntPredicate::LLVMIntSGT => Self::IntSGT,
461            LLVMIntPredicate::LLVMIntSGE => Self::IntSGE,
462            LLVMIntPredicate::LLVMIntSLT => Self::IntSLT,
463            LLVMIntPredicate::LLVMIntSLE => Self::IntSLE,
464        }
465    }
466}
467
468impl From<IntPredicate> for LLVMIntPredicate {
469    fn from(predicate: IntPredicate) -> Self {
470        match predicate {
471            IntPredicate::IntEQ => Self::LLVMIntEQ,
472            IntPredicate::IntNE => Self::LLVMIntNE,
473            IntPredicate::IntUGT => Self::LLVMIntUGT,
474            IntPredicate::IntUGE => Self::LLVMIntUGE,
475            IntPredicate::IntULT => Self::LLVMIntULT,
476            IntPredicate::IntULE => Self::LLVMIntULE,
477            IntPredicate::IntSGT => Self::LLVMIntSGT,
478            IntPredicate::IntSGE => Self::LLVMIntSGE,
479            IntPredicate::IntSLT => Self::LLVMIntSLT,
480            IntPredicate::IntSLE => Self::LLVMIntSLE,
481        }
482    }
483}
484
485/// Represents the various floating-point comparison predicates in LLVM IR.
486///
487/// The `RealPredicate` enum defines the possible predicates that can be used for floating-point comparisons
488/// in LLVM IR. These predicates specify the conditions under which a floating-point comparison is considered true.
489/// The predicates include ordered and unordered comparisons, as well as equality and inequality checks.
490#[derive(Clone, Copy, Debug, PartialEq, Eq)]
491pub enum RealPredicate {
492    /// Represents a predicate that always returns false. No comparison is true under this predicate.
493    RealPredicateFalse = 0,
494    /// Represents an ordered equality comparison (`==`). This predicate is true if the two floating-point numbers are equal and neither is NaN.
495    RealOEQ,
496    /// Represents an ordered greater than comparison (`>`). This predicate is true if the first floating-point number is greater than the second and neither is NaN.
497    RealOGT,
498    /// Represents an ordered greater than or equal comparison (`>=`). This predicate is true if the first floating-point number is greater than or equal to the second and neither is NaN.
499    RealOGE,
500    /// Represents an ordered less than comparison (`<`). This predicate is true if the first floating-point number is less than the second and neither is NaN.
501    RealOLT,
502    /// Represents an ordered less than or equal comparison (`<=`). This predicate is true if the first floating-point number is less than or equal to the second and neither is NaN.
503    RealOLE,
504    /// Represents an ordered inequality comparison (`!=`). This predicate is true if the two floating-point numbers are not equal and neither is NaN.
505    RealONE,
506    /// Represents an ordered comparison. This predicate is true if neither of the floating-point numbers is NaN.
507    RealORD,
508    /// Represents an unordered comparison. This predicate is true if either of the floating-point numbers is NaN.
509    RealUNO,
510    /// Represents an unordered equality comparison. This predicate is true if the two floating-point numbers are equal or either is NaN.
511    RealUEQ,
512    /// Represents an unordered greater than comparison. This predicate is true if the first floating-point number is greater than the second or either is NaN.
513    RealUGT,
514    /// Represents an unordered greater than or equal comparison. This predicate is true if the first floating-point number is greater than or equal to the second or either is NaN.
515    RealUGE,
516    /// Represents an unordered less than comparison. This predicate is true if the first floating-point number is less than the second or either is NaN.
517    RealULT,
518    /// Represents an unordered less than or equal comparison. This predicate is true if the first floating-point number is less than or equal to the second or either is NaN.
519    RealULE,
520    /// Represents an unordered inequality comparison. This predicate is true if the two floating-point numbers are not equal or either is NaN.
521    RealUNE,
522    /// Represents a predicate that always returns true. All comparisons are true under this predicate.
523    RealPredicateTrue,
524}
525
526impl From<LLVMRealPredicate> for RealPredicate {
527    fn from(predicate: LLVMRealPredicate) -> Self {
528        match predicate {
529            LLVMRealPredicate::LLVMRealPredicateFalse => Self::RealPredicateFalse,
530            LLVMRealPredicate::LLVMRealOEQ => Self::RealOEQ,
531            LLVMRealPredicate::LLVMRealOGT => Self::RealOGT,
532            LLVMRealPredicate::LLVMRealOGE => Self::RealOGE,
533            LLVMRealPredicate::LLVMRealOLT => Self::RealOLT,
534            LLVMRealPredicate::LLVMRealOLE => Self::RealOLE,
535            LLVMRealPredicate::LLVMRealONE => Self::RealONE,
536            LLVMRealPredicate::LLVMRealORD => Self::RealORD,
537            LLVMRealPredicate::LLVMRealUNO => Self::RealUNO,
538            LLVMRealPredicate::LLVMRealUEQ => Self::RealUEQ,
539            LLVMRealPredicate::LLVMRealUGT => Self::RealUGT,
540            LLVMRealPredicate::LLVMRealUGE => Self::RealUGE,
541            LLVMRealPredicate::LLVMRealULT => Self::RealULT,
542            LLVMRealPredicate::LLVMRealULE => Self::RealULE,
543            LLVMRealPredicate::LLVMRealUNE => Self::RealUNE,
544            LLVMRealPredicate::LLVMRealPredicateTrue => Self::RealPredicateTrue,
545        }
546    }
547}
548
549impl From<RealPredicate> for LLVMRealPredicate {
550    fn from(predicate: RealPredicate) -> Self {
551        match predicate {
552            RealPredicate::RealPredicateFalse => Self::LLVMRealPredicateFalse,
553            RealPredicate::RealOEQ => Self::LLVMRealOEQ,
554            RealPredicate::RealOGT => Self::LLVMRealOGT,
555            RealPredicate::RealOGE => Self::LLVMRealOGE,
556            RealPredicate::RealOLT => Self::LLVMRealOLT,
557            RealPredicate::RealOLE => Self::LLVMRealOLE,
558            RealPredicate::RealONE => Self::LLVMRealONE,
559            RealPredicate::RealORD => Self::LLVMRealORD,
560            RealPredicate::RealUNO => Self::LLVMRealUNO,
561            RealPredicate::RealUEQ => Self::LLVMRealUEQ,
562            RealPredicate::RealUGT => Self::LLVMRealUGT,
563            RealPredicate::RealUGE => Self::LLVMRealUGE,
564            RealPredicate::RealULT => Self::LLVMRealULT,
565            RealPredicate::RealULE => Self::LLVMRealULE,
566            RealPredicate::RealUNE => Self::LLVMRealUNE,
567            RealPredicate::RealPredicateTrue => Self::LLVMRealPredicateTrue,
568        }
569    }
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)]
575pub 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
612impl 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
636impl 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)]
668pub 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
677impl 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
687impl 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)]
703pub 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
717impl 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
727impl 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)]
743pub 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
758impl 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
768impl 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}