llvm_plugin_inkwell/
lib.rs

1//! Inkwell documentation is a work in progress.
2//!
3//! **This crate is a fork of [Inkwell](https://github.com/TheDan64/inkwell)**.
4//!
5//! If you have any LLVM knowledge that could be used to improve these docs, we would greatly appreciate you opening an issue and/or a pull request on our [GitHub page](https://github.com/TheDan64/inkwell).
6//!
7//! Due to a rustdoc issue, this documentation represents only the latest supported LLVM version. We hope that this issue will be resolved in the future so that multiple versions can be documented side by side.
8//!
9//! # Library Wide Notes
10//!
11//! * Most functions which take a string slice as input may possibly panic in the unlikely event that a c style string cannot be created based on it. (IE if your slice already has a null byte in it)
12
13#![deny(missing_debug_implementations)]
14#![cfg_attr(feature = "nightly", feature(doc_cfg))]
15
16#[macro_use]
17extern crate inkwell_internals;
18
19#[macro_use]
20pub mod support;
21#[deny(missing_docs)]
22pub mod attributes;
23#[deny(missing_docs)]
24pub mod basic_block;
25pub mod builder;
26#[deny(missing_docs)]
27#[cfg(not(any(feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0")))]
28pub mod comdat;
29#[deny(missing_docs)]
30pub mod context;
31pub mod data_layout;
32#[cfg(not(any(feature = "llvm4-0", feature = "llvm5-0", feature = "llvm6-0")))]
33pub mod debug_info;
34pub mod execution_engine;
35pub mod intrinsics;
36pub mod memory_buffer;
37#[deny(missing_docs)]
38pub mod module;
39pub mod object_file;
40pub mod passes;
41pub mod targets;
42pub mod types;
43pub mod values;
44
45// Boilerplate to select a desired llvm_sys version at compile & link time.
46#[cfg(feature = "llvm10-0")]
47pub extern crate llvm_sys_100 as llvm_sys;
48#[cfg(feature = "llvm11-0")]
49pub extern crate llvm_sys_110 as llvm_sys;
50#[cfg(feature = "llvm12-0")]
51pub extern crate llvm_sys_120 as llvm_sys;
52#[cfg(feature = "llvm13-0")]
53pub extern crate llvm_sys_130 as llvm_sys;
54#[cfg(feature = "llvm14-0")]
55pub extern crate llvm_sys_140 as llvm_sys;
56#[cfg(feature = "llvm15-0")]
57pub extern crate llvm_sys_150 as llvm_sys;
58#[cfg(feature = "llvm16-0")]
59pub extern crate llvm_sys_160 as llvm_sys;
60#[cfg(feature = "llvm4-0")]
61pub extern crate llvm_sys_40 as llvm_sys;
62#[cfg(feature = "llvm5-0")]
63pub extern crate llvm_sys_50 as llvm_sys;
64#[cfg(feature = "llvm6-0")]
65pub extern crate llvm_sys_60 as llvm_sys;
66#[cfg(feature = "llvm7-0")]
67pub extern crate llvm_sys_70 as llvm_sys;
68#[cfg(feature = "llvm8-0")]
69pub extern crate llvm_sys_80 as llvm_sys;
70#[cfg(feature = "llvm9-0")]
71pub extern crate llvm_sys_90 as llvm_sys;
72
73use llvm_sys::{
74    LLVMAtomicOrdering, LLVMAtomicRMWBinOp, LLVMDLLStorageClass, LLVMIntPredicate, LLVMRealPredicate,
75    LLVMThreadLocalMode, LLVMVisibility,
76};
77
78#[llvm_versions(7.0..=latest)]
79use llvm_sys::LLVMInlineAsmDialect;
80
81use std::convert::TryFrom;
82
83// Thanks to kennytm for coming up with assert_unique_features!
84// which ensures that the LLVM feature flags are mutually exclusive
85macro_rules! assert_unique_features {
86    () => {};
87    ($first:tt $(,$rest:tt)*) => {
88        $(
89            #[cfg(all(feature = $first, feature = $rest))]
90            compile_error!(concat!("features \"", $first, "\" and \"", $rest, "\" cannot be used together"));
91        )*
92        assert_unique_features!($($rest),*);
93    }
94}
95
96// This macro ensures that at least one of the LLVM feature
97// flags are provided and prints them out if none are provided
98macro_rules! assert_used_features {
99    ($($all:tt),*) => {
100        #[cfg(not(any($(feature = $all),*)))]
101        compile_error!(concat!("One of the LLVM feature flags must be provided: ", $($all, " "),*));
102    }
103}
104
105macro_rules! assert_unique_used_features {
106    ($($all:tt),*) => {
107        assert_unique_features!($($all),*);
108        assert_used_features!($($all),*);
109    }
110}
111
112assert_unique_used_features! {"llvm4-0", "llvm5-0", "llvm6-0", "llvm7-0", "llvm8-0", "llvm9-0", "llvm10-0", "llvm11-0", "llvm12-0", "llvm13-0", "llvm14-0", "llvm15-0", "llvm16-0"}
113
114/// Defines the address space in which a global will be inserted.
115///
116/// The default address space is zero. An address space can always be created from a `u16`:
117/// ```no_run
118/// inkwell::AddressSpace::from(1u16);
119/// ```
120///
121/// An Address space is a 24-bit number. To convert from a u32, use the `TryFrom` instance
122///
123/// ```no_run
124/// inkwell::AddressSpace::try_from(42u32).expect("fits in 24-bit unsigned int");
125/// ```
126///
127/// # Remarks
128/// See also: https://llvm.org/doxygen/NVPTXBaseInfo_8h_source.html
129#[derive(Debug, PartialEq, Eq, Copy, Clone)]
130pub struct AddressSpace(u32);
131
132impl Default for AddressSpace {
133    fn default() -> Self {
134        AddressSpace(0)
135    }
136}
137
138impl From<u16> for AddressSpace {
139    fn from(val: u16) -> Self {
140        AddressSpace(val as u32)
141    }
142}
143
144impl TryFrom<u32> for AddressSpace {
145    type Error = ();
146
147    fn try_from(val: u32) -> Result<Self, Self::Error> {
148        // address space is a 24-bit integer
149        if val < 1 << 24 {
150            Ok(AddressSpace(val))
151        } else {
152            Err(())
153        }
154    }
155}
156
157// REVIEW: Maybe this belongs in some sort of prelude?
158/// This enum defines how to compare a `left` and `right` `IntValue`.
159#[llvm_enum(LLVMIntPredicate)]
160#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
161pub enum IntPredicate {
162    /// Equal
163    #[llvm_variant(LLVMIntEQ)]
164    EQ,
165
166    /// Not Equal
167    #[llvm_variant(LLVMIntNE)]
168    NE,
169
170    /// Unsigned Greater Than
171    #[llvm_variant(LLVMIntUGT)]
172    UGT,
173
174    /// Unsigned Greater Than or Equal
175    #[llvm_variant(LLVMIntUGE)]
176    UGE,
177
178    /// Unsigned Less Than
179    #[llvm_variant(LLVMIntULT)]
180    ULT,
181
182    /// Unsigned Less Than or Equal
183    #[llvm_variant(LLVMIntULE)]
184    ULE,
185
186    /// Signed Greater Than
187    #[llvm_variant(LLVMIntSGT)]
188    SGT,
189
190    /// Signed Greater Than or Equal
191    #[llvm_variant(LLVMIntSGE)]
192    SGE,
193
194    /// Signed Less Than
195    #[llvm_variant(LLVMIntSLT)]
196    SLT,
197
198    /// Signed Less Than or Equal
199    #[llvm_variant(LLVMIntSLE)]
200    SLE,
201}
202
203// REVIEW: Maybe this belongs in some sort of prelude?
204/// Defines how to compare a `left` and `right` `FloatValue`.
205#[llvm_enum(LLVMRealPredicate)]
206#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
207pub enum FloatPredicate {
208    /// Returns true if `left` == `right` and neither are NaN
209    #[llvm_variant(LLVMRealOEQ)]
210    OEQ,
211
212    /// Returns true if `left` >= `right` and neither are NaN
213    #[llvm_variant(LLVMRealOGE)]
214    OGE,
215
216    /// Returns true if `left` > `right` and neither are NaN
217    #[llvm_variant(LLVMRealOGT)]
218    OGT,
219
220    /// Returns true if `left` <= `right` and neither are NaN
221    #[llvm_variant(LLVMRealOLE)]
222    OLE,
223
224    /// Returns true if `left` < `right` and neither are NaN
225    #[llvm_variant(LLVMRealOLT)]
226    OLT,
227
228    /// Returns true if `left` != `right` and neither are NaN
229    #[llvm_variant(LLVMRealONE)]
230    ONE,
231
232    /// Returns true if neither value is NaN
233    #[llvm_variant(LLVMRealORD)]
234    ORD,
235
236    /// Always returns false
237    #[llvm_variant(LLVMRealPredicateFalse)]
238    PredicateFalse,
239
240    /// Always returns true
241    #[llvm_variant(LLVMRealPredicateTrue)]
242    PredicateTrue,
243
244    /// Returns true if `left` == `right` or either is NaN
245    #[llvm_variant(LLVMRealUEQ)]
246    UEQ,
247
248    /// Returns true if `left` >= `right` or either is NaN
249    #[llvm_variant(LLVMRealUGE)]
250    UGE,
251
252    /// Returns true if `left` > `right` or either is NaN
253    #[llvm_variant(LLVMRealUGT)]
254    UGT,
255
256    /// Returns true if `left` <= `right` or either is NaN
257    #[llvm_variant(LLVMRealULE)]
258    ULE,
259
260    /// Returns true if `left` < `right` or either is NaN
261    #[llvm_variant(LLVMRealULT)]
262    ULT,
263
264    /// Returns true if `left` != `right` or either is NaN
265    #[llvm_variant(LLVMRealUNE)]
266    UNE,
267
268    /// Returns true if either value is NaN
269    #[llvm_variant(LLVMRealUNO)]
270    UNO,
271}
272
273// REVIEW: Maybe this belongs in some sort of prelude?
274#[llvm_enum(LLVMAtomicOrdering)]
275#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
276pub enum AtomicOrdering {
277    #[llvm_variant(LLVMAtomicOrderingNotAtomic)]
278    NotAtomic,
279    #[llvm_variant(LLVMAtomicOrderingUnordered)]
280    Unordered,
281    #[llvm_variant(LLVMAtomicOrderingMonotonic)]
282    Monotonic,
283    #[llvm_variant(LLVMAtomicOrderingAcquire)]
284    Acquire,
285    #[llvm_variant(LLVMAtomicOrderingRelease)]
286    Release,
287    #[llvm_variant(LLVMAtomicOrderingAcquireRelease)]
288    AcquireRelease,
289    #[llvm_variant(LLVMAtomicOrderingSequentiallyConsistent)]
290    SequentiallyConsistent,
291}
292
293#[llvm_enum(LLVMAtomicRMWBinOp)]
294#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
295pub enum AtomicRMWBinOp {
296    /// Stores to memory and returns the prior value.
297    #[llvm_variant(LLVMAtomicRMWBinOpXchg)]
298    Xchg,
299
300    /// Adds to the value in memory and returns the prior value.
301    #[llvm_variant(LLVMAtomicRMWBinOpAdd)]
302    Add,
303
304    /// Subtract a value off the value in memory and returns the prior value.
305    #[llvm_variant(LLVMAtomicRMWBinOpSub)]
306    Sub,
307
308    /// Bitwise and into memory and returns the prior value.
309    #[llvm_variant(LLVMAtomicRMWBinOpAnd)]
310    And,
311
312    /// Bitwise nands into memory and returns the prior value.
313    #[llvm_variant(LLVMAtomicRMWBinOpNand)]
314    Nand,
315
316    /// Bitwise ors into memory and returns the prior value.
317    #[llvm_variant(LLVMAtomicRMWBinOpOr)]
318    Or,
319
320    /// Bitwise xors into memory and returns the prior value.
321    #[llvm_variant(LLVMAtomicRMWBinOpXor)]
322    Xor,
323
324    /// Sets memory to the signed-greater of the value provided and the value in memory. Returns the value that was in memory.
325    #[llvm_variant(LLVMAtomicRMWBinOpMax)]
326    Max,
327
328    /// Sets memory to the signed-lesser of the value provided and the value in memory. Returns the value that was in memory.
329    #[llvm_variant(LLVMAtomicRMWBinOpMin)]
330    Min,
331
332    /// Sets memory to the unsigned-greater of the value provided and the value in memory. Returns the value that was in memory.
333    #[llvm_variant(LLVMAtomicRMWBinOpUMax)]
334    UMax,
335
336    /// Sets memory to the unsigned-lesser of the value provided and the value in memory. Returns the value that was in memory.
337    #[llvm_variant(LLVMAtomicRMWBinOpUMin)]
338    UMin,
339
340    /// Adds to the float-typed value in memory and returns the prior value.
341    // Although this was added in LLVM 9, it wasn't exposed to the C API
342    // until 10.0.
343    #[llvm_versions(10.0..=latest)]
344    #[llvm_variant(LLVMAtomicRMWBinOpFAdd)]
345    FAdd,
346
347    /// Subtract a float-typed value off the value in memory and returns the prior value.
348    // Although this was added in LLVM 9, it wasn't exposed to the C API
349    // until 10.0.
350    #[llvm_versions(10.0..=latest)]
351    #[llvm_variant(LLVMAtomicRMWBinOpFSub)]
352    FSub,
353
354    /// Sets memory to the greater of the two float-typed values, one provided and one from memory. Returns the value that was in memory.
355    #[llvm_versions(15.0..=latest)]
356    #[llvm_variant(LLVMAtomicRMWBinOpFMax)]
357    FMax,
358
359    /// Sets memory to the lesser of the two float-typed values, one provided and one from memory. Returns the value that was in memory.
360    #[llvm_versions(15.0..=latest)]
361    #[llvm_variant(LLVMAtomicRMWBinOpFMin)]
362    FMin,
363}
364
365/// Defines the optimization level used to compile a `Module`.
366///
367/// # Remarks
368/// See also: https://llvm.org/doxygen/CodeGen_8h_source.html
369#[repr(u32)]
370#[derive(Debug, PartialEq, Eq, Copy, Clone)]
371pub enum OptimizationLevel {
372    None = 0,
373    Less = 1,
374    Default = 2,
375    Aggressive = 3,
376}
377
378impl Default for OptimizationLevel {
379    /// Returns the default value for `OptimizationLevel`, namely `OptimizationLevel::Default`.
380    fn default() -> Self {
381        OptimizationLevel::Default
382    }
383}
384
385#[llvm_enum(LLVMVisibility)]
386#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
387pub enum GlobalVisibility {
388    #[llvm_variant(LLVMDefaultVisibility)]
389    Default,
390    #[llvm_variant(LLVMHiddenVisibility)]
391    Hidden,
392    #[llvm_variant(LLVMProtectedVisibility)]
393    Protected,
394}
395
396impl Default for GlobalVisibility {
397    /// Returns the default value for `GlobalVisibility`, namely `GlobalVisibility::Default`.
398    fn default() -> Self {
399        GlobalVisibility::Default
400    }
401}
402
403#[derive(Clone, Copy, Debug, Eq, PartialEq)]
404pub enum ThreadLocalMode {
405    GeneralDynamicTLSModel,
406    LocalDynamicTLSModel,
407    InitialExecTLSModel,
408    LocalExecTLSModel,
409}
410
411impl ThreadLocalMode {
412    pub(crate) fn new(thread_local_mode: LLVMThreadLocalMode) -> Option<Self> {
413        match thread_local_mode {
414            LLVMThreadLocalMode::LLVMGeneralDynamicTLSModel => Some(ThreadLocalMode::GeneralDynamicTLSModel),
415            LLVMThreadLocalMode::LLVMLocalDynamicTLSModel => Some(ThreadLocalMode::LocalDynamicTLSModel),
416            LLVMThreadLocalMode::LLVMInitialExecTLSModel => Some(ThreadLocalMode::InitialExecTLSModel),
417            LLVMThreadLocalMode::LLVMLocalExecTLSModel => Some(ThreadLocalMode::LocalExecTLSModel),
418            LLVMThreadLocalMode::LLVMNotThreadLocal => None,
419        }
420    }
421
422    pub(crate) fn as_llvm_mode(self) -> LLVMThreadLocalMode {
423        match self {
424            ThreadLocalMode::GeneralDynamicTLSModel => LLVMThreadLocalMode::LLVMGeneralDynamicTLSModel,
425            ThreadLocalMode::LocalDynamicTLSModel => LLVMThreadLocalMode::LLVMLocalDynamicTLSModel,
426            ThreadLocalMode::InitialExecTLSModel => LLVMThreadLocalMode::LLVMInitialExecTLSModel,
427            ThreadLocalMode::LocalExecTLSModel => LLVMThreadLocalMode::LLVMLocalExecTLSModel,
428            // None => LLVMThreadLocalMode::LLVMNotThreadLocal,
429        }
430    }
431}
432
433#[llvm_enum(LLVMDLLStorageClass)]
434#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
435pub enum DLLStorageClass {
436    #[llvm_variant(LLVMDefaultStorageClass)]
437    Default,
438    #[llvm_variant(LLVMDLLImportStorageClass)]
439    Import,
440    #[llvm_variant(LLVMDLLExportStorageClass)]
441    Export,
442}
443
444impl Default for DLLStorageClass {
445    /// Returns the default value for `DLLStorageClass`, namely `DLLStorageClass::Default`.
446    fn default() -> Self {
447        DLLStorageClass::Default
448    }
449}
450
451#[llvm_versions(7.0..=latest)]
452#[llvm_enum(LLVMInlineAsmDialect)]
453#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
454pub enum InlineAsmDialect {
455    #[llvm_variant(LLVMInlineAsmDialectATT)]
456    ATT,
457    #[llvm_variant(LLVMInlineAsmDialectIntel)]
458    Intel,
459}