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}