llvm_plugin_inkwell/
context.rs

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