Skip to main content

inkwell/
module.rs

1//! A `Module` represents a single code compilation unit.
2
3use llvm_sys::analysis::{LLVMVerifierFailureAction, LLVMVerifyModule};
4#[allow(deprecated)]
5use llvm_sys::bit_reader::LLVMParseBitcodeInContext;
6use llvm_sys::bit_writer::{LLVMWriteBitcodeToFile, LLVMWriteBitcodeToMemoryBuffer};
7#[cfg(feature = "llvm11-0")]
8use llvm_sys::core::LLVMGetTypeByName;
9use llvm_sys::core::{
10    LLVMAddFunction, LLVMAddGlobal, LLVMAddGlobalInAddressSpace, LLVMAddNamedMetadataOperand, LLVMCloneModule,
11    LLVMDisposeMessage, LLVMDisposeModule, LLVMDumpModule, LLVMGetFirstFunction, LLVMGetFirstGlobal,
12    LLVMGetLastFunction, LLVMGetLastGlobal, LLVMGetModuleContext, LLVMGetModuleIdentifier, LLVMGetNamedFunction,
13    LLVMGetNamedGlobal, LLVMGetNamedMetadataNumOperands, LLVMGetNamedMetadataOperands, LLVMGetTarget,
14    LLVMPrintModuleToFile, LLVMPrintModuleToString, LLVMSetDataLayout, LLVMSetModuleIdentifier,
15    LLVMSetModuleInlineAsm2, LLVMSetTarget,
16};
17use llvm_sys::core::{LLVMAddModuleFlag, LLVMGetModuleFlag};
18use llvm_sys::debuginfo::{LLVMGetModuleDebugMetadataVersion, LLVMStripModuleDebugInfo};
19#[llvm_versions(13..)]
20use llvm_sys::error::LLVMGetErrorMessage;
21use llvm_sys::execution_engine::{
22    LLVMCreateExecutionEngineForModule, LLVMCreateInterpreterForModule, LLVMCreateJITCompilerForModule,
23    LLVMCreateSimpleMCJITMemoryManager,
24};
25use llvm_sys::prelude::{LLVMModuleRef, LLVMValueRef};
26#[llvm_versions(13..)]
27use llvm_sys::transforms::pass_builder::LLVMRunPasses;
28use llvm_sys::LLVMLinkage;
29
30use llvm_sys::LLVMModuleFlagBehavior;
31
32use std::cell::{Cell, Ref, RefCell};
33use std::ffi::{c_void, CStr};
34use std::fs::File;
35use std::marker::PhantomData;
36use std::mem::{forget, MaybeUninit};
37use std::path::Path;
38use std::ptr;
39use std::rc::Rc;
40
41use crate::comdat::Comdat;
42use crate::context::{AsContextRef, Context, ContextRef};
43use crate::data_layout::DataLayout;
44
45use crate::debug_info::{DICompileUnit, DWARFEmissionKind, DWARFSourceLanguage, DebugInfoBuilder};
46use crate::execution_engine::ExecutionEngine;
47use crate::memory_buffer::MemoryBuffer;
48use crate::memory_manager::{
49    allocate_code_section_adapter, allocate_data_section_adapter, destroy_adapter, finalize_memory_adapter,
50    McjitMemoryManager, MemoryManagerAdapter,
51};
52#[llvm_versions(13..)]
53use crate::passes::PassBuilderOptions;
54use crate::support::{to_c_str, LLVMString};
55#[llvm_versions(13..)]
56use crate::targets::TargetMachine;
57use crate::targets::{CodeModel, InitializationConfig, Target, TargetTriple};
58use crate::types::{AsTypeRef, BasicType, FunctionType, StructType};
59
60use crate::values::BasicValue;
61use crate::values::{AsValueRef, FunctionValue, GlobalValue, MetadataValue};
62use crate::{AddressSpace, OptimizationLevel};
63
64#[llvm_enum(LLVMLinkage)]
65#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
66/// This enum defines how to link a global variable or function in a module. The variant documentation is
67/// mostly taken straight from LLVM's own documentation except for some minor clarification.
68///
69/// It is illegal for a function declaration to have any linkage type other than external or extern_weak.
70///
71/// All Global Variables, Functions and Aliases can have one of the following DLL storage class: `DLLImport`
72/// & `DLLExport`.
73// REVIEW: Maybe this should go into it's own module?
74pub enum Linkage {
75    /// `Appending` linkage may only be applied to global variables of pointer to array type. When two global
76    /// variables with appending linkage are linked together, the two global arrays are appended together.
77    /// This is the LLVM, typesafe, equivalent of having the system linker append together "sections" with
78    /// identical names when .o files are linked. Unfortunately this doesn't correspond to any feature in .o
79    /// files, so it can only be used for variables like llvm.global_ctors which llvm interprets specially.
80    #[llvm_variant(LLVMAppendingLinkage)]
81    Appending,
82    /// Globals with `AvailableExternally` linkage are never emitted into the object file corresponding to
83    /// the LLVM module. From the linker's perspective, an `AvailableExternally` global is equivalent to an
84    /// external declaration. They exist to allow inlining and other optimizations to take place given
85    /// knowledge of the definition of the global, which is known to be somewhere outside the module. Globals
86    /// with `AvailableExternally` linkage are allowed to be discarded at will, and allow inlining and other
87    /// optimizations. This linkage type is only allowed on definitions, not declarations.
88    #[llvm_variant(LLVMAvailableExternallyLinkage)]
89    AvailableExternally,
90    /// `Common` linkage is most similar to "weak" linkage, but they are used for tentative definitions
91    /// in C, such as "int X;" at global scope. Symbols with Common linkage are merged in the same way as
92    /// weak symbols, and they may not be deleted if unreferenced. `Common` symbols may not have an explicit
93    /// section, must have a zero initializer, and may not be marked 'constant'. Functions and aliases may
94    /// not have `Common` linkage.
95    #[llvm_variant(LLVMCommonLinkage)]
96    Common,
97    /// `DLLExport` causes the compiler to provide a global pointer to a pointer in a DLL, so that it can be
98    /// referenced with the dllimport attribute. On Microsoft Windows targets, the pointer name is formed by
99    /// combining __imp_ and the function or variable name. Since this storage class exists for defining a dll
100    /// interface, the compiler, assembler and linker know it is externally referenced and must refrain from
101    /// deleting the symbol.
102    #[llvm_variant(LLVMDLLExportLinkage)]
103    DLLExport,
104    /// `DLLImport` causes the compiler to reference a function or variable via a global pointer to a pointer
105    /// that is set up by the DLL exporting the symbol. On Microsoft Windows targets, the pointer name is
106    /// formed by combining __imp_ and the function or variable name.
107    #[llvm_variant(LLVMDLLImportLinkage)]
108    DLLImport,
109    /// If none of the other identifiers are used, the global is externally visible, meaning that it
110    /// participates in linkage and can be used to resolve external symbol references.
111    #[llvm_variant(LLVMExternalLinkage)]
112    External,
113    /// The semantics of this linkage follow the ELF object file model: the symbol is weak until linked,
114    /// if not linked, the symbol becomes null instead of being an undefined reference.
115    #[llvm_variant(LLVMExternalWeakLinkage)]
116    ExternalWeak,
117    /// FIXME: Unknown linkage type
118    #[llvm_variant(LLVMGhostLinkage)]
119    Ghost,
120    /// Similar to private, but the value shows as a local symbol (STB_LOCAL in the case of ELF) in the object
121    /// file. This corresponds to the notion of the 'static' keyword in C.
122    #[llvm_variant(LLVMInternalLinkage)]
123    Internal,
124    /// FIXME: Unknown linkage type
125    #[llvm_variant(LLVMLinkerPrivateLinkage)]
126    LinkerPrivate,
127    /// FIXME: Unknown linkage type
128    #[llvm_variant(LLVMLinkerPrivateWeakLinkage)]
129    LinkerPrivateWeak,
130    /// Globals with `LinkOnceAny` linkage are merged with other globals of the same name when linkage occurs.
131    /// This can be used to implement some forms of inline functions, templates, or other code which must be
132    /// generated in each translation unit that uses it, but where the body may be overridden with a more
133    /// definitive definition later. Unreferenced `LinkOnceAny` globals are allowed to be discarded. Note that
134    /// `LinkOnceAny` linkage does not actually allow the optimizer to inline the body of this function into
135    /// callers because it doesn’t know if this definition of the function is the definitive definition within
136    /// the program or whether it will be overridden by a stronger definition. To enable inlining and other
137    /// optimizations, use `LinkOnceODR` linkage.
138    #[llvm_variant(LLVMLinkOnceAnyLinkage)]
139    LinkOnceAny,
140    /// FIXME: Unknown linkage type
141    #[llvm_variant(LLVMLinkOnceODRAutoHideLinkage)]
142    LinkOnceODRAutoHide,
143    /// Some languages allow differing globals to be merged, such as two functions with different semantics.
144    /// Other languages, such as C++, ensure that only equivalent globals are ever merged (the "one definition
145    /// rule" — "ODR"). Such languages can use the `LinkOnceODR` and `WeakODR` linkage types to indicate that
146    /// the global will only be merged with equivalent globals. These linkage types are otherwise the same
147    /// as their non-odr versions.
148    #[llvm_variant(LLVMLinkOnceODRLinkage)]
149    LinkOnceODR,
150    /// Global values with `Private` linkage are only directly accessible by objects in the current module.
151    /// In particular, linking code into a module with a private global value may cause the private to be
152    /// renamed as necessary to avoid collisions. Because the symbol is private to the module, all references
153    /// can be updated. This doesn’t show up in any symbol table in the object file.
154    #[llvm_variant(LLVMPrivateLinkage)]
155    Private,
156    /// `WeakAny` linkage has the same merging semantics as linkonce linkage, except that unreferenced globals
157    /// with weak linkage may not be discarded. This is used for globals that are declared WeakAny in C source code.
158    #[llvm_variant(LLVMWeakAnyLinkage)]
159    WeakAny,
160    /// Some languages allow differing globals to be merged, such as two functions with different semantics.
161    /// Other languages, such as C++, ensure that only equivalent globals are ever merged (the "one definition
162    /// rule" — "ODR"). Such languages can use the `LinkOnceODR` and `WeakODR` linkage types to indicate that
163    /// the global will only be merged with equivalent globals. These linkage types are otherwise the same
164    /// as their non-odr versions.
165    #[llvm_variant(LLVMWeakODRLinkage)]
166    WeakODR,
167}
168
169/// Represents a reference to an LLVM `Module`.
170/// The underlying module will be disposed when dropping this object.
171#[derive(Debug, PartialEq, Eq)]
172pub struct Module<'ctx> {
173    data_layout: RefCell<Option<DataLayout>>,
174    pub(crate) module: Cell<LLVMModuleRef>,
175    pub(crate) owned_by_ee: RefCell<Option<ExecutionEngine<'ctx>>>,
176    _marker: PhantomData<&'ctx Context>,
177}
178
179impl<'ctx> Module<'ctx> {
180    /// Get a module from an [LLVMModuleRef].
181    ///
182    /// # Safety
183    ///
184    /// The ref must be valid.
185    pub unsafe fn new(module: LLVMModuleRef) -> Self {
186        debug_assert!(!module.is_null());
187
188        Module {
189            module: Cell::new(module),
190            owned_by_ee: RefCell::new(None),
191            data_layout: RefCell::new(Some(Module::get_borrowed_data_layout(module))),
192            _marker: PhantomData,
193        }
194    }
195
196    /// Acquires the underlying raw pointer belonging to this `Module` type.
197    pub fn as_mut_ptr(&self) -> LLVMModuleRef {
198        self.module.get()
199    }
200
201    /// Creates a function given its `name` and `ty`, adds it to the `Module`
202    /// and returns it.
203    ///
204    /// An optional `linkage` can be specified, without which the default value
205    /// `Linkage::ExternalLinkage` will be used.
206    ///
207    /// # Example
208    /// ```no_run
209    /// use inkwell::context::Context;
210    /// use inkwell::module::{Module, Linkage};
211    /// use inkwell::types::FunctionType;
212    ///
213    /// let context = Context::create();
214    /// let module = context.create_module("my_module");
215    ///
216    /// let fn_type = context.f32_type().fn_type(&[], false);
217    /// let fn_val = module.add_function("my_function", fn_type, None);
218    ///
219    /// assert_eq!(fn_val.get_name().to_str(), Ok("my_function"));
220    /// assert_eq!(fn_val.get_linkage(), Linkage::External);
221    /// ```
222    pub fn add_function(&self, name: &str, ty: FunctionType<'ctx>, linkage: Option<Linkage>) -> FunctionValue<'ctx> {
223        let c_string = to_c_str(name);
224        let fn_value = unsafe {
225            FunctionValue::new(LLVMAddFunction(self.module.get(), c_string.as_ptr(), ty.as_type_ref()))
226                .expect("add_function should always succeed in adding a new function")
227        };
228
229        if let Some(linkage) = linkage {
230            fn_value.set_linkage(linkage)
231        }
232
233        fn_value
234    }
235
236    /// Gets the `Context` from which this `Module` originates.
237    ///
238    /// # Example
239    /// ```no_run
240    /// use inkwell::context::{Context, ContextRef};
241    /// use inkwell::module::Module;
242    ///
243    /// let local_context = Context::create();
244    /// let local_module = local_context.create_module("my_module");
245    ///
246    /// assert_eq!(local_module.get_context(), local_context);
247    /// ```
248    pub fn get_context(&self) -> ContextRef<'ctx> {
249        unsafe { ContextRef::new(LLVMGetModuleContext(self.module.get())) }
250    }
251
252    /// Gets the first `FunctionValue` defined in this `Module`.
253    ///
254    /// # Example
255    /// ```rust,no_run
256    /// use inkwell::context::Context;
257    /// use inkwell::module::Module;
258    ///
259    /// let context = Context::create();
260    /// let module = context.create_module("my_mod");
261    ///
262    /// assert!(module.get_first_function().is_none());
263    ///
264    /// let void_type = context.void_type();
265    /// let fn_type = void_type.fn_type(&[], false);
266    /// let fn_value = module.add_function("my_fn", fn_type, None);
267    ///
268    /// assert_eq!(fn_value, module.get_first_function().unwrap());
269    /// ```
270    pub fn get_first_function(&self) -> Option<FunctionValue<'ctx>> {
271        unsafe { FunctionValue::new(LLVMGetFirstFunction(self.module.get())) }
272    }
273
274    /// Gets the last `FunctionValue` defined in this `Module`.
275    ///
276    /// # Example
277    /// ```rust,no_run
278    /// use inkwell::context::Context;
279    /// use inkwell::module::Module;
280    ///
281    /// let context = Context::create();
282    /// let module = context.create_module("my_mod");
283    ///
284    /// assert!(module.get_last_function().is_none());
285    ///
286    /// let void_type = context.void_type();
287    /// let fn_type = void_type.fn_type(&[], false);
288    /// let fn_value = module.add_function("my_fn", fn_type, None);
289    ///
290    /// assert_eq!(fn_value, module.get_last_function().unwrap());
291    /// ```
292    pub fn get_last_function(&self) -> Option<FunctionValue<'ctx>> {
293        unsafe { FunctionValue::new(LLVMGetLastFunction(self.module.get())) }
294    }
295
296    /// Gets a `FunctionValue` defined in this `Module` by its name.
297    ///
298    /// # Example
299    /// ```rust,no_run
300    /// use inkwell::context::Context;
301    /// use inkwell::module::Module;
302    ///
303    /// let context = Context::create();
304    /// let module = context.create_module("my_mod");
305    ///
306    /// assert!(module.get_function("my_fn").is_none());
307    ///
308    /// let void_type = context.void_type();
309    /// let fn_type = void_type.fn_type(&[], false);
310    /// let fn_value = module.add_function("my_fn", fn_type, None);
311    ///
312    /// assert_eq!(fn_value, module.get_function("my_fn").unwrap());
313    /// ```
314    pub fn get_function(&self, name: &str) -> Option<FunctionValue<'ctx>> {
315        let c_string = to_c_str(name);
316
317        unsafe { FunctionValue::new(LLVMGetNamedFunction(self.module.get(), c_string.as_ptr())) }
318    }
319
320    /// An iterator over the functions in this `Module`.
321    ///
322    /// ```
323    /// use inkwell::context::Context;
324    /// use inkwell::module::Module;
325    ///
326    /// let context = Context::create();
327    /// let module = context.create_module("my_mod");
328    ///
329    /// assert!(module.get_function("my_fn").is_none());
330    ///
331    /// let void_type = context.void_type();
332    /// let fn_type = void_type.fn_type(&[], false);
333    /// let fn_value = module.add_function("my_fn", fn_type, None);
334    ///
335    /// let names: Vec<String> = module
336    ///     .get_functions()
337    ///     .map(|f| f.get_name().to_string_lossy().to_string())
338    ///     .collect();
339    ///
340    /// assert_eq!(vec!["my_fn".to_owned()], names);
341    /// ```
342    pub fn get_functions(&self) -> FunctionIterator<'ctx> {
343        FunctionIterator::from_module(self)
344    }
345
346    /// Gets a named `StructType` from this `Module`'s `Context`.
347    ///
348    /// # Example
349    ///
350    /// ```rust,no_run
351    /// use inkwell::context::Context;
352    ///
353    /// let context = Context::create();
354    /// let module = context.create_module("my_module");
355    ///
356    /// assert!(module.get_struct_type("foo").is_none());
357    ///
358    /// let opaque = context.opaque_struct_type("foo");
359    ///
360    /// assert_eq!(module.get_struct_type("foo").unwrap(), opaque);
361    /// ```
362    ///
363    #[cfg(feature = "llvm11-0")]
364    pub fn get_struct_type(&self, name: &str) -> Option<StructType<'ctx>> {
365        let c_string = to_c_str(name);
366
367        let struct_type = unsafe { LLVMGetTypeByName(self.module.get(), c_string.as_ptr()) };
368
369        if struct_type.is_null() {
370            return None;
371        }
372
373        unsafe { Some(StructType::new(struct_type)) }
374    }
375
376    /// Gets a named `StructType` from this `Module`'s `Context`.
377    ///
378    /// # Example
379    ///
380    /// ```rust,no_run
381    /// use inkwell::context::Context;
382    ///
383    /// let context = Context::create();
384    /// let module = context.create_module("my_module");
385    ///
386    /// assert!(module.get_struct_type("foo").is_none());
387    ///
388    /// let opaque = context.opaque_struct_type("foo");
389    ///
390    /// assert_eq!(module.get_struct_type("foo").unwrap(), opaque);
391    /// ```
392    #[llvm_versions(12..)]
393    pub fn get_struct_type(&self, name: &str) -> Option<StructType<'ctx>> {
394        self.get_context().get_struct_type(name)
395    }
396
397    /// Assigns a `TargetTriple` to this `Module`.
398    ///
399    /// # Example
400    ///
401    /// ```rust,no_run
402    /// use inkwell::context::Context;
403    /// use inkwell::targets::{Target, TargetTriple};
404    ///
405    /// Target::initialize_x86(&Default::default());
406    /// let context = Context::create();
407    /// let module = context.create_module("mod");
408    /// let triple = TargetTriple::create("x86_64-pc-linux-gnu");
409    ///
410    /// assert_eq!(module.get_triple(), TargetTriple::create(""));
411    ///
412    /// module.set_triple(&triple);
413    ///
414    /// assert_eq!(module.get_triple(), triple);
415    /// ```
416    pub fn set_triple(&self, triple: &TargetTriple) {
417        unsafe { LLVMSetTarget(self.module.get(), triple.as_ptr()) }
418    }
419
420    /// Gets the `TargetTriple` assigned to this `Module`. If none has been
421    /// assigned, the triple will default to "".
422    ///
423    /// # Example
424    ///
425    /// ```rust,no_run
426    /// use inkwell::context::Context;
427    /// use inkwell::targets::{Target, TargetTriple};
428    ///
429    /// Target::initialize_x86(&Default::default());
430    /// let context = Context::create();
431    /// let module = context.create_module("mod");
432    /// let triple = TargetTriple::create("x86_64-pc-linux-gnu");
433    ///
434    /// assert_eq!(module.get_triple(), TargetTriple::create(""));
435    ///
436    /// module.set_triple(&triple);
437    ///
438    /// assert_eq!(module.get_triple(), triple);
439    /// ```
440    pub fn get_triple(&self) -> TargetTriple {
441        // REVIEW: This isn't an owned LLVMString, is it? If so, need to deallocate.
442        let target_str = unsafe { LLVMGetTarget(self.module.get()) };
443
444        unsafe { TargetTriple::new(LLVMString::create_from_c_str(CStr::from_ptr(target_str))) }
445    }
446
447    /// Creates an `ExecutionEngine` from this `Module`.
448    ///
449    /// # Example
450    /// ```no_run
451    /// use inkwell::context::Context;
452    /// use inkwell::module::Module;
453    /// use inkwell::targets::{InitializationConfig, Target};
454    ///
455    /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
456    ///
457    /// let context = Context::create();
458    /// let module = context.create_module("my_module");
459    /// let execution_engine = module.create_execution_engine().unwrap();
460    ///
461    /// assert_eq!(module.get_context(), context);
462    /// ```
463    // SubType: ExecutionEngine<Basic?>
464    pub fn create_execution_engine(&self) -> Result<ExecutionEngine<'ctx>, LLVMString> {
465        Target::initialize_native(&InitializationConfig::default()).map_err(|mut err_string| {
466            err_string.push('\0');
467
468            LLVMString::create_from_str(&err_string)
469        })?;
470
471        if self.owned_by_ee.borrow().is_some() {
472            let string = "This module is already owned by an ExecutionEngine.\0";
473            return Err(LLVMString::create_from_str(string));
474        }
475
476        let mut execution_engine = MaybeUninit::uninit();
477        let mut err_string = MaybeUninit::uninit();
478        let code = unsafe {
479            // Takes ownership of module
480            LLVMCreateExecutionEngineForModule(
481                execution_engine.as_mut_ptr(),
482                self.module.get(),
483                err_string.as_mut_ptr(),
484            )
485        };
486
487        if code == 1 {
488            unsafe {
489                return Err(LLVMString::new(err_string.assume_init()));
490            }
491        }
492
493        let execution_engine = unsafe { execution_engine.assume_init() };
494        let execution_engine = unsafe { ExecutionEngine::new(Rc::new(execution_engine), false) };
495
496        *self.owned_by_ee.borrow_mut() = Some(execution_engine.clone());
497
498        Ok(execution_engine)
499    }
500
501    /// Creates an interpreter `ExecutionEngine` from this `Module`.
502    ///
503    /// # Example
504    /// ```no_run
505    /// use inkwell::context::Context;
506    /// use inkwell::module::Module;
507    /// use inkwell::targets::{InitializationConfig, Target};
508    ///
509    /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
510    ///
511    /// let context = Context::create();
512    /// let module = context.create_module("my_module");
513    /// let execution_engine = module.create_interpreter_execution_engine().unwrap();
514    ///
515    /// assert_eq!(module.get_context(), context);
516    /// ```
517    // SubType: ExecutionEngine<Interpreter>
518    pub fn create_interpreter_execution_engine(&self) -> Result<ExecutionEngine<'ctx>, LLVMString> {
519        Target::initialize_native(&InitializationConfig::default()).map_err(|mut err_string| {
520            err_string.push('\0');
521
522            LLVMString::create_from_str(&err_string)
523        })?;
524
525        if self.owned_by_ee.borrow().is_some() {
526            let string = "This module is already owned by an ExecutionEngine.\0";
527            return Err(LLVMString::create_from_str(string));
528        }
529
530        let mut execution_engine = MaybeUninit::uninit();
531        let mut err_string = MaybeUninit::uninit();
532
533        let code = unsafe {
534            // Takes ownership of module
535            LLVMCreateInterpreterForModule(
536                execution_engine.as_mut_ptr(),
537                self.module.get(),
538                err_string.as_mut_ptr(),
539            )
540        };
541
542        if code == 1 {
543            unsafe {
544                return Err(LLVMString::new(err_string.assume_init()));
545            }
546        }
547
548        let execution_engine = unsafe { execution_engine.assume_init() };
549        let execution_engine = unsafe { ExecutionEngine::new(Rc::new(execution_engine), false) };
550
551        *self.owned_by_ee.borrow_mut() = Some(execution_engine.clone());
552
553        Ok(execution_engine)
554    }
555
556    /// Creates a JIT `ExecutionEngine` from this `Module`.
557    ///
558    /// # Example
559    /// ```no_run
560    /// use inkwell::OptimizationLevel;
561    /// use inkwell::context::Context;
562    /// use inkwell::module::Module;
563    /// use inkwell::targets::{InitializationConfig, Target};
564    ///
565    /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
566    ///
567    /// let context = Context::create();
568    /// let module = context.create_module("my_module");
569    /// let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
570    ///
571    /// assert_eq!(module.get_context(), context);
572    /// ```
573    // SubType: ExecutionEngine<Jit>
574    pub fn create_jit_execution_engine(
575        &self,
576        opt_level: OptimizationLevel,
577    ) -> Result<ExecutionEngine<'ctx>, LLVMString> {
578        Target::initialize_native(&InitializationConfig::default()).map_err(|mut err_string| {
579            err_string.push('\0');
580
581            LLVMString::create_from_str(&err_string)
582        })?;
583
584        if self.owned_by_ee.borrow().is_some() {
585            let string = "This module is already owned by an ExecutionEngine.\0";
586            return Err(LLVMString::create_from_str(string));
587        }
588
589        let mut execution_engine = MaybeUninit::uninit();
590        let mut err_string = MaybeUninit::uninit();
591
592        let code = unsafe {
593            // Takes ownership of module
594            LLVMCreateJITCompilerForModule(
595                execution_engine.as_mut_ptr(),
596                self.module.get(),
597                opt_level as u32,
598                err_string.as_mut_ptr(),
599            )
600        };
601
602        if code == 1 {
603            unsafe {
604                return Err(LLVMString::new(err_string.assume_init()));
605            }
606        }
607
608        let execution_engine = unsafe { execution_engine.assume_init() };
609        let execution_engine = unsafe { ExecutionEngine::new(Rc::new(execution_engine), true) };
610
611        *self.owned_by_ee.borrow_mut() = Some(execution_engine.clone());
612
613        Ok(execution_engine)
614    }
615
616    /// Creates an MCJIT `ExecutionEngine` for this `Module` using a custom memory manager.
617    ///
618    /// # Parameters
619    ///
620    /// * `memory_manager` - Specifies how LLVM allocates and finalizes code and data sections.
621    ///   Implement the [`McjitMemoryManager`] trait to customize these operations.
622    /// * `opt_level` - Sets the desired optimization level (e.g. `None`, `Less`, `Default`, `Aggressive`).
623    ///   Higher levels generally produce faster code at the expense of longer compilation times.
624    /// * `code_model` - Determines how code addresses are represented. Common values include
625    ///   `CodeModel::Default` or `CodeModel::JITDefault`. This impacts the generated machine code layout.
626    /// * `no_frame_pointer_elim` - If true, frame pointer elimination is disabled. This may assist
627    ///   with certain debugging or profiling tasks but can incur a performance cost.
628    /// * `enable_fast_isel` - If true, uses a faster instruction selector where possible. This can
629    ///   improve compilation speed, though it may produce less optimized code in some cases.
630    ///
631    /// # Returns
632    ///
633    /// Returns a newly created [`ExecutionEngine`] for MCJIT on success. Returns an error if:
634    /// - The native target fails to initialize,
635    /// - The `Module` is already owned by another `ExecutionEngine`,
636    /// - Or MCJIT fails to create the engine (in which case an error string is returned from LLVM).
637    ///
638    /// # Notes
639    ///
640    /// Using a custom memory manager can help intercept or manage allocations for specific
641    /// sections (for example, capturing `.llvm_stackmaps` or applying custom permissions).
642    /// For details, refer to the [`McjitMemoryManager`] documentation.
643    ///
644    /// # Safety
645    ///
646    /// The returned [`ExecutionEngine`] takes ownership of the memory manager. Do not move
647    /// or free the `memory_manager` after calling this method. When the `ExecutionEngine`
648    /// is dropped, LLVM will destroy the memory manager by calling
649    /// [`McjitMemoryManager::destroy()`] and freeing its adapter.
650    pub fn create_mcjit_execution_engine_with_memory_manager(
651        &self,
652        memory_manager: impl McjitMemoryManager + 'static,
653        opt_level: OptimizationLevel,
654        code_model: CodeModel,
655        no_frame_pointer_elim: bool,
656        enable_fast_isel: bool,
657    ) -> Result<ExecutionEngine<'ctx>, LLVMString> {
658        use std::mem::MaybeUninit;
659        // ...
660
661        // 1) Initialize the native target
662        Target::initialize_native(&InitializationConfig::default()).map_err(|mut err_string| {
663            err_string.push('\0');
664            LLVMString::create_from_str(&err_string)
665        })?;
666
667        // Check if the module is already owned by an ExecutionEngine
668        if self.owned_by_ee.borrow().is_some() {
669            let string = "This module is already owned by an ExecutionEngine.\0";
670            return Err(LLVMString::create_from_str(string));
671        }
672
673        // 2) Box the memory_manager into a MemoryManagerAdapter
674        let adapter = MemoryManagerAdapter {
675            memory_manager: Box::new(memory_manager),
676        };
677        let adapter_box = Box::new(adapter);
678        // Convert the Box into a raw pointer for LLVM.
679        // In `destroy_adapter`, we use `Box::from_raw` to safely reclaim ownership.
680        let opaque = Box::into_raw(adapter_box) as *mut c_void;
681
682        // 3) Create the LLVMMCJITMemoryManager using the custom callbacks
683        let mmgr = unsafe {
684            LLVMCreateSimpleMCJITMemoryManager(
685                opaque,
686                allocate_code_section_adapter,
687                allocate_data_section_adapter,
688                finalize_memory_adapter,
689                Some(destroy_adapter),
690            )
691        };
692        if mmgr.is_null() {
693            let msg = "Failed to create SimpleMCJITMemoryManager.\0";
694            return Err(LLVMString::create_from_str(msg));
695        }
696
697        // 4) Build LLVMMCJITCompilerOptions
698        let mut options_uninit = MaybeUninit::<llvm_sys::execution_engine::LLVMMCJITCompilerOptions>::zeroed();
699        unsafe {
700            // Ensure defaults are initialized
701            llvm_sys::execution_engine::LLVMInitializeMCJITCompilerOptions(
702                options_uninit.as_mut_ptr(),
703                std::mem::size_of::<llvm_sys::execution_engine::LLVMMCJITCompilerOptions>(),
704            );
705        }
706        let mut options = unsafe { options_uninit.assume_init() };
707
708        // Override fields
709        options.OptLevel = opt_level as u32;
710        options.CodeModel = code_model.into();
711        options.NoFramePointerElim = no_frame_pointer_elim as i32;
712        options.EnableFastISel = enable_fast_isel as i32;
713        options.MCJMM = mmgr;
714
715        // 5) Create MCJIT
716        let mut execution_engine = MaybeUninit::uninit();
717        let mut err_string = MaybeUninit::uninit();
718        let code = unsafe {
719            llvm_sys::execution_engine::LLVMCreateMCJITCompilerForModule(
720                execution_engine.as_mut_ptr(),
721                self.module.get(),
722                &mut options,
723                std::mem::size_of::<llvm_sys::execution_engine::LLVMMCJITCompilerOptions>(),
724                err_string.as_mut_ptr(),
725            )
726        };
727
728        // If creation fails, extract the error string
729        if code == 1 {
730            unsafe {
731                return Err(LLVMString::new(err_string.assume_init()));
732            }
733        }
734
735        // Otherwise, it succeeded, so wrap the raw pointer
736        let execution_engine = unsafe { execution_engine.assume_init() };
737        let execution_engine = unsafe { ExecutionEngine::new(Rc::new(execution_engine), true) };
738
739        *self.owned_by_ee.borrow_mut() = Some(execution_engine.clone());
740
741        Ok(execution_engine)
742    }
743
744    /// Creates a `GlobalValue` based on a type in an address space.
745    ///
746    /// # Example
747    ///
748    /// ```no_run
749    /// use inkwell::AddressSpace;
750    /// use inkwell::context::Context;
751    ///
752    /// let context = Context::create();
753    /// let module = context.create_module("mod");
754    /// let i8_type = context.i8_type();
755    /// let global = module.add_global(i8_type, Some(AddressSpace::from(1u16)), "my_global");
756    ///
757    /// assert_eq!(module.get_first_global().unwrap(), global);
758    /// assert_eq!(module.get_last_global().unwrap(), global);
759    /// ```
760    pub fn add_global<T: BasicType<'ctx>>(
761        &self,
762        type_: T,
763        address_space: Option<AddressSpace>,
764        name: &str,
765    ) -> GlobalValue<'ctx> {
766        let c_string = to_c_str(name);
767
768        let value = unsafe {
769            match address_space {
770                Some(address_space) => LLVMAddGlobalInAddressSpace(
771                    self.module.get(),
772                    type_.as_type_ref(),
773                    c_string.as_ptr(),
774                    address_space.0,
775                ),
776                None => LLVMAddGlobal(self.module.get(), type_.as_type_ref(), c_string.as_ptr()),
777            }
778        };
779
780        unsafe { GlobalValue::new(value) }
781    }
782
783    /// Writes a `Module` to a file.
784    ///
785    /// # Arguments
786    ///
787    /// * `path` - path to write the module's bitcode to. Must be valid Unicode.
788    ///
789    /// # Example
790    ///
791    /// ```no_run
792    /// use inkwell::context::Context;
793    ///
794    /// let context = Context::create();
795    /// let module = context.create_module("my_module");
796    /// let void_type = context.void_type();
797    /// let fn_type = void_type.fn_type(&[], false);
798    ///
799    /// module.add_function("my_fn", fn_type, None);
800    /// module.write_bitcode_to_path("module.bc");
801    /// ```
802    pub fn write_bitcode_to_path(&self, path: impl AsRef<Path>) -> bool {
803        let path_str = path
804            .as_ref()
805            .to_str()
806            .expect("Did not find a valid Unicode path string");
807        let c_string = to_c_str(path_str);
808
809        unsafe { LLVMWriteBitcodeToFile(self.module.get(), c_string.as_ptr()) == 0 }
810    }
811
812    // See GH issue #6
813    /// `write_bitcode_to_path` should be preferred over this method, as it does not work on all operating systems.
814    pub fn write_bitcode_to_file(&self, file: &File, should_close: bool, unbuffered: bool) -> bool {
815        #[cfg(unix)]
816        {
817            use llvm_sys::bit_writer::LLVMWriteBitcodeToFD;
818            use std::os::unix::io::AsRawFd;
819
820            // REVIEW: as_raw_fd docs suggest it only works in *nix
821            // Also, should_close should maybe be hardcoded to true?
822            unsafe {
823                LLVMWriteBitcodeToFD(
824                    self.module.get(),
825                    file.as_raw_fd(),
826                    should_close as i32,
827                    unbuffered as i32,
828                ) == 0
829            }
830        }
831        #[cfg(not(unix))]
832        return false;
833    }
834
835    /// Writes this `Module` to a `MemoryBuffer`.
836    ///
837    /// # Example
838    ///
839    /// ```no_run
840    /// use inkwell::context::Context;
841    ///
842    /// let context = Context::create();
843    /// let module = context.create_module("mod");
844    /// let void_type = context.void_type();
845    /// let fn_type = void_type.fn_type(&[], false);
846    /// let f = module.add_function("f", fn_type, None);
847    /// let basic_block = context.append_basic_block(f, "entry");
848    /// let builder = context.create_builder();
849    ///
850    /// builder.position_at_end(basic_block);
851    /// builder.build_return(None);
852    ///
853    /// let buffer = module.write_bitcode_to_memory();
854    /// ```
855    pub fn write_bitcode_to_memory(&self) -> MemoryBuffer {
856        let memory_buffer = unsafe { LLVMWriteBitcodeToMemoryBuffer(self.module.get()) };
857
858        unsafe { MemoryBuffer::new(memory_buffer) }
859    }
860
861    /// Check whether the current [`Module`] is valid.
862    ///
863    /// The error variant is an LLVM-allocated string.
864    ///
865    /// # Remarks
866    /// See also: [`LLVMVerifyModule`](https://llvm.org/doxygen/group__LLVMCAnalysis.html#ga5645aec2d95116c0432a676db77b2cb0).
867    pub fn verify(&self) -> Result<(), LLVMString> {
868        let mut err_str = MaybeUninit::uninit();
869
870        let action = LLVMVerifierFailureAction::LLVMReturnStatusAction;
871
872        let code = unsafe { LLVMVerifyModule(self.module.get(), action, err_str.as_mut_ptr()) };
873
874        let err_str = unsafe { err_str.assume_init() };
875        if code == 1 && !err_str.is_null() {
876            return unsafe { Err(LLVMString::new(err_str)) };
877        }
878
879        unsafe { LLVMDisposeMessage(err_str) };
880
881        Ok(())
882    }
883
884    fn get_borrowed_data_layout(module: LLVMModuleRef) -> DataLayout {
885        let data_layout = unsafe {
886            use llvm_sys::core::LLVMGetDataLayoutStr;
887
888            LLVMGetDataLayoutStr(module)
889        };
890
891        unsafe { DataLayout::new_borrowed(data_layout) }
892    }
893
894    /// Gets a smart pointer to the `DataLayout` belonging to a particular `Module`.
895    ///
896    /// # Example
897    ///
898    /// ```no_run
899    /// use inkwell::OptimizationLevel;
900    /// use inkwell::context::Context;
901    /// use inkwell::targets::{InitializationConfig, Target};
902    ///
903    /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
904    ///
905    /// let context = Context::create();
906    /// let module = context.create_module("sum");
907    /// let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
908    /// let target_data = execution_engine.get_target_data();
909    /// let data_layout = target_data.get_data_layout();
910    ///
911    /// module.set_data_layout(&data_layout);
912    ///
913    /// assert_eq!(*module.get_data_layout(), data_layout);
914    /// ```
915    pub fn get_data_layout(&self) -> Ref<'_, DataLayout> {
916        Ref::map(self.data_layout.borrow(), |l| {
917            l.as_ref().expect("DataLayout should always exist until Drop")
918        })
919    }
920
921    // REVIEW: Ensure the replaced string ptr still gets cleaned up by the module (I think it does)
922    // valgrind might come in handy once non jemalloc allocators stabilize
923    /// Sets the `DataLayout` for a particular `Module`.
924    ///
925    /// # Example
926    ///
927    /// ```no_run
928    /// use inkwell::OptimizationLevel;
929    /// use inkwell::context::Context;
930    /// use inkwell::targets::{InitializationConfig, Target};
931    ///
932    /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
933    ///
934    /// let context = Context::create();
935    /// let module = context.create_module("sum");
936    /// let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
937    /// let target_data = execution_engine.get_target_data();
938    /// let data_layout = target_data.get_data_layout();
939    ///
940    /// module.set_data_layout(&data_layout);
941    ///
942    /// assert_eq!(*module.get_data_layout(), data_layout);
943    /// ```
944    pub fn set_data_layout(&self, data_layout: &DataLayout) {
945        unsafe {
946            LLVMSetDataLayout(self.module.get(), data_layout.as_ptr());
947        }
948
949        *self.data_layout.borrow_mut() = Some(Module::get_borrowed_data_layout(self.module.get()));
950    }
951
952    /// Prints the content of the `Module` to stderr.
953    pub fn print_to_stderr(&self) {
954        unsafe {
955            LLVMDumpModule(self.module.get());
956        }
957    }
958
959    /// Prints the content of the `Module` to an `LLVMString`.
960    pub fn print_to_string(&self) -> LLVMString {
961        unsafe { LLVMString::new(LLVMPrintModuleToString(self.module.get())) }
962    }
963
964    /// Prints the content of the `Module` to a file.
965    pub fn print_to_file<P: AsRef<Path>>(&self, path: P) -> Result<(), LLVMString> {
966        let path_str = path
967            .as_ref()
968            .to_str()
969            .expect("Did not find a valid Unicode path string");
970        let path = to_c_str(path_str);
971        let mut err_string = MaybeUninit::uninit();
972        let return_code = unsafe {
973            LLVMPrintModuleToFile(
974                self.module.get(),
975                path.as_ptr() as *const ::libc::c_char,
976                err_string.as_mut_ptr(),
977            )
978        };
979
980        if return_code == 1 {
981            unsafe {
982                return Err(LLVMString::new(err_string.assume_init()));
983            }
984        }
985
986        Ok(())
987    }
988
989    /// Prints the content of the `Module` to a `String`.
990    #[allow(clippy::inherent_to_string)]
991    pub fn to_string(&self) -> String {
992        self.print_to_string().to_string()
993    }
994
995    /// Sets the inline assembly for the `Module`.
996    pub fn set_inline_assembly(&self, asm: &str) {
997        unsafe { LLVMSetModuleInlineAsm2(self.module.get(), asm.as_ptr() as *const ::libc::c_char, asm.len()) }
998    }
999
1000    // REVIEW: Should module take ownership of metadata?
1001    // REVIEW: Should we return a MetadataValue for the global since it's its own value?
1002    // it would be the last item in get_global_metadata I believe
1003    // TODOC: Appends your metadata to a global MetadataValue<Node> indexed by key
1004    /// Appends a `MetaDataValue` to a global list indexed by a particular key.
1005    ///
1006    /// # Example
1007    ///
1008    /// ```no_run
1009    /// use inkwell::context::Context;
1010    ///
1011    /// let context = Context::create();
1012    /// let module = context.create_module("my_module");
1013    /// let bool_type = context.bool_type();
1014    /// let f32_type = context.f32_type();
1015    /// let bool_val = bool_type.const_int(0, false);
1016    /// let f32_val = f32_type.const_float(0.0);
1017    ///
1018    /// assert_eq!(module.get_global_metadata_size("my_md"), 0);
1019    ///
1020    /// let md_string = context.metadata_string("lots of metadata here");
1021    /// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
1022    ///
1023    /// module.add_global_metadata("my_md", &md_string).unwrap();
1024    /// module.add_global_metadata("my_md", &md_node).unwrap();
1025    ///
1026    /// assert_eq!(module.get_global_metadata_size("my_md"), 2);
1027    ///
1028    /// let global_md = module.get_global_metadata("my_md");
1029    ///
1030    /// assert_eq!(global_md.len(), 2);
1031    ///
1032    /// let (md_0, md_1) = (global_md[0].get_node_values(), global_md[1].get_node_values());
1033    ///
1034    /// assert_eq!(md_0.len(), 1);
1035    /// assert_eq!(md_1.len(), 2);
1036    /// assert_eq!(md_0[0].into_metadata_value().get_string_value(), md_string.get_string_value());
1037    /// assert_eq!(md_1[0].into_int_value(), bool_val);
1038    /// assert_eq!(md_1[1].into_float_value(), f32_val);
1039    /// ```
1040    pub fn add_global_metadata(&self, key: &str, metadata: &MetadataValue<'ctx>) -> Result<(), crate::Error> {
1041        if !metadata.is_node() {
1042            return Err(crate::Error::GlobalMetadataError);
1043        }
1044
1045        let c_string = to_c_str(key);
1046        unsafe {
1047            LLVMAddNamedMetadataOperand(self.module.get(), c_string.as_ptr(), metadata.as_value_ref());
1048        }
1049
1050        Ok(())
1051    }
1052
1053    // REVIEW: Better name? get_global_metadata_len or _count?
1054    /// Obtains the number of `MetaDataValue`s indexed by a particular key.
1055    ///
1056    /// # Example
1057    ///
1058    /// ```no_run
1059    /// use inkwell::context::Context;
1060    ///
1061    /// let context = Context::create();
1062    /// let module = context.create_module("my_module");
1063    /// let bool_type = context.bool_type();
1064    /// let f32_type = context.f32_type();
1065    /// let bool_val = bool_type.const_int(0, false);
1066    /// let f32_val = f32_type.const_float(0.0);
1067    ///
1068    /// assert_eq!(module.get_global_metadata_size("my_md"), 0);
1069    ///
1070    /// let md_string = context.metadata_string("lots of metadata here");
1071    /// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
1072    ///
1073    /// module.add_global_metadata("my_md", &md_string).unwrap();
1074    /// module.add_global_metadata("my_md", &md_node).unwrap();
1075    ///
1076    /// assert_eq!(module.get_global_metadata_size("my_md"), 2);
1077    ///
1078    /// let global_md = module.get_global_metadata("my_md");
1079    ///
1080    /// assert_eq!(global_md.len(), 2);
1081    ///
1082    /// let (md_0, md_1) = (global_md[0].get_node_values(), global_md[1].get_node_values());
1083    ///
1084    /// assert_eq!(md_0.len(), 1);
1085    /// assert_eq!(md_1.len(), 2);
1086    /// assert_eq!(md_0[0].into_metadata_value().get_string_value(), md_string.get_string_value());
1087    /// assert_eq!(md_1[0].into_int_value(), bool_val);
1088    /// assert_eq!(md_1[1].into_float_value(), f32_val);
1089    /// ```
1090    pub fn get_global_metadata_size(&self, key: &str) -> u32 {
1091        let c_string = to_c_str(key);
1092
1093        unsafe { LLVMGetNamedMetadataNumOperands(self.module.get(), c_string.as_ptr()) }
1094    }
1095
1096    // SubTypes: -> Vec<MetadataValue<Node>>
1097    /// Obtains the global `MetaDataValue` node indexed by key, which may contain 1 string or multiple values as its `get_node_values()`
1098    ///
1099    /// # Example
1100    ///
1101    /// ```no_run
1102    /// use inkwell::context::Context;
1103    ///
1104    /// let context = Context::create();
1105    /// let module = context.create_module("my_module");
1106    /// let bool_type = context.bool_type();
1107    /// let f32_type = context.f32_type();
1108    /// let bool_val = bool_type.const_int(0, false);
1109    /// let f32_val = f32_type.const_float(0.0);
1110    ///
1111    /// assert_eq!(module.get_global_metadata_size("my_md"), 0);
1112    ///
1113    /// let md_string = context.metadata_string("lots of metadata here");
1114    /// let md_node = context.metadata_node(&[bool_val.into(), f32_val.into()]);
1115    ///
1116    /// module.add_global_metadata("my_md", &md_string).unwrap();
1117    /// module.add_global_metadata("my_md", &md_node).unwrap();
1118    ///
1119    /// assert_eq!(module.get_global_metadata_size("my_md"), 2);
1120    ///
1121    /// let global_md = module.get_global_metadata("my_md");
1122    ///
1123    /// assert_eq!(global_md.len(), 2);
1124    ///
1125    /// let (md_0, md_1) = (global_md[0].get_node_values(), global_md[1].get_node_values());
1126    ///
1127    /// assert_eq!(md_0.len(), 1);
1128    /// assert_eq!(md_1.len(), 2);
1129    /// assert_eq!(md_0[0].into_metadata_value().get_string_value(), md_string.get_string_value());
1130    /// assert_eq!(md_1[0].into_int_value(), bool_val);
1131    /// assert_eq!(md_1[1].into_float_value(), f32_val);
1132    /// ```
1133    pub fn get_global_metadata(&self, key: &str) -> Vec<MetadataValue<'ctx>> {
1134        let c_string = to_c_str(key);
1135        let count = self.get_global_metadata_size(key) as usize;
1136
1137        let mut vec: Vec<LLVMValueRef> = Vec::with_capacity(count);
1138        let ptr = vec.as_mut_ptr();
1139
1140        unsafe {
1141            LLVMGetNamedMetadataOperands(self.module.get(), c_string.as_ptr(), ptr);
1142
1143            vec.set_len(count);
1144        };
1145
1146        vec.iter().map(|val| unsafe { MetadataValue::new(*val) }).collect()
1147    }
1148
1149    /// Gets the first `GlobalValue` in a module.
1150    ///
1151    /// # Example
1152    ///
1153    /// ```no_run
1154    /// use inkwell::AddressSpace;
1155    /// use inkwell::context::Context;
1156    ///
1157    /// let context = Context::create();
1158    /// let i8_type = context.i8_type();
1159    /// let module = context.create_module("mod");
1160    ///
1161    /// assert!(module.get_first_global().is_none());
1162    ///
1163    /// let global = module.add_global(i8_type, Some(AddressSpace::from(4u16)), "my_global");
1164    ///
1165    /// assert_eq!(module.get_first_global().unwrap(), global);
1166    /// ```
1167    pub fn get_first_global(&self) -> Option<GlobalValue<'ctx>> {
1168        let value = unsafe { LLVMGetFirstGlobal(self.module.get()) };
1169
1170        if value.is_null() {
1171            return None;
1172        }
1173
1174        unsafe { Some(GlobalValue::new(value)) }
1175    }
1176
1177    /// Gets the last `GlobalValue` in a module.
1178    ///
1179    /// # Example
1180    ///
1181    /// ```no_run
1182    /// use inkwell::AddressSpace;
1183    /// use inkwell::context::Context;
1184    ///
1185    /// let context = Context::create();
1186    /// let module = context.create_module("mod");
1187    /// let i8_type = context.i8_type();
1188    ///
1189    /// assert!(module.get_last_global().is_none());
1190    ///
1191    /// let global = module.add_global(i8_type, Some(AddressSpace::from(4u16)), "my_global");
1192    ///
1193    /// assert_eq!(module.get_last_global().unwrap(), global);
1194    /// ```
1195    pub fn get_last_global(&self) -> Option<GlobalValue<'ctx>> {
1196        let value = unsafe { LLVMGetLastGlobal(self.module.get()) };
1197
1198        if value.is_null() {
1199            return None;
1200        }
1201
1202        unsafe { Some(GlobalValue::new(value)) }
1203    }
1204
1205    /// Gets a named `GlobalValue` in a module.
1206    ///
1207    /// # Example
1208    ///
1209    /// ```no_run
1210    /// use inkwell::AddressSpace;
1211    /// use inkwell::context::Context;
1212    ///
1213    /// let context = Context::create();
1214    /// let module = context.create_module("mod");
1215    /// let i8_type = context.i8_type();
1216    ///
1217    /// assert!(module.get_global("my_global").is_none());
1218    ///
1219    /// let global = module.add_global(i8_type, Some(AddressSpace::from(4u16)), "my_global");
1220    ///
1221    /// assert_eq!(module.get_global("my_global").unwrap(), global);
1222    /// ```
1223    pub fn get_global(&self, name: &str) -> Option<GlobalValue<'ctx>> {
1224        let c_string = to_c_str(name);
1225        let value = unsafe { LLVMGetNamedGlobal(self.module.get(), c_string.as_ptr()) };
1226
1227        if value.is_null() {
1228            return None;
1229        }
1230
1231        unsafe { Some(GlobalValue::new(value)) }
1232    }
1233
1234    /// An iterator over the globals in this `Module`.
1235    pub fn get_globals(&self) -> GlobalIterator<'ctx> {
1236        GlobalIterator::from_module(self)
1237    }
1238
1239    /// Creates a new `Module` from a `MemoryBuffer` with bitcode.
1240    ///
1241    /// # Example
1242    ///
1243    /// ```no_run
1244    /// use inkwell::context::Context;
1245    /// use inkwell::module::Module;
1246    /// use inkwell::memory_buffer::MemoryBuffer;
1247    /// use std::path::Path;
1248    ///
1249    /// let path = Path::new("foo/bar.bc");
1250    /// let context = Context::create();
1251    /// let buffer = MemoryBuffer::create_from_file(&path).unwrap();
1252    /// let module = Module::parse_bitcode_from_buffer(&buffer, &context);
1253    ///
1254    /// assert_eq!(module.unwrap().get_context(), context);
1255    ///
1256    /// ```
1257    pub fn parse_bitcode_from_buffer(
1258        buffer: &MemoryBuffer,
1259        context: impl AsContextRef<'ctx>,
1260    ) -> Result<Self, LLVMString> {
1261        let mut module = MaybeUninit::uninit();
1262        let mut err_string = MaybeUninit::uninit();
1263
1264        // LLVM has a newer version of this function w/o the error result since 3.8 but this deprecated function
1265        // hasen't yet been removed even in LLVM 8. Seems fine to use instead of switching to their
1266        // error diagnostics handler for now.
1267        #[allow(deprecated)]
1268        let success = unsafe {
1269            LLVMParseBitcodeInContext(
1270                context.as_ctx_ref(),
1271                buffer.memory_buffer,
1272                module.as_mut_ptr(),
1273                err_string.as_mut_ptr(),
1274            )
1275        };
1276
1277        if success != 0 {
1278            unsafe {
1279                return Err(LLVMString::new(err_string.assume_init()));
1280            }
1281        }
1282
1283        unsafe { Ok(Module::new(module.assume_init())) }
1284    }
1285
1286    /// A convenience function for creating a `Module` from a bitcode file for a given context.
1287    ///
1288    /// # Example
1289    ///
1290    /// ```no_run
1291    /// use inkwell::context::Context;
1292    /// use inkwell::module::Module;
1293    /// use std::path::Path;
1294    ///
1295    /// let path = Path::new("foo/bar.bc");
1296    /// let context = Context::create();
1297    /// let module = Module::parse_bitcode_from_path(&path, &context);
1298    ///
1299    /// assert_eq!(module.unwrap().get_context(), context);
1300    ///
1301    /// ```
1302    // LLVMGetBitcodeModuleInContext was a pain to use, so I seem to be able to achieve the same effect
1303    // by reusing create_from_file instead. This is basically just a convenience function.
1304    pub fn parse_bitcode_from_path<P: AsRef<Path>>(
1305        path: P,
1306        context: impl AsContextRef<'ctx>,
1307    ) -> Result<Self, LLVMString> {
1308        let buffer = MemoryBuffer::create_from_file(path.as_ref())?;
1309
1310        Self::parse_bitcode_from_buffer(&buffer, context)
1311    }
1312
1313    /// Gets the name of this `Module`.
1314    ///
1315    /// # Example
1316    ///
1317    /// ```no_run
1318    /// use inkwell::context::Context;
1319    ///
1320    /// let context = Context::create();
1321    /// let module = context.create_module("my_module");
1322    ///
1323    /// assert_eq!(module.get_name().to_str(), Ok("my_mdoule"));
1324    /// ```
1325    pub fn get_name(&self) -> &CStr {
1326        let mut length = 0;
1327        let cstr_ptr = unsafe { LLVMGetModuleIdentifier(self.module.get(), &mut length) };
1328
1329        unsafe { CStr::from_ptr(cstr_ptr) }
1330    }
1331
1332    /// Assigns the name of this `Module`.
1333    ///
1334    /// # Example
1335    ///
1336    /// ```no_run
1337    /// use inkwell::context::Context;
1338    ///
1339    /// let context = Context::create();
1340    /// let module = context.create_module("my_module");
1341    ///
1342    /// module.set_name("my_module2");
1343    ///
1344    /// assert_eq!(module.get_name().to_str(), Ok("my_module2"));
1345    /// ```
1346    pub fn set_name(&self, name: &str) {
1347        unsafe { LLVMSetModuleIdentifier(self.module.get(), name.as_ptr() as *const ::libc::c_char, name.len()) }
1348    }
1349
1350    /// Gets the source file name. It defaults to the module identifier but is separate from it.
1351    ///
1352    /// # Example
1353    ///
1354    /// ```no_run
1355    /// use inkwell::context::Context;
1356    ///
1357    /// let context = Context::create();
1358    /// let module = context.create_module("my_mod");
1359    ///
1360    /// assert_eq!(module.get_source_file_name().to_str(), Ok("my_mod"));
1361    ///
1362    /// module.set_source_file_name("my_mod.rs");
1363    ///
1364    /// assert_eq!(module.get_name().to_str(), Ok("my_mod"));
1365    /// assert_eq!(module.get_source_file_name().to_str(), Ok("my_mod.rs"));
1366    /// ```
1367    pub fn get_source_file_name(&self) -> &CStr {
1368        use llvm_sys::core::LLVMGetSourceFileName;
1369
1370        let mut len = 0;
1371        let ptr = unsafe { LLVMGetSourceFileName(self.module.get(), &mut len) };
1372
1373        unsafe { CStr::from_ptr(ptr) }
1374    }
1375
1376    /// Sets the source file name. It defaults to the module identifier but is separate from it.
1377    ///
1378    /// # Example
1379    ///
1380    /// ```no_run
1381    /// use inkwell::context::Context;
1382    ///
1383    /// let context = Context::create();
1384    /// let module = context.create_module("my_mod");
1385    ///
1386    /// assert_eq!(module.get_source_file_name().to_str(), Ok("my_mod"));
1387    ///
1388    /// module.set_source_file_name("my_mod.rs");
1389    ///
1390    /// assert_eq!(module.get_name().to_str(), Ok("my_mod"));
1391    /// assert_eq!(module.get_source_file_name().to_str(), Ok("my_mod.rs"));
1392    /// ```
1393    pub fn set_source_file_name(&self, file_name: &str) {
1394        use llvm_sys::core::LLVMSetSourceFileName;
1395
1396        unsafe {
1397            LLVMSetSourceFileName(
1398                self.module.get(),
1399                file_name.as_ptr() as *const ::libc::c_char,
1400                file_name.len(),
1401            )
1402        }
1403    }
1404
1405    /// Links one module into another. This will merge two `Module`s into one.
1406    ///
1407    /// # Example
1408    ///
1409    /// ```no_run
1410    /// use inkwell::context::Context;
1411    ///
1412    /// let context = Context::create();
1413    /// let module = context.create_module("mod");
1414    /// let module2 = context.create_module("mod2");
1415    ///
1416    /// assert!(module.link_in_module(module2).is_ok());
1417    /// ```
1418    pub fn link_in_module(&self, other: Self) -> Result<(), LLVMString> {
1419        if other.owned_by_ee.borrow().is_some() {
1420            let string = "Cannot link a module which is already owned by an ExecutionEngine.\0";
1421            return Err(LLVMString::create_from_str(string));
1422        }
1423
1424        use crate::support::error_handling::get_error_str_diagnostic_handler;
1425        use libc::c_void;
1426        use llvm_sys::linker::LLVMLinkModules2;
1427
1428        let context = self.get_context();
1429
1430        let mut char_ptr: *mut ::libc::c_char = ptr::null_mut();
1431        let char_ptr_ptr = &mut char_ptr as *mut *mut ::libc::c_char as *mut *mut c_void as *mut c_void;
1432
1433        // Newer LLVM versions don't use an out ptr anymore which was really straightforward...
1434        // Here we assign an error handler to extract the error message, if any, for us.
1435        context.set_diagnostic_handler(get_error_str_diagnostic_handler, char_ptr_ptr);
1436
1437        let code = unsafe { LLVMLinkModules2(self.module.get(), other.module.get()) };
1438
1439        forget(other);
1440
1441        if code == 1 {
1442            debug_assert!(!char_ptr.is_null());
1443
1444            unsafe { Err(LLVMString::new(char_ptr)) }
1445        } else {
1446            Ok(())
1447        }
1448    }
1449
1450    /// Gets the `Comdat` associated with a particular name. If it does not exist, it will be created.
1451    /// A new `Comdat` defaults to a kind of `ComdatSelectionKind::Any`.
1452    pub fn get_or_insert_comdat(&self, name: &str) -> Comdat {
1453        use llvm_sys::comdat::LLVMGetOrInsertComdat;
1454
1455        let c_string = to_c_str(name);
1456        let comdat_ptr = unsafe { LLVMGetOrInsertComdat(self.module.get(), c_string.as_ptr()) };
1457
1458        unsafe { Comdat::new(comdat_ptr) }
1459    }
1460
1461    /// Gets the `MetadataValue` flag associated with the key in this module, if any.
1462    /// If a `BasicValue` was used to create this flag, it will be wrapped in a `MetadataValue`
1463    /// when returned from this function.
1464    // SubTypes: Might need to return Option<BVE, MV<Enum>, or MV<String>>
1465    pub fn get_flag(&self, key: &str) -> Option<MetadataValue<'ctx>> {
1466        use llvm_sys::core::LLVMMetadataAsValue;
1467
1468        let flag = unsafe { LLVMGetModuleFlag(self.module.get(), key.as_ptr() as *const ::libc::c_char, key.len()) };
1469
1470        if flag.is_null() {
1471            return None;
1472        }
1473
1474        let flag_value = unsafe { LLVMMetadataAsValue(LLVMGetModuleContext(self.module.get()), flag) };
1475
1476        unsafe { Some(MetadataValue::new(flag_value)) }
1477    }
1478
1479    /// Append a `MetadataValue` as a module wide flag. Note that using the same key twice
1480    /// will likely invalidate the module.
1481    pub fn add_metadata_flag(&self, key: &str, behavior: FlagBehavior, flag: MetadataValue<'ctx>) {
1482        let md = flag.as_metadata_ref();
1483
1484        unsafe {
1485            LLVMAddModuleFlag(
1486                self.module.get(),
1487                behavior.into(),
1488                key.as_ptr() as *mut ::libc::c_char,
1489                key.len(),
1490                md,
1491            )
1492        }
1493    }
1494
1495    /// Append a `BasicValue` as a module wide flag. Note that using the same key twice
1496    /// will likely invalidate the module.
1497    // REVIEW: What happens if value is not const?
1498    pub fn add_basic_value_flag<BV: BasicValue<'ctx>>(&self, key: &str, behavior: FlagBehavior, flag: BV) {
1499        use llvm_sys::core::LLVMValueAsMetadata;
1500
1501        let md = unsafe { LLVMValueAsMetadata(flag.as_value_ref()) };
1502
1503        unsafe {
1504            LLVMAddModuleFlag(
1505                self.module.get(),
1506                behavior.into(),
1507                key.as_ptr() as *mut ::libc::c_char,
1508                key.len(),
1509                md,
1510            )
1511        }
1512    }
1513
1514    /// Strips and debug info from the module, if it exists.
1515    pub fn strip_debug_info(&self) -> bool {
1516        unsafe { LLVMStripModuleDebugInfo(self.module.get()) == 1 }
1517    }
1518
1519    /// Gets the version of debug metadata contained in this `Module`.
1520    pub fn get_debug_metadata_version(&self) -> libc::c_uint {
1521        unsafe { LLVMGetModuleDebugMetadataVersion(self.module.get()) }
1522    }
1523
1524    /// Creates a `DebugInfoBuilder` for this `Module`.
1525    pub fn create_debug_info_builder(
1526        &self,
1527        allow_unresolved: bool,
1528        language: DWARFSourceLanguage,
1529        filename: &str,
1530        directory: &str,
1531        producer: &str,
1532        is_optimized: bool,
1533        flags: &str,
1534        runtime_ver: libc::c_uint,
1535        split_name: &str,
1536        kind: DWARFEmissionKind,
1537        dwo_id: libc::c_uint,
1538        split_debug_inlining: bool,
1539        debug_info_for_profiling: bool,
1540        #[cfg(any(
1541            feature = "llvm11-0",
1542            feature = "llvm12-0",
1543            feature = "llvm13-0",
1544            feature = "llvm14-0",
1545            feature = "llvm15-0",
1546            feature = "llvm16-0",
1547            feature = "llvm17-0",
1548            feature = "llvm18-1",
1549            feature = "llvm19-1",
1550            feature = "llvm20-1",
1551            feature = "llvm21-1",
1552        ))]
1553        sysroot: &str,
1554        #[cfg(any(
1555            feature = "llvm11-0",
1556            feature = "llvm12-0",
1557            feature = "llvm13-0",
1558            feature = "llvm14-0",
1559            feature = "llvm15-0",
1560            feature = "llvm16-0",
1561            feature = "llvm17-0",
1562            feature = "llvm18-1",
1563            feature = "llvm19-1",
1564            feature = "llvm20-1",
1565            feature = "llvm21-1",
1566        ))]
1567        sdk: &str,
1568    ) -> (DebugInfoBuilder<'ctx>, DICompileUnit<'ctx>) {
1569        DebugInfoBuilder::new(
1570            self,
1571            allow_unresolved,
1572            language,
1573            filename,
1574            directory,
1575            producer,
1576            is_optimized,
1577            flags,
1578            runtime_ver,
1579            split_name,
1580            kind,
1581            dwo_id,
1582            split_debug_inlining,
1583            debug_info_for_profiling,
1584            #[cfg(any(
1585                feature = "llvm11-0",
1586                feature = "llvm12-0",
1587                feature = "llvm13-0",
1588                feature = "llvm14-0",
1589                feature = "llvm15-0",
1590                feature = "llvm16-0",
1591                feature = "llvm17-0",
1592                feature = "llvm18-1",
1593                feature = "llvm19-1",
1594                feature = "llvm20-1",
1595                feature = "llvm21-1",
1596            ))]
1597            sysroot,
1598            #[cfg(any(
1599                feature = "llvm11-0",
1600                feature = "llvm12-0",
1601                feature = "llvm13-0",
1602                feature = "llvm14-0",
1603                feature = "llvm15-0",
1604                feature = "llvm16-0",
1605                feature = "llvm17-0",
1606                feature = "llvm18-1",
1607                feature = "llvm19-1",
1608                feature = "llvm20-1",
1609                feature = "llvm21-1",
1610            ))]
1611            sdk,
1612        )
1613    }
1614
1615    /// Construct and run a set of passes over a module.
1616    ///
1617    /// This function takes a string with the passes that should be used.
1618    /// The format of this string is the same as
1619    /// [`opt`](https://llvm.org/docs/CommandGuide/opt.html)'s
1620    /// `-{passes}` argument for the new pass manager.
1621    /// Individual passes may be specified, separated by commas.
1622    /// Full pipelines may also be invoked using `"default<O3>"` and friends.
1623    /// See [`opt`](https://llvm.org/docs/CommandGuide/opt.html)
1624    /// for full reference of the `passes` format.
1625    #[llvm_versions(13..)]
1626    pub fn run_passes(
1627        &self,
1628        passes: &str,
1629        machine: &TargetMachine,
1630        options: PassBuilderOptions,
1631    ) -> Result<(), LLVMString> {
1632        unsafe {
1633            let error = LLVMRunPasses(
1634                self.module.get(),
1635                to_c_str(passes).as_ptr(),
1636                machine.target_machine,
1637                options.options_ref,
1638            );
1639            if error.is_null() {
1640                Ok(())
1641            } else {
1642                let message = LLVMGetErrorMessage(error);
1643                Err(LLVMString::new(message as *const libc::c_char))
1644            }
1645        }
1646    }
1647}
1648
1649impl Clone for Module<'_> {
1650    fn clone(&self) -> Self {
1651        // REVIEW: Is this just a LLVM 6 bug? We could conditionally compile this assertion for affected versions
1652        let verify = self.verify();
1653
1654        assert!(
1655            verify.is_ok(),
1656            "Cloning a Module seems to segfault when module is not valid. We are preventing that here. Error: {}",
1657            verify.unwrap_err()
1658        );
1659
1660        unsafe { Module::new(LLVMCloneModule(self.module.get())) }
1661    }
1662}
1663
1664// Module owns the data layout string, so LLVMDisposeModule will deallocate it for us.
1665// which is why DataLayout must be called with `new_borrowed`
1666impl Drop for Module<'_> {
1667    fn drop(&mut self) {
1668        if self.owned_by_ee.borrow_mut().take().is_none() {
1669            unsafe {
1670                LLVMDisposeModule(self.module.get());
1671            }
1672        }
1673
1674        // Context & EE will drop naturally if they are unique references at this point
1675    }
1676}
1677
1678#[llvm_enum(LLVMModuleFlagBehavior)]
1679#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1680/// Defines the operational behavior for a module wide flag. This documentation comes directly
1681/// from the LLVM docs
1682pub enum FlagBehavior {
1683    /// Emits an error if two values disagree, otherwise the resulting value is that of the operands.
1684    #[llvm_variant(LLVMModuleFlagBehaviorError)]
1685    Error,
1686    /// Emits a warning if two values disagree. The result value will be the operand for the
1687    /// flag from the first module being linked.
1688    #[llvm_variant(LLVMModuleFlagBehaviorWarning)]
1689    Warning,
1690    /// Adds a requirement that another module flag be present and have a specified value after
1691    /// linking is performed. The value must be a metadata pair, where the first element of the
1692    /// pair is the ID of the module flag to be restricted, and the second element of the pair
1693    /// is the value the module flag should be restricted to. This behavior can be used to
1694    /// restrict the allowable results (via triggering of an error) of linking IDs with the
1695    /// **Override** behavior.
1696    #[llvm_variant(LLVMModuleFlagBehaviorRequire)]
1697    Require,
1698    /// Uses the specified value, regardless of the behavior or value of the other module. If
1699    /// both modules specify **Override**, but the values differ, an error will be emitted.
1700    #[llvm_variant(LLVMModuleFlagBehaviorOverride)]
1701    Override,
1702    /// Appends the two values, which are required to be metadata nodes.
1703    #[llvm_variant(LLVMModuleFlagBehaviorAppend)]
1704    Append,
1705    /// Appends the two values, which are required to be metadata nodes. However, duplicate
1706    /// entries in the second list are dropped during the append operation.
1707    #[llvm_variant(LLVMModuleFlagBehaviorAppendUnique)]
1708    AppendUnique,
1709}
1710
1711/// Iterate over all `FunctionValue`s in an llvm module
1712#[derive(Debug)]
1713pub struct FunctionIterator<'ctx>(Option<FunctionValue<'ctx>>);
1714
1715impl<'ctx> FunctionIterator<'ctx> {
1716    fn from_module(module: &Module<'ctx>) -> Self {
1717        Self(module.get_first_function())
1718    }
1719}
1720
1721impl<'ctx> Iterator for FunctionIterator<'ctx> {
1722    type Item = FunctionValue<'ctx>;
1723
1724    fn next(&mut self) -> Option<Self::Item> {
1725        if let Some(func) = self.0 {
1726            self.0 = func.get_next_function();
1727            Some(func)
1728        } else {
1729            None
1730        }
1731    }
1732}
1733
1734/// Iterate over all `GlobalValue`s in an llvm module
1735#[derive(Debug)]
1736pub struct GlobalIterator<'ctx>(Option<GlobalValue<'ctx>>);
1737
1738impl<'ctx> GlobalIterator<'ctx> {
1739    fn from_module(module: &Module<'ctx>) -> Self {
1740        Self(module.get_first_global())
1741    }
1742}
1743
1744impl<'ctx> Iterator for GlobalIterator<'ctx> {
1745    type Item = GlobalValue<'ctx>;
1746
1747    fn next(&mut self) -> Option<Self::Item> {
1748        if let Some(global) = self.0 {
1749            self.0 = global.get_next_global();
1750            Some(global)
1751        } else {
1752            None
1753        }
1754    }
1755}