Skip to main content

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}