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