inkwell/
context.rs

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