inkwell/context.rs
1//! A `Context` is an opaque owner and manager of core global data.
2
3use crate::InlineAsmDialect;
4use libc::c_void;
5#[cfg(all(any(feature = "llvm15-0", feature = "llvm16-0"), feature = "typed-pointers"))]
6use llvm_sys::core::LLVMContextSetOpaquePointers;
7#[llvm_versions(12..)]
8use llvm_sys::core::LLVMCreateTypeAttribute;
9
10#[llvm_versions(12..)]
11use llvm_sys::core::LLVMGetTypeByName2;
12
13#[cfg(not(feature = "typed-pointers"))]
14use llvm_sys::core::LLVMPointerTypeInContext;
15use llvm_sys::core::{
16 LLVMAppendBasicBlockInContext, LLVMBFloatTypeInContext, LLVMConstStructInContext, LLVMContextCreate,
17 LLVMContextDispose, LLVMContextSetDiagnosticHandler, LLVMCreateBuilderInContext, LLVMCreateEnumAttribute,
18 LLVMCreateStringAttribute, LLVMDoubleTypeInContext, LLVMFP128TypeInContext, LLVMFloatTypeInContext,
19 LLVMGetInlineAsm, LLVMGetMDKindIDInContext, LLVMHalfTypeInContext, LLVMInsertBasicBlockInContext,
20 LLVMInt1TypeInContext, LLVMInt8TypeInContext, LLVMInt16TypeInContext, LLVMInt32TypeInContext,
21 LLVMInt64TypeInContext, LLVMIntTypeInContext, LLVMMDNodeInContext2, LLVMMDStringInContext2, LLVMMetadataAsValue,
22 LLVMMetadataTypeInContext, LLVMModuleCreateWithNameInContext, LLVMPPCFP128TypeInContext, LLVMStructCreateNamed,
23 LLVMStructTypeInContext, LLVMValueAsMetadata, LLVMVoidTypeInContext, LLVMX86FP80TypeInContext,
24};
25
26#[llvm_versions(..19)]
27use llvm_sys::core::LLVMConstStringInContext;
28
29#[llvm_versions(19..)]
30use llvm_sys::core::LLVMConstStringInContext2;
31
32#[llvm_versions(..22)]
33use llvm_sys::ir_reader::LLVMParseIRInContext;
34#[llvm_versions(22..)]
35use llvm_sys::ir_reader::LLVMParseIRInContext2;
36
37use llvm_sys::prelude::{LLVMContextRef, LLVMDiagnosticInfoRef, LLVMMetadataRef, LLVMTypeRef, LLVMValueRef};
38use llvm_sys::target::{LLVMIntPtrTypeForASInContext, LLVMIntPtrTypeInContext};
39use std::cell::LazyCell;
40use std::sync::{LazyLock, Mutex, MutexGuard};
41
42use crate::AddressSpace;
43use crate::attributes::Attribute;
44use crate::basic_block::BasicBlock;
45use crate::builder::Builder;
46use crate::memory_buffer::MemoryBuffer;
47use crate::module::Module;
48use crate::support::{LLVMString, to_c_str};
49use crate::targets::TargetData;
50#[llvm_versions(12..)]
51use crate::types::AnyTypeEnum;
52use crate::types::MetadataType;
53#[cfg(not(feature = "typed-pointers"))]
54use crate::types::PointerType;
55use crate::types::{AsTypeRef, BasicTypeEnum, FloatType, FunctionType, IntType, StructType, VoidType};
56use crate::values::{
57 ArrayValue, AsValueRef, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, MetadataValue, PointerValue,
58 StructValue,
59};
60
61use std::marker::PhantomData;
62use std::mem::forget;
63use std::num::NonZeroU32;
64use std::ptr;
65use std::thread_local;
66
67// The idea of using a Mutex<Context> here and a thread local'd MutexGuard<Context> in
68// GLOBAL_CTX_LOCK is to ensure two things:
69// 1) Only one thread has access to the global context at a time.
70// 2) The thread has shared access across different points in the thread.
71// This is still technically unsafe because another program in the same process
72// could also be accessing the global context via the C API. `get_global` has been
73// marked unsafe for this reason. Iff this isn't the case then this should be fully safe.
74static GLOBAL_CTX: LazyLock<Mutex<Context>> = LazyLock::new(|| Mutex::new(Context::create()));
75
76thread_local! {
77 #[deprecated(note = "use Context::create instead")]
78 pub(crate) static GLOBAL_CTX_LOCK: LazyCell<MutexGuard<'static, Context>> = LazyCell::new(|| {
79 GLOBAL_CTX.lock().unwrap_or_else(|e| e.into_inner())
80 });
81}
82
83// LLVM's arbitrary bit-width integer constraints.
84// "The integer type is a very simple type that simply specifies an arbitrary bit width...
85// Any bit width from 1 bit to 2^23-1 (about 8 million) can be specified."
86// Reference: https://llvm.org/docs/LangRef.html#integer-type
87const LLVM_MAX_INT_BITS: u32 = 1 << 23;
88
89/// This struct allows us to share method impls across Context and ContextRef types
90#[derive(Debug, PartialEq, Eq, Clone, Copy)]
91pub(crate) struct ContextImpl(pub(crate) LLVMContextRef);
92
93impl ContextImpl {
94 pub(crate) unsafe fn new(context: LLVMContextRef) -> Self {
95 assert!(!context.is_null());
96
97 #[cfg(all(any(feature = "llvm15-0", feature = "llvm16-0"), feature = "typed-pointers"))]
98 unsafe {
99 LLVMContextSetOpaquePointers(context, 0)
100 };
101
102 ContextImpl(context)
103 }
104
105 fn create_builder<'ctx>(&self) -> Builder<'ctx> {
106 unsafe { Builder::new(LLVMCreateBuilderInContext(self.0)) }
107 }
108
109 fn create_module<'ctx>(&self, name: &str) -> Module<'ctx> {
110 let c_string = to_c_str(name);
111
112 unsafe { Module::new(LLVMModuleCreateWithNameInContext(c_string.as_ptr(), self.0)) }
113 }
114
115 fn create_module_from_ir<'ctx>(&self, memory_buffer: MemoryBuffer) -> Result<Module<'ctx>, LLVMString> {
116 let mut module = ptr::null_mut();
117 let mut err_str = ptr::null_mut();
118
119 #[cfg(not(feature = "llvm22-1"))]
120 let code = unsafe { LLVMParseIRInContext(self.0, memory_buffer.memory_buffer, &mut module, &mut err_str) };
121 #[cfg(feature = "llvm22-1")]
122 let code = unsafe { LLVMParseIRInContext2(self.0, memory_buffer.memory_buffer, &mut module, &mut err_str) };
123
124 forget(memory_buffer);
125
126 if code == 0 {
127 unsafe {
128 return Ok(Module::new(module));
129 }
130 }
131
132 unsafe { Err(LLVMString::new(err_str)) }
133 }
134
135 fn create_inline_asm<'ctx>(
136 &self,
137 ty: FunctionType<'ctx>,
138 mut assembly: String,
139 mut constraints: String,
140 sideeffects: bool,
141 alignstack: bool,
142 dialect: Option<InlineAsmDialect>,
143 #[cfg(not(any(feature = "llvm11-0", feature = "llvm12-0")))] can_throw: bool,
144 ) -> PointerValue<'ctx> {
145 let value = unsafe {
146 LLVMGetInlineAsm(
147 ty.as_type_ref(),
148 assembly.as_mut_ptr() as *mut ::libc::c_char,
149 assembly.len(),
150 constraints.as_mut_ptr() as *mut ::libc::c_char,
151 constraints.len(),
152 sideeffects as i32,
153 alignstack as i32,
154 dialect.unwrap_or(InlineAsmDialect::ATT).into(),
155 #[cfg(not(any(feature = "llvm11-0", feature = "llvm12-0")))]
156 {
157 can_throw as i32
158 },
159 )
160 };
161
162 unsafe { PointerValue::new(value) }
163 }
164
165 fn void_type<'ctx>(&self) -> VoidType<'ctx> {
166 unsafe { VoidType::new(LLVMVoidTypeInContext(self.0)) }
167 }
168
169 fn bool_type<'ctx>(&self) -> IntType<'ctx> {
170 unsafe { IntType::new(LLVMInt1TypeInContext(self.0)) }
171 }
172
173 fn i8_type<'ctx>(&self) -> IntType<'ctx> {
174 unsafe { IntType::new(LLVMInt8TypeInContext(self.0)) }
175 }
176
177 fn i16_type<'ctx>(&self) -> IntType<'ctx> {
178 unsafe { IntType::new(LLVMInt16TypeInContext(self.0)) }
179 }
180
181 fn i32_type<'ctx>(&self) -> IntType<'ctx> {
182 unsafe { IntType::new(LLVMInt32TypeInContext(self.0)) }
183 }
184
185 fn i64_type<'ctx>(&self) -> IntType<'ctx> {
186 unsafe { IntType::new(LLVMInt64TypeInContext(self.0)) }
187 }
188
189 // TODO: Call LLVMInt128TypeInContext in applicable versions
190 fn i128_type<'ctx>(&self) -> IntType<'ctx> {
191 self.custom_width_int_type(NonZeroU32::new(128).unwrap()).unwrap()
192 }
193
194 fn custom_width_int_type<'ctx>(&self, bits: NonZeroU32) -> Result<IntType<'ctx>, &'static str> {
195 let width = bits.get();
196
197 if width <= LLVM_MAX_INT_BITS {
198 unsafe { Ok(IntType::new(LLVMIntTypeInContext(self.0, width))) }
199 } else {
200 Err("LLVM only supports integers with bit widths between 1 and 8388608 (inclusive)")
201 }
202 }
203
204 fn metadata_type<'ctx>(&self) -> MetadataType<'ctx> {
205 unsafe { MetadataType::new(LLVMMetadataTypeInContext(self.0)) }
206 }
207
208 fn ptr_sized_int_type<'ctx>(&self, target_data: &TargetData, address_space: Option<AddressSpace>) -> IntType<'ctx> {
209 let int_type_ptr = match address_space {
210 Some(address_space) => unsafe {
211 LLVMIntPtrTypeForASInContext(self.0, target_data.target_data, address_space.0)
212 },
213 None => unsafe { LLVMIntPtrTypeInContext(self.0, target_data.target_data) },
214 };
215
216 unsafe { IntType::new(int_type_ptr) }
217 }
218
219 fn f16_type<'ctx>(&self) -> FloatType<'ctx> {
220 unsafe { FloatType::new(LLVMHalfTypeInContext(self.0)) }
221 }
222
223 #[cfg(any(
224 feature = "llvm11-0",
225 feature = "llvm12-0",
226 feature = "llvm13-0",
227 feature = "llvm14-0",
228 feature = "llvm15-0",
229 feature = "llvm16-0",
230 feature = "llvm17-0",
231 feature = "llvm18-1",
232 feature = "llvm19-1",
233 feature = "llvm20-1",
234 feature = "llvm21-1",
235 feature = "llvm22-1",
236 ))]
237 fn bf16_type<'ctx>(&self) -> FloatType<'ctx> {
238 unsafe { FloatType::new(LLVMBFloatTypeInContext(self.0)) }
239 }
240
241 fn f32_type<'ctx>(&self) -> FloatType<'ctx> {
242 unsafe { FloatType::new(LLVMFloatTypeInContext(self.0)) }
243 }
244
245 fn f64_type<'ctx>(&self) -> FloatType<'ctx> {
246 unsafe { FloatType::new(LLVMDoubleTypeInContext(self.0)) }
247 }
248
249 fn x86_f80_type<'ctx>(&self) -> FloatType<'ctx> {
250 unsafe { FloatType::new(LLVMX86FP80TypeInContext(self.0)) }
251 }
252
253 fn f128_type<'ctx>(&self) -> FloatType<'ctx> {
254 unsafe { FloatType::new(LLVMFP128TypeInContext(self.0)) }
255 }
256
257 fn ppc_f128_type<'ctx>(&self) -> FloatType<'ctx> {
258 unsafe { FloatType::new(LLVMPPCFP128TypeInContext(self.0)) }
259 }
260
261 #[cfg(not(feature = "typed-pointers"))]
262 fn ptr_type<'ctx>(&self, address_space: AddressSpace) -> PointerType<'ctx> {
263 unsafe { PointerType::new(LLVMPointerTypeInContext(self.0, address_space.0)) }
264 }
265
266 fn struct_type<'ctx>(&self, field_types: &[BasicTypeEnum], packed: bool) -> StructType<'ctx> {
267 let mut field_types: Vec<LLVMTypeRef> = field_types.iter().map(|val| val.as_type_ref()).collect();
268 unsafe {
269 StructType::new(LLVMStructTypeInContext(
270 self.0,
271 field_types.as_mut_ptr(),
272 field_types.len() as u32,
273 packed as i32,
274 ))
275 }
276 }
277
278 fn opaque_struct_type<'ctx>(&self, name: &str) -> StructType<'ctx> {
279 let c_string = to_c_str(name);
280
281 unsafe { StructType::new(LLVMStructCreateNamed(self.0, c_string.as_ptr())) }
282 }
283
284 #[llvm_versions(12..)]
285 fn get_struct_type<'ctx>(&self, name: &str) -> Option<StructType<'ctx>> {
286 let c_string = to_c_str(name);
287
288 let ty = unsafe { LLVMGetTypeByName2(self.0, c_string.as_ptr()) };
289 if ty.is_null() {
290 return None;
291 }
292
293 unsafe { Some(StructType::new(ty)) }
294 }
295
296 fn const_struct<'ctx>(&self, values: &[BasicValueEnum], packed: bool) -> StructValue<'ctx> {
297 let mut args: Vec<LLVMValueRef> = values.iter().map(|val| val.as_value_ref()).collect();
298 unsafe {
299 StructValue::new(LLVMConstStructInContext(
300 self.0,
301 args.as_mut_ptr(),
302 args.len() as u32,
303 packed as i32,
304 ))
305 }
306 }
307
308 fn append_basic_block<'ctx>(&self, function: FunctionValue<'ctx>, name: &str) -> BasicBlock<'ctx> {
309 let c_string = to_c_str(name);
310
311 unsafe {
312 BasicBlock::new(LLVMAppendBasicBlockInContext(
313 self.0,
314 function.as_value_ref(),
315 c_string.as_ptr(),
316 ))
317 .expect("Appending basic block should never fail")
318 }
319 }
320
321 fn insert_basic_block_after<'ctx>(&self, basic_block: BasicBlock<'ctx>, name: &str) -> BasicBlock<'ctx> {
322 match basic_block.get_next_basic_block() {
323 Some(next_basic_block) => self.prepend_basic_block(next_basic_block, name),
324 None => {
325 let parent_fn = basic_block.get_parent().unwrap();
326
327 self.append_basic_block(parent_fn, name)
328 },
329 }
330 }
331
332 fn prepend_basic_block<'ctx>(&self, basic_block: BasicBlock<'ctx>, name: &str) -> BasicBlock<'ctx> {
333 let c_string = to_c_str(name);
334
335 unsafe {
336 BasicBlock::new(LLVMInsertBasicBlockInContext(
337 self.0,
338 basic_block.basic_block,
339 c_string.as_ptr(),
340 ))
341 .expect("Prepending basic block should never fail")
342 }
343 }
344
345 fn metadata_node<'ctx>(&self, values: &[BasicMetadataValueEnum<'ctx>]) -> MetadataValue<'ctx> {
346 let mut tuple_values: Vec<LLVMMetadataRef> = values
347 .iter()
348 .map(|val| unsafe { LLVMValueAsMetadata(val.as_value_ref()) })
349 .collect();
350
351 unsafe {
352 let metadata = LLVMMDNodeInContext2(self.0, tuple_values.as_mut_ptr(), tuple_values.len());
353 MetadataValue::new(LLVMMetadataAsValue(self.0, metadata))
354 }
355 }
356
357 fn metadata_string<'ctx>(&self, string: &str) -> MetadataValue<'ctx> {
358 let c_string = to_c_str(string);
359
360 unsafe {
361 let metadata = LLVMMDStringInContext2(self.0, c_string.as_ptr(), c_string.count_bytes());
362 MetadataValue::new(LLVMMetadataAsValue(self.0, metadata))
363 }
364 }
365
366 fn get_kind_id(&self, key: &str) -> u32 {
367 unsafe { LLVMGetMDKindIDInContext(self.0, key.as_ptr() as *const ::libc::c_char, key.len() as u32) }
368 }
369
370 fn create_enum_attribute(&self, kind_id: u32, val: u64) -> Attribute {
371 unsafe { Attribute::new(LLVMCreateEnumAttribute(self.0, kind_id, val)) }
372 }
373
374 fn create_string_attribute(&self, key: &str, val: &str) -> Attribute {
375 unsafe {
376 Attribute::new(LLVMCreateStringAttribute(
377 self.0,
378 key.as_ptr() as *const _,
379 key.len() as u32,
380 val.as_ptr() as *const _,
381 val.len() as u32,
382 ))
383 }
384 }
385
386 #[llvm_versions(12..)]
387 fn create_type_attribute(&self, kind_id: u32, type_ref: AnyTypeEnum) -> Attribute {
388 unsafe { Attribute::new(LLVMCreateTypeAttribute(self.0, kind_id, type_ref.as_type_ref())) }
389 }
390
391 #[llvm_versions(..19)]
392 fn const_string<'ctx>(&self, string: &[u8], null_terminated: bool) -> ArrayValue<'ctx> {
393 unsafe {
394 ArrayValue::new(LLVMConstStringInContext(
395 self.0,
396 string.as_ptr() as *const ::libc::c_char,
397 string.len() as u32,
398 !null_terminated as i32,
399 ))
400 }
401 }
402
403 #[llvm_versions(19..)]
404 fn const_string<'ctx>(&self, string: &[u8], null_terminated: bool) -> ArrayValue<'ctx> {
405 unsafe {
406 ArrayValue::new(LLVMConstStringInContext2(
407 self.0,
408 string.as_ptr() as *const ::libc::c_char,
409 string.len(),
410 !null_terminated as i32,
411 ))
412 }
413 }
414
415 fn set_diagnostic_handler(
416 &self,
417 handler: extern "C" fn(LLVMDiagnosticInfoRef, *mut c_void),
418 void_ptr: *mut c_void,
419 ) {
420 unsafe { LLVMContextSetDiagnosticHandler(self.0, Some(handler), void_ptr) }
421 }
422}
423
424impl PartialEq<Context> for ContextRef<'_> {
425 fn eq(&self, other: &Context) -> bool {
426 self.context == other.context
427 }
428}
429
430impl PartialEq<ContextRef<'_>> for Context {
431 fn eq(&self, other: &ContextRef<'_>) -> bool {
432 self.context == other.context
433 }
434}
435
436/// A `Context` is a container for all LLVM entities including `Module`s.
437///
438/// A `Context` is not thread safe and cannot be shared across threads. Multiple `Context`s
439/// can, however, execute on different threads simultaneously according to the LLVM docs.
440#[derive(Debug, PartialEq, Eq)]
441pub struct Context {
442 pub(crate) context: ContextImpl,
443}
444
445unsafe impl Send for Context {}
446
447impl Context {
448 /// Get raw [`LLVMContextRef`].
449 ///
450 /// This function is exposed only for interoperability with other LLVM IR libraries.
451 /// It's not intended to be used by most users.
452 pub fn raw(&self) -> LLVMContextRef {
453 self.context.0
454 }
455
456 /// Creates a new `Context` from [`LLVMContextRef`].
457 ///
458 /// # Safety
459 ///
460 /// This function is exposed only for interoperability with other LLVM IR libraries.
461 /// It's not intended to be used by most users, hence marked as unsafe.
462 /// Use [`Context::create`] instead.
463 pub unsafe fn new(context: LLVMContextRef) -> Self {
464 unsafe {
465 Context {
466 context: ContextImpl::new(context),
467 }
468 }
469 }
470
471 /// Creates a new `Context`.
472 ///
473 /// # Example
474 ///
475 /// ```no_run
476 /// use inkwell::context::Context;
477 ///
478 /// let context = Context::create();
479 /// ```
480 pub fn create() -> Self {
481 unsafe { Context::new(LLVMContextCreate()) }
482 }
483
484 /// Gets a `Mutex<Context>` which points to the global context singleton.
485 /// This function is marked unsafe because another program within the same
486 /// process could easily gain access to the same LLVM context pointer and bypass
487 /// our `Mutex`. Therefore, using `Context::create()` is the preferred context
488 /// creation function when you do not specifically need the global context.
489 ///
490 /// # Example
491 ///
492 /// ```no_run
493 /// use inkwell::context::Context;
494 ///
495 /// let context = unsafe {
496 /// Context::get_global(|_global_context| {
497 /// // do stuff
498 /// })
499 /// };
500 /// ```
501 #[deprecated(note = "use Context::create instead")]
502 pub unsafe fn get_global<F, R>(func: F) -> R
503 where
504 F: FnOnce(&Context) -> R,
505 {
506 #[allow(deprecated)]
507 GLOBAL_CTX_LOCK.with(|lazy| func(lazy))
508 }
509
510 /// Creates a new `Builder` for a `Context`.
511 ///
512 /// # Example
513 ///
514 /// ```no_run
515 /// use inkwell::context::Context;
516 ///
517 /// let context = Context::create();
518 /// let builder = context.create_builder();
519 /// ```
520 #[inline]
521 pub fn create_builder(&self) -> Builder<'_> {
522 self.context.create_builder()
523 }
524
525 /// Creates a new `Module` for a `Context`.
526 ///
527 /// # Example
528 ///
529 /// ```no_run
530 /// use inkwell::context::Context;
531 ///
532 /// let context = Context::create();
533 /// let module = context.create_module("my_module");
534 /// ```
535 #[inline]
536 pub fn create_module(&self, name: &str) -> Module<'_> {
537 self.context.create_module(name)
538 }
539
540 /// Creates a new `Module` for the current `Context` from a `MemoryBuffer`.
541 ///
542 /// # Example
543 ///
544 /// ```no_run
545 /// use inkwell::context::Context;
546 ///
547 /// let context = Context::create();
548 /// let module = context.create_module("my_module");
549 /// let builder = context.create_builder();
550 /// let void_type = context.void_type();
551 /// let fn_type = void_type.fn_type(&[], false);
552 /// let fn_val = module.add_function("my_fn", fn_type, None);
553 /// let basic_block = context.append_basic_block(fn_val, "entry");
554 ///
555 /// builder.position_at_end(basic_block);
556 /// builder.build_return(None).unwrap();
557 ///
558 /// let memory_buffer = module.write_bitcode_to_memory();
559 ///
560 /// let module2 = context.create_module_from_ir(memory_buffer).unwrap();
561 /// ```
562 // REVIEW: I haven't yet been able to find docs or other wrappers that confirm, but my suspicion
563 // is that the method needs to take ownership of the MemoryBuffer... otherwise I see what looks like
564 // a double free in valgrind when the MemoryBuffer drops so we are `forget`ting MemoryBuffer here
565 // for now until we can confirm this is the correct thing to do
566 #[inline]
567 pub fn create_module_from_ir(&self, memory_buffer: MemoryBuffer) -> Result<Module<'_>, LLVMString> {
568 self.context.create_module_from_ir(memory_buffer)
569 }
570
571 /// Creates a inline asm function pointer.
572 ///
573 /// # Example
574 /// ```no_run
575 /// use std::convert::TryFrom;
576 /// use inkwell::context::Context;
577 ///
578 /// let context = Context::create();
579 /// let module = context.create_module("my_module");
580 /// let builder = context.create_builder();
581 /// let void_type = context.void_type();
582 /// let fn_type = void_type.fn_type(&[], false);
583 /// let fn_val = module.add_function("my_fn", fn_type, None);
584 /// let basic_block = context.append_basic_block(fn_val, "entry");
585 ///
586 /// builder.position_at_end(basic_block);
587 /// let asm_fn = context.i64_type().fn_type(&[context.i64_type().into(), context.i64_type().into()], false);
588 /// let asm = context.create_inline_asm(
589 /// asm_fn,
590 /// "syscall".to_string(),
591 /// "=r,{rax},{rdi}".to_string(),
592 /// true,
593 /// false,
594 /// None,
595 /// #[cfg(not(any(
596 /// feature = "llvm11-0",
597 /// feature = "llvm12-0"
598 /// )))]
599 /// false,
600 /// );
601 /// let params = &[context.i64_type().const_int(60, false).into(), context.i64_type().const_int(1, false).into()];
602 ///
603 /// #[cfg(any(
604 /// feature = "llvm11-0",
605 /// feature = "llvm12-0",
606 /// feature = "llvm13-0",
607 /// feature = "llvm14-0"
608 /// ))]
609 /// {
610 /// use inkwell::values::CallableValue;
611 /// let callable_value = CallableValue::try_from(asm).unwrap();
612 /// builder.build_call(callable_value, params, "exit").unwrap();
613 /// }
614 ///
615 /// #[cfg(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-1", feature = "llvm19-1", feature = "llvm20-1", feature = "llvm21-1", feature = "llvm22-1"))]
616 /// builder.build_indirect_call(asm_fn, asm, params, "exit").unwrap();
617 ///
618 /// builder.build_return(None).unwrap();
619 /// ```
620 #[inline]
621 pub fn create_inline_asm<'ctx>(
622 &'ctx self,
623 ty: FunctionType<'ctx>,
624 assembly: String,
625 constraints: String,
626 sideeffects: bool,
627 alignstack: bool,
628 dialect: Option<InlineAsmDialect>,
629 #[cfg(not(any(feature = "llvm11-0", feature = "llvm12-0")))] can_throw: bool,
630 ) -> PointerValue<'ctx> {
631 self.context.create_inline_asm(
632 ty,
633 assembly,
634 constraints,
635 sideeffects,
636 alignstack,
637 dialect,
638 #[cfg(not(any(feature = "llvm11-0", feature = "llvm12-0")))]
639 can_throw,
640 )
641 }
642
643 /// Gets the `VoidType`. It will be assigned the current context.
644 ///
645 /// # Example
646 ///
647 /// ```no_run
648 /// use inkwell::context::Context;
649 ///
650 /// let context = Context::create();
651 /// let void_type = context.void_type();
652 ///
653 /// assert_eq!(void_type.get_context(), context);
654 /// ```
655 #[inline]
656 pub fn void_type(&self) -> VoidType<'_> {
657 self.context.void_type()
658 }
659
660 /// Gets the `IntType` representing 1 bit width. It will be assigned the current context.
661 ///
662 /// # Example
663 ///
664 /// ```no_run
665 /// use inkwell::context::Context;
666 ///
667 /// let context = Context::create();
668 /// let bool_type = context.bool_type();
669 ///
670 /// assert_eq!(bool_type.get_bit_width(), 1);
671 /// assert_eq!(bool_type.get_context(), context);
672 /// ```
673 #[inline]
674 pub fn bool_type(&self) -> IntType<'_> {
675 self.context.bool_type()
676 }
677
678 /// Gets the `IntType` representing 8 bit width. It will be assigned the current context.
679 ///
680 /// # Example
681 ///
682 /// ```no_run
683 /// use inkwell::context::Context;
684 ///
685 /// let context = Context::create();
686 /// let i8_type = context.i8_type();
687 ///
688 /// assert_eq!(i8_type.get_bit_width(), 8);
689 /// assert_eq!(i8_type.get_context(), context);
690 /// ```
691 #[inline]
692 pub fn i8_type(&self) -> IntType<'_> {
693 self.context.i8_type()
694 }
695
696 /// Gets the `IntType` representing 16 bit width. It will be assigned the current context.
697 ///
698 /// # Example
699 ///
700 /// ```no_run
701 /// use inkwell::context::Context;
702 ///
703 /// let context = Context::create();
704 /// let i16_type = context.i16_type();
705 ///
706 /// assert_eq!(i16_type.get_bit_width(), 16);
707 /// assert_eq!(i16_type.get_context(), context);
708 /// ```
709 #[inline]
710 pub fn i16_type(&self) -> IntType<'_> {
711 self.context.i16_type()
712 }
713
714 /// Gets the `IntType` representing 32 bit width. It will be assigned the current context.
715 ///
716 /// # Example
717 ///
718 /// ```no_run
719 /// use inkwell::context::Context;
720 ///
721 /// let context = Context::create();
722 /// let i32_type = context.i32_type();
723 ///
724 /// assert_eq!(i32_type.get_bit_width(), 32);
725 /// assert_eq!(i32_type.get_context(), context);
726 /// ```
727 #[inline]
728 pub fn i32_type(&self) -> IntType<'_> {
729 self.context.i32_type()
730 }
731
732 /// Gets the `IntType` representing 64 bit width. It will be assigned the current context.
733 ///
734 /// # Example
735 ///
736 /// ```no_run
737 /// use inkwell::context::Context;
738 ///
739 /// let context = Context::create();
740 /// let i64_type = context.i64_type();
741 ///
742 /// assert_eq!(i64_type.get_bit_width(), 64);
743 /// assert_eq!(i64_type.get_context(), context);
744 /// ```
745 #[inline]
746 pub fn i64_type(&self) -> IntType<'_> {
747 self.context.i64_type()
748 }
749
750 /// Gets the `IntType` representing 128 bit width. It will be assigned the current context.
751 ///
752 /// # Example
753 ///
754 /// ```no_run
755 /// use inkwell::context::Context;
756 ///
757 /// let context = Context::create();
758 /// let i128_type = context.i128_type();
759 ///
760 /// assert_eq!(i128_type.get_bit_width(), 128);
761 /// assert_eq!(i128_type.get_context(), context);
762 /// ```
763 #[inline]
764 pub fn i128_type(&self) -> IntType<'_> {
765 self.context.i128_type()
766 }
767
768 /// Gets the `IntType` representing a custom bit width. It will be assigned the current context.
769 ///
770 /// # Example
771 ///
772 /// ```no_run
773 /// use std::num::NonZeroU32;
774 /// use inkwell::context::Context;
775 ///
776 /// let context = Context::create();
777 /// let width = NonZeroU32::new(42).unwrap();
778 /// let i42_type = context.custom_width_int_type(width).unwrap();
779 ///
780 /// assert_eq!(i42_type.get_bit_width(), 42);
781 /// assert_eq!(i42_type.get_context(), context);
782 /// ```
783 #[inline]
784 pub fn custom_width_int_type(&self, bits: NonZeroU32) -> Result<IntType<'_>, &'static str> {
785 self.context.custom_width_int_type(bits)
786 }
787
788 /// Gets the `MetadataType` representing 128 bit width. It will be assigned the current context.
789 ///
790 /// # Example
791 ///
792 /// ```
793 /// use inkwell::context::Context;
794 /// use inkwell::values::IntValue;
795 ///
796 /// let context = Context::create();
797 /// let md_type = context.metadata_type();
798 ///
799 /// assert_eq!(md_type.get_context(), context);
800 /// ```
801 #[inline]
802 pub fn metadata_type(&self) -> MetadataType<'_> {
803 self.context.metadata_type()
804 }
805
806 /// Gets the `IntType` representing a bit width of a pointer. It will be assigned the referenced context.
807 ///
808 /// # Example
809 ///
810 /// ```no_run
811 /// use inkwell::OptimizationLevel;
812 /// use inkwell::context::Context;
813 /// use inkwell::targets::{InitializationConfig, Target};
814 ///
815 /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
816 ///
817 /// let context = Context::create();
818 /// let module = context.create_module("sum");
819 /// let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
820 /// let target_data = execution_engine.get_target_data();
821 /// let int_type = context.ptr_sized_int_type(&target_data, None);
822 /// ```
823 #[inline]
824 pub fn ptr_sized_int_type(&self, target_data: &TargetData, address_space: Option<AddressSpace>) -> IntType<'_> {
825 self.context.ptr_sized_int_type(target_data, address_space)
826 }
827
828 /// Gets the `FloatType` representing a 16 bit width. It will be assigned the current context.
829 ///
830 /// # Example
831 ///
832 /// ```no_run
833 /// use inkwell::context::Context;
834 ///
835 /// let context = Context::create();
836 ///
837 /// let f16_type = context.f16_type();
838 ///
839 /// assert_eq!(f16_type.get_context(), context);
840 /// ```
841 #[inline]
842 pub fn f16_type(&self) -> FloatType<'_> {
843 self.context.f16_type()
844 }
845
846 /// Gets the `FloatType` representing bfloat16 with a 16 bit width. It will be assigned the current context.
847 /// This is only available with LLVM >= 11.
848 ///
849 /// # Example
850 ///
851 /// ```no_run
852 /// use inkwell::context::Context;
853 ///
854 /// let context = Context::create();
855 ///
856 /// let bf16_type = context.bf16_type();
857 ///
858 /// assert_eq!(bf16_type.get_context(), context);
859 /// ```
860 #[cfg(any(
861 feature = "llvm11-0",
862 feature = "llvm12-0",
863 feature = "llvm13-0",
864 feature = "llvm14-0",
865 feature = "llvm15-0",
866 feature = "llvm16-0",
867 feature = "llvm17-0",
868 feature = "llvm18-1",
869 feature = "llvm19-1",
870 feature = "llvm20-1",
871 feature = "llvm21-1",
872 feature = "llvm22-1",
873 ))]
874 #[inline]
875 pub fn bf16_type(&self) -> FloatType<'_> {
876 self.context.bf16_type()
877 }
878
879 /// Gets the `FloatType` representing a 32 bit width. It will be assigned the current context.
880 ///
881 /// # Example
882 ///
883 /// ```no_run
884 /// use inkwell::context::Context;
885 ///
886 /// let context = Context::create();
887 ///
888 /// let f32_type = context.f32_type();
889 ///
890 /// assert_eq!(f32_type.get_context(), context);
891 /// ```
892 #[inline]
893 pub fn f32_type(&self) -> FloatType<'_> {
894 self.context.f32_type()
895 }
896
897 /// Gets the `FloatType` representing a 64 bit width. It will be assigned the current context.
898 ///
899 /// # Example
900 ///
901 /// ```no_run
902 /// use inkwell::context::Context;
903 ///
904 /// let context = Context::create();
905 ///
906 /// let f64_type = context.f64_type();
907 ///
908 /// assert_eq!(f64_type.get_context(), context);
909 /// ```
910 #[inline]
911 pub fn f64_type(&self) -> FloatType<'_> {
912 self.context.f64_type()
913 }
914
915 /// Gets the `FloatType` representing a 80 bit width. It will be assigned the current context.
916 ///
917 /// # Example
918 ///
919 /// ```no_run
920 /// use inkwell::context::Context;
921 ///
922 /// let context = Context::create();
923 ///
924 /// let x86_f80_type = context.x86_f80_type();
925 ///
926 /// assert_eq!(x86_f80_type.get_context(), context);
927 /// ```
928 #[inline]
929 pub fn x86_f80_type(&self) -> FloatType<'_> {
930 self.context.x86_f80_type()
931 }
932
933 /// Gets the `FloatType` representing a 128 bit width. It will be assigned the current context.
934 ///
935 /// # Example
936 ///
937 /// ```no_run
938 /// use inkwell::context::Context;
939 ///
940 /// let context = Context::create();
941 ///
942 /// let f128_type = context.f128_type();
943 ///
944 /// assert_eq!(f128_type.get_context(), context);
945 /// ```
946 // IEEE 754-2008’s binary128 floats according to https://internals.rust-lang.org/t/pre-rfc-introduction-of-half-and-quadruple-precision-floats-f16-and-f128/7521
947 #[inline]
948 pub fn f128_type(&self) -> FloatType<'_> {
949 self.context.f128_type()
950 }
951
952 /// Gets the `FloatType` representing a 128 bit width. It will be assigned the current context.
953 ///
954 /// PPC is two 64 bits side by side rather than one single 128 bit float.
955 ///
956 /// # Example
957 ///
958 /// ```no_run
959 /// use inkwell::context::Context;
960 ///
961 /// let context = Context::create();
962 ///
963 /// let f128_type = context.ppc_f128_type();
964 ///
965 /// assert_eq!(f128_type.get_context(), context);
966 /// ```
967 // Two 64 bits according to https://internals.rust-lang.org/t/pre-rfc-introduction-of-half-and-quadruple-precision-floats-f16-and-f128/7521
968 #[inline]
969 pub fn ppc_f128_type(&self) -> FloatType<'_> {
970 self.context.ppc_f128_type()
971 }
972
973 /// Gets the `PointerType`. It will be assigned the current context.
974 ///
975 /// # Example
976 ///
977 /// ```no_run
978 /// use inkwell::context::Context;
979 /// use inkwell::AddressSpace;
980 ///
981 /// let context = Context::create();
982 /// let ptr_type = context.ptr_type(AddressSpace::default());
983 ///
984 /// assert_eq!(ptr_type.get_address_space(), AddressSpace::default());
985 /// assert_eq!(ptr_type.get_context(), context);
986 /// ```
987 #[cfg(not(feature = "typed-pointers"))]
988 #[inline]
989 pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType<'_> {
990 self.context.ptr_type(address_space)
991 }
992
993 /// Creates a `StructType` definition from heterogeneous types in the current `Context`.
994 ///
995 /// # Example
996 ///
997 /// ```no_run
998 /// use inkwell::context::Context;
999 ///
1000 /// let context = Context::create();
1001 /// let f32_type = context.f32_type();
1002 /// let i16_type = context.i16_type();
1003 /// let struct_type = context.struct_type(&[i16_type.into(), f32_type.into()], false);
1004 ///
1005 /// assert_eq!(struct_type.get_field_types(), &[i16_type.into(), f32_type.into()]);
1006 /// ```
1007 // REVIEW: AnyType but VoidType? FunctionType?
1008 #[inline]
1009 pub fn struct_type<'ctx>(&'ctx self, field_types: &[BasicTypeEnum], packed: bool) -> StructType<'ctx> {
1010 self.context.struct_type(field_types, packed)
1011 }
1012
1013 /// Creates an opaque `StructType` with no type definition yet defined.
1014 ///
1015 /// # Example
1016 ///
1017 /// ```no_run
1018 /// use inkwell::context::Context;
1019 ///
1020 /// let context = Context::create();
1021 /// let f32_type = context.f32_type();
1022 /// let i16_type = context.i16_type();
1023 /// let struct_type = context.opaque_struct_type("my_struct");
1024 ///
1025 /// assert_eq!(struct_type.get_field_types(), &[]);
1026 /// ```
1027 #[inline]
1028 pub fn opaque_struct_type<'ctx>(&'ctx self, name: &str) -> StructType<'ctx> {
1029 self.context.opaque_struct_type(name)
1030 }
1031
1032 /// Gets a named [`StructType`] from this `Context`.
1033 ///
1034 /// # Example
1035 ///
1036 /// ```rust,no_run
1037 /// use inkwell::context::Context;
1038 ///
1039 /// let context = Context::create();
1040 ///
1041 /// assert!(context.get_struct_type("foo").is_none());
1042 ///
1043 /// let opaque = context.opaque_struct_type("foo");
1044 ///
1045 /// assert_eq!(context.get_struct_type("foo").unwrap(), opaque);
1046 /// ```
1047 #[inline]
1048 #[llvm_versions(12..)]
1049 pub fn get_struct_type<'ctx>(&self, name: &str) -> Option<StructType<'ctx>> {
1050 self.context.get_struct_type(name)
1051 }
1052
1053 /// Creates a constant `StructValue` from constant values.
1054 ///
1055 /// # Example
1056 ///
1057 /// ```no_run
1058 /// use inkwell::context::Context;
1059 ///
1060 /// let context = Context::create();
1061 /// let f32_type = context.f32_type();
1062 /// let i16_type = context.i16_type();
1063 /// let f32_one = f32_type.const_float(1.);
1064 /// let i16_two = i16_type.const_int(2, false);
1065 /// let const_struct = context.const_struct(&[i16_two.into(), f32_one.into()], false);
1066 ///
1067 /// assert_eq!(const_struct.get_type().get_field_types(), &[i16_type.into(), f32_type.into()]);
1068 /// ```
1069 #[inline]
1070 pub fn const_struct<'ctx>(&'ctx self, values: &[BasicValueEnum], packed: bool) -> StructValue<'ctx> {
1071 self.context.const_struct(values, packed)
1072 }
1073
1074 /// Append a named `BasicBlock` at the end of the referenced `FunctionValue`.
1075 ///
1076 /// # Example
1077 ///
1078 /// ```no_run
1079 /// use inkwell::context::Context;
1080 ///
1081 /// let context = Context::create();
1082 /// let module = context.create_module("my_mod");
1083 /// let void_type = context.void_type();
1084 /// let fn_type = void_type.fn_type(&[], false);
1085 /// let fn_value = module.add_function("my_fn", fn_type, None);
1086 /// let entry_basic_block = context.append_basic_block(fn_value, "entry");
1087 ///
1088 /// assert_eq!(fn_value.count_basic_blocks(), 1);
1089 ///
1090 /// let last_basic_block = context.append_basic_block(fn_value, "last");
1091 ///
1092 /// assert_eq!(fn_value.count_basic_blocks(), 2);
1093 /// assert_eq!(fn_value.get_first_basic_block().unwrap(), entry_basic_block);
1094 /// assert_eq!(fn_value.get_last_basic_block().unwrap(), last_basic_block);
1095 /// ```
1096 #[inline]
1097 pub fn append_basic_block<'ctx>(&'ctx self, function: FunctionValue<'ctx>, name: &str) -> BasicBlock<'ctx> {
1098 self.context.append_basic_block(function, name)
1099 }
1100
1101 /// Append a named `BasicBlock` after the referenced `BasicBlock`.
1102 ///
1103 /// # Example
1104 ///
1105 /// ```no_run
1106 /// use inkwell::context::Context;
1107 ///
1108 /// let context = Context::create();
1109 /// let module = context.create_module("my_mod");
1110 /// let void_type = context.void_type();
1111 /// let fn_type = void_type.fn_type(&[], false);
1112 /// let fn_value = module.add_function("my_fn", fn_type, None);
1113 /// let entry_basic_block = context.append_basic_block(fn_value, "entry");
1114 ///
1115 /// assert_eq!(fn_value.count_basic_blocks(), 1);
1116 ///
1117 /// let last_basic_block = context.insert_basic_block_after(entry_basic_block, "last");
1118 ///
1119 /// assert_eq!(fn_value.count_basic_blocks(), 2);
1120 /// assert_eq!(fn_value.get_first_basic_block().unwrap(), entry_basic_block);
1121 /// assert_eq!(fn_value.get_last_basic_block().unwrap(), last_basic_block);
1122 /// ```
1123 // REVIEW: What happens when using these methods and the BasicBlock doesn't have a parent?
1124 // Should they be callable at all? Needs testing to see what LLVM will do, I suppose. See below unwrap.
1125 // Maybe need SubTypes: BasicBlock<HasParent>, BasicBlock<Orphan>?
1126 #[inline]
1127 pub fn insert_basic_block_after<'ctx>(&'ctx self, basic_block: BasicBlock<'ctx>, name: &str) -> BasicBlock<'ctx> {
1128 self.context.insert_basic_block_after(basic_block, name)
1129 }
1130
1131 /// Prepend a named `BasicBlock` before the referenced `BasicBlock`.
1132 ///
1133 /// # Example
1134 ///
1135 /// ```no_run
1136 /// use inkwell::context::Context;
1137 ///
1138 /// let context = Context::create();
1139 /// let module = context.create_module("my_mod");
1140 /// let void_type = context.void_type();
1141 /// let fn_type = void_type.fn_type(&[], false);
1142 /// let fn_value = module.add_function("my_fn", fn_type, None);
1143 /// let entry_basic_block = context.append_basic_block(fn_value, "entry");
1144 ///
1145 /// assert_eq!(fn_value.count_basic_blocks(), 1);
1146 ///
1147 /// let first_basic_block = context.prepend_basic_block(entry_basic_block, "first");
1148 ///
1149 /// assert_eq!(fn_value.count_basic_blocks(), 2);
1150 /// assert_eq!(fn_value.get_first_basic_block().unwrap(), first_basic_block);
1151 /// assert_eq!(fn_value.get_last_basic_block().unwrap(), entry_basic_block);
1152 /// ```
1153 #[inline]
1154 pub fn prepend_basic_block<'ctx>(&'ctx self, basic_block: BasicBlock<'ctx>, name: &str) -> BasicBlock<'ctx> {
1155 self.context.prepend_basic_block(basic_block, name)
1156 }
1157
1158 /// Creates a `MetadataValue` tuple of heterogeneous types (a "Node") for the current context. It can be assigned to a value.
1159 ///
1160 /// # Example
1161 ///
1162 /// ```no_run
1163 /// use inkwell::context::Context;
1164 ///
1165 /// let context = Context::create();
1166 /// let i8_type = context.i8_type();
1167 /// let i8_two = i8_type.const_int(2, false);
1168 /// let f32_type = context.f32_type();
1169 /// let f32_zero = f32_type.const_float(0.);
1170 /// let md_node = context.metadata_node(&[i8_two.into(), f32_zero.into()]);
1171 /// let f32_one = f32_type.const_float(1.);
1172 /// let void_type = context.void_type();
1173 ///
1174 /// let builder = context.create_builder();
1175 /// let module = context.create_module("my_mod");
1176 /// let fn_type = void_type.fn_type(&[f32_type.into()], false);
1177 /// let fn_value = module.add_function("my_func", fn_type, None);
1178 /// let entry_block = context.append_basic_block(fn_value, "entry");
1179 ///
1180 /// builder.position_at_end(entry_block);
1181 ///
1182 /// let ret_instr = builder.build_return(None).unwrap();
1183 ///
1184 /// assert!(md_node.is_node());
1185 ///
1186 /// ret_instr.set_metadata(md_node, 0);
1187 /// ```
1188 // REVIEW: Maybe more helpful to beginners to call this metadata_tuple?
1189 // REVIEW: Seems to be unassgned to anything
1190 #[inline]
1191 pub fn metadata_node<'ctx>(&'ctx self, values: &[BasicMetadataValueEnum<'ctx>]) -> MetadataValue<'ctx> {
1192 self.context.metadata_node(values)
1193 }
1194
1195 /// Creates a `MetadataValue` string for the current context. It can be assigned to a value.
1196 ///
1197 /// # Example
1198 ///
1199 /// ```no_run
1200 /// use inkwell::context::Context;
1201 ///
1202 /// let context = Context::create();
1203 /// let md_string = context.metadata_string("Floats are awesome!");
1204 /// let md_node = context.metadata_node(&[md_string.into()]);
1205 /// let f32_type = context.f32_type();
1206 /// let f32_one = f32_type.const_float(1.);
1207 /// let void_type = context.void_type();
1208 ///
1209 /// let builder = context.create_builder();
1210 /// let module = context.create_module("my_mod");
1211 /// let fn_type = void_type.fn_type(&[f32_type.into()], false);
1212 /// let fn_value = module.add_function("my_func", fn_type, None);
1213 /// let entry_block = context.append_basic_block(fn_value, "entry");
1214 ///
1215 /// builder.position_at_end(entry_block);
1216 ///
1217 /// let ret_instr = builder.build_return(None).unwrap();
1218 ///
1219 /// assert!(md_string.is_string());
1220 ///
1221 /// ret_instr.set_metadata(md_node, 0);
1222 /// ```
1223 // REVIEW: Seems to be unassigned to anything
1224 #[inline]
1225 pub fn metadata_string<'ctx>(&'ctx self, string: &str) -> MetadataValue<'ctx> {
1226 self.context.metadata_string(string)
1227 }
1228
1229 /// Obtains the index of a metadata kind id. If the string doesn't exist, LLVM will add it at index `FIRST_CUSTOM_METADATA_KIND_ID` onward.
1230 ///
1231 /// # Example
1232 ///
1233 /// ```no_run
1234 /// use inkwell::context::Context;
1235 /// use inkwell::values::FIRST_CUSTOM_METADATA_KIND_ID;
1236 ///
1237 /// let context = Context::create();
1238 ///
1239 /// assert_eq!(context.get_kind_id("dbg"), 0);
1240 /// assert_eq!(context.get_kind_id("tbaa"), 1);
1241 /// assert_eq!(context.get_kind_id("prof"), 2);
1242 ///
1243 /// // Custom kind id doesn't exist in LLVM until now:
1244 /// assert_eq!(context.get_kind_id("foo"), FIRST_CUSTOM_METADATA_KIND_ID);
1245 /// ```
1246 #[inline]
1247 pub fn get_kind_id(&self, key: &str) -> u32 {
1248 self.context.get_kind_id(key)
1249 }
1250
1251 // LLVM 3.9+
1252 // pub fn get_diagnostic_handler(&self) -> DiagnosticHandler {
1253 // let handler = unsafe {
1254 // LLVMContextGetDiagnosticHandler(self.context)
1255 // };
1256
1257 // // REVIEW: Can this be null?
1258
1259 // DiagnosticHandler::new(handler)
1260 // }
1261
1262 /// Creates an enum `Attribute` in this `Context`.
1263 ///
1264 /// # Example
1265 ///
1266 /// ```no_run
1267 /// use inkwell::context::Context;
1268 ///
1269 /// let context = Context::create();
1270 /// let enum_attribute = context.create_enum_attribute(0, 10);
1271 ///
1272 /// assert!(enum_attribute.is_enum());
1273 /// ```
1274 #[inline]
1275 pub fn create_enum_attribute(&self, kind_id: u32, val: u64) -> Attribute {
1276 self.context.create_enum_attribute(kind_id, val)
1277 }
1278
1279 /// Creates a string `Attribute` in this `Context`.
1280 ///
1281 /// # Example
1282 ///
1283 /// ```no_run
1284 /// use inkwell::context::Context;
1285 ///
1286 /// let context = Context::create();
1287 /// let string_attribute = context.create_string_attribute("my_key_123", "my_val");
1288 ///
1289 /// assert!(string_attribute.is_string());
1290 /// ```
1291 #[inline]
1292 pub fn create_string_attribute(&self, key: &str, val: &str) -> Attribute {
1293 self.context.create_string_attribute(key, val)
1294 }
1295
1296 /// Create an enum `Attribute` with an `AnyTypeEnum` attached to it.
1297 ///
1298 /// # Example
1299 /// ```rust
1300 /// use inkwell::context::Context;
1301 /// use inkwell::attributes::Attribute;
1302 /// use inkwell::types::AnyType;
1303 ///
1304 /// let context = Context::create();
1305 /// let kind_id = Attribute::get_named_enum_kind_id("sret");
1306 /// let any_type = context.i32_type().as_any_type_enum();
1307 /// let type_attribute = context.create_type_attribute(
1308 /// kind_id,
1309 /// any_type,
1310 /// );
1311 ///
1312 /// assert!(type_attribute.is_type());
1313 /// assert_eq!(type_attribute.get_type_value(), any_type);
1314 /// assert_ne!(type_attribute.get_type_value(), context.i64_type().as_any_type_enum());
1315 /// ```
1316 #[inline]
1317 #[llvm_versions(12..)]
1318 pub fn create_type_attribute(&self, kind_id: u32, type_ref: AnyTypeEnum) -> Attribute {
1319 self.context.create_type_attribute(kind_id, type_ref)
1320 }
1321
1322 /// Creates a const string which may be null terminated.
1323 ///
1324 /// # Example
1325 ///
1326 /// ```no_run
1327 /// use inkwell::context::Context;
1328 /// use inkwell::values::AnyValue;
1329 ///
1330 /// let context = Context::create();
1331 /// let string = context.const_string(b"my_string", false);
1332 ///
1333 /// assert_eq!(string.print_to_string().to_string(), "[9 x i8] c\"my_string\"");
1334 /// ```
1335 // SubTypes: Should return ArrayValue<IntValue<i8>>
1336 #[inline]
1337 pub fn const_string<'ctx>(&'ctx self, string: &[u8], null_terminated: bool) -> ArrayValue<'ctx> {
1338 self.context.const_string(string, null_terminated)
1339 }
1340
1341 #[allow(dead_code)]
1342 #[inline]
1343 pub(crate) fn set_diagnostic_handler(
1344 &self,
1345 handler: extern "C" fn(LLVMDiagnosticInfoRef, *mut c_void),
1346 void_ptr: *mut c_void,
1347 ) {
1348 self.context.set_diagnostic_handler(handler, void_ptr)
1349 }
1350}
1351
1352impl Drop for Context {
1353 fn drop(&mut self) {
1354 unsafe {
1355 LLVMContextDispose(self.context.0);
1356 }
1357 }
1358}
1359
1360/// A `ContextRef` is a smart pointer allowing borrowed access to a type's `Context`.
1361#[derive(Debug, PartialEq, Eq, Clone, Copy)]
1362pub struct ContextRef<'ctx> {
1363 pub(crate) context: ContextImpl,
1364 _marker: PhantomData<&'ctx Context>,
1365}
1366
1367impl<'ctx> ContextRef<'ctx> {
1368 /// Get raw [`LLVMContextRef`].
1369 ///
1370 /// This function is exposed only for interoperability with other LLVM IR libraries.
1371 /// It's not intended to be used by most users.
1372 pub fn raw(&self) -> LLVMContextRef {
1373 self.context.0
1374 }
1375
1376 /// Creates a new `ContextRef` from [`LLVMContextRef`].
1377 ///
1378 /// # Safety
1379 ///
1380 /// This function is exposed only for interoperability with other LLVM IR libraries.
1381 /// It's not intended to be used by most users, hence marked as unsafe.
1382 pub unsafe fn new(context: LLVMContextRef) -> Self {
1383 unsafe {
1384 ContextRef {
1385 context: ContextImpl::new(context),
1386 _marker: PhantomData,
1387 }
1388 }
1389 }
1390
1391 /// Creates a new `Builder` for a `Context`.
1392 ///
1393 /// # Example
1394 ///
1395 /// ```no_run
1396 /// use inkwell::context::Context;
1397 ///
1398 /// let context = Context::create();
1399 /// let builder = context.create_builder();
1400 /// ```
1401 #[inline]
1402 pub fn create_builder(&self) -> Builder<'ctx> {
1403 self.context.create_builder()
1404 }
1405
1406 /// Creates a new `Module` for a `Context`.
1407 ///
1408 /// # Example
1409 ///
1410 /// ```no_run
1411 /// use inkwell::context::Context;
1412 ///
1413 /// let context = Context::create();
1414 /// let module = context.create_module("my_module");
1415 /// ```
1416 #[inline]
1417 pub fn create_module(&self, name: &str) -> Module<'ctx> {
1418 self.context.create_module(name)
1419 }
1420
1421 /// Creates a new `Module` for the current `Context` from a `MemoryBuffer`.
1422 ///
1423 /// # Example
1424 ///
1425 /// ```no_run
1426 /// use inkwell::context::Context;
1427 ///
1428 /// let context = Context::create();
1429 /// let module = context.create_module("my_module");
1430 /// let builder = context.create_builder();
1431 /// let void_type = context.void_type();
1432 /// let fn_type = void_type.fn_type(&[], false);
1433 /// let fn_val = module.add_function("my_fn", fn_type, None);
1434 /// let basic_block = context.append_basic_block(fn_val, "entry");
1435 ///
1436 /// builder.position_at_end(basic_block);
1437 /// builder.build_return(None).unwrap();
1438 ///
1439 /// let memory_buffer = module.write_bitcode_to_memory();
1440 ///
1441 /// let module2 = context.create_module_from_ir(memory_buffer).unwrap();
1442 /// ```
1443 // REVIEW: I haven't yet been able to find docs or other wrappers that confirm, but my suspicion
1444 // is that the method needs to take ownership of the MemoryBuffer... otherwise I see what looks like
1445 // a double free in valgrind when the MemoryBuffer drops so we are `forget`ting MemoryBuffer here
1446 // for now until we can confirm this is the correct thing to do
1447 #[inline]
1448 pub fn create_module_from_ir(&self, memory_buffer: MemoryBuffer) -> Result<Module<'ctx>, LLVMString> {
1449 self.context.create_module_from_ir(memory_buffer)
1450 }
1451
1452 /// Creates a inline asm function pointer.
1453 ///
1454 /// # Example
1455 /// ```no_run
1456 /// use std::convert::TryFrom;
1457 /// use inkwell::context::Context;
1458 ///
1459 /// let context = Context::create();
1460 /// let module = context.create_module("my_module");
1461 /// let builder = context.create_builder();
1462 /// let void_type = context.void_type();
1463 /// let fn_type = void_type.fn_type(&[], false);
1464 /// let fn_val = module.add_function("my_fn", fn_type, None);
1465 /// let basic_block = context.append_basic_block(fn_val, "entry");
1466 ///
1467 /// builder.position_at_end(basic_block);
1468 /// let asm_fn = context.i64_type().fn_type(&[context.i64_type().into(), context.i64_type().into()], false);
1469 /// let asm = context.create_inline_asm(
1470 /// asm_fn,
1471 /// "syscall".to_string(),
1472 /// "=r,{rax},{rdi}".to_string(),
1473 /// true,
1474 /// false,
1475 /// None,
1476 /// #[cfg(not(any(
1477 /// feature = "llvm11-0",
1478 /// feature = "llvm12-0"
1479 /// )))]
1480 /// false,
1481 /// );
1482 /// let params = &[context.i64_type().const_int(60, false).into(), context.i64_type().const_int(1, false).into()];
1483 ///
1484 /// #[cfg(any(
1485 /// feature = "llvm11-0",
1486 /// feature = "llvm12-0",
1487 /// feature = "llvm13-0",
1488 /// feature = "llvm14-0"
1489 /// ))]
1490 /// {
1491 /// use inkwell::values::CallableValue;
1492 /// let callable_value = CallableValue::try_from(asm).unwrap();
1493 /// builder.build_call(callable_value, params, "exit").unwrap();
1494 /// }
1495 ///
1496 /// #[cfg(any(feature = "llvm15-0", feature = "llvm16-0", feature = "llvm17-0", feature = "llvm18-1", feature = "llvm19-1", feature = "llvm20-1", feature = "llvm21-1", feature = "llvm22-1"))]
1497 /// builder.build_indirect_call(asm_fn, asm, params, "exit").unwrap();
1498 ///
1499 /// builder.build_return(None).unwrap();
1500 /// ```
1501 #[inline]
1502 pub fn create_inline_asm(
1503 &self,
1504 ty: FunctionType<'ctx>,
1505 assembly: String,
1506 constraints: String,
1507 sideeffects: bool,
1508 alignstack: bool,
1509 dialect: Option<InlineAsmDialect>,
1510 #[cfg(not(any(feature = "llvm11-0", feature = "llvm12-0")))] can_throw: bool,
1511 ) -> PointerValue<'ctx> {
1512 self.context.create_inline_asm(
1513 ty,
1514 assembly,
1515 constraints,
1516 sideeffects,
1517 alignstack,
1518 dialect,
1519 #[cfg(not(any(feature = "llvm11-0", feature = "llvm12-0")))]
1520 can_throw,
1521 )
1522 }
1523
1524 /// Gets the `VoidType`. It will be assigned the current context.
1525 ///
1526 /// # Example
1527 ///
1528 /// ```no_run
1529 /// use inkwell::context::Context;
1530 ///
1531 /// let context = Context::create();
1532 /// let void_type = context.void_type();
1533 ///
1534 /// assert_eq!(void_type.get_context(), context);
1535 /// ```
1536 #[inline]
1537 pub fn void_type(&self) -> VoidType<'ctx> {
1538 self.context.void_type()
1539 }
1540
1541 /// Gets the `IntType` representing 1 bit width. It will be assigned the current context.
1542 ///
1543 /// # Example
1544 ///
1545 /// ```no_run
1546 /// use inkwell::context::Context;
1547 ///
1548 /// let context = Context::create();
1549 /// let bool_type = context.bool_type();
1550 ///
1551 /// assert_eq!(bool_type.get_bit_width(), 1);
1552 /// assert_eq!(bool_type.get_context(), context);
1553 /// ```
1554 #[inline]
1555 pub fn bool_type(&self) -> IntType<'ctx> {
1556 self.context.bool_type()
1557 }
1558
1559 /// Gets the `IntType` representing 8 bit width. It will be assigned the current context.
1560 ///
1561 /// # Example
1562 ///
1563 /// ```no_run
1564 /// use inkwell::context::Context;
1565 ///
1566 /// let context = Context::create();
1567 /// let i8_type = context.i8_type();
1568 ///
1569 /// assert_eq!(i8_type.get_bit_width(), 8);
1570 /// assert_eq!(i8_type.get_context(), context);
1571 /// ```
1572 #[inline]
1573 pub fn i8_type(&self) -> IntType<'ctx> {
1574 self.context.i8_type()
1575 }
1576
1577 /// Gets the `IntType` representing 16 bit width. It will be assigned the current context.
1578 ///
1579 /// # Example
1580 ///
1581 /// ```no_run
1582 /// use inkwell::context::Context;
1583 ///
1584 /// let context = Context::create();
1585 /// let i16_type = context.i16_type();
1586 ///
1587 /// assert_eq!(i16_type.get_bit_width(), 16);
1588 /// assert_eq!(i16_type.get_context(), context);
1589 /// ```
1590 #[inline]
1591 pub fn i16_type(&self) -> IntType<'ctx> {
1592 self.context.i16_type()
1593 }
1594
1595 /// Gets the `IntType` representing 32 bit width. It will be assigned the current context.
1596 ///
1597 /// # Example
1598 ///
1599 /// ```no_run
1600 /// use inkwell::context::Context;
1601 ///
1602 /// let context = Context::create();
1603 /// let i32_type = context.i32_type();
1604 ///
1605 /// assert_eq!(i32_type.get_bit_width(), 32);
1606 /// assert_eq!(i32_type.get_context(), context);
1607 /// ```
1608 #[inline]
1609 pub fn i32_type(&self) -> IntType<'ctx> {
1610 self.context.i32_type()
1611 }
1612
1613 /// Gets the `IntType` representing 64 bit width. It will be assigned the current context.
1614 ///
1615 /// # Example
1616 ///
1617 /// ```no_run
1618 /// use inkwell::context::Context;
1619 ///
1620 /// let context = Context::create();
1621 /// let i64_type = context.i64_type();
1622 ///
1623 /// assert_eq!(i64_type.get_bit_width(), 64);
1624 /// assert_eq!(i64_type.get_context(), context);
1625 /// ```
1626 #[inline]
1627 pub fn i64_type(&self) -> IntType<'ctx> {
1628 self.context.i64_type()
1629 }
1630
1631 /// Gets the `IntType` representing 128 bit width. It will be assigned the current context.
1632 ///
1633 /// # Example
1634 ///
1635 /// ```no_run
1636 /// use inkwell::context::Context;
1637 ///
1638 /// let context = Context::create();
1639 /// let i128_type = context.i128_type();
1640 ///
1641 /// assert_eq!(i128_type.get_bit_width(), 128);
1642 /// assert_eq!(i128_type.get_context(), context);
1643 /// ```
1644 #[inline]
1645 pub fn i128_type(&self) -> IntType<'ctx> {
1646 self.context.i128_type()
1647 }
1648
1649 /// Gets the `IntType` representing a custom bit width. It will be assigned the current context.
1650 ///
1651 /// # Example
1652 ///
1653 /// ```no_run
1654 /// use std::num::NonZeroU32;
1655 /// use inkwell::context::Context;
1656 ///
1657 /// let context = Context::create();
1658 /// let width = NonZeroU32::new(42).unwrap();
1659 /// let i42_type = context.custom_width_int_type(width).unwrap();
1660 ///
1661 /// assert_eq!(i42_type.get_bit_width(), 42);
1662 /// assert_eq!(i42_type.get_context(), context);
1663 /// ```
1664 #[inline]
1665 pub fn custom_width_int_type(&self, bits: NonZeroU32) -> Result<IntType<'ctx>, &'static str> {
1666 self.context.custom_width_int_type(bits)
1667 }
1668
1669 /// Gets the `MetadataType` representing 128 bit width. It will be assigned the current context.
1670 ///
1671 /// # Example
1672 ///
1673 /// ```
1674 /// use inkwell::context::Context;
1675 /// use inkwell::values::IntValue;
1676 ///
1677 /// let context = Context::create();
1678 /// let md_type = context.metadata_type();
1679 ///
1680 /// assert_eq!(md_type.get_context(), context);
1681 /// ```
1682 #[inline]
1683 pub fn metadata_type(&self) -> MetadataType<'ctx> {
1684 self.context.metadata_type()
1685 }
1686
1687 /// Gets the `IntType` representing a bit width of a pointer. It will be assigned the referenced context.
1688 ///
1689 /// # Example
1690 ///
1691 /// ```no_run
1692 /// use inkwell::OptimizationLevel;
1693 /// use inkwell::context::Context;
1694 /// use inkwell::targets::{InitializationConfig, Target};
1695 ///
1696 /// Target::initialize_native(&InitializationConfig::default()).expect("Failed to initialize native target");
1697 ///
1698 /// let context = Context::create();
1699 /// let module = context.create_module("sum");
1700 /// let execution_engine = module.create_jit_execution_engine(OptimizationLevel::None).unwrap();
1701 /// let target_data = execution_engine.get_target_data();
1702 /// let int_type = context.ptr_sized_int_type(&target_data, None);
1703 /// ```
1704 #[inline]
1705 pub fn ptr_sized_int_type(&self, target_data: &TargetData, address_space: Option<AddressSpace>) -> IntType<'ctx> {
1706 self.context.ptr_sized_int_type(target_data, address_space)
1707 }
1708
1709 /// Gets the `FloatType` representing a 16 bit width. It will be assigned the current context.
1710 ///
1711 /// # Example
1712 ///
1713 /// ```no_run
1714 /// use inkwell::context::Context;
1715 ///
1716 /// let context = Context::create();
1717 ///
1718 /// let f16_type = context.f16_type();
1719 ///
1720 /// assert_eq!(f16_type.get_context(), context);
1721 /// ```
1722 #[inline]
1723 pub fn f16_type(&self) -> FloatType<'ctx> {
1724 self.context.f16_type()
1725 }
1726
1727 /// Gets the `FloatType` representing bfloat16 with a 16 bit width. It will be assigned the current context.
1728 /// This is only available with LLVM >= 11.
1729 ///
1730 /// # Example
1731 ///
1732 /// ```no_run
1733 /// use inkwell::context::Context;
1734 ///
1735 /// let context = Context::create();
1736 ///
1737 /// let bf16_type = context.bf16_type();
1738 ///
1739 /// assert_eq!(bf16_type.get_context(), context);
1740 /// ```
1741 #[cfg(any(
1742 feature = "llvm11-0",
1743 feature = "llvm12-0",
1744 feature = "llvm13-0",
1745 feature = "llvm14-0",
1746 feature = "llvm15-0",
1747 feature = "llvm16-0",
1748 feature = "llvm17-0",
1749 feature = "llvm18-1",
1750 feature = "llvm19-1",
1751 feature = "llvm20-1",
1752 feature = "llvm21-1",
1753 feature = "llvm22-1",
1754 ))]
1755 #[inline]
1756 pub fn bf16_type(&self) -> FloatType<'ctx> {
1757 self.context.bf16_type()
1758 }
1759
1760 /// Gets the `FloatType` representing a 32 bit width. It will be assigned the current context.
1761 ///
1762 /// # Example
1763 ///
1764 /// ```no_run
1765 /// use inkwell::context::Context;
1766 ///
1767 /// let context = Context::create();
1768 ///
1769 /// let f32_type = context.f32_type();
1770 ///
1771 /// assert_eq!(f32_type.get_context(), context);
1772 /// ```
1773 #[inline]
1774 pub fn f32_type(&self) -> FloatType<'ctx> {
1775 self.context.f32_type()
1776 }
1777
1778 /// Gets the `FloatType` representing a 64 bit width. It will be assigned the current context.
1779 ///
1780 /// # Example
1781 ///
1782 /// ```no_run
1783 /// use inkwell::context::Context;
1784 ///
1785 /// let context = Context::create();
1786 ///
1787 /// let f64_type = context.f64_type();
1788 ///
1789 /// assert_eq!(f64_type.get_context(), context);
1790 /// ```
1791 #[inline]
1792 pub fn f64_type(&self) -> FloatType<'ctx> {
1793 self.context.f64_type()
1794 }
1795
1796 /// Gets the `FloatType` representing a 80 bit width. It will be assigned the current context.
1797 ///
1798 /// # Example
1799 ///
1800 /// ```no_run
1801 /// use inkwell::context::Context;
1802 ///
1803 /// let context = Context::create();
1804 ///
1805 /// let x86_f80_type = context.x86_f80_type();
1806 ///
1807 /// assert_eq!(x86_f80_type.get_context(), context);
1808 /// ```
1809 #[inline]
1810 pub fn x86_f80_type(&self) -> FloatType<'ctx> {
1811 self.context.x86_f80_type()
1812 }
1813
1814 /// Gets the `FloatType` representing a 128 bit width. It will be assigned the current context.
1815 ///
1816 /// # Example
1817 ///
1818 /// ```no_run
1819 /// use inkwell::context::Context;
1820 ///
1821 /// let context = Context::create();
1822 ///
1823 /// let f128_type = context.f128_type();
1824 ///
1825 /// assert_eq!(f128_type.get_context(), context);
1826 /// ```
1827 // IEEE 754-2008’s binary128 floats according to https://internals.rust-lang.org/t/pre-rfc-introduction-of-half-and-quadruple-precision-floats-f16-and-f128/7521
1828 #[inline]
1829 pub fn f128_type(&self) -> FloatType<'ctx> {
1830 self.context.f128_type()
1831 }
1832
1833 /// Gets the `FloatType` representing a 128 bit width. It will be assigned the current context.
1834 ///
1835 /// PPC is two 64 bits side by side rather than one single 128 bit float.
1836 ///
1837 /// # Example
1838 ///
1839 /// ```no_run
1840 /// use inkwell::context::Context;
1841 ///
1842 /// let context = Context::create();
1843 ///
1844 /// let f128_type = context.ppc_f128_type();
1845 ///
1846 /// assert_eq!(f128_type.get_context(), context);
1847 /// ```
1848 // Two 64 bits according to https://internals.rust-lang.org/t/pre-rfc-introduction-of-half-and-quadruple-precision-floats-f16-and-f128/7521
1849 #[inline]
1850 pub fn ppc_f128_type(&self) -> FloatType<'ctx> {
1851 self.context.ppc_f128_type()
1852 }
1853
1854 /// Gets the `PointerType`. It will be assigned the current context.
1855 ///
1856 /// # Example
1857 ///
1858 /// ```no_run
1859 /// use inkwell::context::Context;
1860 /// use inkwell::AddressSpace;
1861 ///
1862 /// let context = Context::create();
1863 /// let ptr_type = context.ptr_type(AddressSpace::default());
1864 ///
1865 /// assert_eq!(ptr_type.get_address_space(), AddressSpace::default());
1866 /// assert_eq!(ptr_type.get_context(), context);
1867 /// ```
1868 #[cfg(not(feature = "typed-pointers"))]
1869 #[inline]
1870 pub fn ptr_type(&self, address_space: AddressSpace) -> PointerType<'ctx> {
1871 self.context.ptr_type(address_space)
1872 }
1873
1874 /// Creates a `StructType` definition from heterogeneous types in the current `Context`.
1875 ///
1876 /// # Example
1877 ///
1878 /// ```no_run
1879 /// use inkwell::context::Context;
1880 ///
1881 /// let context = Context::create();
1882 /// let f32_type = context.f32_type();
1883 /// let i16_type = context.i16_type();
1884 /// let struct_type = context.struct_type(&[i16_type.into(), f32_type.into()], false);
1885 ///
1886 /// assert_eq!(struct_type.get_field_types(), &[i16_type.into(), f32_type.into()]);
1887 /// ```
1888 // REVIEW: AnyType but VoidType? FunctionType?
1889 #[inline]
1890 pub fn struct_type(&self, field_types: &[BasicTypeEnum<'ctx>], packed: bool) -> StructType<'ctx> {
1891 self.context.struct_type(field_types, packed)
1892 }
1893
1894 /// Creates an opaque `StructType` with no type definition yet defined.
1895 ///
1896 /// # Example
1897 ///
1898 /// ```no_run
1899 /// use inkwell::context::Context;
1900 ///
1901 /// let context = Context::create();
1902 /// let f32_type = context.f32_type();
1903 /// let i16_type = context.i16_type();
1904 /// let struct_type = context.opaque_struct_type("my_struct");
1905 ///
1906 /// assert_eq!(struct_type.get_field_types(), &[]);
1907 /// ```
1908 #[inline]
1909 pub fn opaque_struct_type(&self, name: &str) -> StructType<'ctx> {
1910 self.context.opaque_struct_type(name)
1911 }
1912
1913 /// Gets a named [`StructType`] from this `Context`.
1914 ///
1915 /// # Example
1916 ///
1917 /// ```rust,no_run
1918 /// use inkwell::context::Context;
1919 ///
1920 /// let context = Context::create();
1921 ///
1922 /// assert!(context.get_struct_type("foo").is_none());
1923 ///
1924 /// let opaque = context.opaque_struct_type("foo");
1925 ///
1926 /// assert_eq!(context.get_struct_type("foo").unwrap(), opaque);
1927 /// ```
1928 #[inline]
1929 #[llvm_versions(12..)]
1930 pub fn get_struct_type(&self, name: &str) -> Option<StructType<'ctx>> {
1931 self.context.get_struct_type(name)
1932 }
1933
1934 /// Creates a constant `StructValue` from constant values.
1935 ///
1936 /// # Example
1937 ///
1938 /// ```no_run
1939 /// use inkwell::context::Context;
1940 ///
1941 /// let context = Context::create();
1942 /// let f32_type = context.f32_type();
1943 /// let i16_type = context.i16_type();
1944 /// let f32_one = f32_type.const_float(1.);
1945 /// let i16_two = i16_type.const_int(2, false);
1946 /// let const_struct = context.const_struct(&[i16_two.into(), f32_one.into()], false);
1947 ///
1948 /// assert_eq!(const_struct.get_type().get_field_types(), &[i16_type.into(), f32_type.into()]);
1949 /// ```
1950 #[inline]
1951 pub fn const_struct(&self, values: &[BasicValueEnum<'ctx>], packed: bool) -> StructValue<'ctx> {
1952 self.context.const_struct(values, packed)
1953 }
1954
1955 /// Append a named `BasicBlock` at the end of the referenced `FunctionValue`.
1956 ///
1957 /// # Example
1958 ///
1959 /// ```no_run
1960 /// use inkwell::context::Context;
1961 ///
1962 /// let context = Context::create();
1963 /// let module = context.create_module("my_mod");
1964 /// let void_type = context.void_type();
1965 /// let fn_type = void_type.fn_type(&[], false);
1966 /// let fn_value = module.add_function("my_fn", fn_type, None);
1967 /// let entry_basic_block = context.append_basic_block(fn_value, "entry");
1968 ///
1969 /// assert_eq!(fn_value.count_basic_blocks(), 1);
1970 ///
1971 /// let last_basic_block = context.append_basic_block(fn_value, "last");
1972 ///
1973 /// assert_eq!(fn_value.count_basic_blocks(), 2);
1974 /// assert_eq!(fn_value.get_first_basic_block().unwrap(), entry_basic_block);
1975 /// assert_eq!(fn_value.get_last_basic_block().unwrap(), last_basic_block);
1976 /// ```
1977 #[inline]
1978 pub fn append_basic_block(&self, function: FunctionValue<'ctx>, name: &str) -> BasicBlock<'ctx> {
1979 self.context.append_basic_block(function, name)
1980 }
1981
1982 /// Append a named `BasicBlock` after the referenced `BasicBlock`.
1983 ///
1984 /// # Example
1985 ///
1986 /// ```no_run
1987 /// use inkwell::context::Context;
1988 ///
1989 /// let context = Context::create();
1990 /// let module = context.create_module("my_mod");
1991 /// let void_type = context.void_type();
1992 /// let fn_type = void_type.fn_type(&[], false);
1993 /// let fn_value = module.add_function("my_fn", fn_type, None);
1994 /// let entry_basic_block = context.append_basic_block(fn_value, "entry");
1995 ///
1996 /// assert_eq!(fn_value.count_basic_blocks(), 1);
1997 ///
1998 /// let last_basic_block = context.insert_basic_block_after(entry_basic_block, "last");
1999 ///
2000 /// assert_eq!(fn_value.count_basic_blocks(), 2);
2001 /// assert_eq!(fn_value.get_first_basic_block().unwrap(), entry_basic_block);
2002 /// assert_eq!(fn_value.get_last_basic_block().unwrap(), last_basic_block);
2003 /// ```
2004 // REVIEW: What happens when using these methods and the BasicBlock doesn't have a parent?
2005 // Should they be callable at all? Needs testing to see what LLVM will do, I suppose. See below unwrap.
2006 // Maybe need SubTypes: BasicBlock<HasParent>, BasicBlock<Orphan>?
2007 #[inline]
2008 pub fn insert_basic_block_after(&self, basic_block: BasicBlock<'ctx>, name: &str) -> BasicBlock<'ctx> {
2009 self.context.insert_basic_block_after(basic_block, name)
2010 }
2011
2012 /// Prepend a named `BasicBlock` before the referenced `BasicBlock`.
2013 ///
2014 /// # Example
2015 ///
2016 /// ```no_run
2017 /// use inkwell::context::Context;
2018 ///
2019 /// let context = Context::create();
2020 /// let module = context.create_module("my_mod");
2021 /// let void_type = context.void_type();
2022 /// let fn_type = void_type.fn_type(&[], false);
2023 /// let fn_value = module.add_function("my_fn", fn_type, None);
2024 /// let entry_basic_block = context.append_basic_block(fn_value, "entry");
2025 ///
2026 /// assert_eq!(fn_value.count_basic_blocks(), 1);
2027 ///
2028 /// let first_basic_block = context.prepend_basic_block(entry_basic_block, "first");
2029 ///
2030 /// assert_eq!(fn_value.count_basic_blocks(), 2);
2031 /// assert_eq!(fn_value.get_first_basic_block().unwrap(), first_basic_block);
2032 /// assert_eq!(fn_value.get_last_basic_block().unwrap(), entry_basic_block);
2033 /// ```
2034 #[inline]
2035 pub fn prepend_basic_block(&self, basic_block: BasicBlock<'ctx>, name: &str) -> BasicBlock<'ctx> {
2036 self.context.prepend_basic_block(basic_block, name)
2037 }
2038
2039 /// Creates a `MetadataValue` tuple of heterogeneous types (a "Node") for the current context. It can be assigned to a value.
2040 ///
2041 /// # Example
2042 ///
2043 /// ```no_run
2044 /// use inkwell::context::Context;
2045 ///
2046 /// let context = Context::create();
2047 /// let i8_type = context.i8_type();
2048 /// let i8_two = i8_type.const_int(2, false);
2049 /// let f32_type = context.f32_type();
2050 /// let f32_zero = f32_type.const_float(0.);
2051 /// let md_node = context.metadata_node(&[i8_two.into(), f32_zero.into()]);
2052 /// let f32_one = f32_type.const_float(1.);
2053 /// let void_type = context.void_type();
2054 ///
2055 /// let builder = context.create_builder();
2056 /// let module = context.create_module("my_mod");
2057 /// let fn_type = void_type.fn_type(&[f32_type.into()], false);
2058 /// let fn_value = module.add_function("my_func", fn_type, None);
2059 /// let entry_block = context.append_basic_block(fn_value, "entry");
2060 ///
2061 /// builder.position_at_end(entry_block);
2062 ///
2063 /// let ret_instr = builder.build_return(None).unwrap();
2064 ///
2065 /// assert!(md_node.is_node());
2066 ///
2067 /// ret_instr.set_metadata(md_node, 0);
2068 /// ```
2069 // REVIEW: Maybe more helpful to beginners to call this metadata_tuple?
2070 // REVIEW: Seems to be unassgned to anything
2071 #[inline]
2072 pub fn metadata_node(&self, values: &[BasicMetadataValueEnum<'ctx>]) -> MetadataValue<'ctx> {
2073 self.context.metadata_node(values)
2074 }
2075
2076 /// Creates a `MetadataValue` string for the current context. It can be assigned to a value.
2077 ///
2078 /// # Example
2079 ///
2080 /// ```no_run
2081 /// use inkwell::context::Context;
2082 ///
2083 /// let context = Context::create();
2084 /// let md_string = context.metadata_string("Floats are awesome!");
2085 /// let f32_type = context.f32_type();
2086 /// let f32_one = f32_type.const_float(1.);
2087 /// let void_type = context.void_type();
2088 ///
2089 /// let builder = context.create_builder();
2090 /// let module = context.create_module("my_mod");
2091 /// let fn_type = void_type.fn_type(&[f32_type.into()], false);
2092 /// let fn_value = module.add_function("my_func", fn_type, None);
2093 /// let entry_block = context.append_basic_block(fn_value, "entry");
2094 ///
2095 /// builder.position_at_end(entry_block);
2096 ///
2097 /// let ret_instr = builder.build_return(None).unwrap();
2098 ///
2099 /// assert!(md_string.is_string());
2100 ///
2101 /// ret_instr.set_metadata(md_string, 0);
2102 /// ```
2103 // REVIEW: Seems to be unassigned to anything
2104 #[inline]
2105 pub fn metadata_string(&self, string: &str) -> MetadataValue<'ctx> {
2106 self.context.metadata_string(string)
2107 }
2108
2109 /// Obtains the index of a metadata kind id. If the string doesn't exist, LLVM will add it at index `FIRST_CUSTOM_METADATA_KIND_ID` onward.
2110 ///
2111 /// # Example
2112 ///
2113 /// ```no_run
2114 /// use inkwell::context::Context;
2115 /// use inkwell::values::FIRST_CUSTOM_METADATA_KIND_ID;
2116 ///
2117 /// let context = Context::create();
2118 ///
2119 /// assert_eq!(context.get_kind_id("dbg"), 0);
2120 /// assert_eq!(context.get_kind_id("tbaa"), 1);
2121 /// assert_eq!(context.get_kind_id("prof"), 2);
2122 ///
2123 /// // Custom kind id doesn't exist in LLVM until now:
2124 /// assert_eq!(context.get_kind_id("foo"), FIRST_CUSTOM_METADATA_KIND_ID);
2125 /// ```
2126 #[inline]
2127 pub fn get_kind_id(&self, key: &str) -> u32 {
2128 self.context.get_kind_id(key)
2129 }
2130
2131 /// Creates an enum `Attribute` in this `Context`.
2132 ///
2133 /// # Example
2134 ///
2135 /// ```no_run
2136 /// use inkwell::context::Context;
2137 ///
2138 /// let context = Context::create();
2139 /// let enum_attribute = context.create_enum_attribute(0, 10);
2140 ///
2141 /// assert!(enum_attribute.is_enum());
2142 /// ```
2143 #[inline]
2144 pub fn create_enum_attribute(&self, kind_id: u32, val: u64) -> Attribute {
2145 self.context.create_enum_attribute(kind_id, val)
2146 }
2147
2148 /// Creates a string `Attribute` in this `Context`.
2149 ///
2150 /// # Example
2151 ///
2152 /// ```no_run
2153 /// use inkwell::context::Context;
2154 ///
2155 /// let context = Context::create();
2156 /// let string_attribute = context.create_string_attribute("my_key_123", "my_val");
2157 ///
2158 /// assert!(string_attribute.is_string());
2159 /// ```
2160 #[inline]
2161 pub fn create_string_attribute(&self, key: &str, val: &str) -> Attribute {
2162 self.context.create_string_attribute(key, val)
2163 }
2164
2165 /// Create an enum `Attribute` with an `AnyTypeEnum` attached to it.
2166 ///
2167 /// # Example
2168 /// ```rust
2169 /// use inkwell::context::Context;
2170 /// use inkwell::attributes::Attribute;
2171 /// use inkwell::types::AnyType;
2172 ///
2173 /// let context = Context::create();
2174 /// let kind_id = Attribute::get_named_enum_kind_id("sret");
2175 /// let any_type = context.i32_type().as_any_type_enum();
2176 /// let type_attribute = context.create_type_attribute(
2177 /// kind_id,
2178 /// any_type,
2179 /// );
2180 ///
2181 /// assert!(type_attribute.is_type());
2182 /// assert_eq!(type_attribute.get_type_value(), any_type);
2183 /// assert_ne!(type_attribute.get_type_value(), context.i64_type().as_any_type_enum());
2184 /// ```
2185 #[inline]
2186 #[llvm_versions(12..)]
2187 pub fn create_type_attribute(&self, kind_id: u32, type_ref: AnyTypeEnum) -> Attribute {
2188 self.context.create_type_attribute(kind_id, type_ref)
2189 }
2190
2191 /// Creates a const string which may be null terminated.
2192 ///
2193 /// # Example
2194 ///
2195 /// ```no_run
2196 /// use inkwell::context::Context;
2197 /// use inkwell::values::AnyValue;
2198 ///
2199 /// let context = Context::create();
2200 /// let string = context.const_string(b"my_string", false);
2201 ///
2202 /// assert_eq!(string.print_to_string().to_string(), "[9 x i8] c\"my_string\"");
2203 /// ```
2204 // SubTypes: Should return ArrayValue<IntValue<i8>>
2205 #[inline]
2206 pub fn const_string(&self, string: &[u8], null_terminated: bool) -> ArrayValue<'ctx> {
2207 self.context.const_string(string, null_terminated)
2208 }
2209
2210 #[inline]
2211 pub(crate) fn set_diagnostic_handler(
2212 &self,
2213 handler: extern "C" fn(LLVMDiagnosticInfoRef, *mut c_void),
2214 void_ptr: *mut c_void,
2215 ) {
2216 self.context.set_diagnostic_handler(handler, void_ptr)
2217 }
2218}
2219
2220/// This trait abstracts an LLVM `Context` type and should be implemented with caution.
2221pub unsafe trait AsContextRef<'ctx> {
2222 /// Returns the internal LLVM reference behind the type
2223 fn as_ctx_ref(&self) -> LLVMContextRef;
2224}
2225
2226unsafe impl<'ctx> AsContextRef<'ctx> for &'ctx Context {
2227 /// Acquires the underlying raw pointer belonging to this `Context` type.
2228 fn as_ctx_ref(&self) -> LLVMContextRef {
2229 self.context.0
2230 }
2231}
2232
2233unsafe impl<'ctx> AsContextRef<'ctx> for ContextRef<'ctx> {
2234 /// Acquires the underlying raw pointer belonging to this `ContextRef` type.
2235 fn as_ctx_ref(&self) -> LLVMContextRef {
2236 self.context.0
2237 }
2238}