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}