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