Coverage Report

Created: 2026-02-14 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/inkwell-0.8.0/src/builder.rs
Line
Count
Source
1
//! A `Builder` enables you to build instructions.
2
3
#[llvm_versions(18..)]
4
use llvm_sys::core::LLVMBuildCallWithOperandBundles;
5
use llvm_sys::core::{
6
    LLVMAddCase, LLVMAddClause, LLVMAddDestination, LLVMBuildAShr, LLVMBuildAdd, LLVMBuildAddrSpaceCast,
7
    LLVMBuildAggregateRet, LLVMBuildAlloca, LLVMBuildAnd, LLVMBuildArrayAlloca, LLVMBuildArrayMalloc,
8
    LLVMBuildAtomicCmpXchg, LLVMBuildAtomicRMW, LLVMBuildBinOp, LLVMBuildBitCast, LLVMBuildBr, LLVMBuildCast,
9
    LLVMBuildCondBr, LLVMBuildExactSDiv, LLVMBuildExtractElement, LLVMBuildExtractValue, LLVMBuildFAdd, LLVMBuildFCmp,
10
    LLVMBuildFDiv, LLVMBuildFMul, LLVMBuildFNeg, LLVMBuildFPCast, LLVMBuildFPExt, LLVMBuildFPToSI, LLVMBuildFPToUI,
11
    LLVMBuildFPTrunc, LLVMBuildFRem, LLVMBuildFSub, LLVMBuildFence, LLVMBuildFree, LLVMBuildGlobalString,
12
    LLVMBuildICmp, LLVMBuildIndirectBr, LLVMBuildInsertElement, LLVMBuildInsertValue, LLVMBuildIntCast,
13
    LLVMBuildIntToPtr, LLVMBuildIsNotNull, LLVMBuildIsNull, LLVMBuildLShr, LLVMBuildLandingPad, LLVMBuildMalloc,
14
    LLVMBuildMul, LLVMBuildNSWAdd, LLVMBuildNSWMul, LLVMBuildNSWNeg, LLVMBuildNSWSub, LLVMBuildNUWAdd, LLVMBuildNUWMul,
15
    LLVMBuildNUWSub, LLVMBuildNeg, LLVMBuildNot, LLVMBuildOr, LLVMBuildPhi, LLVMBuildPointerCast, LLVMBuildPtrToInt,
16
    LLVMBuildResume, LLVMBuildRet, LLVMBuildRetVoid, LLVMBuildSDiv, LLVMBuildSExt, LLVMBuildSExtOrBitCast,
17
    LLVMBuildSIToFP, LLVMBuildSRem, LLVMBuildSelect, LLVMBuildShl, LLVMBuildShuffleVector, LLVMBuildStore,
18
    LLVMBuildSub, LLVMBuildSwitch, LLVMBuildTrunc, LLVMBuildTruncOrBitCast, LLVMBuildUDiv, LLVMBuildUIToFP,
19
    LLVMBuildURem, LLVMBuildUnreachable, LLVMBuildVAArg, LLVMBuildXor, LLVMBuildZExt, LLVMBuildZExtOrBitCast,
20
    LLVMClearInsertionPosition, LLVMDisposeBuilder, LLVMGetInsertBlock, LLVMInsertIntoBuilder,
21
    LLVMInsertIntoBuilderWithName, LLVMPositionBuilder, LLVMPositionBuilderAtEnd, LLVMPositionBuilderBefore,
22
    LLVMSetCleanup,
23
};
24
25
#[llvm_versions(..20)]
26
use llvm_sys::core::LLVMBuildGlobalStringPtr;
27
28
#[llvm_versions(20..)]
29
use llvm_sys::core::LLVMBuildGlobalString as LLVMBuildGlobalStringPtr;
30
31
#[llvm_versions(..17)]
32
use llvm_sys::core::LLVMBuildNUWNeg;
33
34
#[llvm_versions(17..)]
35
use llvm_sys::core::LLVMSetNUW;
36
37
#[llvm_versions(..=14)]
38
#[allow(deprecated)]
39
use llvm_sys::core::{LLVMBuildCall, LLVMBuildInvoke};
40
#[llvm_versions(15..)]
41
use llvm_sys::core::{LLVMBuildCall2, LLVMBuildInvoke2};
42
#[cfg(all(feature = "typed-pointers", not(feature = "llvm16-0")))]
43
#[allow(deprecated)]
44
use llvm_sys::core::{LLVMBuildGEP, LLVMBuildInBoundsGEP, LLVMBuildLoad, LLVMBuildPtrDiff, LLVMBuildStructGEP};
45
#[cfg(any(not(feature = "typed-pointers"), feature = "llvm16-0"))]
46
use llvm_sys::core::{LLVMBuildGEP2, LLVMBuildInBoundsGEP2, LLVMBuildLoad2, LLVMBuildPtrDiff2, LLVMBuildStructGEP2};
47
use llvm_sys::core::{LLVMBuildIntCast2, LLVMBuildMemCpy, LLVMBuildMemMove, LLVMBuildMemSet};
48
use llvm_sys::prelude::{LLVMBuilderRef, LLVMValueRef};
49
use thiserror::Error;
50
51
use crate::basic_block::BasicBlock;
52
use crate::debug_info::DILocation;
53
use crate::support::to_c_str;
54
#[llvm_versions(15..)]
55
use crate::types::FunctionType;
56
use crate::types::{AsTypeRef, BasicType, FloatMathType, IntMathType, PointerMathType, PointerType};
57
#[llvm_versions(18..)]
58
use crate::values::operand_bundle::OperandBundle;
59
#[llvm_versions(..=14)]
60
use crate::values::CallableValue;
61
use crate::values::{
62
    AggregateValue, AggregateValueEnum, AsValueRef, BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallSiteValue,
63
    FloatMathValue, FunctionValue, GlobalValue, InstructionOpcode, InstructionValue, IntMathValue, IntValue, PhiValue,
64
    PointerMathValue, PointerValue, StructValue, VectorBaseValue,
65
};
66
67
use crate::error::AlignmentError;
68
use crate::{AtomicOrdering, AtomicRMWBinOp, FloatPredicate, IntPredicate};
69
70
use std::cell::Cell;
71
use std::marker::PhantomData;
72
73
#[derive(Debug, PartialEq, Clone, Copy)]
74
enum PositionState {
75
    NotSet,
76
    Set,
77
}
78
79
#[derive(Error, Debug, PartialEq, Eq)]
80
pub enum OrderingError {
81
    #[error("Both success and failure orderings must be monotonic or stronger.")]
82
    WeakerThanMonotic,
83
    #[error("The failure ordering may not be stronger than the success ordering.")]
84
    WeakerSuccessOrdering,
85
    #[error("The failure ordering may not be release or acquire release.")]
86
    ReleaseOrAcqRel,
87
}
88
89
/// Errors that can be generated by the Builder. All `build_*` methods return a `Result<_, BuilderError>`, which must be handled.
90
#[derive(Error, Debug, PartialEq, Eq)]
91
pub enum BuilderError {
92
    #[error("Builder position is not set")]
93
    UnsetPosition,
94
    #[error("Alignment error")]
95
    AlignmentError(#[from] crate::error::AlignmentError),
96
    #[error("Aggregate extract index out of range")]
97
    ExtractOutOfRange,
98
    #[error("The bitwidth of value must be a power of 2 and greater than or equal to 8.")]
99
    BitwidthError,
100
    #[error("Pointee type does not match the value's type")]
101
    PointeeTypeMismatch,
102
    #[error("Values must have the same type")]
103
    NotSameType,
104
    #[error("Values must have pointer or integer type")]
105
    NotPointerOrInteger,
106
    #[error("Ordering error or mismatch")]
107
    OrderingError(OrderingError),
108
    #[error("GEP pointee is not a struct")]
109
    GEPPointee,
110
    #[error("GEP index out of range")]
111
    GEPIndex,
112
}
113
114
#[derive(Debug)]
115
/// All `build_*` methods return a `Result<_, BuilderError>` type containing either the returned value or some error.
116
/// Those methods all may return `BuilderError::UnsetPosition` if a `position_*` method has not yet been called, in addition
117
/// to any other possibility.
118
pub struct Builder<'ctx> {
119
    builder: LLVMBuilderRef,
120
    positioned: Cell<PositionState>,
121
    _marker: PhantomData<&'ctx ()>,
122
}
123
124
#[allow(unused)] // only used in documentation
125
use crate::context::Context;
126
127
impl<'ctx> Builder<'ctx> {
128
338k
    pub unsafe fn new(builder: LLVMBuilderRef) -> Self {
129
338k
        debug_assert!(!builder.is_null());
130
131
338k
        Builder {
132
338k
            positioned: Cell::from(PositionState::NotSet),
133
338k
            builder,
134
338k
            _marker: PhantomData,
135
338k
        }
136
338k
    }
137
138
    /// Acquires the underlying raw pointer belonging to this `Builder` type.
139
0
    pub fn as_mut_ptr(&self) -> LLVMBuilderRef {
140
0
        self.builder
141
0
    }
142
143
    // REVIEW: Would probably make this API a bit simpler by taking Into<Option<&BasicValue>>
144
    // So that you could just do build_return(&value) or build_return(None). Is that frowned upon?
145
    /// Builds a function return instruction. It should be provided with `None` if the return type
146
    /// is void otherwise `Some(&value)` should be provided.
147
    ///
148
    /// # Example
149
    ///
150
    /// ```no_run
151
    /// use inkwell::context::Context;
152
    ///
153
    /// // A simple function which returns its argument:
154
    /// let context = Context::create();
155
    /// let module = context.create_module("ret");
156
    /// let builder = context.create_builder();
157
    /// let i32_type = context.i32_type();
158
    /// let arg_types = [i32_type.into()];
159
    /// let fn_type = i32_type.fn_type(&arg_types, false);
160
    /// let fn_value = module.add_function("ret", fn_type, None);
161
    /// let entry = context.append_basic_block(fn_value, "entry");
162
    /// let i32_arg = fn_value.get_first_param().unwrap();
163
    ///
164
    /// builder.position_at_end(entry);
165
    /// builder.build_return(Some(&i32_arg)).unwrap();
166
    /// ```
167
181k
    pub fn build_return(&self, value: Option<&dyn BasicValue<'ctx>>) -> Result<InstructionValue<'ctx>, BuilderError> {
168
181k
        if self.positioned.get() != PositionState::Set {
169
0
            return Err(BuilderError::UnsetPosition);
170
181k
        }
171
181k
        let value = unsafe {
172
181k
            value.map_or_else(
173
160k
                || LLVMBuildRetVoid(self.builder),
174
21.3k
                |value| LLVMBuildRet(self.builder, value.as_value_ref()),
175
            )
176
        };
177
178
181k
        unsafe { Ok(InstructionValue::new(value)) }
179
181k
    }
180
181
    /// Builds a function return instruction for a return type which is an aggregate type (ie structs and arrays).
182
    /// It is not necessary to use this over `build_return` but may be more convenient to use.
183
    ///
184
    /// # Example
185
    ///
186
    /// ```no_run
187
    /// use inkwell::context::Context;
188
    ///
189
    /// // This builds a simple function which returns a struct (tuple) of two ints.
190
    /// let context = Context::create();
191
    /// let module = context.create_module("ret");
192
    /// let builder = context.create_builder();
193
    /// let i32_type = context.i32_type();
194
    /// let i32_three = i32_type.const_int(3, false);
195
    /// let i32_seven = i32_type.const_int(7, false);
196
    /// let struct_type = context.struct_type(&[i32_type.into(), i32_type.into()], false);
197
    /// let fn_type = struct_type.fn_type(&[], false);
198
    /// let fn_value = module.add_function("ret", fn_type, None);
199
    /// let entry = context.append_basic_block(fn_value, "entry");
200
    ///
201
    /// builder.position_at_end(entry);
202
    /// builder.build_aggregate_return(&[i32_three.into(), i32_seven.into()]).unwrap();
203
    /// ```
204
0
    pub fn build_aggregate_return(
205
0
        &self,
206
0
        values: &[BasicValueEnum<'ctx>],
207
0
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
208
0
        if self.positioned.get() != PositionState::Set {
209
0
            return Err(BuilderError::UnsetPosition);
210
0
        }
211
0
        let mut args: Vec<LLVMValueRef> = values.iter().map(|val| val.as_value_ref()).collect();
212
0
        let value = unsafe { LLVMBuildAggregateRet(self.builder, args.as_mut_ptr(), args.len() as u32) };
213
214
0
        unsafe { Ok(InstructionValue::new(value)) }
215
0
    }
216
217
    /// Builds a function call instruction.
218
    /// [`FunctionValue`]s can be implicitly converted into a [`CallableValue`].
219
    /// See [`CallableValue`] for details on calling a [`PointerValue`] that points to a function.
220
    ///
221
    /// [`FunctionValue`]: crate::values::FunctionValue
222
    ///
223
    /// # Example
224
    ///
225
    /// ```no_run
226
    /// use inkwell::context::Context;
227
    ///
228
    /// // A simple function which calls itself:
229
    /// let context = Context::create();
230
    /// let module = context.create_module("ret");
231
    /// let builder = context.create_builder();
232
    /// let i32_type = context.i32_type();
233
    /// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
234
    /// let fn_value = module.add_function("ret", fn_type, None);
235
    /// let entry = context.append_basic_block(fn_value, "entry");
236
    /// let i32_arg = fn_value.get_first_param().unwrap();
237
    /// let md_string = context.metadata_string("a metadata");
238
    ///
239
    /// builder.position_at_end(entry);
240
    ///
241
    /// let ret_val = builder.build_call(fn_value, &[i32_arg.into(), md_string.into()], "call").unwrap()
242
    ///     .try_as_basic_value()
243
    ///     .unwrap_basic();
244
    ///
245
    /// builder.build_return(Some(&ret_val)).unwrap();
246
    /// ```
247
    #[llvm_versions(..=14)]
248
    pub fn build_call<F>(
249
        &self,
250
        function: F,
251
        args: &[BasicMetadataValueEnum<'ctx>],
252
        name: &str,
253
    ) -> Result<CallSiteValue<'ctx>, BuilderError>
254
    where
255
        F: Into<CallableValue<'ctx>>,
256
    {
257
        if self.positioned.get() != PositionState::Set {
258
            return Err(BuilderError::UnsetPosition);
259
        }
260
        let callable_value = function.into();
261
        let fn_val_ref = callable_value.as_value_ref();
262
263
        // LLVM gets upset when void return calls are named because they don't return anything
264
        let name = if callable_value.returns_void() { "" } else { name };
265
266
        let c_string = to_c_str(name);
267
        let mut args: Vec<LLVMValueRef> = args.iter().map(|val| val.as_value_ref()).collect();
268
269
        #[allow(deprecated)]
270
        let value = unsafe {
271
            LLVMBuildCall(
272
                self.builder,
273
                fn_val_ref,
274
                args.as_mut_ptr(),
275
                args.len() as u32,
276
                c_string.as_ptr(),
277
            )
278
        };
279
280
        unsafe { Ok(CallSiteValue::new(value)) }
281
    }
282
283
    /// Builds a function call instruction. Alias for [Builder::build_direct_call].
284
    #[llvm_versions(15..)]
285
803k
    pub fn build_call(
286
803k
        &self,
287
803k
        function: FunctionValue<'ctx>,
288
803k
        args: &[BasicMetadataValueEnum<'ctx>],
289
803k
        name: &str,
290
803k
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
291
803k
        if self.positioned.get() != PositionState::Set {
292
0
            return Err(BuilderError::UnsetPosition);
293
803k
        }
294
803k
        self.build_direct_call(function, args, name)
295
803k
    }
296
297
    /// Builds a function call instruction. The function being called is known at compile time. If
298
    /// you want to call a function pointer, see [Builder::build_indirect_call].
299
    ///
300
    /// # Example
301
    ///
302
    /// ```no_run
303
    /// use inkwell::context::Context;
304
    ///
305
    /// // A simple function which calls itself:
306
    /// let context = Context::create();
307
    /// let module = context.create_module("ret");
308
    /// let builder = context.create_builder();
309
    /// let i32_type = context.i32_type();
310
    /// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
311
    /// let fn_value = module.add_function("ret", fn_type, None);
312
    /// let entry = context.append_basic_block(fn_value, "entry");
313
    /// let i32_arg = fn_value.get_first_param().unwrap();
314
    /// let md_string = context.metadata_string("a metadata");
315
    ///
316
    /// builder.position_at_end(entry);
317
    ///
318
    /// let ret_val = builder.build_call(fn_value, &[i32_arg.into(), md_string.into()], "call").unwrap()
319
    ///     .try_as_basic_value()
320
    ///     .unwrap_basic();
321
    ///
322
    /// builder.build_return(Some(&ret_val)).unwrap();
323
    /// ```
324
    #[llvm_versions(15..)]
325
862k
    pub fn build_direct_call(
326
862k
        &self,
327
862k
        function: FunctionValue<'ctx>,
328
862k
        args: &[BasicMetadataValueEnum<'ctx>],
329
862k
        name: &str,
330
862k
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
331
862k
        if self.positioned.get() != PositionState::Set {
332
0
            return Err(BuilderError::UnsetPosition);
333
862k
        }
334
862k
        self.build_call_help(function.get_type(), function.as_value_ref(), args, name)
335
862k
    }
336
337
    /// Build a function call instruction, with attached operand bundles.
338
    ///
339
    /// # Example
340
    ///
341
    /// ```
342
    /// use inkwell::context::Context;
343
    /// use inkwell::values::OperandBundle;
344
    ///
345
    /// let context = Context::create();
346
    /// let module = context.create_module("call_with_op_bundles");
347
    /// let builder = context.create_builder();
348
    /// let i32_type = context.i32_type();
349
    ///
350
    /// // declare i32 @func(i32)
351
    /// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
352
    /// let fn_value = module.add_function("func", fn_type, None);
353
    ///
354
    /// let basic_block = context.append_basic_block(fn_value, "entry");
355
    /// builder.position_at_end(basic_block);
356
    ///
357
    /// // %func_ret = call i32 @func(i32 0) [ "tag"(i32 0) ]
358
    /// let ret_val = builder.build_direct_call_with_operand_bundles(
359
    ///     fn_value,
360
    ///     &[i32_type.const_zero().into()],
361
    ///     &[OperandBundle::create("tag", &[i32_type.const_zero().into()])],
362
    ///     "func_ret"
363
    /// )
364
    ///     .unwrap()
365
    ///     .try_as_basic_value()
366
    ///     .unwrap_basic();
367
    /// builder.build_return(Some(&ret_val)).unwrap();
368
    ///
369
    /// # module.verify().unwrap();
370
    /// ```
371
    #[llvm_versions(18..)]
372
0
    pub fn build_direct_call_with_operand_bundles(
373
0
        &self,
374
0
        function: FunctionValue<'ctx>,
375
0
        args: &[BasicMetadataValueEnum<'ctx>],
376
0
        operand_bundles: &[OperandBundle<'ctx>],
377
0
        name: &str,
378
0
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
379
0
        self.build_call_with_operand_bundles_help(
380
0
            function.get_type(),
381
0
            function.as_value_ref(),
382
0
            args,
383
0
            operand_bundles,
384
0
            name,
385
        )
386
0
    }
387
388
    /// Call a function pointer. Because a pointer does not carry a type, the type of the function
389
    /// must be specified explicitly.
390
    ///
391
    /// See [Context::create_inline_asm] for a practical example. Basic usage looks like this:
392
    ///
393
    /// ```no_run
394
    /// use inkwell::context::Context;
395
    ///
396
    /// // A simple function which calls itself:
397
    /// let context = Context::create();
398
    /// let module = context.create_module("ret");
399
    /// let builder = context.create_builder();
400
    /// let i32_type = context.i32_type();
401
    /// let fn_type = i32_type.fn_type(&[i32_type.into()], false);
402
    /// let fn_value = module.add_function("ret", fn_type, None);
403
    /// let entry = context.append_basic_block(fn_value, "entry");
404
    /// let i32_arg = fn_value.get_first_param().unwrap();
405
    /// let md_string = context.metadata_string("a metadata");
406
    ///
407
    /// builder.position_at_end(entry);
408
    ///
409
    /// let function_pointer = fn_value.as_global_value().as_pointer_value();
410
    /// let ret_val = builder.build_indirect_call(fn_value.get_type(), function_pointer, &[i32_arg.into(), md_string.into()], "call").unwrap()
411
    ///     .try_as_basic_value()
412
    ///     .unwrap_basic();
413
    ///
414
    /// builder.build_return(Some(&ret_val)).unwrap();
415
    /// ```
416
    ///
417
    #[llvm_versions(15..)]
418
192k
    pub fn build_indirect_call(
419
192k
        &self,
420
192k
        function_type: FunctionType<'ctx>,
421
192k
        function_pointer: PointerValue<'ctx>,
422
192k
        args: &[BasicMetadataValueEnum<'ctx>],
423
192k
        name: &str,
424
192k
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
425
192k
        if self.positioned.get() != PositionState::Set {
426
0
            return Err(BuilderError::UnsetPosition);
427
192k
        }
428
192k
        self.build_call_help(function_type, function_pointer.as_value_ref(), args, name)
429
192k
    }
430
431
    /// Build a call instruction to a function pointer, with attached operand bundles.
432
    ///
433
    /// See [Builder::build_direct_call_with_operand_bundles] for a usage example
434
    /// with operand bundles.
435
    #[llvm_versions(18..)]
436
0
    pub fn build_indirect_call_with_operand_bundles(
437
0
        &self,
438
0
        function_type: FunctionType<'ctx>,
439
0
        function_pointer: PointerValue<'ctx>,
440
0
        args: &[BasicMetadataValueEnum<'ctx>],
441
0
        operand_bundles: &[OperandBundle<'ctx>],
442
0
        name: &str,
443
0
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
444
0
        self.build_call_with_operand_bundles_help(
445
0
            function_type,
446
0
            function_pointer.as_value_ref(),
447
0
            args,
448
0
            operand_bundles,
449
0
            name,
450
        )
451
0
    }
452
453
    #[llvm_versions(15..)]
454
1.05M
    fn build_call_help(
455
1.05M
        &self,
456
1.05M
        function_type: FunctionType<'ctx>,
457
1.05M
        fn_val_ref: LLVMValueRef,
458
1.05M
        args: &[BasicMetadataValueEnum<'ctx>],
459
1.05M
        name: &str,
460
1.05M
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
461
1.05M
        if self.positioned.get() != PositionState::Set {
462
0
            return Err(BuilderError::UnsetPosition);
463
1.05M
        }
464
        // LLVM gets upset when void return calls are named because they don't return anything
465
1.05M
        let name = match function_type.get_return_type() {
466
293k
            None => "",
467
761k
            Some(_) => name,
468
        };
469
470
1.05M
        let fn_ty_ref = function_type.as_type_ref();
471
472
1.05M
        let c_string = to_c_str(name);
473
2.51M
        let mut args: Vec<LLVMValueRef> = args.iter().map(|val| val.as_value_ref()).collect();
474
475
1.05M
        let value = unsafe {
476
1.05M
            LLVMBuildCall2(
477
1.05M
                self.builder,
478
1.05M
                fn_ty_ref,
479
1.05M
                fn_val_ref,
480
1.05M
                args.as_mut_ptr(),
481
1.05M
                args.len() as u32,
482
1.05M
                c_string.as_ptr(),
483
            )
484
        };
485
486
1.05M
        unsafe { Ok(CallSiteValue::new(value)) }
487
1.05M
    }
488
489
    #[llvm_versions(18..)]
490
0
    fn build_call_with_operand_bundles_help(
491
0
        &self,
492
0
        function_type: FunctionType<'ctx>,
493
0
        fn_val_ref: LLVMValueRef,
494
0
        args: &[BasicMetadataValueEnum<'ctx>],
495
0
        operand_bundles: &[OperandBundle<'ctx>],
496
0
        name: &str,
497
0
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
498
        use llvm_sys::prelude::LLVMOperandBundleRef;
499
500
0
        if self.positioned.get() != PositionState::Set {
501
0
            return Err(BuilderError::UnsetPosition);
502
0
        }
503
        // LLVM gets upset when void return calls are named because they don't return anything
504
0
        let name = match function_type.get_return_type() {
505
0
            None => "",
506
0
            Some(_) => name,
507
        };
508
509
0
        let fn_ty_ref = function_type.as_type_ref();
510
511
0
        let c_string = to_c_str(name);
512
0
        let mut args: Vec<LLVMValueRef> = args.iter().map(|val| val.as_value_ref()).collect();
513
0
        let mut operand_bundles: Vec<LLVMOperandBundleRef> =
514
0
            operand_bundles.iter().map(|val| val.as_mut_ptr()).collect();
515
516
0
        let value = unsafe {
517
0
            LLVMBuildCallWithOperandBundles(
518
0
                self.builder,
519
0
                fn_ty_ref,
520
0
                fn_val_ref,
521
0
                args.as_mut_ptr(),
522
0
                args.len() as u32,
523
0
                operand_bundles.as_mut_ptr(),
524
0
                operand_bundles.len() as u32,
525
0
                c_string.as_ptr(),
526
            )
527
        };
528
529
0
        unsafe { Ok(CallSiteValue::new(value)) }
530
0
    }
531
532
    /// An invoke is similar to a normal function call, but used to
533
    /// call functions that may throw an exception, and then respond to the exception.
534
    ///
535
    /// When the called function returns normally, the `then` block is evaluated next. If instead
536
    /// the function threw an exception, the `catch` block is entered. The first non-phi
537
    /// instruction of the catch block must be a `landingpad` instruction. See also
538
    /// [`Builder::build_landing_pad`].
539
    ///
540
    /// The [`add_prune_eh_pass`] turns an invoke into a call when the called function is
541
    /// guaranteed to never throw an exception.
542
    ///
543
    /// [`add_prune_eh_pass`]: crate::passes::PassManager::add_prune_eh_pass
544
    ///
545
    /// This example catches C++ exceptions of type `int`, and returns `0` if an exceptions is thrown.
546
    /// For usage of a cleanup landing pad and the `resume` instruction, see [`Builder::build_resume`]
547
    /// ```no_run
548
    /// use inkwell::context::Context;
549
    /// use inkwell::AddressSpace;
550
    /// use inkwell::module::Linkage;
551
    ///
552
    /// let context = Context::create();
553
    /// let module = context.create_module("sum");
554
    /// let builder = context.create_builder();
555
    ///
556
    /// let f32_type = context.f32_type();
557
    /// let fn_type = f32_type.fn_type(&[], false);
558
    ///
559
    /// // we will pretend this function can throw an exception
560
    /// let function = module.add_function("bomb", fn_type, None);
561
    /// let basic_block = context.append_basic_block(function, "entry");
562
    ///
563
    /// builder.position_at_end(basic_block);
564
    ///
565
    /// let pi = f32_type.const_float(std::f64::consts::PI);
566
    ///
567
    /// builder.build_return(Some(&pi)).unwrap();
568
    ///
569
    /// let function2 = module.add_function("wrapper", fn_type, None);
570
    /// let basic_block2 = context.append_basic_block(function2, "entry");
571
    ///
572
    /// builder.position_at_end(basic_block2);
573
    ///
574
    /// let then_block = context.append_basic_block(function2, "then_block");
575
    /// let catch_block = context.append_basic_block(function2, "catch_block");
576
    ///
577
    /// let call_site = builder.build_invoke(function, &[], then_block, catch_block, "get_pi").unwrap();
578
    ///
579
    /// {
580
    ///     builder.position_at_end(then_block);
581
    ///
582
    ///     // in the then_block, the `call_site` value is defined and can be used
583
    ///     let result = call_site.try_as_basic_value().unwrap_basic();
584
    ///
585
    ///     builder.build_return(Some(&result)).unwrap();
586
    /// }
587
    ///
588
    /// {
589
    ///     builder.position_at_end(catch_block);
590
    ///
591
    ///     // the personality function used by C++
592
    ///     let personality_function = {
593
    ///         let name = "__gxx_personality_v0";
594
    ///         let linkage = Some(Linkage::External);
595
    ///
596
    ///         module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
597
    ///     };
598
    ///
599
    ///     // type of an exception in C++
600
    ///     #[cfg(feature = "typed-pointers")]
601
    ///     let i8_ptr_type = context.i32_type().ptr_type(AddressSpace::default());
602
    ///     #[cfg(not(feature = "typed-pointers"))]
603
    ///     let i32_ptr_ty = context.ptr_type(AddressSpace::default());
604
    ///     let i32_type = context.i32_type();
605
    ///     let exception_type = context.struct_type(&[i8_ptr_type.into(), i32_type.into()], false);
606
    ///
607
    ///     let null = i8_ptr_type.const_zero();
608
    ///     let res = builder.build_landing_pad(exception_type, personality_function, &[null.into()], false, "res").unwrap();
609
    ///
610
    ///     // we handle the exception by returning a default value
611
    ///     builder.build_return(Some(&f32_type.const_zero())).unwrap();
612
    /// }
613
    /// ```
614
    #[llvm_versions(..=14)]
615
    pub fn build_invoke<F>(
616
        &self,
617
        function: F,
618
        args: &[BasicValueEnum<'ctx>],
619
        then_block: BasicBlock<'ctx>,
620
        catch_block: BasicBlock<'ctx>,
621
        name: &str,
622
    ) -> Result<CallSiteValue<'ctx>, BuilderError>
623
    where
624
        F: Into<CallableValue<'ctx>>,
625
    {
626
        if self.positioned.get() != PositionState::Set {
627
            return Err(BuilderError::UnsetPosition);
628
        }
629
        let callable_value: CallableValue<'ctx> = function.into();
630
        let fn_val_ref = callable_value.as_value_ref();
631
632
        // LLVM gets upset when void return calls are named because they don't return anything
633
        let name = if callable_value.returns_void() { "" } else { name };
634
635
        let c_string = to_c_str(name);
636
        let mut args: Vec<LLVMValueRef> = args.iter().map(|val| val.as_value_ref()).collect();
637
638
        #[allow(deprecated)]
639
        let value = unsafe {
640
            LLVMBuildInvoke(
641
                self.builder,
642
                fn_val_ref,
643
                args.as_mut_ptr(),
644
                args.len() as u32,
645
                then_block.basic_block,
646
                catch_block.basic_block,
647
                c_string.as_ptr(),
648
            )
649
        };
650
651
        Ok(unsafe { CallSiteValue::new(value) })
652
    }
653
654
    /// An invoke is similar to a normal function call, but used to
655
    /// call functions that may throw an exception, and then respond to the exception.
656
    ///
657
    /// When the called function returns normally, the `then` block is evaluated next. If instead
658
    /// the function threw an exception, the `catch` block is entered. The first non-phi
659
    /// instruction of the catch block must be a `landingpad` instruction. See also
660
    /// [`Builder::build_landing_pad`].
661
    ///
662
    /// The [`add_prune_eh_pass`] turns an invoke into a call when the called function is
663
    /// guaranteed to never throw an exception.
664
    ///
665
    /// [`add_prune_eh_pass`]: crate::passes::PassManager::add_prune_eh_pass
666
    ///
667
    /// This example catches C++ exceptions of type `int`, and returns `0` if an exceptions is thrown.
668
    /// For usage of a cleanup landing pad and the `resume` instruction, see [`Builder::build_resume`]
669
    /// ```no_run
670
    /// use inkwell::context::Context;
671
    /// use inkwell::AddressSpace;
672
    /// use inkwell::module::Linkage;
673
    ///
674
    /// let context = Context::create();
675
    /// let module = context.create_module("sum");
676
    /// let builder = context.create_builder();
677
    ///
678
    /// let f32_type = context.f32_type();
679
    /// let fn_type = f32_type.fn_type(&[], false);
680
    ///
681
    /// // we will pretend this function can throw an exception
682
    /// let function = module.add_function("bomb", fn_type, None);
683
    /// let basic_block = context.append_basic_block(function, "entry");
684
    ///
685
    /// builder.position_at_end(basic_block);
686
    ///
687
    /// let pi = f32_type.const_float(std::f64::consts::PI);
688
    ///
689
    /// builder.build_return(Some(&pi)).unwrap();
690
    ///
691
    /// let function2 = module.add_function("wrapper", fn_type, None);
692
    /// let basic_block2 = context.append_basic_block(function2, "entry");
693
    ///
694
    /// builder.position_at_end(basic_block2);
695
    ///
696
    /// let then_block = context.append_basic_block(function2, "then_block");
697
    /// let catch_block = context.append_basic_block(function2, "catch_block");
698
    ///
699
    /// let call_site = builder.build_invoke(function, &[], then_block, catch_block, "get_pi").unwrap();
700
    ///
701
    /// {
702
    ///     builder.position_at_end(then_block);
703
    ///
704
    ///     // in the then_block, the `call_site` value is defined and can be used
705
    ///     let result = call_site.try_as_basic_value().unwrap_basic();
706
    ///
707
    ///     builder.build_return(Some(&result)).unwrap();
708
    /// }
709
    ///
710
    /// {
711
    ///     builder.position_at_end(catch_block);
712
    ///
713
    ///     // the personality function used by C++
714
    ///     let personality_function = {
715
    ///         let name = "__gxx_personality_v0";
716
    ///         let linkage = Some(Linkage::External);
717
    ///
718
    ///         module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
719
    ///     };
720
    ///
721
    ///     // type of an exception in C++
722
    ///     #[cfg(feature = "typed-pointers")]
723
    ///     let ptr_type = context.i8_type().ptr_type(AddressSpace::default());
724
    ///     #[cfg(not(feature = "typed-pointers"))]
725
    ///     let ptr_type = context.ptr_type(AddressSpace::default());
726
    ///     let i32_type = context.i32_type();
727
    ///     let exception_type = context.struct_type(&[ptr_type.into(), i32_type.into()], false);
728
    ///
729
    ///     let null = ptr_type.const_zero();
730
    ///     let res = builder.build_landing_pad(exception_type, personality_function, &[null.into()], false, "res").unwrap();
731
    ///
732
    ///     // we handle the exception by returning a default value
733
    ///     builder.build_return(Some(&f32_type.const_zero())).unwrap();
734
    /// }
735
    /// ```
736
    #[llvm_versions(15..)]
737
10
    pub fn build_invoke(
738
10
        &self,
739
10
        function: FunctionValue<'ctx>,
740
10
        args: &[BasicValueEnum<'ctx>],
741
10
        then_block: BasicBlock<'ctx>,
742
10
        catch_block: BasicBlock<'ctx>,
743
10
        name: &str,
744
10
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
745
10
        if self.positioned.get() != PositionState::Set {
746
0
            return Err(BuilderError::UnsetPosition);
747
10
        }
748
10
        self.build_direct_invoke(function, args, then_block, catch_block, name)
749
10
    }
750
751
    #[llvm_versions(15..)]
752
10
    pub fn build_direct_invoke(
753
10
        &self,
754
10
        function: FunctionValue<'ctx>,
755
10
        args: &[BasicValueEnum<'ctx>],
756
10
        then_block: BasicBlock<'ctx>,
757
10
        catch_block: BasicBlock<'ctx>,
758
10
        name: &str,
759
10
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
760
10
        if self.positioned.get() != PositionState::Set {
761
0
            return Err(BuilderError::UnsetPosition);
762
10
        }
763
10
        self.build_invoke_help(
764
10
            function.get_type(),
765
10
            function.as_value_ref(),
766
10
            args,
767
10
            then_block,
768
10
            catch_block,
769
10
            name,
770
        )
771
10
    }
772
773
    #[llvm_versions(15..)]
774
1.59k
    pub fn build_indirect_invoke(
775
1.59k
        &self,
776
1.59k
        function_type: FunctionType<'ctx>,
777
1.59k
        function_pointer: PointerValue<'ctx>,
778
1.59k
        args: &[BasicValueEnum<'ctx>],
779
1.59k
        then_block: BasicBlock<'ctx>,
780
1.59k
        catch_block: BasicBlock<'ctx>,
781
1.59k
        name: &str,
782
1.59k
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
783
1.59k
        if self.positioned.get() != PositionState::Set {
784
0
            return Err(BuilderError::UnsetPosition);
785
1.59k
        }
786
1.59k
        self.build_invoke_help(
787
1.59k
            function_type,
788
1.59k
            function_pointer.as_value_ref(),
789
1.59k
            args,
790
1.59k
            then_block,
791
1.59k
            catch_block,
792
1.59k
            name,
793
        )
794
1.59k
    }
795
796
    #[llvm_versions(15..)]
797
1.60k
    fn build_invoke_help(
798
1.60k
        &self,
799
1.60k
        fn_ty: FunctionType<'ctx>,
800
1.60k
        fn_val_ref: LLVMValueRef,
801
1.60k
        args: &[BasicValueEnum<'ctx>],
802
1.60k
        then_block: BasicBlock<'ctx>,
803
1.60k
        catch_block: BasicBlock<'ctx>,
804
1.60k
        name: &str,
805
1.60k
    ) -> Result<CallSiteValue<'ctx>, BuilderError> {
806
1.60k
        if self.positioned.get() != PositionState::Set {
807
0
            return Err(BuilderError::UnsetPosition);
808
1.60k
        }
809
1.60k
        let fn_ty_ref = fn_ty.as_type_ref();
810
811
        // LLVM gets upset when void return calls are named because they don't return anything
812
1.60k
        let name = if fn_ty.get_return_type().is_none() { "" } else { name };
813
814
1.60k
        let c_string = to_c_str(name);
815
2.00k
        let mut args: Vec<LLVMValueRef> = args.iter().map(|val| val.as_value_ref()).collect();
816
817
1.60k
        let value = unsafe {
818
1.60k
            LLVMBuildInvoke2(
819
1.60k
                self.builder,
820
1.60k
                fn_ty_ref,
821
1.60k
                fn_val_ref,
822
1.60k
                args.as_mut_ptr(),
823
1.60k
                args.len() as u32,
824
1.60k
                then_block.basic_block,
825
1.60k
                catch_block.basic_block,
826
1.60k
                c_string.as_ptr(),
827
            )
828
        };
829
830
1.60k
        unsafe { Ok(CallSiteValue::new(value)) }
831
1.60k
    }
832
833
    /// Landing pads are places where control flow jumps to if a [`Builder::build_invoke`] triggered an exception.
834
    /// The landing pad will match the exception against its `clauses`. Depending on the clause
835
    /// that is matched, the exception can then be handled, or resumed after some optional cleanup,
836
    /// causing the exception to bubble up.
837
    ///
838
    /// Exceptions in LLVM are designed based on the needs of a C++ compiler, but can be used more generally.
839
    /// Here are some specific examples of landing pads. For a full example of handling an exception, see [`Builder::build_invoke`].
840
    ///
841
    /// * **cleanup**: a cleanup landing pad is always visited when unwinding the stack.
842
    ///   A cleanup is extra code that needs to be run when unwinding a scope. C++ destructors are a typical example.
843
    ///   In a language with reference counting, the cleanup block can decrement the refcount of values in scope.
844
    ///   The [`Builder::build_resume`] function has a full example using a cleanup lading pad.
845
    ///
846
    /// ```no_run
847
    /// use inkwell::context::Context;
848
    /// use inkwell::AddressSpace;
849
    /// use inkwell::module::Linkage;
850
    ///
851
    /// let context = Context::create();
852
    /// let module = context.create_module("sum");
853
    /// let builder = context.create_builder();
854
    ///
855
    /// // type of an exception in C++
856
    /// #[cfg(feature = "typed-pointers")]
857
    /// let i8_ptr_type = context.i8_type().ptr_type(AddressSpace::default());
858
    /// #[cfg(not(feature = "typed-pointers"))]
859
    /// let i8_ptr_type = context.ptr_type(AddressSpace::default());
860
    /// let i32_type = context.i32_type();
861
    /// let exception_type = context.struct_type(&[i8_ptr_type.into(), i32_type.into()], false);
862
    ///
863
    /// // the personality function used by C++
864
    /// let personality_function = {
865
    ///     let name = "__gxx_personality_v0";
866
    ///     let linkage = Some(Linkage::External);
867
    ///
868
    ///     module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
869
    /// };
870
    ///
871
    /// // make the cleanup landing pad
872
    /// let res = builder.build_landing_pad( exception_type, personality_function, &[], true, "res").unwrap();
873
    /// ```
874
    ///
875
    /// * **catch all**: An implementation of the C++ `catch(...)`, which catches all exceptions.
876
    ///   A catch clause with a NULL pointer value will match anything.
877
    ///
878
    /// ```no_run
879
    /// use inkwell::context::Context;
880
    /// use inkwell::AddressSpace;
881
    /// use inkwell::module::Linkage;
882
    ///
883
    /// let context = Context::create();
884
    /// let module = context.create_module("sum");
885
    /// let builder = context.create_builder();
886
    ///
887
    /// // type of an exception in C++
888
    /// #[cfg(feature = "typed-pointers")]
889
    /// let i8_ptr_type = context.i8_type().ptr_type(AddressSpace::default());
890
    /// #[cfg(not(feature = "typed-pointers"))]
891
    /// let i8_ptr_type = context.ptr_type(AddressSpace::default());
892
    /// let i32_type = context.i32_type();
893
    /// let exception_type = context.struct_type(&[i8_ptr_type.into(), i32_type.into()], false);
894
    ///
895
    /// // the personality function used by C++
896
    /// let personality_function = {
897
    ///     let name = "__gxx_personality_v0";
898
    ///     let linkage = Some(Linkage::External);
899
    ///
900
    ///     module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
901
    /// };
902
    ///
903
    /// // make a null pointer of type i8
904
    /// let null = i8_ptr_type.const_zero();
905
    ///
906
    /// // make the catch all landing pad
907
    /// let res = builder.build_landing_pad(exception_type, personality_function, &[null.into()], false, "res").unwrap();
908
    /// ```
909
    ///
910
    /// * **catch a type of exception**: Catch a specific type of exception. The example uses C++'s type info.
911
    ///
912
    /// ```no_run
913
    /// use inkwell::context::Context;
914
    /// use inkwell::module::Linkage;
915
    /// use inkwell::AddressSpace;
916
    /// use inkwell::values::BasicValue;
917
    ///
918
    /// let context = Context::create();
919
    /// let module = context.create_module("sum");
920
    /// let builder = context.create_builder();
921
    ///
922
    /// // type of an exception in C++
923
    /// #[cfg(feature = "typed-pointers")]
924
    /// let i8_ptr_type = context.i8_type().ptr_type(AddressSpace::default());
925
    /// #[cfg(not(feature = "typed-pointers"))]
926
    /// let i8_ptr_type = context.ptr_type(AddressSpace::default());
927
    /// let i32_type = context.i32_type();
928
    /// let exception_type = context.struct_type(&[i8_ptr_type.into(), i32_type.into()], false);
929
    ///
930
    /// // the personality function used by C++
931
    /// let personality_function = {
932
    ///     let name = "__gxx_personality_v0";
933
    ///     let linkage = Some(Linkage::External);
934
    ///
935
    ///     module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
936
    /// };
937
    ///
938
    /// // link in the C++ type info for the `int` type
939
    /// let type_info_int = module.add_global(i8_ptr_type, Some(AddressSpace::default()), "_ZTIi");
940
    /// type_info_int.set_linkage(Linkage::External);
941
    ///
942
    /// // make the catch landing pad
943
    /// let clause = type_info_int.as_basic_value_enum();
944
    /// let res = builder.build_landing_pad(exception_type, personality_function, &[clause], false, "res").unwrap();
945
    /// ```
946
    ///
947
    /// * **filter**: A filter clause encodes that only some types of exceptions are valid at this
948
    ///   point. A filter clause is made by constructing a clause from a constant array.
949
    ///
950
    /// ```no_run
951
    /// use inkwell::context::Context;
952
    /// use inkwell::module::Linkage;
953
    /// use inkwell::values::AnyValue;
954
    /// use inkwell::AddressSpace;
955
    ///
956
    /// let context = Context::create();
957
    /// let module = context.create_module("sum");
958
    /// let builder = context.create_builder();
959
    ///
960
    /// // type of an exception in C++
961
    /// #[cfg(feature = "typed-pointers")]
962
    /// let i8_ptr_type = context.i8_type().ptr_type(AddressSpace::default());
963
    /// #[cfg(not(feature = "typed-pointers"))]
964
    /// let i8_ptr_type = context.ptr_type(AddressSpace::default());
965
    /// let i32_type = context.i32_type();
966
    /// let exception_type = context.struct_type(&[i8_ptr_type.into(), i32_type.into()], false);
967
    ///
968
    /// // the personality function used by C++
969
    /// let personality_function = {
970
    ///     let name = "__gxx_personality_v0";
971
    ///     let linkage = Some(Linkage::External);
972
    ///
973
    ///     module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
974
    /// };
975
    ///
976
    /// // link in the C++ type info for the `int` type
977
    /// let type_info_int = module.add_global(i8_ptr_type, Some(AddressSpace::default()), "_ZTIi");
978
    /// type_info_int.set_linkage(Linkage::External);
979
    ///
980
    /// // make the filter landing pad
981
    /// let filter_pattern = i8_ptr_type.const_array(&[type_info_int.as_any_value_enum().into_pointer_value()]);
982
    /// let res = builder.build_landing_pad(exception_type, personality_function, &[filter_pattern.into()], false, "res").unwrap();
983
    /// ```
984
96.3k
    pub fn build_landing_pad<T>(
985
96.3k
        &self,
986
96.3k
        exception_type: T,
987
96.3k
        personality_function: FunctionValue<'ctx>,
988
96.3k
        clauses: &[BasicValueEnum<'ctx>],
989
96.3k
        is_cleanup: bool,
990
96.3k
        name: &str,
991
96.3k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError>
992
96.3k
    where
993
96.3k
        T: BasicType<'ctx>,
994
    {
995
96.3k
        if self.positioned.get() != PositionState::Set {
996
0
            return Err(BuilderError::UnsetPosition);
997
96.3k
        }
998
96.3k
        let c_string = to_c_str(name);
999
96.3k
        let num_clauses = clauses.len() as u32;
1000
1001
96.3k
        let value = unsafe {
1002
96.3k
            LLVMBuildLandingPad(
1003
96.3k
                self.builder,
1004
96.3k
                exception_type.as_type_ref(),
1005
96.3k
                personality_function.as_value_ref(),
1006
96.3k
                num_clauses,
1007
96.3k
                c_string.as_ptr(),
1008
            )
1009
        };
1010
1011
108k
        for clause in clauses {
1012
108k
            unsafe {
1013
108k
                LLVMAddClause(value, clause.as_value_ref());
1014
108k
            }
1015
        }
1016
1017
96.3k
        unsafe {
1018
96.3k
            LLVMSetCleanup(value, is_cleanup as _);
1019
96.3k
        };
1020
1021
96.3k
        unsafe { Ok(BasicValueEnum::new(value)) }
1022
96.3k
    }
<inkwell::builder::Builder>::build_landing_pad::<inkwell::types::struct_type::StructType>
Line
Count
Source
984
96.3k
    pub fn build_landing_pad<T>(
985
96.3k
        &self,
986
96.3k
        exception_type: T,
987
96.3k
        personality_function: FunctionValue<'ctx>,
988
96.3k
        clauses: &[BasicValueEnum<'ctx>],
989
96.3k
        is_cleanup: bool,
990
96.3k
        name: &str,
991
96.3k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError>
992
96.3k
    where
993
96.3k
        T: BasicType<'ctx>,
994
    {
995
96.3k
        if self.positioned.get() != PositionState::Set {
996
0
            return Err(BuilderError::UnsetPosition);
997
96.3k
        }
998
96.3k
        let c_string = to_c_str(name);
999
96.3k
        let num_clauses = clauses.len() as u32;
1000
1001
96.3k
        let value = unsafe {
1002
96.3k
            LLVMBuildLandingPad(
1003
96.3k
                self.builder,
1004
96.3k
                exception_type.as_type_ref(),
1005
96.3k
                personality_function.as_value_ref(),
1006
96.3k
                num_clauses,
1007
96.3k
                c_string.as_ptr(),
1008
            )
1009
        };
1010
1011
108k
        for clause in clauses {
1012
108k
            unsafe {
1013
108k
                LLVMAddClause(value, clause.as_value_ref());
1014
108k
            }
1015
        }
1016
1017
96.3k
        unsafe {
1018
96.3k
            LLVMSetCleanup(value, is_cleanup as _);
1019
96.3k
        };
1020
1021
96.3k
        unsafe { Ok(BasicValueEnum::new(value)) }
1022
96.3k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_landing_pad::<_>
1023
1024
    /// Resume propagation of an existing (in-flight) exception whose unwinding was interrupted with a landingpad instruction.
1025
    ///
1026
    /// This example uses a cleanup landing pad. A cleanup is extra code that needs to be run when
1027
    /// unwinding a scope. C++ destructors are a typical example. In a language with reference counting,
1028
    /// the cleanup block can decrement the refcount of values in scope.
1029
    ///
1030
    /// ```no_run
1031
    /// use inkwell::context::Context;
1032
    /// use inkwell::AddressSpace;
1033
    /// use inkwell::module::Linkage;
1034
    ///
1035
    /// let context = Context::create();
1036
    /// let module = context.create_module("sum");
1037
    /// let builder = context.create_builder();
1038
    ///
1039
    /// let f32_type = context.f32_type();
1040
    /// let fn_type = f32_type.fn_type(&[], false);
1041
    ///
1042
    /// // we will pretend this function can throw an exception
1043
    /// let function = module.add_function("bomb", fn_type, None);
1044
    /// let basic_block = context.append_basic_block(function, "entry");
1045
    ///
1046
    /// builder.position_at_end(basic_block);
1047
    ///
1048
    /// let pi = f32_type.const_float(std::f64::consts::PI);
1049
    ///
1050
    /// builder.build_return(Some(&pi)).unwrap();
1051
    ///
1052
    /// let function2 = module.add_function("wrapper", fn_type, None);
1053
    /// let basic_block2 = context.append_basic_block(function2, "entry");
1054
    ///
1055
    /// builder.position_at_end(basic_block2);
1056
    ///
1057
    /// let then_block = context.append_basic_block(function2, "then_block");
1058
    /// let catch_block = context.append_basic_block(function2, "catch_block");
1059
    ///
1060
    /// let call_site = builder.build_invoke(function, &[], then_block, catch_block, "get_pi").unwrap();
1061
    ///
1062
    /// {
1063
    ///     builder.position_at_end(then_block);
1064
    ///
1065
    ///     // in the then_block, the `call_site` value is defined and can be used
1066
    ///     let result = call_site.try_as_basic_value().unwrap_basic();
1067
    ///
1068
    ///     builder.build_return(Some(&result)).unwrap();
1069
    /// }
1070
    ///
1071
    /// {
1072
    ///     builder.position_at_end(catch_block);
1073
    ///
1074
    ///     // the personality function used by C++
1075
    ///     let personality_function = {
1076
    ///         let name = "__gxx_personality_v0";
1077
    ///         let linkage = Some(Linkage::External);
1078
    ///
1079
    ///         module.add_function(name, context.i64_type().fn_type(&[], false), linkage)
1080
    ///     };
1081
    ///
1082
    ///     // type of an exception in C++
1083
    ///     #[cfg(feature = "typed-pointers")]
1084
    ///     let i8_ptr_type = context.i8_type().ptr_type(AddressSpace::default());
1085
    ///     #[cfg(not(feature = "typed-pointers"))]
1086
    ///     let i8_ptr_type = context.ptr_type(AddressSpace::default());
1087
    ///     let i32_type = context.i32_type();
1088
    ///     let exception_type = context.struct_type(&[i8_ptr_type.into(), i32_type.into()], false);
1089
    ///
1090
    ///     // make the landing pad; must give a concrete type to the slice
1091
    ///     let res = builder.build_landing_pad( exception_type, personality_function, &[], true, "res").unwrap();
1092
    ///
1093
    ///     // do cleanup ...
1094
    ///
1095
    ///     builder.build_resume(res).unwrap();
1096
    /// }
1097
    /// ```
1098
0
    pub fn build_resume<V: BasicValue<'ctx>>(&self, value: V) -> Result<InstructionValue<'ctx>, BuilderError> {
1099
0
        if self.positioned.get() != PositionState::Set {
1100
0
            return Err(BuilderError::UnsetPosition);
1101
0
        }
1102
0
        let val = unsafe { LLVMBuildResume(self.builder, value.as_value_ref()) };
1103
1104
0
        unsafe { Ok(InstructionValue::new(val)) }
1105
0
    }
1106
1107
    // REVIEW: Doesn't GEP work on array too?
1108
    /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future.
1109
    #[cfg(feature = "typed-pointers")]
1110
    pub unsafe fn build_gep(
1111
        &self,
1112
        ptr: PointerValue<'ctx>,
1113
        ordered_indexes: &[IntValue<'ctx>],
1114
        name: &str,
1115
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1116
        if self.positioned.get() != PositionState::Set {
1117
            return Err(BuilderError::UnsetPosition);
1118
        }
1119
        let c_string = to_c_str(name);
1120
1121
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
1122
1123
        #[cfg(not(feature = "llvm16-0"))]
1124
        #[allow(deprecated)]
1125
        let value = LLVMBuildGEP(
1126
            self.builder,
1127
            ptr.as_value_ref(),
1128
            index_values.as_mut_ptr(),
1129
            index_values.len() as u32,
1130
            c_string.as_ptr(),
1131
        );
1132
        #[cfg(feature = "llvm16-0")]
1133
        let value = LLVMBuildGEP2(
1134
            self.builder,
1135
            ptr.get_type().get_element_type().as_type_ref(),
1136
            ptr.as_value_ref(),
1137
            index_values.as_mut_ptr(),
1138
            index_values.len() as u32,
1139
            c_string.as_ptr(),
1140
        );
1141
1142
        Ok(PointerValue::new(value))
1143
    }
1144
1145
    // REVIEW: Doesn't GEP work on array too?
1146
    /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future.
1147
    #[cfg(not(feature = "typed-pointers"))]
1148
846k
    pub unsafe fn build_gep<T: BasicType<'ctx>>(
1149
846k
        &self,
1150
846k
        pointee_ty: T,
1151
846k
        ptr: PointerValue<'ctx>,
1152
846k
        ordered_indexes: &[IntValue<'ctx>],
1153
846k
        name: &str,
1154
846k
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1155
846k
        if self.positioned.get() != PositionState::Set {
1156
0
            return Err(BuilderError::UnsetPosition);
1157
846k
        }
1158
846k
        let c_string = to_c_str(name);
1159
1160
846k
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
<inkwell::builder::Builder>::build_gep::<inkwell::types::int_type::IntType>::{closure#0}
Line
Count
Source
1160
846k
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
Unexecuted instantiation: <inkwell::builder::Builder>::build_gep::<_>::{closure#0}
1161
1162
846k
        let value = LLVMBuildGEP2(
1163
846k
            self.builder,
1164
846k
            pointee_ty.as_type_ref(),
1165
846k
            ptr.as_value_ref(),
1166
846k
            index_values.as_mut_ptr(),
1167
846k
            index_values.len() as u32,
1168
846k
            c_string.as_ptr(),
1169
        );
1170
1171
846k
        Ok(PointerValue::new(value))
1172
846k
    }
<inkwell::builder::Builder>::build_gep::<inkwell::types::int_type::IntType>
Line
Count
Source
1148
846k
    pub unsafe fn build_gep<T: BasicType<'ctx>>(
1149
846k
        &self,
1150
846k
        pointee_ty: T,
1151
846k
        ptr: PointerValue<'ctx>,
1152
846k
        ordered_indexes: &[IntValue<'ctx>],
1153
846k
        name: &str,
1154
846k
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1155
846k
        if self.positioned.get() != PositionState::Set {
1156
0
            return Err(BuilderError::UnsetPosition);
1157
846k
        }
1158
846k
        let c_string = to_c_str(name);
1159
1160
846k
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
1161
1162
846k
        let value = LLVMBuildGEP2(
1163
846k
            self.builder,
1164
846k
            pointee_ty.as_type_ref(),
1165
846k
            ptr.as_value_ref(),
1166
846k
            index_values.as_mut_ptr(),
1167
846k
            index_values.len() as u32,
1168
846k
            c_string.as_ptr(),
1169
        );
1170
1171
846k
        Ok(PointerValue::new(value))
1172
846k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_gep::<_>
1173
1174
    // REVIEW: Doesn't GEP work on array too?
1175
    // REVIEW: This could be merge in with build_gep via a in_bounds: bool param
1176
    /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future.
1177
    #[cfg(feature = "typed-pointers")]
1178
    pub unsafe fn build_in_bounds_gep(
1179
        &self,
1180
        ptr: PointerValue<'ctx>,
1181
        ordered_indexes: &[IntValue<'ctx>],
1182
        name: &str,
1183
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1184
        if self.positioned.get() != PositionState::Set {
1185
            return Err(BuilderError::UnsetPosition);
1186
        }
1187
        let c_string = to_c_str(name);
1188
1189
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
1190
1191
        #[cfg(not(feature = "llvm16-0"))]
1192
        #[allow(deprecated)]
1193
        let value = LLVMBuildInBoundsGEP(
1194
            self.builder,
1195
            ptr.as_value_ref(),
1196
            index_values.as_mut_ptr(),
1197
            index_values.len() as u32,
1198
            c_string.as_ptr(),
1199
        );
1200
        #[cfg(feature = "llvm16-0")]
1201
        let value = LLVMBuildInBoundsGEP2(
1202
            self.builder,
1203
            ptr.get_type().get_element_type().as_type_ref(),
1204
            ptr.as_value_ref(),
1205
            index_values.as_mut_ptr(),
1206
            index_values.len() as u32,
1207
            c_string.as_ptr(),
1208
        );
1209
1210
        Ok(PointerValue::new(value))
1211
    }
1212
1213
    // REVIEW: Doesn't GEP work on array too?
1214
    // REVIEW: This could be merge in with build_gep via a in_bounds: bool param
1215
    /// GEP is very likely to segfault if indexes are used incorrectly, and is therefore an unsafe function. Maybe we can change this in the future.
1216
    #[cfg(not(feature = "typed-pointers"))]
1217
810k
    pub unsafe fn build_in_bounds_gep<T: BasicType<'ctx>>(
1218
810k
        &self,
1219
810k
        pointee_ty: T,
1220
810k
        ptr: PointerValue<'ctx>,
1221
810k
        ordered_indexes: &[IntValue<'ctx>],
1222
810k
        name: &str,
1223
810k
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1224
810k
        if self.positioned.get() != PositionState::Set {
1225
0
            return Err(BuilderError::UnsetPosition);
1226
810k
        }
1227
810k
        let c_string = to_c_str(name);
1228
1229
810k
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
<inkwell::builder::Builder>::build_in_bounds_gep::<inkwell::types::int_type::IntType>::{closure#0}
Line
Count
Source
1229
810k
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
<inkwell::builder::Builder>::build_in_bounds_gep::<inkwell::types::ptr_type::PointerType>::{closure#0}
Line
Count
Source
1229
474
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
Unexecuted instantiation: <inkwell::builder::Builder>::build_in_bounds_gep::<_>::{closure#0}
1230
1231
810k
        let value = LLVMBuildInBoundsGEP2(
1232
810k
            self.builder,
1233
810k
            pointee_ty.as_type_ref(),
1234
810k
            ptr.as_value_ref(),
1235
810k
            index_values.as_mut_ptr(),
1236
810k
            index_values.len() as u32,
1237
810k
            c_string.as_ptr(),
1238
        );
1239
1240
810k
        Ok(PointerValue::new(value))
1241
810k
    }
<inkwell::builder::Builder>::build_in_bounds_gep::<inkwell::types::int_type::IntType>
Line
Count
Source
1217
810k
    pub unsafe fn build_in_bounds_gep<T: BasicType<'ctx>>(
1218
810k
        &self,
1219
810k
        pointee_ty: T,
1220
810k
        ptr: PointerValue<'ctx>,
1221
810k
        ordered_indexes: &[IntValue<'ctx>],
1222
810k
        name: &str,
1223
810k
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1224
810k
        if self.positioned.get() != PositionState::Set {
1225
0
            return Err(BuilderError::UnsetPosition);
1226
810k
        }
1227
810k
        let c_string = to_c_str(name);
1228
1229
810k
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
1230
1231
810k
        let value = LLVMBuildInBoundsGEP2(
1232
810k
            self.builder,
1233
810k
            pointee_ty.as_type_ref(),
1234
810k
            ptr.as_value_ref(),
1235
810k
            index_values.as_mut_ptr(),
1236
810k
            index_values.len() as u32,
1237
810k
            c_string.as_ptr(),
1238
        );
1239
1240
810k
        Ok(PointerValue::new(value))
1241
810k
    }
<inkwell::builder::Builder>::build_in_bounds_gep::<inkwell::types::ptr_type::PointerType>
Line
Count
Source
1217
474
    pub unsafe fn build_in_bounds_gep<T: BasicType<'ctx>>(
1218
474
        &self,
1219
474
        pointee_ty: T,
1220
474
        ptr: PointerValue<'ctx>,
1221
474
        ordered_indexes: &[IntValue<'ctx>],
1222
474
        name: &str,
1223
474
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1224
474
        if self.positioned.get() != PositionState::Set {
1225
0
            return Err(BuilderError::UnsetPosition);
1226
474
        }
1227
474
        let c_string = to_c_str(name);
1228
1229
474
        let mut index_values: Vec<LLVMValueRef> = ordered_indexes.iter().map(|val| val.as_value_ref()).collect();
1230
1231
474
        let value = LLVMBuildInBoundsGEP2(
1232
474
            self.builder,
1233
474
            pointee_ty.as_type_ref(),
1234
474
            ptr.as_value_ref(),
1235
474
            index_values.as_mut_ptr(),
1236
474
            index_values.len() as u32,
1237
474
            c_string.as_ptr(),
1238
        );
1239
1240
474
        Ok(PointerValue::new(value))
1241
474
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_in_bounds_gep::<_>
1242
1243
    /// Builds a GEP instruction on a struct pointer. Returns `Err(BuilderError::GEPError)` if input `PointerValue` doesn't
1244
    /// point to a struct or if index is out of bounds.
1245
    ///
1246
    /// # Example
1247
    ///
1248
    /// ```no_run
1249
    /// use inkwell::AddressSpace;
1250
    /// use inkwell::context::Context;
1251
    ///
1252
    /// let context = Context::create();
1253
    /// let builder = context.create_builder();
1254
    /// let module = context.create_module("struct_gep");
1255
    /// let void_type = context.void_type();
1256
    /// let i32_ty = context.i32_type();
1257
    /// #[cfg(feature = "typed-pointers")]
1258
    /// let i32_ptr_ty = i32_ty.ptr_type(AddressSpace::default());
1259
    /// #[cfg(not(feature = "typed-pointers"))]
1260
    /// let i32_ptr_ty = context.ptr_type(AddressSpace::default());
1261
    /// let field_types = &[i32_ty.into(), i32_ty.into()];
1262
    /// let struct_ty = context.struct_type(field_types, false);
1263
    /// let struct_ptr_ty = struct_ty.ptr_type(AddressSpace::default());
1264
    /// let fn_type = void_type.fn_type(&[i32_ptr_ty.into(), struct_ptr_ty.into()], false);
1265
    /// let fn_value = module.add_function("", fn_type, None);
1266
    /// let entry = context.append_basic_block(fn_value, "entry");
1267
    ///
1268
    /// builder.position_at_end(entry);
1269
    ///
1270
    /// let i32_ptr = fn_value.get_first_param().unwrap().into_pointer_value();
1271
    /// let struct_ptr = fn_value.get_last_param().unwrap().into_pointer_value();
1272
    ///
1273
    /// assert!(builder.build_struct_gep(i32_ptr, 0, "struct_gep").is_err());
1274
    /// assert!(builder.build_struct_gep(i32_ptr, 10, "struct_gep").is_err());
1275
    /// assert!(builder.build_struct_gep(struct_ptr, 0, "struct_gep").is_ok());
1276
    /// assert!(builder.build_struct_gep(struct_ptr, 1, "struct_gep").is_ok());
1277
    /// assert!(builder.build_struct_gep(struct_ptr, 2, "struct_gep").is_err());
1278
    /// ```
1279
    #[cfg(feature = "typed-pointers")]
1280
    pub fn build_struct_gep(
1281
        &self,
1282
        ptr: PointerValue<'ctx>,
1283
        index: u32,
1284
        name: &str,
1285
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1286
        if self.positioned.get() != PositionState::Set {
1287
            return Err(BuilderError::UnsetPosition);
1288
        }
1289
        let ptr_ty = ptr.get_type();
1290
        let pointee_ty = ptr_ty.get_element_type();
1291
1292
        if !pointee_ty.is_struct_type() {
1293
            return Err(BuilderError::GEPPointee);
1294
        }
1295
1296
        let struct_ty = pointee_ty.into_struct_type();
1297
1298
        if index >= struct_ty.count_fields() {
1299
            return Err(BuilderError::GEPIndex);
1300
        }
1301
1302
        let c_string = to_c_str(name);
1303
1304
        #[cfg(not(feature = "llvm16-0"))]
1305
        #[allow(deprecated)]
1306
        let value = unsafe { LLVMBuildStructGEP(self.builder, ptr.as_value_ref(), index, c_string.as_ptr()) };
1307
        #[cfg(feature = "llvm16-0")]
1308
        let value = unsafe {
1309
            LLVMBuildStructGEP2(
1310
                self.builder,
1311
                ptr.get_type().get_element_type().as_type_ref(),
1312
                ptr.as_value_ref(),
1313
                index,
1314
                c_string.as_ptr(),
1315
            )
1316
        };
1317
1318
        unsafe { Ok(PointerValue::new(value)) }
1319
    }
1320
1321
    /// Builds a GEP instruction on a struct pointer. Returns `Err` `BuilderError::GEPPointee` or `BuilderError::GEPIndex` if input `PointerValue` doesn't
1322
    /// point to a struct or if index is out of bounds.
1323
    ///
1324
    /// # Example
1325
    ///
1326
    /// ```no_run
1327
    /// use inkwell::AddressSpace;
1328
    /// use inkwell::context::Context;
1329
    ///
1330
    /// let context = Context::create();
1331
    /// let builder = context.create_builder();
1332
    /// let module = context.create_module("struct_gep");
1333
    /// let void_type = context.void_type();
1334
    /// let i32_ty = context.i32_type();
1335
    /// #[cfg(feature = "typed-pointers")]
1336
    /// let i32_ptr_ty = i32_ty.ptr_type(AddressSpace::default());
1337
    /// #[cfg(not(feature = "typed-pointers"))]
1338
    /// let i32_ptr_ty = context.ptr_type(AddressSpace::default());
1339
    /// let field_types = &[i32_ty.into(), i32_ty.into()];
1340
    /// let struct_ty = context.struct_type(field_types, false);
1341
    /// let struct_ptr_ty = struct_ty.ptr_type(AddressSpace::default());
1342
    /// let fn_type = void_type.fn_type(&[i32_ptr_ty.into(), struct_ptr_ty.into()], false);
1343
    /// let fn_value = module.add_function("", fn_type, None);
1344
    /// let entry = context.append_basic_block(fn_value, "entry");
1345
    ///
1346
    /// builder.position_at_end(entry);
1347
    ///
1348
    /// let i32_ptr = fn_value.get_first_param().unwrap().into_pointer_value();
1349
    /// let struct_ptr = fn_value.get_last_param().unwrap().into_pointer_value();
1350
    ///
1351
    /// assert!(builder.build_struct_gep(i32_ty, i32_ptr, 0, "struct_gep").is_err());
1352
    /// assert!(builder.build_struct_gep(i32_ty, i32_ptr, 10, "struct_gep").is_err());
1353
    /// assert!(builder.build_struct_gep(struct_ty, struct_ptr, 0, "struct_gep").is_ok());
1354
    /// assert!(builder.build_struct_gep(struct_ty, struct_ptr, 1, "struct_gep").is_ok());
1355
    /// assert!(builder.build_struct_gep(struct_ty, struct_ptr, 2, "struct_gep").is_err());
1356
    /// ```
1357
    #[cfg(not(feature = "typed-pointers"))]
1358
5.80k
    pub fn build_struct_gep<T: BasicType<'ctx>>(
1359
5.80k
        &self,
1360
5.80k
        pointee_ty: T,
1361
5.80k
        ptr: PointerValue<'ctx>,
1362
5.80k
        index: u32,
1363
5.80k
        name: &str,
1364
5.80k
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1365
5.80k
        if self.positioned.get() != PositionState::Set {
1366
0
            return Err(BuilderError::UnsetPosition);
1367
5.80k
        }
1368
5.80k
        let pointee_ty = pointee_ty.as_any_type_enum();
1369
1370
5.80k
        if !pointee_ty.is_struct_type() {
1371
0
            return Err(BuilderError::GEPPointee);
1372
5.80k
        }
1373
1374
5.80k
        let struct_ty = pointee_ty.into_struct_type();
1375
1376
5.80k
        if index >= struct_ty.count_fields() {
1377
0
            return Err(BuilderError::GEPIndex);
1378
5.80k
        }
1379
1380
5.80k
        let c_string = to_c_str(name);
1381
1382
5.80k
        let value = unsafe {
1383
5.80k
            LLVMBuildStructGEP2(
1384
5.80k
                self.builder,
1385
5.80k
                pointee_ty.as_type_ref(),
1386
5.80k
                ptr.as_value_ref(),
1387
5.80k
                index,
1388
5.80k
                c_string.as_ptr(),
1389
            )
1390
        };
1391
1392
5.80k
        unsafe { Ok(PointerValue::new(value)) }
1393
5.80k
    }
<inkwell::builder::Builder>::build_struct_gep::<inkwell::types::struct_type::StructType>
Line
Count
Source
1358
5.80k
    pub fn build_struct_gep<T: BasicType<'ctx>>(
1359
5.80k
        &self,
1360
5.80k
        pointee_ty: T,
1361
5.80k
        ptr: PointerValue<'ctx>,
1362
5.80k
        index: u32,
1363
5.80k
        name: &str,
1364
5.80k
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1365
5.80k
        if self.positioned.get() != PositionState::Set {
1366
0
            return Err(BuilderError::UnsetPosition);
1367
5.80k
        }
1368
5.80k
        let pointee_ty = pointee_ty.as_any_type_enum();
1369
1370
5.80k
        if !pointee_ty.is_struct_type() {
1371
0
            return Err(BuilderError::GEPPointee);
1372
5.80k
        }
1373
1374
5.80k
        let struct_ty = pointee_ty.into_struct_type();
1375
1376
5.80k
        if index >= struct_ty.count_fields() {
1377
0
            return Err(BuilderError::GEPIndex);
1378
5.80k
        }
1379
1380
5.80k
        let c_string = to_c_str(name);
1381
1382
5.80k
        let value = unsafe {
1383
5.80k
            LLVMBuildStructGEP2(
1384
5.80k
                self.builder,
1385
5.80k
                pointee_ty.as_type_ref(),
1386
5.80k
                ptr.as_value_ref(),
1387
5.80k
                index,
1388
5.80k
                c_string.as_ptr(),
1389
            )
1390
        };
1391
1392
5.80k
        unsafe { Ok(PointerValue::new(value)) }
1393
5.80k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_struct_gep::<_>
1394
1395
    /// Builds an instruction which calculates the difference of two pointers.
1396
    ///
1397
    /// # Example
1398
    ///
1399
    /// ```no_run
1400
    /// use inkwell::context::Context;
1401
    /// use inkwell::AddressSpace;
1402
    ///
1403
    /// // Builds a function which diffs two pointers
1404
    /// let context = Context::create();
1405
    /// let module = context.create_module("ret");
1406
    /// let builder = context.create_builder();
1407
    /// let void_type = context.void_type();
1408
    /// let i32_type = context.i32_type();
1409
    /// #[cfg(feature = "typed-pointers")]
1410
    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
1411
    /// #[cfg(not(feature = "typed-pointers"))]
1412
    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
1413
    /// let fn_type = void_type.fn_type(&[i32_ptr_type.into(), i32_ptr_type.into()], false);
1414
    /// let fn_value = module.add_function("ret", fn_type, None);
1415
    /// let entry = context.append_basic_block(fn_value, "entry");
1416
    /// let i32_ptr_param1 = fn_value.get_first_param().unwrap().into_pointer_value();
1417
    /// let i32_ptr_param2 = fn_value.get_nth_param(1).unwrap().into_pointer_value();
1418
    ///
1419
    /// builder.position_at_end(entry);
1420
    /// builder.build_ptr_diff(i32_ptr_param1, i32_ptr_param2, "diff").unwrap();
1421
    /// builder.build_return(None).unwrap();
1422
    /// ```
1423
    #[cfg(feature = "typed-pointers")]
1424
    pub fn build_ptr_diff(
1425
        &self,
1426
        lhs_ptr: PointerValue<'ctx>,
1427
        rhs_ptr: PointerValue<'ctx>,
1428
        name: &str,
1429
    ) -> Result<IntValue<'ctx>, BuilderError> {
1430
        if self.positioned.get() != PositionState::Set {
1431
            return Err(BuilderError::UnsetPosition);
1432
        }
1433
        let c_string = to_c_str(name);
1434
        #[cfg(not(feature = "llvm16-0"))]
1435
        #[allow(deprecated)]
1436
        let value = unsafe {
1437
            LLVMBuildPtrDiff(
1438
                self.builder,
1439
                lhs_ptr.as_value_ref(),
1440
                rhs_ptr.as_value_ref(),
1441
                c_string.as_ptr(),
1442
            )
1443
        };
1444
        #[cfg(feature = "llvm16-0")]
1445
        let value = {
1446
            if lhs_ptr.get_type().as_basic_type_enum() != rhs_ptr.get_type().as_basic_type_enum() {
1447
                return Err(BuilderError::NotSameType);
1448
            }
1449
1450
            unsafe {
1451
                LLVMBuildPtrDiff2(
1452
                    self.builder,
1453
                    lhs_ptr.get_type().get_element_type().as_type_ref(),
1454
                    lhs_ptr.as_value_ref(),
1455
                    rhs_ptr.as_value_ref(),
1456
                    c_string.as_ptr(),
1457
                )
1458
            }
1459
        };
1460
1461
        unsafe { Ok(IntValue::new(value)) }
1462
    }
1463
1464
    /// Builds an instruction which calculates the difference of two pointers.
1465
    ///
1466
    /// # Example
1467
    ///
1468
    /// ```no_run
1469
    /// use inkwell::context::Context;
1470
    /// use inkwell::AddressSpace;
1471
    ///
1472
    /// // Builds a function which diffs two pointers
1473
    /// let context = Context::create();
1474
    /// let module = context.create_module("ret");
1475
    /// let builder = context.create_builder();
1476
    /// let void_type = context.void_type();
1477
    /// let i32_type = context.i32_type();
1478
    /// #[cfg(feature = "typed-pointers")]
1479
    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
1480
    /// #[cfg(not(feature = "typed-pointers"))]
1481
    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
1482
    /// let fn_type = void_type.fn_type(&[i32_ptr_type.into(), i32_ptr_type.into()], false);
1483
    /// let fn_value = module.add_function("ret", fn_type, None);
1484
    /// let entry = context.append_basic_block(fn_value, "entry");
1485
    /// let i32_ptr_param1 = fn_value.get_first_param().unwrap().into_pointer_value();
1486
    /// let i32_ptr_param2 = fn_value.get_nth_param(1).unwrap().into_pointer_value();
1487
    ///
1488
    /// builder.position_at_end(entry);
1489
    /// builder.build_ptr_diff(i32_ptr_type, i32_ptr_param1, i32_ptr_param2, "diff").unwrap();
1490
    /// builder.build_return(None).unwrap();
1491
    /// ```
1492
    #[cfg(not(feature = "typed-pointers"))]
1493
0
    pub fn build_ptr_diff<T: BasicType<'ctx>>(
1494
0
        &self,
1495
0
        pointee_ty: T,
1496
0
        lhs_ptr: PointerValue<'ctx>,
1497
0
        rhs_ptr: PointerValue<'ctx>,
1498
0
        name: &str,
1499
0
    ) -> Result<IntValue<'ctx>, BuilderError> {
1500
0
        if self.positioned.get() != PositionState::Set {
1501
0
            return Err(BuilderError::UnsetPosition);
1502
0
        }
1503
0
        let c_string = to_c_str(name);
1504
1505
0
        let value = unsafe {
1506
0
            LLVMBuildPtrDiff2(
1507
0
                self.builder,
1508
0
                pointee_ty.as_type_ref(),
1509
0
                lhs_ptr.as_value_ref(),
1510
0
                rhs_ptr.as_value_ref(),
1511
0
                c_string.as_ptr(),
1512
            )
1513
        };
1514
1515
0
        unsafe { Ok(IntValue::new(value)) }
1516
0
    }
1517
1518
    // SubTypes: Maybe this should return PhiValue<T>? That way we could force incoming values to be of T::Value?
1519
    // That is, assuming LLVM complains about different phi types.. which I imagine it would. But this would get
1520
    // tricky with VoidType since it has no instance value?
1521
    // TODOC: Phi Instruction(s) must be first instruction(s) in a BasicBlock.
1522
    // REVIEW: Not sure if we can enforce the above somehow via types.
1523
1.17M
    pub fn build_phi<T: BasicType<'ctx>>(&self, type_: T, name: &str) -> Result<PhiValue<'ctx>, BuilderError> {
1524
1.17M
        if self.positioned.get() != PositionState::Set {
1525
0
            return Err(BuilderError::UnsetPosition);
1526
1.17M
        }
1527
1.17M
        let c_string = to_c_str(name);
1528
1.17M
        let value = unsafe { LLVMBuildPhi(self.builder, type_.as_type_ref(), c_string.as_ptr()) };
1529
1530
1.17M
        unsafe { Ok(PhiValue::new(value)) }
1531
1.17M
    }
<inkwell::builder::Builder>::build_phi::<inkwell::types::enums::BasicTypeEnum>
Line
Count
Source
1523
1.02M
    pub fn build_phi<T: BasicType<'ctx>>(&self, type_: T, name: &str) -> Result<PhiValue<'ctx>, BuilderError> {
1524
1.02M
        if self.positioned.get() != PositionState::Set {
1525
0
            return Err(BuilderError::UnsetPosition);
1526
1.02M
        }
1527
1.02M
        let c_string = to_c_str(name);
1528
1.02M
        let value = unsafe { LLVMBuildPhi(self.builder, type_.as_type_ref(), c_string.as_ptr()) };
1529
1530
1.02M
        unsafe { Ok(PhiValue::new(value)) }
1531
1.02M
    }
<inkwell::builder::Builder>::build_phi::<inkwell::types::int_type::IntType>
Line
Count
Source
1523
157k
    pub fn build_phi<T: BasicType<'ctx>>(&self, type_: T, name: &str) -> Result<PhiValue<'ctx>, BuilderError> {
1524
157k
        if self.positioned.get() != PositionState::Set {
1525
0
            return Err(BuilderError::UnsetPosition);
1526
157k
        }
1527
157k
        let c_string = to_c_str(name);
1528
157k
        let value = unsafe { LLVMBuildPhi(self.builder, type_.as_type_ref(), c_string.as_ptr()) };
1529
1530
157k
        unsafe { Ok(PhiValue::new(value)) }
1531
157k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_phi::<_>
1532
1533
    /// Builds a store instruction. It allows you to store a value of type `T` in a pointer to a type `T`.
1534
    ///
1535
    /// # Example
1536
    ///
1537
    /// ```no_run
1538
    /// use inkwell::context::Context;
1539
    /// use inkwell::AddressSpace;
1540
    ///
1541
    /// // Builds a function which takes an i32 pointer and stores a 7 in it.
1542
    /// let context = Context::create();
1543
    /// let module = context.create_module("ret");
1544
    /// let builder = context.create_builder();
1545
    /// let void_type = context.void_type();
1546
    /// let i32_type = context.i32_type();
1547
    /// #[cfg(feature = "typed-pointers")]
1548
    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
1549
    /// #[cfg(not(feature = "typed-pointers"))]
1550
    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
1551
    /// let i32_seven = i32_type.const_int(7, false);
1552
    /// let fn_type = void_type.fn_type(&[i32_ptr_type.into()], false);
1553
    /// let fn_value = module.add_function("ret", fn_type, None);
1554
    /// let entry = context.append_basic_block(fn_value, "entry");
1555
    /// let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value();
1556
    ///
1557
    /// builder.position_at_end(entry);
1558
    /// builder.build_store(i32_ptr_param, i32_seven).unwrap();
1559
    /// builder.build_return(None).unwrap();
1560
    /// ```
1561
2.37M
    pub fn build_store<V: BasicValue<'ctx>>(
1562
2.37M
        &self,
1563
2.37M
        ptr: PointerValue<'ctx>,
1564
2.37M
        value: V,
1565
2.37M
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
1566
2.37M
        if self.positioned.get() != PositionState::Set {
1567
0
            return Err(BuilderError::UnsetPosition);
1568
2.37M
        }
1569
2.37M
        let value = unsafe { LLVMBuildStore(self.builder, value.as_value_ref(), ptr.as_value_ref()) };
1570
1571
2.37M
        unsafe { Ok(InstructionValue::new(value)) }
1572
2.37M
    }
<inkwell::builder::Builder>::build_store::<inkwell::values::struct_value::StructValue>
Line
Count
Source
1561
39.1k
    pub fn build_store<V: BasicValue<'ctx>>(
1562
39.1k
        &self,
1563
39.1k
        ptr: PointerValue<'ctx>,
1564
39.1k
        value: V,
1565
39.1k
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
1566
39.1k
        if self.positioned.get() != PositionState::Set {
1567
0
            return Err(BuilderError::UnsetPosition);
1568
39.1k
        }
1569
39.1k
        let value = unsafe { LLVMBuildStore(self.builder, value.as_value_ref(), ptr.as_value_ref()) };
1570
1571
39.1k
        unsafe { Ok(InstructionValue::new(value)) }
1572
39.1k
    }
<inkwell::builder::Builder>::build_store::<inkwell::values::enums::BasicValueEnum>
Line
Count
Source
1561
2.32M
    pub fn build_store<V: BasicValue<'ctx>>(
1562
2.32M
        &self,
1563
2.32M
        ptr: PointerValue<'ctx>,
1564
2.32M
        value: V,
1565
2.32M
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
1566
2.32M
        if self.positioned.get() != PositionState::Set {
1567
0
            return Err(BuilderError::UnsetPosition);
1568
2.32M
        }
1569
2.32M
        let value = unsafe { LLVMBuildStore(self.builder, value.as_value_ref(), ptr.as_value_ref()) };
1570
1571
2.32M
        unsafe { Ok(InstructionValue::new(value)) }
1572
2.32M
    }
<inkwell::builder::Builder>::build_store::<inkwell::values::int_value::IntValue>
Line
Count
Source
1561
2.76k
    pub fn build_store<V: BasicValue<'ctx>>(
1562
2.76k
        &self,
1563
2.76k
        ptr: PointerValue<'ctx>,
1564
2.76k
        value: V,
1565
2.76k
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
1566
2.76k
        if self.positioned.get() != PositionState::Set {
1567
0
            return Err(BuilderError::UnsetPosition);
1568
2.76k
        }
1569
2.76k
        let value = unsafe { LLVMBuildStore(self.builder, value.as_value_ref(), ptr.as_value_ref()) };
1570
1571
2.76k
        unsafe { Ok(InstructionValue::new(value)) }
1572
2.76k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_store::<_>
1573
1574
    /// Builds a load instruction. It allows you to retrieve a value of type `T` from a pointer to a type `T`.
1575
    ///
1576
    /// # Example
1577
    ///
1578
    /// ```no_run
1579
    /// use inkwell::context::Context;
1580
    /// use inkwell::AddressSpace;
1581
    ///
1582
    /// // Builds a function which takes an i32 pointer and returns the pointed at i32.
1583
    /// let context = Context::create();
1584
    /// let module = context.create_module("ret");
1585
    /// let builder = context.create_builder();
1586
    /// let i32_type = context.i32_type();
1587
    /// #[cfg(feature = "typed-pointers")]
1588
    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
1589
    /// #[cfg(not(feature = "typed-pointers"))]
1590
    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
1591
    /// let fn_type = i32_type.fn_type(&[i32_ptr_type.into()], false);
1592
    /// let fn_value = module.add_function("ret", fn_type, None);
1593
    /// let entry = context.append_basic_block(fn_value, "entry");
1594
    /// let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value();
1595
    ///
1596
    /// builder.position_at_end(entry);
1597
    ///
1598
    /// let pointee = builder.build_load(i32_ptr_param, "load").unwrap();
1599
    ///
1600
    /// builder.build_return(Some(&pointee)).unwrap();
1601
    /// ```
1602
    #[cfg(feature = "typed-pointers")]
1603
    pub fn build_load(&self, ptr: PointerValue<'ctx>, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError> {
1604
        if self.positioned.get() != PositionState::Set {
1605
            return Err(BuilderError::UnsetPosition);
1606
        }
1607
        let c_string = to_c_str(name);
1608
1609
        #[cfg(not(feature = "llvm16-0"))]
1610
        #[allow(deprecated)]
1611
        let value = unsafe { LLVMBuildLoad(self.builder, ptr.as_value_ref(), c_string.as_ptr()) };
1612
        #[cfg(feature = "llvm16-0")]
1613
        let value = unsafe {
1614
            LLVMBuildLoad2(
1615
                self.builder,
1616
                ptr.get_type().get_element_type().as_type_ref(),
1617
                ptr.as_value_ref(),
1618
                c_string.as_ptr(),
1619
            )
1620
        };
1621
1622
        unsafe { Ok(BasicValueEnum::new(value)) }
1623
    }
1624
1625
    /// Builds a load2 instruction. It allows you to retrieve a value of type `T` from a pointer to a type `T`.
1626
    ///
1627
    /// # Example
1628
    ///
1629
    /// ```no_run
1630
    /// use inkwell::context::Context;
1631
    /// use inkwell::AddressSpace;
1632
    ///
1633
    /// // Builds a function which takes an i32 pointer and returns the pointed at i32.
1634
    /// let context = Context::create();
1635
    /// let module = context.create_module("ret");
1636
    /// let builder = context.create_builder();
1637
    /// let i32_type = context.i32_type();
1638
    /// #[cfg(feature = "typed-pointers")]
1639
    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
1640
    /// #[cfg(not(feature = "typed-pointers"))]
1641
    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
1642
    /// let fn_type = i32_type.fn_type(&[i32_ptr_type.into()], false);
1643
    /// let fn_value = module.add_function("ret", fn_type, None);
1644
    /// let entry = context.append_basic_block(fn_value, "entry");
1645
    /// let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value();
1646
    ///
1647
    /// builder.position_at_end(entry);
1648
    ///
1649
    /// let pointee = builder.build_load(i32_type, i32_ptr_param, "load2").unwrap();
1650
    ///
1651
    /// builder.build_return(Some(&pointee)).unwrap();
1652
    /// ```
1653
    #[cfg(not(feature = "typed-pointers"))]
1654
1.40M
    pub fn build_load<T: BasicType<'ctx>>(
1655
1.40M
        &self,
1656
1.40M
        pointee_ty: T,
1657
1.40M
        ptr: PointerValue<'ctx>,
1658
1.40M
        name: &str,
1659
1.40M
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
1660
1.40M
        if self.positioned.get() != PositionState::Set {
1661
0
            return Err(BuilderError::UnsetPosition);
1662
1.40M
        }
1663
1.40M
        let c_string = to_c_str(name);
1664
1665
1.40M
        let value = unsafe {
1666
1.40M
            LLVMBuildLoad2(
1667
1.40M
                self.builder,
1668
1.40M
                pointee_ty.as_type_ref(),
1669
1.40M
                ptr.as_value_ref(),
1670
1.40M
                c_string.as_ptr(),
1671
            )
1672
        };
1673
1674
1.40M
        unsafe { Ok(BasicValueEnum::new(value)) }
1675
1.40M
    }
<inkwell::builder::Builder>::build_load::<inkwell::types::float_type::FloatType>
Line
Count
Source
1654
4.16k
    pub fn build_load<T: BasicType<'ctx>>(
1655
4.16k
        &self,
1656
4.16k
        pointee_ty: T,
1657
4.16k
        ptr: PointerValue<'ctx>,
1658
4.16k
        name: &str,
1659
4.16k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
1660
4.16k
        if self.positioned.get() != PositionState::Set {
1661
0
            return Err(BuilderError::UnsetPosition);
1662
4.16k
        }
1663
4.16k
        let c_string = to_c_str(name);
1664
1665
4.16k
        let value = unsafe {
1666
4.16k
            LLVMBuildLoad2(
1667
4.16k
                self.builder,
1668
4.16k
                pointee_ty.as_type_ref(),
1669
4.16k
                ptr.as_value_ref(),
1670
4.16k
                c_string.as_ptr(),
1671
            )
1672
        };
1673
1674
4.16k
        unsafe { Ok(BasicValueEnum::new(value)) }
1675
4.16k
    }
<inkwell::builder::Builder>::build_load::<inkwell::types::struct_type::StructType>
Line
Count
Source
1654
43.8k
    pub fn build_load<T: BasicType<'ctx>>(
1655
43.8k
        &self,
1656
43.8k
        pointee_ty: T,
1657
43.8k
        ptr: PointerValue<'ctx>,
1658
43.8k
        name: &str,
1659
43.8k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
1660
43.8k
        if self.positioned.get() != PositionState::Set {
1661
0
            return Err(BuilderError::UnsetPosition);
1662
43.8k
        }
1663
43.8k
        let c_string = to_c_str(name);
1664
1665
43.8k
        let value = unsafe {
1666
43.8k
            LLVMBuildLoad2(
1667
43.8k
                self.builder,
1668
43.8k
                pointee_ty.as_type_ref(),
1669
43.8k
                ptr.as_value_ref(),
1670
43.8k
                c_string.as_ptr(),
1671
            )
1672
        };
1673
1674
43.8k
        unsafe { Ok(BasicValueEnum::new(value)) }
1675
43.8k
    }
<inkwell::builder::Builder>::build_load::<inkwell::types::enums::BasicTypeEnum>
Line
Count
Source
1654
1.24M
    pub fn build_load<T: BasicType<'ctx>>(
1655
1.24M
        &self,
1656
1.24M
        pointee_ty: T,
1657
1.24M
        ptr: PointerValue<'ctx>,
1658
1.24M
        name: &str,
1659
1.24M
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
1660
1.24M
        if self.positioned.get() != PositionState::Set {
1661
0
            return Err(BuilderError::UnsetPosition);
1662
1.24M
        }
1663
1.24M
        let c_string = to_c_str(name);
1664
1665
1.24M
        let value = unsafe {
1666
1.24M
            LLVMBuildLoad2(
1667
1.24M
                self.builder,
1668
1.24M
                pointee_ty.as_type_ref(),
1669
1.24M
                ptr.as_value_ref(),
1670
1.24M
                c_string.as_ptr(),
1671
            )
1672
        };
1673
1674
1.24M
        unsafe { Ok(BasicValueEnum::new(value)) }
1675
1.24M
    }
<inkwell::builder::Builder>::build_load::<inkwell::types::int_type::IntType>
Line
Count
Source
1654
80.0k
    pub fn build_load<T: BasicType<'ctx>>(
1655
80.0k
        &self,
1656
80.0k
        pointee_ty: T,
1657
80.0k
        ptr: PointerValue<'ctx>,
1658
80.0k
        name: &str,
1659
80.0k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
1660
80.0k
        if self.positioned.get() != PositionState::Set {
1661
0
            return Err(BuilderError::UnsetPosition);
1662
80.0k
        }
1663
80.0k
        let c_string = to_c_str(name);
1664
1665
80.0k
        let value = unsafe {
1666
80.0k
            LLVMBuildLoad2(
1667
80.0k
                self.builder,
1668
80.0k
                pointee_ty.as_type_ref(),
1669
80.0k
                ptr.as_value_ref(),
1670
80.0k
                c_string.as_ptr(),
1671
            )
1672
        };
1673
1674
80.0k
        unsafe { Ok(BasicValueEnum::new(value)) }
1675
80.0k
    }
<inkwell::builder::Builder>::build_load::<inkwell::types::ptr_type::PointerType>
Line
Count
Source
1654
31.2k
    pub fn build_load<T: BasicType<'ctx>>(
1655
31.2k
        &self,
1656
31.2k
        pointee_ty: T,
1657
31.2k
        ptr: PointerValue<'ctx>,
1658
31.2k
        name: &str,
1659
31.2k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
1660
31.2k
        if self.positioned.get() != PositionState::Set {
1661
0
            return Err(BuilderError::UnsetPosition);
1662
31.2k
        }
1663
31.2k
        let c_string = to_c_str(name);
1664
1665
31.2k
        let value = unsafe {
1666
31.2k
            LLVMBuildLoad2(
1667
31.2k
                self.builder,
1668
31.2k
                pointee_ty.as_type_ref(),
1669
31.2k
                ptr.as_value_ref(),
1670
31.2k
                c_string.as_ptr(),
1671
            )
1672
        };
1673
1674
31.2k
        unsafe { Ok(BasicValueEnum::new(value)) }
1675
31.2k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_load::<_>
1676
1677
    // TODOC: Stack allocation
1678
1.28M
    pub fn build_alloca<T: BasicType<'ctx>>(&self, ty: T, name: &str) -> Result<PointerValue<'ctx>, BuilderError> {
1679
1.28M
        if self.positioned.get() != PositionState::Set {
1680
0
            return Err(BuilderError::UnsetPosition);
1681
1.28M
        }
1682
1.28M
        let c_string = to_c_str(name);
1683
1.28M
        let value = unsafe { LLVMBuildAlloca(self.builder, ty.as_type_ref(), c_string.as_ptr()) };
1684
1685
1.28M
        unsafe { Ok(PointerValue::new(value)) }
1686
1.28M
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_alloca::<inkwell::types::array_type::ArrayType>
<inkwell::builder::Builder>::build_alloca::<inkwell::types::struct_type::StructType>
Line
Count
Source
1678
43.8k
    pub fn build_alloca<T: BasicType<'ctx>>(&self, ty: T, name: &str) -> Result<PointerValue<'ctx>, BuilderError> {
1679
43.8k
        if self.positioned.get() != PositionState::Set {
1680
0
            return Err(BuilderError::UnsetPosition);
1681
43.8k
        }
1682
43.8k
        let c_string = to_c_str(name);
1683
43.8k
        let value = unsafe { LLVMBuildAlloca(self.builder, ty.as_type_ref(), c_string.as_ptr()) };
1684
1685
43.8k
        unsafe { Ok(PointerValue::new(value)) }
1686
43.8k
    }
<inkwell::builder::Builder>::build_alloca::<inkwell::types::enums::BasicTypeEnum>
Line
Count
Source
1678
1.23M
    pub fn build_alloca<T: BasicType<'ctx>>(&self, ty: T, name: &str) -> Result<PointerValue<'ctx>, BuilderError> {
1679
1.23M
        if self.positioned.get() != PositionState::Set {
1680
0
            return Err(BuilderError::UnsetPosition);
1681
1.23M
        }
1682
1.23M
        let c_string = to_c_str(name);
1683
1.23M
        let value = unsafe { LLVMBuildAlloca(self.builder, ty.as_type_ref(), c_string.as_ptr()) };
1684
1685
1.23M
        unsafe { Ok(PointerValue::new(value)) }
1686
1.23M
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_alloca::<_>
1687
1688
    // TODOC: Stack allocation
1689
0
    pub fn build_array_alloca<T: BasicType<'ctx>>(
1690
0
        &self,
1691
0
        ty: T,
1692
0
        size: IntValue<'ctx>,
1693
0
        name: &str,
1694
0
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1695
0
        if self.positioned.get() != PositionState::Set {
1696
0
            return Err(BuilderError::UnsetPosition);
1697
0
        }
1698
0
        let c_string = to_c_str(name);
1699
0
        let value =
1700
0
            unsafe { LLVMBuildArrayAlloca(self.builder, ty.as_type_ref(), size.as_value_ref(), c_string.as_ptr()) };
1701
1702
0
        unsafe { Ok(PointerValue::new(value)) }
1703
0
    }
1704
1705
    /// Build a [memcpy](https://llvm.org/docs/LangRef.html#llvm-memcpy-intrinsic) instruction.
1706
    ///
1707
    /// Alignment arguments are specified in bytes, and should always be
1708
    /// both a power of 2 and under 2^64.
1709
    ///
1710
    /// The final argument should be a pointer-sized integer.
1711
    ///
1712
    /// Returns an `Err(BuilderError::AlignmentError)` if the source or destination alignments are not a power of 2.
1713
    ///
1714
    /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those.
1715
0
    pub fn build_memcpy(
1716
0
        &self,
1717
0
        dest: PointerValue<'ctx>,
1718
0
        dest_align_bytes: u32,
1719
0
        src: PointerValue<'ctx>,
1720
0
        src_align_bytes: u32,
1721
0
        size: IntValue<'ctx>,
1722
0
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1723
0
        if self.positioned.get() != PositionState::Set {
1724
0
            return Err(BuilderError::UnsetPosition);
1725
0
        }
1726
0
        if !is_alignment_ok(src_align_bytes) {
1727
0
            return Err(BuilderError::AlignmentError(AlignmentError::SrcNonPowerOfTwo(
1728
0
                src_align_bytes,
1729
0
            )));
1730
0
        }
1731
1732
0
        if !is_alignment_ok(dest_align_bytes) {
1733
0
            return Err(BuilderError::AlignmentError(AlignmentError::DestNonPowerOfTwo(
1734
0
                dest_align_bytes,
1735
0
            )));
1736
0
        }
1737
1738
0
        let value = unsafe {
1739
0
            LLVMBuildMemCpy(
1740
0
                self.builder,
1741
0
                dest.as_value_ref(),
1742
0
                dest_align_bytes,
1743
0
                src.as_value_ref(),
1744
0
                src_align_bytes,
1745
0
                size.as_value_ref(),
1746
            )
1747
        };
1748
1749
0
        unsafe { Ok(PointerValue::new(value)) }
1750
0
    }
1751
1752
    /// Build a [memmove](http://llvm.org/docs/LangRef.html#llvm-memmove-intrinsic) instruction.
1753
    ///
1754
    /// Alignment arguments are specified in bytes, and should always be
1755
    /// both a power of 2 and under 2^64.
1756
    ///
1757
    /// The final argument should be a pointer-sized integer.
1758
    ///
1759
    /// Returns an `Err(BuilderError::AlignmentError)` if the source or destination alignments are not a power of 2 under 2^64.
1760
    ///
1761
    /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those.
1762
0
    pub fn build_memmove(
1763
0
        &self,
1764
0
        dest: PointerValue<'ctx>,
1765
0
        dest_align_bytes: u32,
1766
0
        src: PointerValue<'ctx>,
1767
0
        src_align_bytes: u32,
1768
0
        size: IntValue<'ctx>,
1769
0
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1770
0
        if self.positioned.get() != PositionState::Set {
1771
0
            return Err(BuilderError::UnsetPosition);
1772
0
        }
1773
0
        if !is_alignment_ok(src_align_bytes) {
1774
0
            return Err(BuilderError::AlignmentError(AlignmentError::SrcNonPowerOfTwo(
1775
0
                src_align_bytes,
1776
0
            )));
1777
0
        }
1778
1779
0
        if !is_alignment_ok(dest_align_bytes) {
1780
0
            return Err(BuilderError::AlignmentError(AlignmentError::DestNonPowerOfTwo(
1781
0
                dest_align_bytes,
1782
0
            )));
1783
0
        }
1784
1785
0
        let value = unsafe {
1786
0
            LLVMBuildMemMove(
1787
0
                self.builder,
1788
0
                dest.as_value_ref(),
1789
0
                dest_align_bytes,
1790
0
                src.as_value_ref(),
1791
0
                src_align_bytes,
1792
0
                size.as_value_ref(),
1793
            )
1794
        };
1795
1796
0
        unsafe { Ok(PointerValue::new(value)) }
1797
0
    }
1798
1799
    /// Build a [memset](http://llvm.org/docs/LangRef.html#llvm-memset-intrinsics) instruction.
1800
    ///
1801
    /// Alignment arguments are specified in bytes, and should always be
1802
    /// both a power of 2 and under 2^64.
1803
    ///
1804
    /// The final argument should be a pointer-sized integer.
1805
    ///
1806
    /// Returns an `Err(BuilderError::AlignmentError)` if the source alignment is not a power of 2 under 2^64.
1807
    ///
1808
    /// [`TargetData::ptr_sized_int_type_in_context`](https://thedan64.github.io/inkwell/inkwell/targets/struct.TargetData.html#method.ptr_sized_int_type_in_context) will get you one of those.
1809
0
    pub fn build_memset(
1810
0
        &self,
1811
0
        dest: PointerValue<'ctx>,
1812
0
        dest_align_bytes: u32,
1813
0
        val: IntValue<'ctx>,
1814
0
        size: IntValue<'ctx>,
1815
0
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1816
0
        if self.positioned.get() != PositionState::Set {
1817
0
            return Err(BuilderError::UnsetPosition);
1818
0
        }
1819
0
        if !is_alignment_ok(dest_align_bytes) {
1820
0
            return Err(BuilderError::AlignmentError(AlignmentError::DestNonPowerOfTwo(
1821
0
                dest_align_bytes,
1822
0
            )));
1823
0
        }
1824
1825
0
        let value = unsafe {
1826
0
            LLVMBuildMemSet(
1827
0
                self.builder,
1828
0
                dest.as_value_ref(),
1829
0
                val.as_value_ref(),
1830
0
                size.as_value_ref(),
1831
0
                dest_align_bytes,
1832
            )
1833
        };
1834
1835
0
        unsafe { Ok(PointerValue::new(value)) }
1836
0
    }
1837
1838
    // TODOC: Heap allocation
1839
    /// Returns `Err(BuilderError::AlignmentError)` if the type is unsized.
1840
0
    pub fn build_malloc<T: BasicType<'ctx>>(&self, ty: T, name: &str) -> Result<PointerValue<'ctx>, BuilderError> {
1841
0
        if self.positioned.get() != PositionState::Set {
1842
0
            return Err(BuilderError::UnsetPosition);
1843
0
        }
1844
        // LLVMBuildMalloc segfaults if ty is unsized
1845
0
        if !ty.is_sized() {
1846
0
            return Err(BuilderError::AlignmentError(AlignmentError::Unsized));
1847
0
        }
1848
1849
0
        let c_string = to_c_str(name);
1850
1851
0
        let value = unsafe { LLVMBuildMalloc(self.builder, ty.as_type_ref(), c_string.as_ptr()) };
1852
1853
0
        unsafe { Ok(PointerValue::new(value)) }
1854
0
    }
1855
1856
    // TODOC: Heap allocation
1857
    /// Returns `Err(BuilderError::AlignmentError)` if the type is unsized.
1858
0
    pub fn build_array_malloc<T: BasicType<'ctx>>(
1859
0
        &self,
1860
0
        ty: T,
1861
0
        size: IntValue<'ctx>,
1862
0
        name: &str,
1863
0
    ) -> Result<PointerValue<'ctx>, BuilderError> {
1864
0
        if self.positioned.get() != PositionState::Set {
1865
0
            return Err(BuilderError::UnsetPosition);
1866
0
        }
1867
        // LLVMBuildArrayMalloc segfaults if ty is unsized
1868
0
        if !ty.is_sized() {
1869
0
            return Err(BuilderError::AlignmentError(AlignmentError::Unsized));
1870
0
        }
1871
1872
0
        let c_string = to_c_str(name);
1873
1874
0
        let value =
1875
0
            unsafe { LLVMBuildArrayMalloc(self.builder, ty.as_type_ref(), size.as_value_ref(), c_string.as_ptr()) };
1876
1877
0
        unsafe { Ok(PointerValue::new(value)) }
1878
0
    }
1879
1880
    // SubType: <P>(&self, ptr: PointerValue<P>) -> InstructionValue {
1881
0
    pub fn build_free(&self, ptr: PointerValue<'ctx>) -> Result<InstructionValue<'ctx>, BuilderError> {
1882
0
        if self.positioned.get() != PositionState::Set {
1883
0
            return Err(BuilderError::UnsetPosition);
1884
0
        }
1885
0
        unsafe { Ok(InstructionValue::new(LLVMBuildFree(self.builder, ptr.as_value_ref()))) }
1886
0
    }
1887
1888
0
    pub fn insert_instruction(&self, instruction: &InstructionValue<'ctx>, name: Option<&str>) {
1889
0
        match name {
1890
0
            Some(name) => {
1891
0
                let c_string = to_c_str(name);
1892
1893
0
                unsafe { LLVMInsertIntoBuilderWithName(self.builder, instruction.as_value_ref(), c_string.as_ptr()) }
1894
            },
1895
0
            None => unsafe {
1896
0
                LLVMInsertIntoBuilder(self.builder, instruction.as_value_ref());
1897
0
            },
1898
        }
1899
0
    }
1900
1901
878k
    pub fn get_insert_block(&self) -> Option<BasicBlock<'ctx>> {
1902
878k
        unsafe { BasicBlock::new(LLVMGetInsertBlock(self.builder)) }
1903
878k
    }
1904
1905
    // TODO: Possibly make this generic over sign via struct metadata or subtypes
1906
    // SubType: <I: IntSubType>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
1907
    //     if I::sign() == Unsigned { LLVMBuildUDiv() } else { LLVMBuildSDiv() }
1908
2.95k
    pub fn build_int_unsigned_div<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1909
2.95k
        if self.positioned.get() != PositionState::Set {
1910
0
            return Err(BuilderError::UnsetPosition);
1911
2.95k
        }
1912
2.95k
        let c_string = to_c_str(name);
1913
2.95k
        let value = unsafe { LLVMBuildUDiv(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1914
1915
2.95k
        unsafe { Ok(T::new(value)) }
1916
2.95k
    }
<inkwell::builder::Builder>::build_int_unsigned_div::<inkwell::values::int_value::IntValue>
Line
Count
Source
1908
2.95k
    pub fn build_int_unsigned_div<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1909
2.95k
        if self.positioned.get() != PositionState::Set {
1910
0
            return Err(BuilderError::UnsetPosition);
1911
2.95k
        }
1912
2.95k
        let c_string = to_c_str(name);
1913
2.95k
        let value = unsafe { LLVMBuildUDiv(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1914
1915
2.95k
        unsafe { Ok(T::new(value)) }
1916
2.95k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_unsigned_div::<_>
1917
1918
    // TODO: Possibly make this generic over sign via struct metadata or subtypes
1919
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
1920
1.07k
    pub fn build_int_signed_div<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1921
1.07k
        if self.positioned.get() != PositionState::Set {
1922
0
            return Err(BuilderError::UnsetPosition);
1923
1.07k
        }
1924
1.07k
        let c_string = to_c_str(name);
1925
1.07k
        let value = unsafe { LLVMBuildSDiv(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1926
1927
1.07k
        unsafe { Ok(T::new(value)) }
1928
1.07k
    }
<inkwell::builder::Builder>::build_int_signed_div::<inkwell::values::int_value::IntValue>
Line
Count
Source
1920
1.07k
    pub fn build_int_signed_div<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1921
1.07k
        if self.positioned.get() != PositionState::Set {
1922
0
            return Err(BuilderError::UnsetPosition);
1923
1.07k
        }
1924
1.07k
        let c_string = to_c_str(name);
1925
1.07k
        let value = unsafe { LLVMBuildSDiv(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1926
1927
1.07k
        unsafe { Ok(T::new(value)) }
1928
1.07k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_signed_div::<_>
1929
1930
    // TODO: Possibly make this generic over sign via struct metadata or subtypes
1931
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
1932
0
    pub fn build_int_exact_signed_div<T: IntMathValue<'ctx>>(
1933
0
        &self,
1934
0
        lhs: T,
1935
0
        rhs: T,
1936
0
        name: &str,
1937
0
    ) -> Result<T, BuilderError> {
1938
0
        if self.positioned.get() != PositionState::Set {
1939
0
            return Err(BuilderError::UnsetPosition);
1940
0
        }
1941
0
        let c_string = to_c_str(name);
1942
0
        let value =
1943
0
            unsafe { LLVMBuildExactSDiv(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1944
1945
0
        unsafe { Ok(T::new(value)) }
1946
0
    }
1947
1948
    // TODO: Possibly make this generic over sign via struct metadata or subtypes
1949
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
1950
1.70k
    pub fn build_int_unsigned_rem<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1951
1.70k
        if self.positioned.get() != PositionState::Set {
1952
0
            return Err(BuilderError::UnsetPosition);
1953
1.70k
        }
1954
1.70k
        let c_string = to_c_str(name);
1955
1.70k
        let value = unsafe { LLVMBuildURem(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1956
1957
1.70k
        unsafe { Ok(T::new(value)) }
1958
1.70k
    }
<inkwell::builder::Builder>::build_int_unsigned_rem::<inkwell::values::int_value::IntValue>
Line
Count
Source
1950
1.70k
    pub fn build_int_unsigned_rem<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1951
1.70k
        if self.positioned.get() != PositionState::Set {
1952
0
            return Err(BuilderError::UnsetPosition);
1953
1.70k
        }
1954
1.70k
        let c_string = to_c_str(name);
1955
1.70k
        let value = unsafe { LLVMBuildURem(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1956
1957
1.70k
        unsafe { Ok(T::new(value)) }
1958
1.70k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_unsigned_rem::<_>
1959
1960
    // TODO: Possibly make this generic over sign via struct metadata or subtypes
1961
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
1962
1.44k
    pub fn build_int_signed_rem<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1963
1.44k
        if self.positioned.get() != PositionState::Set {
1964
0
            return Err(BuilderError::UnsetPosition);
1965
1.44k
        }
1966
1.44k
        let c_string = to_c_str(name);
1967
1.44k
        let value = unsafe { LLVMBuildSRem(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1968
1969
1.44k
        unsafe { Ok(T::new(value)) }
1970
1.44k
    }
<inkwell::builder::Builder>::build_int_signed_rem::<inkwell::values::int_value::IntValue>
Line
Count
Source
1962
1.44k
    pub fn build_int_signed_rem<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
1963
1.44k
        if self.positioned.get() != PositionState::Set {
1964
0
            return Err(BuilderError::UnsetPosition);
1965
1.44k
        }
1966
1.44k
        let c_string = to_c_str(name);
1967
1.44k
        let value = unsafe { LLVMBuildSRem(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
1968
1969
1.44k
        unsafe { Ok(T::new(value)) }
1970
1.44k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_signed_rem::<_>
1971
1972
158k
    pub fn build_int_s_extend<T: IntMathValue<'ctx>>(
1973
158k
        &self,
1974
158k
        int_value: T,
1975
158k
        int_type: T::BaseType,
1976
158k
        name: &str,
1977
158k
    ) -> Result<T, BuilderError> {
1978
158k
        if self.positioned.get() != PositionState::Set {
1979
0
            return Err(BuilderError::UnsetPosition);
1980
158k
        }
1981
158k
        let c_string = to_c_str(name);
1982
158k
        let value = unsafe {
1983
158k
            LLVMBuildSExt(
1984
158k
                self.builder,
1985
158k
                int_value.as_value_ref(),
1986
158k
                int_type.as_type_ref(),
1987
158k
                c_string.as_ptr(),
1988
            )
1989
        };
1990
1991
158k
        unsafe { Ok(T::new(value)) }
1992
158k
    }
<inkwell::builder::Builder>::build_int_s_extend::<inkwell::values::int_value::IntValue>
Line
Count
Source
1972
140k
    pub fn build_int_s_extend<T: IntMathValue<'ctx>>(
1973
140k
        &self,
1974
140k
        int_value: T,
1975
140k
        int_type: T::BaseType,
1976
140k
        name: &str,
1977
140k
    ) -> Result<T, BuilderError> {
1978
140k
        if self.positioned.get() != PositionState::Set {
1979
0
            return Err(BuilderError::UnsetPosition);
1980
140k
        }
1981
140k
        let c_string = to_c_str(name);
1982
140k
        let value = unsafe {
1983
140k
            LLVMBuildSExt(
1984
140k
                self.builder,
1985
140k
                int_value.as_value_ref(),
1986
140k
                int_type.as_type_ref(),
1987
140k
                c_string.as_ptr(),
1988
            )
1989
        };
1990
1991
140k
        unsafe { Ok(T::new(value)) }
1992
140k
    }
<inkwell::builder::Builder>::build_int_s_extend::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
1972
17.9k
    pub fn build_int_s_extend<T: IntMathValue<'ctx>>(
1973
17.9k
        &self,
1974
17.9k
        int_value: T,
1975
17.9k
        int_type: T::BaseType,
1976
17.9k
        name: &str,
1977
17.9k
    ) -> Result<T, BuilderError> {
1978
17.9k
        if self.positioned.get() != PositionState::Set {
1979
0
            return Err(BuilderError::UnsetPosition);
1980
17.9k
        }
1981
17.9k
        let c_string = to_c_str(name);
1982
17.9k
        let value = unsafe {
1983
17.9k
            LLVMBuildSExt(
1984
17.9k
                self.builder,
1985
17.9k
                int_value.as_value_ref(),
1986
17.9k
                int_type.as_type_ref(),
1987
17.9k
                c_string.as_ptr(),
1988
            )
1989
        };
1990
1991
17.9k
        unsafe { Ok(T::new(value)) }
1992
17.9k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_s_extend::<_>
1993
1994
    // REVIEW: Does this need vector support?
1995
0
    pub fn build_address_space_cast(
1996
0
        &self,
1997
0
        ptr_val: PointerValue<'ctx>,
1998
0
        ptr_type: PointerType<'ctx>,
1999
0
        name: &str,
2000
0
    ) -> Result<PointerValue<'ctx>, BuilderError> {
2001
0
        if self.positioned.get() != PositionState::Set {
2002
0
            return Err(BuilderError::UnsetPosition);
2003
0
        }
2004
0
        let c_string = to_c_str(name);
2005
0
        let value = unsafe {
2006
0
            LLVMBuildAddrSpaceCast(
2007
0
                self.builder,
2008
0
                ptr_val.as_value_ref(),
2009
0
                ptr_type.as_type_ref(),
2010
0
                c_string.as_ptr(),
2011
            )
2012
        };
2013
2014
0
        unsafe { Ok(PointerValue::new(value)) }
2015
0
    }
2016
2017
    /// Builds a bitcast instruction. A bitcast reinterprets the bits of one value
2018
    /// into a value of another type which has the same bit width.
2019
    ///
2020
    /// # Example
2021
    ///
2022
    /// ```no_run
2023
    /// use inkwell::AddressSpace;
2024
    /// use inkwell::context::Context;
2025
    ///
2026
    /// let context = Context::create();
2027
    /// let module = context.create_module("bc");
2028
    /// let void_type = context.void_type();
2029
    /// let f32_type = context.f32_type();
2030
    /// let i32_type = context.i32_type();
2031
    /// let arg_types = [i32_type.into()];
2032
    /// let fn_type = void_type.fn_type(&arg_types, false);
2033
    /// let fn_value = module.add_function("bc", fn_type, None);
2034
    /// let builder = context.create_builder();
2035
    /// let entry = context.append_basic_block(fn_value, "entry");
2036
    /// let i32_arg = fn_value.get_first_param().unwrap();
2037
    ///
2038
    /// builder.position_at_end(entry);
2039
    ///
2040
    /// builder.build_bit_cast(i32_arg, f32_type, "i32tof32").unwrap();
2041
    /// builder.build_return(None).unwrap();
2042
    ///
2043
    /// assert!(module.verify().is_ok());
2044
    /// ```
2045
1.52M
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
1.52M
    where
2047
1.52M
        T: BasicType<'ctx>,
2048
1.52M
        V: BasicValue<'ctx>,
2049
    {
2050
1.52M
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
1.52M
        }
2053
1.52M
        let c_string = to_c_str(name);
2054
1.52M
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
1.52M
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
1.52M
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::float_type::FloatType, inkwell::values::enums::BasicValueEnum>
Line
Count
Source
2045
19.2k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
19.2k
    where
2047
19.2k
        T: BasicType<'ctx>,
2048
19.2k
        V: BasicValue<'ctx>,
2049
    {
2050
19.2k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
19.2k
        }
2053
19.2k
        let c_string = to_c_str(name);
2054
19.2k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
19.2k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
19.2k
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::float_type::FloatType, inkwell::values::int_value::IntValue>
Line
Count
Source
2045
479k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
479k
    where
2047
479k
        T: BasicType<'ctx>,
2048
479k
        V: BasicValue<'ctx>,
2049
    {
2050
479k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
479k
        }
2053
479k
        let c_string = to_c_str(name);
2054
479k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
479k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
479k
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::enums::BasicTypeEnum, inkwell::values::enums::BasicValueEnum>
Line
Count
Source
2045
666k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
666k
    where
2047
666k
        T: BasicType<'ctx>,
2048
666k
        V: BasicValue<'ctx>,
2049
    {
2050
666k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
666k
        }
2053
666k
        let c_string = to_c_str(name);
2054
666k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
666k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
666k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_bit_cast::<inkwell::types::enums::BasicTypeEnum, inkwell::values::int_value::IntValue>
Unexecuted instantiation: <inkwell::builder::Builder>::build_bit_cast::<inkwell::types::int_type::IntType, inkwell::values::float_value::FloatValue>
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::int_type::IntType, inkwell::values::enums::BasicValueEnum>
Line
Count
Source
2045
75.4k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
75.4k
    where
2047
75.4k
        T: BasicType<'ctx>,
2048
75.4k
        V: BasicValue<'ctx>,
2049
    {
2050
75.4k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
75.4k
        }
2053
75.4k
        let c_string = to_c_str(name);
2054
75.4k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
75.4k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
75.4k
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::int_type::IntType, inkwell::values::int_value::IntValue>
Line
Count
Source
2045
21.4k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
21.4k
    where
2047
21.4k
        T: BasicType<'ctx>,
2048
21.4k
        V: BasicValue<'ctx>,
2049
    {
2050
21.4k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
21.4k
        }
2053
21.4k
        let c_string = to_c_str(name);
2054
21.4k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
21.4k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
21.4k
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::int_type::IntType, inkwell::values::vec_value::VectorValue>
Line
Count
Source
2045
50.2k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
50.2k
    where
2047
50.2k
        T: BasicType<'ctx>,
2048
50.2k
        V: BasicValue<'ctx>,
2049
    {
2050
50.2k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
50.2k
        }
2053
50.2k
        let c_string = to_c_str(name);
2054
50.2k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
50.2k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
50.2k
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::ptr_type::PointerType, inkwell::values::enums::BasicValueEnum>
Line
Count
Source
2045
738
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
738
    where
2047
738
        T: BasicType<'ctx>,
2048
738
        V: BasicValue<'ctx>,
2049
    {
2050
738
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
738
        }
2053
738
        let c_string = to_c_str(name);
2054
738
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
738
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
738
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::ptr_type::PointerType, inkwell::values::ptr_value::PointerValue>
Line
Count
Source
2045
139k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
139k
    where
2047
139k
        T: BasicType<'ctx>,
2048
139k
        V: BasicValue<'ctx>,
2049
    {
2050
139k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
139k
        }
2053
139k
        let c_string = to_c_str(name);
2054
139k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
139k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
139k
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::vec_type::VectorType, inkwell::values::enums::BasicValueEnum>
Line
Count
Source
2045
65.2k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
65.2k
    where
2047
65.2k
        T: BasicType<'ctx>,
2048
65.2k
        V: BasicValue<'ctx>,
2049
    {
2050
65.2k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
65.2k
        }
2053
65.2k
        let c_string = to_c_str(name);
2054
65.2k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
65.2k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
65.2k
    }
<inkwell::builder::Builder>::build_bit_cast::<inkwell::types::vec_type::VectorType, inkwell::values::int_value::IntValue>
Line
Count
Source
2045
5.86k
    pub fn build_bit_cast<T, V>(&self, val: V, ty: T, name: &str) -> Result<BasicValueEnum<'ctx>, BuilderError>
2046
5.86k
    where
2047
5.86k
        T: BasicType<'ctx>,
2048
5.86k
        V: BasicValue<'ctx>,
2049
    {
2050
5.86k
        if self.positioned.get() != PositionState::Set {
2051
0
            return Err(BuilderError::UnsetPosition);
2052
5.86k
        }
2053
5.86k
        let c_string = to_c_str(name);
2054
5.86k
        let value = unsafe { LLVMBuildBitCast(self.builder, val.as_value_ref(), ty.as_type_ref(), c_string.as_ptr()) };
2055
2056
5.86k
        unsafe { Ok(BasicValueEnum::new(value)) }
2057
5.86k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_bit_cast::<inkwell::types::vec_type::VectorType, inkwell::values::vec_value::VectorValue>
Unexecuted instantiation: <inkwell::builder::Builder>::build_bit_cast::<_, _>
2058
2059
0
    pub fn build_int_s_extend_or_bit_cast<T: IntMathValue<'ctx>>(
2060
0
        &self,
2061
0
        int_value: T,
2062
0
        int_type: T::BaseType,
2063
0
        name: &str,
2064
0
    ) -> Result<T, BuilderError> {
2065
0
        if self.positioned.get() != PositionState::Set {
2066
0
            return Err(BuilderError::UnsetPosition);
2067
0
        }
2068
0
        let c_string = to_c_str(name);
2069
0
        let value = unsafe {
2070
0
            LLVMBuildSExtOrBitCast(
2071
0
                self.builder,
2072
0
                int_value.as_value_ref(),
2073
0
                int_type.as_type_ref(),
2074
0
                c_string.as_ptr(),
2075
            )
2076
        };
2077
2078
0
        unsafe { Ok(T::new(value)) }
2079
0
    }
2080
2081
325k
    pub fn build_int_z_extend<T: IntMathValue<'ctx>>(
2082
325k
        &self,
2083
325k
        int_value: T,
2084
325k
        int_type: T::BaseType,
2085
325k
        name: &str,
2086
325k
    ) -> Result<T, BuilderError> {
2087
325k
        if self.positioned.get() != PositionState::Set {
2088
0
            return Err(BuilderError::UnsetPosition);
2089
325k
        }
2090
325k
        let c_string = to_c_str(name);
2091
325k
        let value = unsafe {
2092
325k
            LLVMBuildZExt(
2093
325k
                self.builder,
2094
325k
                int_value.as_value_ref(),
2095
325k
                int_type.as_type_ref(),
2096
325k
                c_string.as_ptr(),
2097
            )
2098
        };
2099
2100
325k
        unsafe { Ok(T::new(value)) }
2101
325k
    }
<inkwell::builder::Builder>::build_int_z_extend::<inkwell::values::int_value::IntValue>
Line
Count
Source
2081
312k
    pub fn build_int_z_extend<T: IntMathValue<'ctx>>(
2082
312k
        &self,
2083
312k
        int_value: T,
2084
312k
        int_type: T::BaseType,
2085
312k
        name: &str,
2086
312k
    ) -> Result<T, BuilderError> {
2087
312k
        if self.positioned.get() != PositionState::Set {
2088
0
            return Err(BuilderError::UnsetPosition);
2089
312k
        }
2090
312k
        let c_string = to_c_str(name);
2091
312k
        let value = unsafe {
2092
312k
            LLVMBuildZExt(
2093
312k
                self.builder,
2094
312k
                int_value.as_value_ref(),
2095
312k
                int_type.as_type_ref(),
2096
312k
                c_string.as_ptr(),
2097
            )
2098
        };
2099
2100
312k
        unsafe { Ok(T::new(value)) }
2101
312k
    }
<inkwell::builder::Builder>::build_int_z_extend::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2081
13.7k
    pub fn build_int_z_extend<T: IntMathValue<'ctx>>(
2082
13.7k
        &self,
2083
13.7k
        int_value: T,
2084
13.7k
        int_type: T::BaseType,
2085
13.7k
        name: &str,
2086
13.7k
    ) -> Result<T, BuilderError> {
2087
13.7k
        if self.positioned.get() != PositionState::Set {
2088
0
            return Err(BuilderError::UnsetPosition);
2089
13.7k
        }
2090
13.7k
        let c_string = to_c_str(name);
2091
13.7k
        let value = unsafe {
2092
13.7k
            LLVMBuildZExt(
2093
13.7k
                self.builder,
2094
13.7k
                int_value.as_value_ref(),
2095
13.7k
                int_type.as_type_ref(),
2096
13.7k
                c_string.as_ptr(),
2097
            )
2098
        };
2099
2100
13.7k
        unsafe { Ok(T::new(value)) }
2101
13.7k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_z_extend::<_>
2102
2103
0
    pub fn build_int_z_extend_or_bit_cast<T: IntMathValue<'ctx>>(
2104
0
        &self,
2105
0
        int_value: T,
2106
0
        int_type: T::BaseType,
2107
0
        name: &str,
2108
0
    ) -> Result<T, BuilderError> {
2109
0
        if self.positioned.get() != PositionState::Set {
2110
0
            return Err(BuilderError::UnsetPosition);
2111
0
        }
2112
0
        let c_string = to_c_str(name);
2113
0
        let value = unsafe {
2114
0
            LLVMBuildZExtOrBitCast(
2115
0
                self.builder,
2116
0
                int_value.as_value_ref(),
2117
0
                int_type.as_type_ref(),
2118
0
                c_string.as_ptr(),
2119
            )
2120
        };
2121
2122
0
        unsafe { Ok(T::new(value)) }
2123
0
    }
2124
2125
126k
    pub fn build_int_truncate<T: IntMathValue<'ctx>>(
2126
126k
        &self,
2127
126k
        int_value: T,
2128
126k
        int_type: T::BaseType,
2129
126k
        name: &str,
2130
126k
    ) -> Result<T, BuilderError> {
2131
126k
        if self.positioned.get() != PositionState::Set {
2132
0
            return Err(BuilderError::UnsetPosition);
2133
126k
        }
2134
126k
        let c_string = to_c_str(name);
2135
2136
126k
        let value = unsafe {
2137
126k
            LLVMBuildTrunc(
2138
126k
                self.builder,
2139
126k
                int_value.as_value_ref(),
2140
126k
                int_type.as_type_ref(),
2141
126k
                c_string.as_ptr(),
2142
            )
2143
        };
2144
2145
126k
        unsafe { Ok(T::new(value)) }
2146
126k
    }
<inkwell::builder::Builder>::build_int_truncate::<inkwell::values::int_value::IntValue>
Line
Count
Source
2125
126k
    pub fn build_int_truncate<T: IntMathValue<'ctx>>(
2126
126k
        &self,
2127
126k
        int_value: T,
2128
126k
        int_type: T::BaseType,
2129
126k
        name: &str,
2130
126k
    ) -> Result<T, BuilderError> {
2131
126k
        if self.positioned.get() != PositionState::Set {
2132
0
            return Err(BuilderError::UnsetPosition);
2133
126k
        }
2134
126k
        let c_string = to_c_str(name);
2135
2136
126k
        let value = unsafe {
2137
126k
            LLVMBuildTrunc(
2138
126k
                self.builder,
2139
126k
                int_value.as_value_ref(),
2140
126k
                int_type.as_type_ref(),
2141
126k
                c_string.as_ptr(),
2142
            )
2143
        };
2144
2145
126k
        unsafe { Ok(T::new(value)) }
2146
126k
    }
<inkwell::builder::Builder>::build_int_truncate::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2125
239
    pub fn build_int_truncate<T: IntMathValue<'ctx>>(
2126
239
        &self,
2127
239
        int_value: T,
2128
239
        int_type: T::BaseType,
2129
239
        name: &str,
2130
239
    ) -> Result<T, BuilderError> {
2131
239
        if self.positioned.get() != PositionState::Set {
2132
0
            return Err(BuilderError::UnsetPosition);
2133
239
        }
2134
239
        let c_string = to_c_str(name);
2135
2136
239
        let value = unsafe {
2137
239
            LLVMBuildTrunc(
2138
239
                self.builder,
2139
239
                int_value.as_value_ref(),
2140
239
                int_type.as_type_ref(),
2141
239
                c_string.as_ptr(),
2142
            )
2143
        };
2144
2145
239
        unsafe { Ok(T::new(value)) }
2146
239
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_truncate::<_>
2147
2148
0
    pub fn build_int_truncate_or_bit_cast<T: IntMathValue<'ctx>>(
2149
0
        &self,
2150
0
        int_value: T,
2151
0
        int_type: T::BaseType,
2152
0
        name: &str,
2153
0
    ) -> Result<T, BuilderError> {
2154
0
        if self.positioned.get() != PositionState::Set {
2155
0
            return Err(BuilderError::UnsetPosition);
2156
0
        }
2157
0
        let c_string = to_c_str(name);
2158
2159
0
        let value = unsafe {
2160
0
            LLVMBuildTruncOrBitCast(
2161
0
                self.builder,
2162
0
                int_value.as_value_ref(),
2163
0
                int_type.as_type_ref(),
2164
0
                c_string.as_ptr(),
2165
            )
2166
        };
2167
2168
0
        unsafe { Ok(T::new(value)) }
2169
0
    }
2170
2171
0
    pub fn build_float_rem<T: FloatMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2172
0
        if self.positioned.get() != PositionState::Set {
2173
0
            return Err(BuilderError::UnsetPosition);
2174
0
        }
2175
0
        let c_string = to_c_str(name);
2176
0
        let value = unsafe { LLVMBuildFRem(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2177
2178
0
        unsafe { Ok(T::new(value)) }
2179
0
    }
2180
2181
    // REVIEW: Consolidate these two casts into one via subtypes
2182
20.8k
    pub fn build_float_to_unsigned_int<T: FloatMathValue<'ctx>>(
2183
20.8k
        &self,
2184
20.8k
        float: T,
2185
20.8k
        int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
2186
20.8k
        name: &str,
2187
20.8k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2188
    {
2189
20.8k
        if self.positioned.get() != PositionState::Set {
2190
0
            return Err(BuilderError::UnsetPosition);
2191
20.8k
        }
2192
20.8k
        let c_string = to_c_str(name);
2193
20.8k
        let value = unsafe {
2194
20.8k
            LLVMBuildFPToUI(
2195
20.8k
                self.builder,
2196
20.8k
                float.as_value_ref(),
2197
20.8k
                int_type.as_type_ref(),
2198
20.8k
                c_string.as_ptr(),
2199
            )
2200
        };
2201
2202
20.8k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2203
20.8k
    }
<inkwell::builder::Builder>::build_float_to_unsigned_int::<inkwell::values::float_value::FloatValue>
Line
Count
Source
2182
19.8k
    pub fn build_float_to_unsigned_int<T: FloatMathValue<'ctx>>(
2183
19.8k
        &self,
2184
19.8k
        float: T,
2185
19.8k
        int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
2186
19.8k
        name: &str,
2187
19.8k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2188
    {
2189
19.8k
        if self.positioned.get() != PositionState::Set {
2190
0
            return Err(BuilderError::UnsetPosition);
2191
19.8k
        }
2192
19.8k
        let c_string = to_c_str(name);
2193
19.8k
        let value = unsafe {
2194
19.8k
            LLVMBuildFPToUI(
2195
19.8k
                self.builder,
2196
19.8k
                float.as_value_ref(),
2197
19.8k
                int_type.as_type_ref(),
2198
19.8k
                c_string.as_ptr(),
2199
            )
2200
        };
2201
2202
19.8k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2203
19.8k
    }
<inkwell::builder::Builder>::build_float_to_unsigned_int::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2182
1.02k
    pub fn build_float_to_unsigned_int<T: FloatMathValue<'ctx>>(
2183
1.02k
        &self,
2184
1.02k
        float: T,
2185
1.02k
        int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
2186
1.02k
        name: &str,
2187
1.02k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2188
    {
2189
1.02k
        if self.positioned.get() != PositionState::Set {
2190
0
            return Err(BuilderError::UnsetPosition);
2191
1.02k
        }
2192
1.02k
        let c_string = to_c_str(name);
2193
1.02k
        let value = unsafe {
2194
1.02k
            LLVMBuildFPToUI(
2195
1.02k
                self.builder,
2196
1.02k
                float.as_value_ref(),
2197
1.02k
                int_type.as_type_ref(),
2198
1.02k
                c_string.as_ptr(),
2199
            )
2200
        };
2201
2202
1.02k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2203
1.02k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_float_to_unsigned_int::<_>
2204
2205
27.2k
    pub fn build_float_to_signed_int<T: FloatMathValue<'ctx>>(
2206
27.2k
        &self,
2207
27.2k
        float: T,
2208
27.2k
        int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
2209
27.2k
        name: &str,
2210
27.2k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2211
    {
2212
27.2k
        if self.positioned.get() != PositionState::Set {
2213
0
            return Err(BuilderError::UnsetPosition);
2214
27.2k
        }
2215
27.2k
        let c_string = to_c_str(name);
2216
27.2k
        let value = unsafe {
2217
27.2k
            LLVMBuildFPToSI(
2218
27.2k
                self.builder,
2219
27.2k
                float.as_value_ref(),
2220
27.2k
                int_type.as_type_ref(),
2221
27.2k
                c_string.as_ptr(),
2222
            )
2223
        };
2224
2225
27.2k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2226
27.2k
    }
<inkwell::builder::Builder>::build_float_to_signed_int::<inkwell::values::float_value::FloatValue>
Line
Count
Source
2205
26.5k
    pub fn build_float_to_signed_int<T: FloatMathValue<'ctx>>(
2206
26.5k
        &self,
2207
26.5k
        float: T,
2208
26.5k
        int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
2209
26.5k
        name: &str,
2210
26.5k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2211
    {
2212
26.5k
        if self.positioned.get() != PositionState::Set {
2213
0
            return Err(BuilderError::UnsetPosition);
2214
26.5k
        }
2215
26.5k
        let c_string = to_c_str(name);
2216
26.5k
        let value = unsafe {
2217
26.5k
            LLVMBuildFPToSI(
2218
26.5k
                self.builder,
2219
26.5k
                float.as_value_ref(),
2220
26.5k
                int_type.as_type_ref(),
2221
26.5k
                c_string.as_ptr(),
2222
            )
2223
        };
2224
2225
26.5k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2226
26.5k
    }
<inkwell::builder::Builder>::build_float_to_signed_int::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2205
693
    pub fn build_float_to_signed_int<T: FloatMathValue<'ctx>>(
2206
693
        &self,
2207
693
        float: T,
2208
693
        int_type: <T::BaseType as FloatMathType<'ctx>>::MathConvType,
2209
693
        name: &str,
2210
693
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2211
    {
2212
693
        if self.positioned.get() != PositionState::Set {
2213
0
            return Err(BuilderError::UnsetPosition);
2214
693
        }
2215
693
        let c_string = to_c_str(name);
2216
693
        let value = unsafe {
2217
693
            LLVMBuildFPToSI(
2218
693
                self.builder,
2219
693
                float.as_value_ref(),
2220
693
                int_type.as_type_ref(),
2221
693
                c_string.as_ptr(),
2222
            )
2223
        };
2224
2225
693
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2226
693
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_float_to_signed_int::<_>
2227
2228
    // REVIEW: Consolidate these two casts into one via subtypes
2229
24.0k
    pub fn build_unsigned_int_to_float<T: IntMathValue<'ctx>>(
2230
24.0k
        &self,
2231
24.0k
        int: T,
2232
24.0k
        float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
2233
24.0k
        name: &str,
2234
24.0k
    ) -> Result<<<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType, BuilderError>
2235
    {
2236
24.0k
        if self.positioned.get() != PositionState::Set {
2237
0
            return Err(BuilderError::UnsetPosition);
2238
24.0k
        }
2239
24.0k
        let c_string = to_c_str(name);
2240
24.0k
        let value = unsafe {
2241
24.0k
            LLVMBuildUIToFP(
2242
24.0k
                self.builder,
2243
24.0k
                int.as_value_ref(),
2244
24.0k
                float_type.as_type_ref(),
2245
24.0k
                c_string.as_ptr(),
2246
            )
2247
        };
2248
2249
24.0k
        unsafe { Ok(<<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType::new(value)) }
2250
24.0k
    }
<inkwell::builder::Builder>::build_unsigned_int_to_float::<inkwell::values::int_value::IntValue>
Line
Count
Source
2229
23.5k
    pub fn build_unsigned_int_to_float<T: IntMathValue<'ctx>>(
2230
23.5k
        &self,
2231
23.5k
        int: T,
2232
23.5k
        float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
2233
23.5k
        name: &str,
2234
23.5k
    ) -> Result<<<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType, BuilderError>
2235
    {
2236
23.5k
        if self.positioned.get() != PositionState::Set {
2237
0
            return Err(BuilderError::UnsetPosition);
2238
23.5k
        }
2239
23.5k
        let c_string = to_c_str(name);
2240
23.5k
        let value = unsafe {
2241
23.5k
            LLVMBuildUIToFP(
2242
23.5k
                self.builder,
2243
23.5k
                int.as_value_ref(),
2244
23.5k
                float_type.as_type_ref(),
2245
23.5k
                c_string.as_ptr(),
2246
            )
2247
        };
2248
2249
23.5k
        unsafe { Ok(<<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType::new(value)) }
2250
23.5k
    }
<inkwell::builder::Builder>::build_unsigned_int_to_float::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2229
483
    pub fn build_unsigned_int_to_float<T: IntMathValue<'ctx>>(
2230
483
        &self,
2231
483
        int: T,
2232
483
        float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
2233
483
        name: &str,
2234
483
    ) -> Result<<<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType, BuilderError>
2235
    {
2236
483
        if self.positioned.get() != PositionState::Set {
2237
0
            return Err(BuilderError::UnsetPosition);
2238
483
        }
2239
483
        let c_string = to_c_str(name);
2240
483
        let value = unsafe {
2241
483
            LLVMBuildUIToFP(
2242
483
                self.builder,
2243
483
                int.as_value_ref(),
2244
483
                float_type.as_type_ref(),
2245
483
                c_string.as_ptr(),
2246
            )
2247
        };
2248
2249
483
        unsafe { Ok(<<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType::new(value)) }
2250
483
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_unsigned_int_to_float::<_>
2251
2252
52.3k
    pub fn build_signed_int_to_float<T: IntMathValue<'ctx>>(
2253
52.3k
        &self,
2254
52.3k
        int: T,
2255
52.3k
        float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
2256
52.3k
        name: &str,
2257
52.3k
    ) -> Result<<<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType, BuilderError>
2258
    {
2259
52.3k
        if self.positioned.get() != PositionState::Set {
2260
0
            return Err(BuilderError::UnsetPosition);
2261
52.3k
        }
2262
52.3k
        let c_string = to_c_str(name);
2263
52.3k
        let value = unsafe {
2264
52.3k
            LLVMBuildSIToFP(
2265
52.3k
                self.builder,
2266
52.3k
                int.as_value_ref(),
2267
52.3k
                float_type.as_type_ref(),
2268
52.3k
                c_string.as_ptr(),
2269
            )
2270
        };
2271
2272
52.3k
        unsafe { Ok(<<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType::new(value)) }
2273
52.3k
    }
<inkwell::builder::Builder>::build_signed_int_to_float::<inkwell::values::int_value::IntValue>
Line
Count
Source
2252
51.8k
    pub fn build_signed_int_to_float<T: IntMathValue<'ctx>>(
2253
51.8k
        &self,
2254
51.8k
        int: T,
2255
51.8k
        float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
2256
51.8k
        name: &str,
2257
51.8k
    ) -> Result<<<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType, BuilderError>
2258
    {
2259
51.8k
        if self.positioned.get() != PositionState::Set {
2260
0
            return Err(BuilderError::UnsetPosition);
2261
51.8k
        }
2262
51.8k
        let c_string = to_c_str(name);
2263
51.8k
        let value = unsafe {
2264
51.8k
            LLVMBuildSIToFP(
2265
51.8k
                self.builder,
2266
51.8k
                int.as_value_ref(),
2267
51.8k
                float_type.as_type_ref(),
2268
51.8k
                c_string.as_ptr(),
2269
            )
2270
        };
2271
2272
51.8k
        unsafe { Ok(<<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType::new(value)) }
2273
51.8k
    }
<inkwell::builder::Builder>::build_signed_int_to_float::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2252
427
    pub fn build_signed_int_to_float<T: IntMathValue<'ctx>>(
2253
427
        &self,
2254
427
        int: T,
2255
427
        float_type: <T::BaseType as IntMathType<'ctx>>::MathConvType,
2256
427
        name: &str,
2257
427
    ) -> Result<<<T::BaseType as IntMathType<'ctx>>::MathConvType as FloatMathType<'ctx>>::ValueType, BuilderError>
2258
    {
2259
427
        if self.positioned.get() != PositionState::Set {
2260
0
            return Err(BuilderError::UnsetPosition);
2261
427
        }
2262
427
        let c_string = to_c_str(name);
2263
427
        let value = unsafe {
2264
427
            LLVMBuildSIToFP(
2265
427
                self.builder,
2266
427
                int.as_value_ref(),
2267
427
                float_type.as_type_ref(),
2268
427
                c_string.as_ptr(),
2269
            )
2270
        };
2271
2272
427
        unsafe { Ok(<<T::BaseType as IntMathType>::MathConvType as FloatMathType>::ValueType::new(value)) }
2273
427
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_signed_int_to_float::<_>
2274
2275
60
    pub fn build_float_trunc<T: FloatMathValue<'ctx>>(
2276
60
        &self,
2277
60
        float: T,
2278
60
        float_type: T::BaseType,
2279
60
        name: &str,
2280
60
    ) -> Result<T, BuilderError> {
2281
60
        if self.positioned.get() != PositionState::Set {
2282
0
            return Err(BuilderError::UnsetPosition);
2283
60
        }
2284
60
        let c_string = to_c_str(name);
2285
60
        let value = unsafe {
2286
60
            LLVMBuildFPTrunc(
2287
60
                self.builder,
2288
60
                float.as_value_ref(),
2289
60
                float_type.as_type_ref(),
2290
60
                c_string.as_ptr(),
2291
            )
2292
        };
2293
2294
60
        unsafe { Ok(T::new(value)) }
2295
60
    }
<inkwell::builder::Builder>::build_float_trunc::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2275
60
    pub fn build_float_trunc<T: FloatMathValue<'ctx>>(
2276
60
        &self,
2277
60
        float: T,
2278
60
        float_type: T::BaseType,
2279
60
        name: &str,
2280
60
    ) -> Result<T, BuilderError> {
2281
60
        if self.positioned.get() != PositionState::Set {
2282
0
            return Err(BuilderError::UnsetPosition);
2283
60
        }
2284
60
        let c_string = to_c_str(name);
2285
60
        let value = unsafe {
2286
60
            LLVMBuildFPTrunc(
2287
60
                self.builder,
2288
60
                float.as_value_ref(),
2289
60
                float_type.as_type_ref(),
2290
60
                c_string.as_ptr(),
2291
            )
2292
        };
2293
2294
60
        unsafe { Ok(T::new(value)) }
2295
60
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_float_trunc::<_>
2296
2297
54
    pub fn build_float_ext<T: FloatMathValue<'ctx>>(
2298
54
        &self,
2299
54
        float: T,
2300
54
        float_type: T::BaseType,
2301
54
        name: &str,
2302
54
    ) -> Result<T, BuilderError> {
2303
54
        if self.positioned.get() != PositionState::Set {
2304
0
            return Err(BuilderError::UnsetPosition);
2305
54
        }
2306
54
        let c_string = to_c_str(name);
2307
54
        let value = unsafe {
2308
54
            LLVMBuildFPExt(
2309
54
                self.builder,
2310
54
                float.as_value_ref(),
2311
54
                float_type.as_type_ref(),
2312
54
                c_string.as_ptr(),
2313
            )
2314
        };
2315
2316
54
        unsafe { Ok(T::new(value)) }
2317
54
    }
<inkwell::builder::Builder>::build_float_ext::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2297
54
    pub fn build_float_ext<T: FloatMathValue<'ctx>>(
2298
54
        &self,
2299
54
        float: T,
2300
54
        float_type: T::BaseType,
2301
54
        name: &str,
2302
54
    ) -> Result<T, BuilderError> {
2303
54
        if self.positioned.get() != PositionState::Set {
2304
0
            return Err(BuilderError::UnsetPosition);
2305
54
        }
2306
54
        let c_string = to_c_str(name);
2307
54
        let value = unsafe {
2308
54
            LLVMBuildFPExt(
2309
54
                self.builder,
2310
54
                float.as_value_ref(),
2311
54
                float_type.as_type_ref(),
2312
54
                c_string.as_ptr(),
2313
            )
2314
        };
2315
2316
54
        unsafe { Ok(T::new(value)) }
2317
54
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_float_ext::<_>
2318
2319
0
    pub fn build_float_cast<T: FloatMathValue<'ctx>>(
2320
0
        &self,
2321
0
        float: T,
2322
0
        float_type: T::BaseType,
2323
0
        name: &str,
2324
0
    ) -> Result<T, BuilderError> {
2325
0
        if self.positioned.get() != PositionState::Set {
2326
0
            return Err(BuilderError::UnsetPosition);
2327
0
        }
2328
0
        let c_string = to_c_str(name);
2329
0
        let value = unsafe {
2330
0
            LLVMBuildFPCast(
2331
0
                self.builder,
2332
0
                float.as_value_ref(),
2333
0
                float_type.as_type_ref(),
2334
0
                c_string.as_ptr(),
2335
            )
2336
        };
2337
2338
0
        unsafe { Ok(T::new(value)) }
2339
0
    }
2340
2341
    // SubType: <L, R>(&self, lhs: &IntValue<L>, rhs: &IntType<R>, name: &str) -> IntValue<R> {
2342
27
    pub fn build_int_cast<T: IntMathValue<'ctx>>(
2343
27
        &self,
2344
27
        int: T,
2345
27
        int_type: T::BaseType,
2346
27
        name: &str,
2347
27
    ) -> Result<T, BuilderError> {
2348
27
        if self.positioned.get() != PositionState::Set {
2349
0
            return Err(BuilderError::UnsetPosition);
2350
27
        }
2351
27
        let c_string = to_c_str(name);
2352
27
        let value = unsafe {
2353
27
            LLVMBuildIntCast(
2354
27
                self.builder,
2355
27
                int.as_value_ref(),
2356
27
                int_type.as_type_ref(),
2357
27
                c_string.as_ptr(),
2358
            )
2359
        };
2360
2361
27
        unsafe { Ok(T::new(value)) }
2362
27
    }
<inkwell::builder::Builder>::build_int_cast::<inkwell::values::int_value::IntValue>
Line
Count
Source
2342
27
    pub fn build_int_cast<T: IntMathValue<'ctx>>(
2343
27
        &self,
2344
27
        int: T,
2345
27
        int_type: T::BaseType,
2346
27
        name: &str,
2347
27
    ) -> Result<T, BuilderError> {
2348
27
        if self.positioned.get() != PositionState::Set {
2349
0
            return Err(BuilderError::UnsetPosition);
2350
27
        }
2351
27
        let c_string = to_c_str(name);
2352
27
        let value = unsafe {
2353
27
            LLVMBuildIntCast(
2354
27
                self.builder,
2355
27
                int.as_value_ref(),
2356
27
                int_type.as_type_ref(),
2357
27
                c_string.as_ptr(),
2358
            )
2359
        };
2360
2361
27
        unsafe { Ok(T::new(value)) }
2362
27
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_cast::<_>
2363
2364
    /// Like `build_int_cast`, but respects the signedness of the type being cast to.
2365
0
    pub fn build_int_cast_sign_flag<T: IntMathValue<'ctx>>(
2366
0
        &self,
2367
0
        int: T,
2368
0
        int_type: T::BaseType,
2369
0
        is_signed: bool,
2370
0
        name: &str,
2371
0
    ) -> Result<T, BuilderError> {
2372
0
        if self.positioned.get() != PositionState::Set {
2373
0
            return Err(BuilderError::UnsetPosition);
2374
0
        }
2375
0
        let c_string = to_c_str(name);
2376
0
        let value = unsafe {
2377
0
            LLVMBuildIntCast2(
2378
0
                self.builder,
2379
0
                int.as_value_ref(),
2380
0
                int_type.as_type_ref(),
2381
0
                is_signed.into(),
2382
0
                c_string.as_ptr(),
2383
            )
2384
        };
2385
2386
0
        unsafe { Ok(T::new(value)) }
2387
0
    }
2388
2389
0
    pub fn build_float_div<T: FloatMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2390
0
        if self.positioned.get() != PositionState::Set {
2391
0
            return Err(BuilderError::UnsetPosition);
2392
0
        }
2393
0
        let c_string = to_c_str(name);
2394
0
        let value = unsafe { LLVMBuildFDiv(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2395
2396
0
        unsafe { Ok(T::new(value)) }
2397
0
    }
2398
2399
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2400
131k
    pub fn build_int_add<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2401
131k
        if self.positioned.get() != PositionState::Set {
2402
0
            return Err(BuilderError::UnsetPosition);
2403
131k
        }
2404
131k
        let c_string = to_c_str(name);
2405
131k
        let value = unsafe { LLVMBuildAdd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2406
2407
131k
        unsafe { Ok(T::new(value)) }
2408
131k
    }
<inkwell::builder::Builder>::build_int_add::<inkwell::values::int_value::IntValue>
Line
Count
Source
2400
124k
    pub fn build_int_add<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2401
124k
        if self.positioned.get() != PositionState::Set {
2402
0
            return Err(BuilderError::UnsetPosition);
2403
124k
        }
2404
124k
        let c_string = to_c_str(name);
2405
124k
        let value = unsafe { LLVMBuildAdd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2406
2407
124k
        unsafe { Ok(T::new(value)) }
2408
124k
    }
<inkwell::builder::Builder>::build_int_add::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2400
6.59k
    pub fn build_int_add<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2401
6.59k
        if self.positioned.get() != PositionState::Set {
2402
0
            return Err(BuilderError::UnsetPosition);
2403
6.59k
        }
2404
6.59k
        let c_string = to_c_str(name);
2405
6.59k
        let value = unsafe { LLVMBuildAdd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2406
2407
6.59k
        unsafe { Ok(T::new(value)) }
2408
6.59k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_add::<_>
2409
2410
    // REVIEW: Possibly incorporate into build_int_add via flag param
2411
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2412
0
    pub fn build_int_nsw_add<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2413
0
        let c_string = to_c_str(name);
2414
0
        let value = unsafe { LLVMBuildNSWAdd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2415
2416
0
        unsafe { Ok(T::new(value)) }
2417
0
    }
2418
2419
    // REVIEW: Possibly incorporate into build_int_add via flag param
2420
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2421
0
    pub fn build_int_nuw_add<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2422
0
        if self.positioned.get() != PositionState::Set {
2423
0
            return Err(BuilderError::UnsetPosition);
2424
0
        }
2425
0
        let c_string = to_c_str(name);
2426
0
        let value = unsafe { LLVMBuildNUWAdd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2427
2428
0
        unsafe { Ok(T::new(value)) }
2429
0
    }
2430
2431
    // SubType: <F>(&self, lhs: &FloatValue<F>, rhs: &FloatValue<F>, name: &str) -> FloatValue<F> {
2432
0
    pub fn build_float_add<T: FloatMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2433
0
        if self.positioned.get() != PositionState::Set {
2434
0
            return Err(BuilderError::UnsetPosition);
2435
0
        }
2436
0
        let c_string = to_c_str(name);
2437
0
        let value = unsafe { LLVMBuildFAdd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2438
2439
0
        unsafe { Ok(T::new(value)) }
2440
0
    }
2441
2442
    // SubType: (&self, lhs: &IntValue<bool>, rhs: &IntValue<bool>, name: &str) -> IntValue<bool> {
2443
175k
    pub fn build_xor<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2444
175k
        if self.positioned.get() != PositionState::Set {
2445
0
            return Err(BuilderError::UnsetPosition);
2446
175k
        }
2447
175k
        let c_string = to_c_str(name);
2448
175k
        let value = unsafe { LLVMBuildXor(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2449
2450
175k
        unsafe { Ok(T::new(value)) }
2451
175k
    }
<inkwell::builder::Builder>::build_xor::<inkwell::values::int_value::IntValue>
Line
Count
Source
2443
170k
    pub fn build_xor<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2444
170k
        if self.positioned.get() != PositionState::Set {
2445
0
            return Err(BuilderError::UnsetPosition);
2446
170k
        }
2447
170k
        let c_string = to_c_str(name);
2448
170k
        let value = unsafe { LLVMBuildXor(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2449
2450
170k
        unsafe { Ok(T::new(value)) }
2451
170k
    }
<inkwell::builder::Builder>::build_xor::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2443
5.02k
    pub fn build_xor<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2444
5.02k
        if self.positioned.get() != PositionState::Set {
2445
0
            return Err(BuilderError::UnsetPosition);
2446
5.02k
        }
2447
5.02k
        let c_string = to_c_str(name);
2448
5.02k
        let value = unsafe { LLVMBuildXor(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2449
2450
5.02k
        unsafe { Ok(T::new(value)) }
2451
5.02k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_xor::<_>
2452
2453
    // SubType: (&self, lhs: &IntValue<bool>, rhs: &IntValue<bool>, name: &str) -> IntValue<bool> {
2454
25.5k
    pub fn build_and<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2455
25.5k
        if self.positioned.get() != PositionState::Set {
2456
0
            return Err(BuilderError::UnsetPosition);
2457
25.5k
        }
2458
25.5k
        let c_string = to_c_str(name);
2459
25.5k
        let value = unsafe { LLVMBuildAnd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2460
2461
25.5k
        unsafe { Ok(T::new(value)) }
2462
25.5k
    }
<inkwell::builder::Builder>::build_and::<inkwell::values::int_value::IntValue>
Line
Count
Source
2454
25.5k
    pub fn build_and<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2455
25.5k
        if self.positioned.get() != PositionState::Set {
2456
0
            return Err(BuilderError::UnsetPosition);
2457
25.5k
        }
2458
25.5k
        let c_string = to_c_str(name);
2459
25.5k
        let value = unsafe { LLVMBuildAnd(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2460
2461
25.5k
        unsafe { Ok(T::new(value)) }
2462
25.5k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_and::<_>
2463
2464
    // SubType: (&self, lhs: &IntValue<bool>, rhs: &IntValue<bool>, name: &str) -> IntValue<bool> {
2465
94.0k
    pub fn build_or<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2466
94.0k
        if self.positioned.get() != PositionState::Set {
2467
0
            return Err(BuilderError::UnsetPosition);
2468
94.0k
        }
2469
94.0k
        let c_string = to_c_str(name);
2470
94.0k
        let value = unsafe { LLVMBuildOr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2471
2472
94.0k
        unsafe { Ok(T::new(value)) }
2473
94.0k
    }
<inkwell::builder::Builder>::build_or::<inkwell::values::int_value::IntValue>
Line
Count
Source
2465
90.6k
    pub fn build_or<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2466
90.6k
        if self.positioned.get() != PositionState::Set {
2467
0
            return Err(BuilderError::UnsetPosition);
2468
90.6k
        }
2469
90.6k
        let c_string = to_c_str(name);
2470
90.6k
        let value = unsafe { LLVMBuildOr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2471
2472
90.6k
        unsafe { Ok(T::new(value)) }
2473
90.6k
    }
<inkwell::builder::Builder>::build_or::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2465
3.44k
    pub fn build_or<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2466
3.44k
        if self.positioned.get() != PositionState::Set {
2467
0
            return Err(BuilderError::UnsetPosition);
2468
3.44k
        }
2469
3.44k
        let c_string = to_c_str(name);
2470
3.44k
        let value = unsafe { LLVMBuildOr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2471
2472
3.44k
        unsafe { Ok(T::new(value)) }
2473
3.44k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_or::<_>
2474
2475
    /// Builds an `IntValue` containing the result of a logical left shift instruction.
2476
    ///
2477
    /// # Example
2478
    /// A logical left shift is an operation in which an integer value's bits are shifted left by N number of positions.
2479
    ///
2480
    /// ```rust,no_run
2481
    /// assert_eq!(0b0000_0001 << 0, 0b0000_0001);
2482
    /// assert_eq!(0b0000_0001 << 1, 0b0000_0010);
2483
    /// assert_eq!(0b0000_0011 << 2, 0b0000_1100);
2484
    /// ```
2485
    ///
2486
    /// In Rust, a function that could do this for 8bit values looks like:
2487
    ///
2488
    /// ```rust,no_run
2489
    /// fn left_shift(value: u8, n: u8) -> u8 {
2490
    ///     value << n
2491
    /// }
2492
    /// ```
2493
    ///
2494
    /// And in Inkwell, the corresponding function would look roughly like:
2495
    ///
2496
    /// ```rust,no_run
2497
    /// use inkwell::context::Context;
2498
    ///
2499
    /// // Setup
2500
    /// let context = Context::create();
2501
    /// let module = context.create_module("my_module");
2502
    /// let builder = context.create_builder();
2503
    /// let i8_type = context.i8_type();
2504
    /// let fn_type = i8_type.fn_type(&[i8_type.into(), i8_type.into()], false);
2505
    ///
2506
    /// // Function Definition
2507
    /// let function = module.add_function("left_shift", fn_type, None);
2508
    /// let value = function.get_first_param().unwrap().into_int_value();
2509
    /// let n = function.get_nth_param(1).unwrap().into_int_value();
2510
    /// let entry_block = context.append_basic_block(function, "entry");
2511
    ///
2512
    /// builder.position_at_end(entry_block);
2513
    ///
2514
    /// let shift = builder.build_left_shift(value, n, "left_shift").unwrap(); // value << n
2515
    ///
2516
    /// builder.build_return(Some(&shift)).unwrap();
2517
    /// ```
2518
4.85k
    pub fn build_left_shift<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2519
4.85k
        if self.positioned.get() != PositionState::Set {
2520
0
            return Err(BuilderError::UnsetPosition);
2521
4.85k
        }
2522
4.85k
        let c_string = to_c_str(name);
2523
4.85k
        let value = unsafe { LLVMBuildShl(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2524
2525
4.85k
        unsafe { Ok(T::new(value)) }
2526
4.85k
    }
<inkwell::builder::Builder>::build_left_shift::<inkwell::values::int_value::IntValue>
Line
Count
Source
2518
4.81k
    pub fn build_left_shift<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2519
4.81k
        if self.positioned.get() != PositionState::Set {
2520
0
            return Err(BuilderError::UnsetPosition);
2521
4.81k
        }
2522
4.81k
        let c_string = to_c_str(name);
2523
4.81k
        let value = unsafe { LLVMBuildShl(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2524
2525
4.81k
        unsafe { Ok(T::new(value)) }
2526
4.81k
    }
<inkwell::builder::Builder>::build_left_shift::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2518
35
    pub fn build_left_shift<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2519
35
        if self.positioned.get() != PositionState::Set {
2520
0
            return Err(BuilderError::UnsetPosition);
2521
35
        }
2522
35
        let c_string = to_c_str(name);
2523
35
        let value = unsafe { LLVMBuildShl(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2524
2525
35
        unsafe { Ok(T::new(value)) }
2526
35
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_left_shift::<_>
2527
2528
    /// Builds an `IntValue` containing the result of a right shift instruction.
2529
    ///
2530
    /// # Example
2531
    /// A right shift is an operation in which an integer value's bits are shifted right by N number of positions.
2532
    /// It may either be logical and have its leftmost N bit(s) filled with zeros or sign extended and filled with ones
2533
    /// if the leftmost bit was one.
2534
    ///
2535
    /// ```rust,no_run
2536
    /// //fix doc error about overflowing_literals
2537
    /// //rendered rfc: https://github.com/rust-lang/rfcs/blob/master/text/2438-deny-integer-literal-overflow-lint.md
2538
    /// //tracking issue: https://github.com/rust-lang/rust/issues/54502
2539
    /// #![allow(overflowing_literals)]
2540
    ///
2541
    /// // Logical Right Shift
2542
    /// assert_eq!(0b1100_0000u8 >> 2, 0b0011_0000);
2543
    /// assert_eq!(0b0000_0010u8 >> 1, 0b0000_0001);
2544
    /// assert_eq!(0b0000_1100u8 >> 2, 0b0000_0011);
2545
    ///
2546
    /// // Sign Extended Right Shift
2547
    /// assert_eq!(0b0100_0000i8 >> 2, 0b0001_0000);
2548
    /// assert_eq!(0b1110_0000u8 as i8 >> 1, 0b1111_0000u8 as i8);
2549
    /// assert_eq!(0b1100_0000u8 as i8 >> 2, 0b1111_0000u8 as i8);
2550
    /// ```
2551
    ///
2552
    /// In Rust, functions that could do this for 8bit values look like:
2553
    ///
2554
    /// ```rust,no_run
2555
    /// fn logical_right_shift(value: u8, n: u8) -> u8 {
2556
    ///     value >> n
2557
    /// }
2558
    ///
2559
    /// fn sign_extended_right_shift(value: i8, n: u8) -> i8 {
2560
    ///     value >> n
2561
    /// }
2562
    /// ```
2563
    /// Notice that, in Rust (and most other languages), whether or not a value is sign extended depends wholly on whether
2564
    /// or not the type is signed (ie an i8 is a signed 8 bit value). LLVM does not make this distinction for you.
2565
    ///
2566
    /// In Inkwell, the corresponding functions would look roughly like:
2567
    ///
2568
    /// ```rust,no_run
2569
    /// use inkwell::context::Context;
2570
    ///
2571
    /// // Setup
2572
    /// let context = Context::create();
2573
    /// let module = context.create_module("my_module");
2574
    /// let builder = context.create_builder();
2575
    /// let i8_type = context.i8_type();
2576
    /// let fn_type = i8_type.fn_type(&[i8_type.into(), i8_type.into()], false);
2577
    ///
2578
    /// // Function Definition
2579
    /// let function = module.add_function("right_shift", fn_type, None);
2580
    /// let value = function.get_first_param().unwrap().into_int_value();
2581
    /// let n = function.get_nth_param(1).unwrap().into_int_value();
2582
    /// let entry_block = context.append_basic_block(function, "entry");
2583
    ///
2584
    /// builder.position_at_end(entry_block);
2585
    ///
2586
    /// // Whether or not your right shift is sign extended (true) or logical (false) depends
2587
    /// // on the boolean input parameter:
2588
    /// let shift = builder.build_right_shift(value, n, false, "right_shift").unwrap(); // value >> n
2589
    ///
2590
    /// builder.build_return(Some(&shift)).unwrap();
2591
    /// ```
2592
12.5k
    pub fn build_right_shift<T: IntMathValue<'ctx>>(
2593
12.5k
        &self,
2594
12.5k
        lhs: T,
2595
12.5k
        rhs: T,
2596
12.5k
        sign_extend: bool,
2597
12.5k
        name: &str,
2598
12.5k
    ) -> Result<T, BuilderError> {
2599
12.5k
        if self.positioned.get() != PositionState::Set {
2600
0
            return Err(BuilderError::UnsetPosition);
2601
12.5k
        }
2602
12.5k
        let c_string = to_c_str(name);
2603
12.5k
        let value = unsafe {
2604
12.5k
            if sign_extend {
2605
6.61k
                LLVMBuildAShr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
2606
            } else {
2607
5.97k
                LLVMBuildLShr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
2608
            }
2609
        };
2610
2611
12.5k
        unsafe { Ok(T::new(value)) }
2612
12.5k
    }
<inkwell::builder::Builder>::build_right_shift::<inkwell::values::int_value::IntValue>
Line
Count
Source
2592
6.80k
    pub fn build_right_shift<T: IntMathValue<'ctx>>(
2593
6.80k
        &self,
2594
6.80k
        lhs: T,
2595
6.80k
        rhs: T,
2596
6.80k
        sign_extend: bool,
2597
6.80k
        name: &str,
2598
6.80k
    ) -> Result<T, BuilderError> {
2599
6.80k
        if self.positioned.get() != PositionState::Set {
2600
0
            return Err(BuilderError::UnsetPosition);
2601
6.80k
        }
2602
6.80k
        let c_string = to_c_str(name);
2603
6.80k
        let value = unsafe {
2604
6.80k
            if sign_extend {
2605
1.16k
                LLVMBuildAShr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
2606
            } else {
2607
5.63k
                LLVMBuildLShr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
2608
            }
2609
        };
2610
2611
6.80k
        unsafe { Ok(T::new(value)) }
2612
6.80k
    }
<inkwell::builder::Builder>::build_right_shift::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2592
5.78k
    pub fn build_right_shift<T: IntMathValue<'ctx>>(
2593
5.78k
        &self,
2594
5.78k
        lhs: T,
2595
5.78k
        rhs: T,
2596
5.78k
        sign_extend: bool,
2597
5.78k
        name: &str,
2598
5.78k
    ) -> Result<T, BuilderError> {
2599
5.78k
        if self.positioned.get() != PositionState::Set {
2600
0
            return Err(BuilderError::UnsetPosition);
2601
5.78k
        }
2602
5.78k
        let c_string = to_c_str(name);
2603
5.78k
        let value = unsafe {
2604
5.78k
            if sign_extend {
2605
5.44k
                LLVMBuildAShr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
2606
            } else {
2607
339
                LLVMBuildLShr(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr())
2608
            }
2609
        };
2610
2611
5.78k
        unsafe { Ok(T::new(value)) }
2612
5.78k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_right_shift::<_>
2613
2614
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2615
12.5k
    pub fn build_int_sub<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2616
12.5k
        if self.positioned.get() != PositionState::Set {
2617
0
            return Err(BuilderError::UnsetPosition);
2618
12.5k
        }
2619
12.5k
        let c_string = to_c_str(name);
2620
12.5k
        let value = unsafe { LLVMBuildSub(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2621
2622
12.5k
        unsafe { Ok(T::new(value)) }
2623
12.5k
    }
<inkwell::builder::Builder>::build_int_sub::<inkwell::values::int_value::IntValue>
Line
Count
Source
2615
2.57k
    pub fn build_int_sub<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2616
2.57k
        if self.positioned.get() != PositionState::Set {
2617
0
            return Err(BuilderError::UnsetPosition);
2618
2.57k
        }
2619
2.57k
        let c_string = to_c_str(name);
2620
2.57k
        let value = unsafe { LLVMBuildSub(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2621
2622
2.57k
        unsafe { Ok(T::new(value)) }
2623
2.57k
    }
<inkwell::builder::Builder>::build_int_sub::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2615
10.0k
    pub fn build_int_sub<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2616
10.0k
        if self.positioned.get() != PositionState::Set {
2617
0
            return Err(BuilderError::UnsetPosition);
2618
10.0k
        }
2619
10.0k
        let c_string = to_c_str(name);
2620
10.0k
        let value = unsafe { LLVMBuildSub(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2621
2622
10.0k
        unsafe { Ok(T::new(value)) }
2623
10.0k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_sub::<_>
2624
2625
    // REVIEW: Possibly incorporate into build_int_sub via flag param
2626
0
    pub fn build_int_nsw_sub<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2627
0
        if self.positioned.get() != PositionState::Set {
2628
0
            return Err(BuilderError::UnsetPosition);
2629
0
        }
2630
0
        let c_string = to_c_str(name);
2631
0
        let value = unsafe { LLVMBuildNSWSub(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2632
2633
0
        unsafe { Ok(T::new(value)) }
2634
0
    }
2635
2636
    // REVIEW: Possibly incorporate into build_int_sub via flag param
2637
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2638
0
    pub fn build_int_nuw_sub<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2639
0
        if self.positioned.get() != PositionState::Set {
2640
0
            return Err(BuilderError::UnsetPosition);
2641
0
        }
2642
0
        let c_string = to_c_str(name);
2643
0
        let value = unsafe { LLVMBuildNUWSub(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2644
2645
0
        unsafe { Ok(T::new(value)) }
2646
0
    }
2647
2648
    // SubType: <F>(&self, lhs: &FloatValue<F>, rhs: &FloatValue<F>, name: &str) -> FloatValue<F> {
2649
0
    pub fn build_float_sub<T: FloatMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2650
0
        if self.positioned.get() != PositionState::Set {
2651
0
            return Err(BuilderError::UnsetPosition);
2652
0
        }
2653
0
        let c_string = to_c_str(name);
2654
0
        let value = unsafe { LLVMBuildFSub(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2655
2656
0
        unsafe { Ok(T::new(value)) }
2657
0
    }
2658
2659
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2660
35.9k
    pub fn build_int_mul<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2661
35.9k
        if self.positioned.get() != PositionState::Set {
2662
0
            return Err(BuilderError::UnsetPosition);
2663
35.9k
        }
2664
35.9k
        let c_string = to_c_str(name);
2665
35.9k
        let value = unsafe { LLVMBuildMul(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2666
2667
35.9k
        unsafe { Ok(T::new(value)) }
2668
35.9k
    }
<inkwell::builder::Builder>::build_int_mul::<inkwell::values::int_value::IntValue>
Line
Count
Source
2660
35.7k
    pub fn build_int_mul<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2661
35.7k
        if self.positioned.get() != PositionState::Set {
2662
0
            return Err(BuilderError::UnsetPosition);
2663
35.7k
        }
2664
35.7k
        let c_string = to_c_str(name);
2665
35.7k
        let value = unsafe { LLVMBuildMul(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2666
2667
35.7k
        unsafe { Ok(T::new(value)) }
2668
35.7k
    }
<inkwell::builder::Builder>::build_int_mul::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2660
206
    pub fn build_int_mul<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2661
206
        if self.positioned.get() != PositionState::Set {
2662
0
            return Err(BuilderError::UnsetPosition);
2663
206
        }
2664
206
        let c_string = to_c_str(name);
2665
206
        let value = unsafe { LLVMBuildMul(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2666
2667
206
        unsafe { Ok(T::new(value)) }
2668
206
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_mul::<_>
2669
2670
    // REVIEW: Possibly incorporate into build_int_mul via flag param
2671
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2672
0
    pub fn build_int_nsw_mul<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2673
0
        if self.positioned.get() != PositionState::Set {
2674
0
            return Err(BuilderError::UnsetPosition);
2675
0
        }
2676
0
        let c_string = to_c_str(name);
2677
0
        let value = unsafe { LLVMBuildNSWMul(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2678
2679
0
        unsafe { Ok(T::new(value)) }
2680
0
    }
2681
2682
    // REVIEW: Possibly incorporate into build_int_mul via flag param
2683
    // SubType: <I>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> {
2684
0
    pub fn build_int_nuw_mul<T: IntMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2685
0
        if self.positioned.get() != PositionState::Set {
2686
0
            return Err(BuilderError::UnsetPosition);
2687
0
        }
2688
0
        let c_string = to_c_str(name);
2689
0
        let value = unsafe { LLVMBuildNUWMul(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2690
2691
0
        unsafe { Ok(T::new(value)) }
2692
0
    }
2693
2694
    // SubType: <F>(&self, lhs: &FloatValue<F>, rhs: &FloatValue<F>, name: &str) -> FloatValue<F> {
2695
0
    pub fn build_float_mul<T: FloatMathValue<'ctx>>(&self, lhs: T, rhs: T, name: &str) -> Result<T, BuilderError> {
2696
0
        if self.positioned.get() != PositionState::Set {
2697
0
            return Err(BuilderError::UnsetPosition);
2698
0
        }
2699
0
        let c_string = to_c_str(name);
2700
0
        let value = unsafe { LLVMBuildFMul(self.builder, lhs.as_value_ref(), rhs.as_value_ref(), c_string.as_ptr()) };
2701
2702
0
        unsafe { Ok(T::new(value)) }
2703
0
    }
2704
2705
0
    pub fn build_binop<T: BasicValue<'ctx>>(
2706
0
        &self,
2707
0
        op: InstructionOpcode,
2708
0
        lhs: T,
2709
0
        rhs: T,
2710
0
        name: &str,
2711
0
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
2712
0
        if self.positioned.get() != PositionState::Set {
2713
0
            return Err(BuilderError::UnsetPosition);
2714
0
        }
2715
0
        let c_string = to_c_str(name);
2716
0
        let value = unsafe {
2717
0
            LLVMBuildBinOp(
2718
0
                self.builder,
2719
0
                op.into(),
2720
0
                lhs.as_value_ref(),
2721
0
                rhs.as_value_ref(),
2722
0
                c_string.as_ptr(),
2723
            )
2724
        };
2725
2726
0
        unsafe { Ok(BasicValueEnum::new(value)) }
2727
0
    }
2728
2729
0
    pub fn build_cast<T: BasicType<'ctx>, V: BasicValue<'ctx>>(
2730
0
        &self,
2731
0
        op: InstructionOpcode,
2732
0
        from_value: V,
2733
0
        to_type: T,
2734
0
        name: &str,
2735
0
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
2736
0
        if self.positioned.get() != PositionState::Set {
2737
0
            return Err(BuilderError::UnsetPosition);
2738
0
        }
2739
0
        let c_string = to_c_str(name);
2740
0
        let value = unsafe {
2741
0
            LLVMBuildCast(
2742
0
                self.builder,
2743
0
                op.into(),
2744
0
                from_value.as_value_ref(),
2745
0
                to_type.as_type_ref(),
2746
0
                c_string.as_ptr(),
2747
            )
2748
        };
2749
2750
0
        unsafe { Ok(BasicValueEnum::new(value)) }
2751
0
    }
2752
2753
    // SubType: <F, T>(&self, from: &PointerValue<F>, to: &PointerType<T>, name: &str) -> PointerValue<T> {
2754
1.52M
    pub fn build_pointer_cast<T: PointerMathValue<'ctx>>(
2755
1.52M
        &self,
2756
1.52M
        from: T,
2757
1.52M
        to: T::BaseType,
2758
1.52M
        name: &str,
2759
1.52M
    ) -> Result<T, BuilderError> {
2760
1.52M
        if self.positioned.get() != PositionState::Set {
2761
0
            return Err(BuilderError::UnsetPosition);
2762
1.52M
        }
2763
1.52M
        let c_string = to_c_str(name);
2764
1.52M
        let value =
2765
1.52M
            unsafe { LLVMBuildPointerCast(self.builder, from.as_value_ref(), to.as_type_ref(), c_string.as_ptr()) };
2766
2767
1.52M
        unsafe { Ok(T::new(value)) }
2768
1.52M
    }
<inkwell::builder::Builder>::build_pointer_cast::<inkwell::values::ptr_value::PointerValue>
Line
Count
Source
2754
1.52M
    pub fn build_pointer_cast<T: PointerMathValue<'ctx>>(
2755
1.52M
        &self,
2756
1.52M
        from: T,
2757
1.52M
        to: T::BaseType,
2758
1.52M
        name: &str,
2759
1.52M
    ) -> Result<T, BuilderError> {
2760
1.52M
        if self.positioned.get() != PositionState::Set {
2761
0
            return Err(BuilderError::UnsetPosition);
2762
1.52M
        }
2763
1.52M
        let c_string = to_c_str(name);
2764
1.52M
        let value =
2765
1.52M
            unsafe { LLVMBuildPointerCast(self.builder, from.as_value_ref(), to.as_type_ref(), c_string.as_ptr()) };
2766
2767
1.52M
        unsafe { Ok(T::new(value)) }
2768
1.52M
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_pointer_cast::<_>
2769
2770
    // SubType: <I>(&self, op, lhs: &IntValue<I>, rhs: &IntValue<I>, name) -> IntValue<bool> { ?
2771
    // Note: we need a way to get an appropriate return type, since this method's return value
2772
    // is always a bool (or vector of bools), not necessarily the same as the input value
2773
    // See https://github.com/TheDan64/inkwell/pull/47#discussion_r197599297
2774
351k
    pub fn build_int_compare<T: IntMathValue<'ctx>>(
2775
351k
        &self,
2776
351k
        op: IntPredicate,
2777
351k
        lhs: T,
2778
351k
        rhs: T,
2779
351k
        name: &str,
2780
351k
    ) -> Result<<T::BaseType as IntMathType<'ctx>>::ValueType, BuilderError> {
2781
351k
        if self.positioned.get() != PositionState::Set {
2782
0
            return Err(BuilderError::UnsetPosition);
2783
351k
        }
2784
351k
        let c_string = to_c_str(name);
2785
351k
        let value = unsafe {
2786
351k
            LLVMBuildICmp(
2787
351k
                self.builder,
2788
351k
                op.into(),
2789
351k
                lhs.as_value_ref(),
2790
351k
                rhs.as_value_ref(),
2791
351k
                c_string.as_ptr(),
2792
            )
2793
        };
2794
2795
351k
        unsafe { Ok(<T::BaseType as IntMathType<'ctx>>::ValueType::new(value)) }
2796
351k
    }
<inkwell::builder::Builder>::build_int_compare::<inkwell::values::int_value::IntValue>
Line
Count
Source
2774
342k
    pub fn build_int_compare<T: IntMathValue<'ctx>>(
2775
342k
        &self,
2776
342k
        op: IntPredicate,
2777
342k
        lhs: T,
2778
342k
        rhs: T,
2779
342k
        name: &str,
2780
342k
    ) -> Result<<T::BaseType as IntMathType<'ctx>>::ValueType, BuilderError> {
2781
342k
        if self.positioned.get() != PositionState::Set {
2782
0
            return Err(BuilderError::UnsetPosition);
2783
342k
        }
2784
342k
        let c_string = to_c_str(name);
2785
342k
        let value = unsafe {
2786
342k
            LLVMBuildICmp(
2787
342k
                self.builder,
2788
342k
                op.into(),
2789
342k
                lhs.as_value_ref(),
2790
342k
                rhs.as_value_ref(),
2791
342k
                c_string.as_ptr(),
2792
            )
2793
        };
2794
2795
342k
        unsafe { Ok(<T::BaseType as IntMathType<'ctx>>::ValueType::new(value)) }
2796
342k
    }
<inkwell::builder::Builder>::build_int_compare::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2774
8.47k
    pub fn build_int_compare<T: IntMathValue<'ctx>>(
2775
8.47k
        &self,
2776
8.47k
        op: IntPredicate,
2777
8.47k
        lhs: T,
2778
8.47k
        rhs: T,
2779
8.47k
        name: &str,
2780
8.47k
    ) -> Result<<T::BaseType as IntMathType<'ctx>>::ValueType, BuilderError> {
2781
8.47k
        if self.positioned.get() != PositionState::Set {
2782
0
            return Err(BuilderError::UnsetPosition);
2783
8.47k
        }
2784
8.47k
        let c_string = to_c_str(name);
2785
8.47k
        let value = unsafe {
2786
8.47k
            LLVMBuildICmp(
2787
8.47k
                self.builder,
2788
8.47k
                op.into(),
2789
8.47k
                lhs.as_value_ref(),
2790
8.47k
                rhs.as_value_ref(),
2791
8.47k
                c_string.as_ptr(),
2792
            )
2793
        };
2794
2795
8.47k
        unsafe { Ok(<T::BaseType as IntMathType<'ctx>>::ValueType::new(value)) }
2796
8.47k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_compare::<_>
2797
2798
    // SubType: <F>(&self, op, lhs: &FloatValue<F>, rhs: &FloatValue<F>, name) -> IntValue<bool> { ?
2799
    // Note: see comment on build_int_compare regarding return value type
2800
200k
    pub fn build_float_compare<T: FloatMathValue<'ctx>>(
2801
200k
        &self,
2802
200k
        op: FloatPredicate,
2803
200k
        lhs: T,
2804
200k
        rhs: T,
2805
200k
        name: &str,
2806
200k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2807
    {
2808
200k
        if self.positioned.get() != PositionState::Set {
2809
0
            return Err(BuilderError::UnsetPosition);
2810
200k
        }
2811
200k
        let c_string = to_c_str(name);
2812
2813
200k
        let value = unsafe {
2814
200k
            LLVMBuildFCmp(
2815
200k
                self.builder,
2816
200k
                op.into(),
2817
200k
                lhs.as_value_ref(),
2818
200k
                rhs.as_value_ref(),
2819
200k
                c_string.as_ptr(),
2820
            )
2821
        };
2822
2823
200k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2824
200k
    }
<inkwell::builder::Builder>::build_float_compare::<inkwell::values::float_value::FloatValue>
Line
Count
Source
2800
194k
    pub fn build_float_compare<T: FloatMathValue<'ctx>>(
2801
194k
        &self,
2802
194k
        op: FloatPredicate,
2803
194k
        lhs: T,
2804
194k
        rhs: T,
2805
194k
        name: &str,
2806
194k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2807
    {
2808
194k
        if self.positioned.get() != PositionState::Set {
2809
0
            return Err(BuilderError::UnsetPosition);
2810
194k
        }
2811
194k
        let c_string = to_c_str(name);
2812
2813
194k
        let value = unsafe {
2814
194k
            LLVMBuildFCmp(
2815
194k
                self.builder,
2816
194k
                op.into(),
2817
194k
                lhs.as_value_ref(),
2818
194k
                rhs.as_value_ref(),
2819
194k
                c_string.as_ptr(),
2820
            )
2821
        };
2822
2823
194k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2824
194k
    }
<inkwell::builder::Builder>::build_float_compare::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2800
5.92k
    pub fn build_float_compare<T: FloatMathValue<'ctx>>(
2801
5.92k
        &self,
2802
5.92k
        op: FloatPredicate,
2803
5.92k
        lhs: T,
2804
5.92k
        rhs: T,
2805
5.92k
        name: &str,
2806
5.92k
    ) -> Result<<<T::BaseType as FloatMathType<'ctx>>::MathConvType as IntMathType<'ctx>>::ValueType, BuilderError>
2807
    {
2808
5.92k
        if self.positioned.get() != PositionState::Set {
2809
0
            return Err(BuilderError::UnsetPosition);
2810
5.92k
        }
2811
5.92k
        let c_string = to_c_str(name);
2812
2813
5.92k
        let value = unsafe {
2814
5.92k
            LLVMBuildFCmp(
2815
5.92k
                self.builder,
2816
5.92k
                op.into(),
2817
5.92k
                lhs.as_value_ref(),
2818
5.92k
                rhs.as_value_ref(),
2819
5.92k
                c_string.as_ptr(),
2820
            )
2821
        };
2822
2823
5.92k
        unsafe { Ok(<<T::BaseType as FloatMathType>::MathConvType as IntMathType>::ValueType::new(value)) }
2824
5.92k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_float_compare::<_>
2825
2826
842k
    pub fn build_unconditional_branch(
2827
842k
        &self,
2828
842k
        destination_block: BasicBlock<'ctx>,
2829
842k
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
2830
842k
        if self.positioned.get() != PositionState::Set {
2831
0
            return Err(BuilderError::UnsetPosition);
2832
842k
        }
2833
842k
        let value = unsafe { LLVMBuildBr(self.builder, destination_block.basic_block) };
2834
2835
842k
        unsafe { Ok(InstructionValue::new(value)) }
2836
842k
    }
2837
2838
233k
    pub fn build_conditional_branch(
2839
233k
        &self,
2840
233k
        comparison: IntValue<'ctx>,
2841
233k
        then_block: BasicBlock<'ctx>,
2842
233k
        else_block: BasicBlock<'ctx>,
2843
233k
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
2844
233k
        if self.positioned.get() != PositionState::Set {
2845
0
            return Err(BuilderError::UnsetPosition);
2846
233k
        }
2847
233k
        let value = unsafe {
2848
233k
            LLVMBuildCondBr(
2849
233k
                self.builder,
2850
233k
                comparison.as_value_ref(),
2851
233k
                then_block.basic_block,
2852
233k
                else_block.basic_block,
2853
            )
2854
        };
2855
2856
233k
        unsafe { Ok(InstructionValue::new(value)) }
2857
233k
    }
2858
2859
0
    pub fn build_indirect_branch<BV: BasicValue<'ctx>>(
2860
0
        &self,
2861
0
        address: BV,
2862
0
        destinations: &[BasicBlock<'ctx>],
2863
0
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
2864
0
        if self.positioned.get() != PositionState::Set {
2865
0
            return Err(BuilderError::UnsetPosition);
2866
0
        }
2867
0
        let value = unsafe { LLVMBuildIndirectBr(self.builder, address.as_value_ref(), destinations.len() as u32) };
2868
2869
0
        for destination in destinations {
2870
0
            unsafe { LLVMAddDestination(value, destination.basic_block) }
2871
        }
2872
2873
0
        unsafe { Ok(InstructionValue::new(value)) }
2874
0
    }
2875
2876
    // SubType: <I>(&self, value: &IntValue<I>, name) -> IntValue<I> {
2877
3.17k
    pub fn build_int_neg<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2878
3.17k
        if self.positioned.get() != PositionState::Set {
2879
0
            return Err(BuilderError::UnsetPosition);
2880
3.17k
        }
2881
3.17k
        let c_string = to_c_str(name);
2882
3.17k
        let value = unsafe { LLVMBuildNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2883
2884
3.17k
        unsafe { Ok(T::new(value)) }
2885
3.17k
    }
<inkwell::builder::Builder>::build_int_neg::<inkwell::values::int_value::IntValue>
Line
Count
Source
2877
3.17k
    pub fn build_int_neg<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2878
3.17k
        if self.positioned.get() != PositionState::Set {
2879
0
            return Err(BuilderError::UnsetPosition);
2880
3.17k
        }
2881
3.17k
        let c_string = to_c_str(name);
2882
3.17k
        let value = unsafe { LLVMBuildNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2883
2884
3.17k
        unsafe { Ok(T::new(value)) }
2885
3.17k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_neg::<_>
2886
2887
    // REVIEW: Possibly incorporate into build_int_neg via flag and subtypes
2888
    // SubType: <I>(&self, value: &IntValue<I>, name) -> IntValue<I> {
2889
0
    pub fn build_int_nsw_neg<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2890
0
        if self.positioned.get() != PositionState::Set {
2891
0
            return Err(BuilderError::UnsetPosition);
2892
0
        }
2893
0
        let c_string = to_c_str(name);
2894
0
        let value = unsafe { LLVMBuildNSWNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2895
2896
0
        unsafe { Ok(T::new(value)) }
2897
0
    }
2898
2899
    // SubType: <I>(&self, value: &IntValue<I>, name) -> IntValue<I> {
2900
    #[llvm_versions(..17)]
2901
    pub fn build_int_nuw_neg<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2902
        if self.positioned.get() != PositionState::Set {
2903
            return Err(BuilderError::UnsetPosition);
2904
        }
2905
        let c_string = to_c_str(name);
2906
        let value = unsafe { LLVMBuildNUWNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2907
        unsafe { Ok(T::new(value)) }
2908
    }
2909
2910
    // SubType: <I>(&self, value: &IntValue<I>, name) -> IntValue<I> {
2911
    #[llvm_versions(17..)]
2912
0
    pub fn build_int_nuw_neg<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2913
0
        if self.positioned.get() != PositionState::Set {
2914
0
            return Err(BuilderError::UnsetPosition);
2915
0
        }
2916
0
        let c_string = to_c_str(name);
2917
0
        let value = unsafe { LLVMBuildNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2918
0
        unsafe {
2919
0
            LLVMSetNUW(value, true.into());
2920
0
        }
2921
2922
0
        unsafe { Ok(T::new(value)) }
2923
0
    }
2924
2925
    // SubType: <F>(&self, value: &FloatValue<F>, name) -> FloatValue<F> {
2926
26.8k
    pub fn build_float_neg<T: FloatMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2927
26.8k
        if self.positioned.get() != PositionState::Set {
2928
0
            return Err(BuilderError::UnsetPosition);
2929
26.8k
        }
2930
26.8k
        let c_string = to_c_str(name);
2931
26.8k
        let value = unsafe { LLVMBuildFNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2932
2933
26.8k
        unsafe { Ok(T::new(value)) }
2934
26.8k
    }
<inkwell::builder::Builder>::build_float_neg::<inkwell::values::float_value::FloatValue>
Line
Count
Source
2926
26.1k
    pub fn build_float_neg<T: FloatMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2927
26.1k
        if self.positioned.get() != PositionState::Set {
2928
0
            return Err(BuilderError::UnsetPosition);
2929
26.1k
        }
2930
26.1k
        let c_string = to_c_str(name);
2931
26.1k
        let value = unsafe { LLVMBuildFNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2932
2933
26.1k
        unsafe { Ok(T::new(value)) }
2934
26.1k
    }
<inkwell::builder::Builder>::build_float_neg::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
2926
662
    pub fn build_float_neg<T: FloatMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2927
662
        if self.positioned.get() != PositionState::Set {
2928
0
            return Err(BuilderError::UnsetPosition);
2929
662
        }
2930
662
        let c_string = to_c_str(name);
2931
662
        let value = unsafe { LLVMBuildFNeg(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2932
2933
662
        unsafe { Ok(T::new(value)) }
2934
662
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_float_neg::<_>
2935
2936
    // SubType: <I>(&self, value: &IntValue<I>, name) -> IntValue<bool> { ?
2937
2.06k
    pub fn build_not<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2938
2.06k
        if self.positioned.get() != PositionState::Set {
2939
0
            return Err(BuilderError::UnsetPosition);
2940
2.06k
        }
2941
2.06k
        let c_string = to_c_str(name);
2942
2.06k
        let value = unsafe { LLVMBuildNot(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2943
2944
2.06k
        unsafe { Ok(T::new(value)) }
2945
2.06k
    }
<inkwell::builder::Builder>::build_not::<inkwell::values::int_value::IntValue>
Line
Count
Source
2937
2.06k
    pub fn build_not<T: IntMathValue<'ctx>>(&self, value: T, name: &str) -> Result<T, BuilderError> {
2938
2.06k
        if self.positioned.get() != PositionState::Set {
2939
0
            return Err(BuilderError::UnsetPosition);
2940
2.06k
        }
2941
2.06k
        let c_string = to_c_str(name);
2942
2.06k
        let value = unsafe { LLVMBuildNot(self.builder, value.as_value_ref(), c_string.as_ptr()) };
2943
2944
2.06k
        unsafe { Ok(T::new(value)) }
2945
2.06k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_not::<_>
2946
2947
    // REVIEW: What if instruction and basic_block are completely unrelated?
2948
    // It'd be great if we could get the BB from the instruction behind the scenes
2949
    /// Set the position of the builder to after an instruction.
2950
    ///
2951
    /// Be sure to call one of the `position_*` methods or all `build_*` methods will return `Err(BuilderError::UnsetPosition)`.
2952
65.1k
    pub fn position_at(&self, basic_block: BasicBlock<'ctx>, instruction: &InstructionValue<'ctx>) {
2953
65.1k
        self.positioned.set(PositionState::Set);
2954
2955
65.1k
        unsafe { LLVMPositionBuilder(self.builder, basic_block.basic_block, instruction.as_value_ref()) }
2956
65.1k
    }
2957
2958
    /// Set the position of the builder to before an instruction.
2959
    ///
2960
    /// Be sure to call one of the `position_*` methods or all `build_*` methods will return `Err(BuilderError::UnsetPosition)`.
2961
156k
    pub fn position_before(&self, instruction: &InstructionValue<'ctx>) {
2962
156k
        self.positioned.set(PositionState::Set);
2963
2964
156k
        unsafe { LLVMPositionBuilderBefore(self.builder, instruction.as_value_ref()) }
2965
156k
    }
2966
2967
    /// Set the position of the builder to the end of a basic block.
2968
    ///
2969
    /// Be sure to call one of the `position_*` methods or all `build_*` methods will return `Err(BuilderError::UnsetPosition)`.
2970
2.73M
    pub fn position_at_end(&self, basic_block: BasicBlock<'ctx>) {
2971
2.73M
        self.positioned.set(PositionState::Set);
2972
2973
2.73M
        unsafe {
2974
2.73M
            LLVMPositionBuilderAtEnd(self.builder, basic_block.basic_block);
2975
2.73M
        }
2976
2.73M
    }
2977
2978
    /// Builds an extract value instruction which extracts a `BasicValueEnum`
2979
    /// from a struct or array.
2980
    ///
2981
    /// Returns `Err(BuilderError::ExtractOutOfRange)` if the provided index is out of bounds of the aggregate value length.
2982
    ///
2983
    /// # Example
2984
    ///
2985
    /// ```no_run
2986
    /// use inkwell::context::Context;
2987
    /// use inkwell::builder::BuilderError;
2988
    ///
2989
    /// let context = Context::create();
2990
    /// let module = context.create_module("av");
2991
    /// let void_type = context.void_type();
2992
    /// let f32_type = context.f32_type();
2993
    /// let i32_type = context.i32_type();
2994
    /// let struct_type = context.struct_type(&[i32_type.into(), f32_type.into()], false);
2995
    /// let array_type = i32_type.array_type(3);
2996
    /// let fn_type = void_type.fn_type(&[], false);
2997
    /// let fn_value = module.add_function("av_fn", fn_type, None);
2998
    /// let builder = context.create_builder();
2999
    /// let entry = context.append_basic_block(fn_value, "entry");
3000
    ///
3001
    /// builder.position_at_end(entry);
3002
    ///
3003
    /// let array_alloca = builder.build_alloca(array_type, "array_alloca").unwrap();
3004
    ///
3005
    /// #[cfg(feature = "typed-pointers")]
3006
    /// let array = builder.build_load(array_alloca, "array_load").unwrap().into_array_value();
3007
    /// #[cfg(not(feature = "typed-pointers"))]
3008
    /// let array = builder.build_load(i32_type, array_alloca, "array_load").unwrap().into_array_value();
3009
    ///
3010
    /// let const_int1 = i32_type.const_int(2, false);
3011
    /// let const_int2 = i32_type.const_int(5, false);
3012
    /// let const_int3 = i32_type.const_int(6, false);
3013
    ///
3014
    /// assert!(builder.build_insert_value(array, const_int1, 0, "insert").is_ok());
3015
    /// assert!(builder.build_insert_value(array, const_int2, 1, "insert").is_ok());
3016
    /// assert!(builder.build_insert_value(array, const_int3, 2, "insert").is_ok());
3017
    /// assert!(builder.build_insert_value(array, const_int3, 3, "insert").is_err_and(|e| e == BuilderError::ExtractOutOfRange));
3018
    ///
3019
    /// assert!(builder.build_extract_value(array, 0, "extract").unwrap().is_int_value());
3020
    /// assert!(builder.build_extract_value(array, 1, "extract").unwrap().is_int_value());
3021
    /// assert!(builder.build_extract_value(array, 2, "extract").unwrap().is_int_value());
3022
    /// assert!(builder.build_extract_value(array, 3, "extract").is_err_and(|e| e == BuilderError::ExtractOutOfRange));
3023
    /// ```
3024
877k
    pub fn build_extract_value<AV: AggregateValue<'ctx>>(
3025
877k
        &self,
3026
877k
        agg: AV,
3027
877k
        index: u32,
3028
877k
        name: &str,
3029
877k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3030
877k
        if self.positioned.get() != PositionState::Set {
3031
0
            return Err(BuilderError::UnsetPosition);
3032
877k
        }
3033
877k
        let size = match agg.as_aggregate_value_enum() {
3034
0
            AggregateValueEnum::ArrayValue(av) => av.get_type().len(),
3035
877k
            AggregateValueEnum::StructValue(sv) => sv.get_type().count_fields(),
3036
        };
3037
3038
877k
        if index >= size {
3039
0
            return Err(BuilderError::ExtractOutOfRange);
3040
877k
        }
3041
3042
877k
        let c_string = to_c_str(name);
3043
3044
877k
        let value = unsafe { LLVMBuildExtractValue(self.builder, agg.as_value_ref(), index, c_string.as_ptr()) };
3045
3046
877k
        unsafe { Ok(BasicValueEnum::new(value)) }
3047
877k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_extract_value::<inkwell::values::array_value::ArrayValue>
<inkwell::builder::Builder>::build_extract_value::<inkwell::values::struct_value::StructValue>
Line
Count
Source
3024
877k
    pub fn build_extract_value<AV: AggregateValue<'ctx>>(
3025
877k
        &self,
3026
877k
        agg: AV,
3027
877k
        index: u32,
3028
877k
        name: &str,
3029
877k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3030
877k
        if self.positioned.get() != PositionState::Set {
3031
0
            return Err(BuilderError::UnsetPosition);
3032
877k
        }
3033
877k
        let size = match agg.as_aggregate_value_enum() {
3034
0
            AggregateValueEnum::ArrayValue(av) => av.get_type().len(),
3035
877k
            AggregateValueEnum::StructValue(sv) => sv.get_type().count_fields(),
3036
        };
3037
3038
877k
        if index >= size {
3039
0
            return Err(BuilderError::ExtractOutOfRange);
3040
877k
        }
3041
3042
877k
        let c_string = to_c_str(name);
3043
3044
877k
        let value = unsafe { LLVMBuildExtractValue(self.builder, agg.as_value_ref(), index, c_string.as_ptr()) };
3045
3046
877k
        unsafe { Ok(BasicValueEnum::new(value)) }
3047
877k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_extract_value::<_>
3048
3049
    /// Builds an insert value instruction which inserts a `BasicValue` into a struct
3050
    /// or array and returns the resulting aggregate value.
3051
    ///
3052
    /// Returns `Err(BuilderError::ExtractOutOfRange)` if the provided index is out of bounds of the aggregate value length.
3053
    ///
3054
    /// # Example
3055
    ///
3056
    /// ```no_run
3057
    /// use inkwell::context::Context;
3058
    /// use inkwell::builder::BuilderError;
3059
    ///
3060
    /// let context = Context::create();
3061
    /// let module = context.create_module("av");
3062
    /// let void_type = context.void_type();
3063
    /// let f32_type = context.f32_type();
3064
    /// let i32_type = context.i32_type();
3065
    /// let struct_type = context.struct_type(&[i32_type.into(), f32_type.into()], false);
3066
    /// let array_type = i32_type.array_type(3);
3067
    /// let fn_type = void_type.fn_type(&[], false);
3068
    /// let fn_value = module.add_function("av_fn", fn_type, None);
3069
    /// let builder = context.create_builder();
3070
    /// let entry = context.append_basic_block(fn_value, "entry");
3071
    ///
3072
    /// builder.position_at_end(entry);
3073
    ///
3074
    /// let array_alloca = builder.build_alloca(array_type, "array_alloca").unwrap();
3075
    ///
3076
    /// #[cfg(feature = "typed-pointers")]
3077
    /// let array = builder.build_load(array_alloca, "array_load").unwrap().into_array_value();
3078
    /// #[cfg(not(feature = "typed-pointers"))]
3079
    /// let array = builder.build_load(i32_type, array_alloca, "array_load").unwrap().into_array_value();
3080
    ///
3081
    /// let const_int1 = i32_type.const_int(2, false);
3082
    /// let const_int2 = i32_type.const_int(5, false);
3083
    /// let const_int3 = i32_type.const_int(6, false);
3084
    ///
3085
    /// assert!(builder.build_insert_value(array, const_int1, 0, "insert").is_ok());
3086
    /// assert!(builder.build_insert_value(array, const_int2, 1, "insert").is_ok());
3087
    /// assert!(builder.build_insert_value(array, const_int3, 2, "insert").is_ok());
3088
    /// assert!(builder.build_insert_value(array, const_int3, 3, "insert").is_err_and(|e| e == BuilderError::ExtractOutOfRange));
3089
    /// ```
3090
670k
    pub fn build_insert_value<AV, BV>(
3091
670k
        &self,
3092
670k
        agg: AV,
3093
670k
        value: BV,
3094
670k
        index: u32,
3095
670k
        name: &str,
3096
670k
    ) -> Result<AggregateValueEnum<'ctx>, BuilderError>
3097
670k
    where
3098
670k
        AV: AggregateValue<'ctx>,
3099
670k
        BV: BasicValue<'ctx>,
3100
    {
3101
670k
        if self.positioned.get() != PositionState::Set {
3102
0
            return Err(BuilderError::UnsetPosition);
3103
670k
        }
3104
670k
        let size = match agg.as_aggregate_value_enum() {
3105
0
            AggregateValueEnum::ArrayValue(av) => av.get_type().len(),
3106
670k
            AggregateValueEnum::StructValue(sv) => sv.get_type().count_fields(),
3107
        };
3108
3109
670k
        if index >= size {
3110
0
            return Err(BuilderError::ExtractOutOfRange);
3111
670k
        }
3112
3113
670k
        let c_string = to_c_str(name);
3114
3115
670k
        let value = unsafe {
3116
670k
            LLVMBuildInsertValue(
3117
670k
                self.builder,
3118
670k
                agg.as_value_ref(),
3119
670k
                value.as_value_ref(),
3120
670k
                index,
3121
670k
                c_string.as_ptr(),
3122
            )
3123
        };
3124
3125
670k
        unsafe { Ok(AggregateValueEnum::new(value)) }
3126
670k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_insert_value::<inkwell::values::array_value::ArrayValue, inkwell::values::enums::BasicValueEnum>
<inkwell::builder::Builder>::build_insert_value::<inkwell::values::struct_value::StructValue, inkwell::values::enums::BasicValueEnum>
Line
Count
Source
3090
670k
    pub fn build_insert_value<AV, BV>(
3091
670k
        &self,
3092
670k
        agg: AV,
3093
670k
        value: BV,
3094
670k
        index: u32,
3095
670k
        name: &str,
3096
670k
    ) -> Result<AggregateValueEnum<'ctx>, BuilderError>
3097
670k
    where
3098
670k
        AV: AggregateValue<'ctx>,
3099
670k
        BV: BasicValue<'ctx>,
3100
    {
3101
670k
        if self.positioned.get() != PositionState::Set {
3102
0
            return Err(BuilderError::UnsetPosition);
3103
670k
        }
3104
670k
        let size = match agg.as_aggregate_value_enum() {
3105
0
            AggregateValueEnum::ArrayValue(av) => av.get_type().len(),
3106
670k
            AggregateValueEnum::StructValue(sv) => sv.get_type().count_fields(),
3107
        };
3108
3109
670k
        if index >= size {
3110
0
            return Err(BuilderError::ExtractOutOfRange);
3111
670k
        }
3112
3113
670k
        let c_string = to_c_str(name);
3114
3115
670k
        let value = unsafe {
3116
670k
            LLVMBuildInsertValue(
3117
670k
                self.builder,
3118
670k
                agg.as_value_ref(),
3119
670k
                value.as_value_ref(),
3120
670k
                index,
3121
670k
                c_string.as_ptr(),
3122
            )
3123
        };
3124
3125
670k
        unsafe { Ok(AggregateValueEnum::new(value)) }
3126
670k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_insert_value::<inkwell::values::enums::AggregateValueEnum, inkwell::values::enums::BasicValueEnum>
Unexecuted instantiation: <inkwell::builder::Builder>::build_insert_value::<_, _>
3127
3128
    /// Builds an extract element instruction which extracts a `BasicValueEnum`
3129
    /// from a vector.
3130
    /// # Example
3131
    ///
3132
    /// ```no_run
3133
    /// use inkwell::context::Context;
3134
    ///
3135
    /// let context = Context::create();
3136
    /// let module = context.create_module("av");
3137
    /// let i32_type = context.i32_type();
3138
    /// let i32_zero = i32_type.const_int(0, false);
3139
    /// let vec_type = i32_type.vec_type(2);
3140
    /// let fn_type = i32_type.fn_type(&[vec_type.into()], false);
3141
    /// let fn_value = module.add_function("vec_fn", fn_type, None);
3142
    /// let builder = context.create_builder();
3143
    /// let entry = context.append_basic_block(fn_value, "entry");
3144
    /// let vector_param = fn_value.get_first_param().unwrap().into_vector_value();
3145
    ///
3146
    /// builder.position_at_end(entry);
3147
    ///
3148
    /// let extracted = builder.build_extract_element(vector_param, i32_zero, "insert").unwrap();
3149
    ///
3150
    /// builder.build_return(Some(&extracted)).unwrap();
3151
    /// ```
3152
6.71k
    pub fn build_extract_element<V: VectorBaseValue<'ctx>>(
3153
6.71k
        &self,
3154
6.71k
        vector: V,
3155
6.71k
        index: IntValue<'ctx>,
3156
6.71k
        name: &str,
3157
6.71k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3158
6.71k
        if self.positioned.get() != PositionState::Set {
3159
0
            return Err(BuilderError::UnsetPosition);
3160
6.71k
        }
3161
6.71k
        let c_string = to_c_str(name);
3162
3163
6.71k
        let value = unsafe {
3164
6.71k
            LLVMBuildExtractElement(
3165
6.71k
                self.builder,
3166
6.71k
                vector.as_value_ref(),
3167
6.71k
                index.as_value_ref(),
3168
6.71k
                c_string.as_ptr(),
3169
            )
3170
        };
3171
3172
6.71k
        unsafe { Ok(BasicValueEnum::new(value)) }
3173
6.71k
    }
<inkwell::builder::Builder>::build_extract_element::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
3152
6.71k
    pub fn build_extract_element<V: VectorBaseValue<'ctx>>(
3153
6.71k
        &self,
3154
6.71k
        vector: V,
3155
6.71k
        index: IntValue<'ctx>,
3156
6.71k
        name: &str,
3157
6.71k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3158
6.71k
        if self.positioned.get() != PositionState::Set {
3159
0
            return Err(BuilderError::UnsetPosition);
3160
6.71k
        }
3161
6.71k
        let c_string = to_c_str(name);
3162
3163
6.71k
        let value = unsafe {
3164
6.71k
            LLVMBuildExtractElement(
3165
6.71k
                self.builder,
3166
6.71k
                vector.as_value_ref(),
3167
6.71k
                index.as_value_ref(),
3168
6.71k
                c_string.as_ptr(),
3169
            )
3170
        };
3171
3172
6.71k
        unsafe { Ok(BasicValueEnum::new(value)) }
3173
6.71k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_extract_element::<_>
3174
3175
    /// Builds an insert element instruction which inserts a `BasicValue` into a vector
3176
    /// and returns the resulting vector.
3177
    ///
3178
    /// # Example
3179
    ///
3180
    /// ```no_run
3181
    /// use inkwell::context::Context;
3182
    ///
3183
    /// let context = Context::create();
3184
    /// let module = context.create_module("av");
3185
    /// let void_type = context.void_type();
3186
    /// let i32_type = context.i32_type();
3187
    /// let i32_zero = i32_type.const_int(0, false);
3188
    /// let i32_seven = i32_type.const_int(7, false);
3189
    /// let vec_type = i32_type.vec_type(2);
3190
    /// let fn_type = void_type.fn_type(&[vec_type.into()], false);
3191
    /// let fn_value = module.add_function("vec_fn", fn_type, None);
3192
    /// let builder = context.create_builder();
3193
    /// let entry = context.append_basic_block(fn_value, "entry");
3194
    /// let vector_param = fn_value.get_first_param().unwrap().into_vector_value();
3195
    ///
3196
    /// builder.position_at_end(entry);
3197
    /// builder.build_insert_element(vector_param, i32_seven, i32_zero, "insert").unwrap();
3198
    /// builder.build_return(None).unwrap();
3199
    /// ```
3200
13.9k
    pub fn build_insert_element<V: BasicValue<'ctx>, W: VectorBaseValue<'ctx>>(
3201
13.9k
        &self,
3202
13.9k
        vector: W,
3203
13.9k
        element: V,
3204
13.9k
        index: IntValue<'ctx>,
3205
13.9k
        name: &str,
3206
13.9k
    ) -> Result<W, BuilderError> {
3207
13.9k
        if self.positioned.get() != PositionState::Set {
3208
0
            return Err(BuilderError::UnsetPosition);
3209
13.9k
        }
3210
13.9k
        let c_string = to_c_str(name);
3211
3212
13.9k
        let value = unsafe {
3213
13.9k
            LLVMBuildInsertElement(
3214
13.9k
                self.builder,
3215
13.9k
                vector.as_value_ref(),
3216
13.9k
                element.as_value_ref(),
3217
13.9k
                index.as_value_ref(),
3218
13.9k
                c_string.as_ptr(),
3219
            )
3220
        };
3221
3222
13.9k
        unsafe { Ok(W::new(value)) }
3223
13.9k
    }
<inkwell::builder::Builder>::build_insert_element::<inkwell::values::float_value::FloatValue, inkwell::values::vec_value::VectorValue>
Line
Count
Source
3200
843
    pub fn build_insert_element<V: BasicValue<'ctx>, W: VectorBaseValue<'ctx>>(
3201
843
        &self,
3202
843
        vector: W,
3203
843
        element: V,
3204
843
        index: IntValue<'ctx>,
3205
843
        name: &str,
3206
843
    ) -> Result<W, BuilderError> {
3207
843
        if self.positioned.get() != PositionState::Set {
3208
0
            return Err(BuilderError::UnsetPosition);
3209
843
        }
3210
843
        let c_string = to_c_str(name);
3211
3212
843
        let value = unsafe {
3213
843
            LLVMBuildInsertElement(
3214
843
                self.builder,
3215
843
                vector.as_value_ref(),
3216
843
                element.as_value_ref(),
3217
843
                index.as_value_ref(),
3218
843
                c_string.as_ptr(),
3219
            )
3220
        };
3221
3222
843
        unsafe { Ok(W::new(value)) }
3223
843
    }
<inkwell::builder::Builder>::build_insert_element::<inkwell::values::enums::BasicValueEnum, inkwell::values::vec_value::VectorValue>
Line
Count
Source
3200
12.8k
    pub fn build_insert_element<V: BasicValue<'ctx>, W: VectorBaseValue<'ctx>>(
3201
12.8k
        &self,
3202
12.8k
        vector: W,
3203
12.8k
        element: V,
3204
12.8k
        index: IntValue<'ctx>,
3205
12.8k
        name: &str,
3206
12.8k
    ) -> Result<W, BuilderError> {
3207
12.8k
        if self.positioned.get() != PositionState::Set {
3208
0
            return Err(BuilderError::UnsetPosition);
3209
12.8k
        }
3210
12.8k
        let c_string = to_c_str(name);
3211
3212
12.8k
        let value = unsafe {
3213
12.8k
            LLVMBuildInsertElement(
3214
12.8k
                self.builder,
3215
12.8k
                vector.as_value_ref(),
3216
12.8k
                element.as_value_ref(),
3217
12.8k
                index.as_value_ref(),
3218
12.8k
                c_string.as_ptr(),
3219
            )
3220
        };
3221
3222
12.8k
        unsafe { Ok(W::new(value)) }
3223
12.8k
    }
<inkwell::builder::Builder>::build_insert_element::<inkwell::values::int_value::IntValue, inkwell::values::vec_value::VectorValue>
Line
Count
Source
3200
268
    pub fn build_insert_element<V: BasicValue<'ctx>, W: VectorBaseValue<'ctx>>(
3201
268
        &self,
3202
268
        vector: W,
3203
268
        element: V,
3204
268
        index: IntValue<'ctx>,
3205
268
        name: &str,
3206
268
    ) -> Result<W, BuilderError> {
3207
268
        if self.positioned.get() != PositionState::Set {
3208
0
            return Err(BuilderError::UnsetPosition);
3209
268
        }
3210
268
        let c_string = to_c_str(name);
3211
3212
268
        let value = unsafe {
3213
268
            LLVMBuildInsertElement(
3214
268
                self.builder,
3215
268
                vector.as_value_ref(),
3216
268
                element.as_value_ref(),
3217
268
                index.as_value_ref(),
3218
268
                c_string.as_ptr(),
3219
            )
3220
        };
3221
3222
268
        unsafe { Ok(W::new(value)) }
3223
268
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_insert_element::<_, _>
3224
3225
151k
    pub fn build_unreachable(&self) -> Result<InstructionValue<'ctx>, BuilderError> {
3226
151k
        if self.positioned.get() != PositionState::Set {
3227
0
            return Err(BuilderError::UnsetPosition);
3228
151k
        }
3229
151k
        let val = unsafe { LLVMBuildUnreachable(self.builder) };
3230
3231
151k
        unsafe { Ok(InstructionValue::new(val)) }
3232
151k
    }
3233
3234
    // REVIEW: Not sure if this should return InstructionValue or an actual value
3235
    // TODO: Better name for num?
3236
0
    pub fn build_fence(
3237
0
        &self,
3238
0
        atomic_ordering: AtomicOrdering,
3239
0
        num: i32,
3240
0
        name: &str,
3241
0
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
3242
0
        if self.positioned.get() != PositionState::Set {
3243
0
            return Err(BuilderError::UnsetPosition);
3244
0
        }
3245
0
        let c_string = to_c_str(name);
3246
3247
0
        let val = unsafe { LLVMBuildFence(self.builder, atomic_ordering.into(), num, c_string.as_ptr()) };
3248
3249
0
        unsafe { Ok(InstructionValue::new(val)) }
3250
0
    }
3251
3252
    // SubType: <P>(&self, ptr: &PointerValue<P>, name) -> IntValue<bool> {
3253
6.67k
    pub fn build_is_null<T: PointerMathValue<'ctx>>(
3254
6.67k
        &self,
3255
6.67k
        ptr: T,
3256
6.67k
        name: &str,
3257
6.67k
    ) -> Result<<<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType, BuilderError>
3258
    {
3259
6.67k
        if self.positioned.get() != PositionState::Set {
3260
0
            return Err(BuilderError::UnsetPosition);
3261
6.67k
        }
3262
6.67k
        let c_string = to_c_str(name);
3263
6.67k
        let val = unsafe { LLVMBuildIsNull(self.builder, ptr.as_value_ref(), c_string.as_ptr()) };
3264
3265
6.67k
        unsafe { Ok(<<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType::new(val)) }
3266
6.67k
    }
<inkwell::builder::Builder>::build_is_null::<inkwell::values::ptr_value::PointerValue>
Line
Count
Source
3253
6.67k
    pub fn build_is_null<T: PointerMathValue<'ctx>>(
3254
6.67k
        &self,
3255
6.67k
        ptr: T,
3256
6.67k
        name: &str,
3257
6.67k
    ) -> Result<<<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType, BuilderError>
3258
    {
3259
6.67k
        if self.positioned.get() != PositionState::Set {
3260
0
            return Err(BuilderError::UnsetPosition);
3261
6.67k
        }
3262
6.67k
        let c_string = to_c_str(name);
3263
6.67k
        let val = unsafe { LLVMBuildIsNull(self.builder, ptr.as_value_ref(), c_string.as_ptr()) };
3264
3265
6.67k
        unsafe { Ok(<<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType::new(val)) }
3266
6.67k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_is_null::<_>
3267
3268
    // SubType: <P>(&self, ptr: &PointerValue<P>, name) -> IntValue<bool> {
3269
948
    pub fn build_is_not_null<T: PointerMathValue<'ctx>>(
3270
948
        &self,
3271
948
        ptr: T,
3272
948
        name: &str,
3273
948
    ) -> Result<<<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType, BuilderError>
3274
    {
3275
948
        if self.positioned.get() != PositionState::Set {
3276
0
            return Err(BuilderError::UnsetPosition);
3277
948
        }
3278
948
        let c_string = to_c_str(name);
3279
948
        let val = unsafe { LLVMBuildIsNotNull(self.builder, ptr.as_value_ref(), c_string.as_ptr()) };
3280
3281
948
        unsafe { Ok(<<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType::new(val)) }
3282
948
    }
<inkwell::builder::Builder>::build_is_not_null::<inkwell::values::ptr_value::PointerValue>
Line
Count
Source
3269
948
    pub fn build_is_not_null<T: PointerMathValue<'ctx>>(
3270
948
        &self,
3271
948
        ptr: T,
3272
948
        name: &str,
3273
948
    ) -> Result<<<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType, BuilderError>
3274
    {
3275
948
        if self.positioned.get() != PositionState::Set {
3276
0
            return Err(BuilderError::UnsetPosition);
3277
948
        }
3278
948
        let c_string = to_c_str(name);
3279
948
        let val = unsafe { LLVMBuildIsNotNull(self.builder, ptr.as_value_ref(), c_string.as_ptr()) };
3280
3281
948
        unsafe { Ok(<<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType::new(val)) }
3282
948
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_is_not_null::<_>
3283
3284
    // SubType: <I, P>(&self, int: &IntValue<I>, ptr_type: &PointerType<P>, name) -> PointerValue<P> {
3285
0
    pub fn build_int_to_ptr<T: IntMathValue<'ctx>>(
3286
0
        &self,
3287
0
        int: T,
3288
0
        ptr_type: <T::BaseType as IntMathType<'ctx>>::PtrConvType,
3289
0
        name: &str,
3290
0
    ) -> Result<<<T::BaseType as IntMathType<'ctx>>::PtrConvType as PointerMathType<'ctx>>::ValueType, BuilderError>
3291
    {
3292
0
        if self.positioned.get() != PositionState::Set {
3293
0
            return Err(BuilderError::UnsetPosition);
3294
0
        }
3295
0
        let c_string = to_c_str(name);
3296
3297
0
        let value = unsafe {
3298
0
            LLVMBuildIntToPtr(
3299
0
                self.builder,
3300
0
                int.as_value_ref(),
3301
0
                ptr_type.as_type_ref(),
3302
0
                c_string.as_ptr(),
3303
            )
3304
        };
3305
3306
0
        unsafe { Ok(<<T::BaseType as IntMathType>::PtrConvType as PointerMathType>::ValueType::new(value)) }
3307
0
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_to_ptr::<inkwell::values::int_value::IntValue>
Unexecuted instantiation: <inkwell::builder::Builder>::build_int_to_ptr::<_>
3308
3309
    // SubType: <I, P>(&self, ptr: &PointerValue<P>, int_type: &IntType<I>, name) -> IntValue<I> {
3310
7.22k
    pub fn build_ptr_to_int<T: PointerMathValue<'ctx>>(
3311
7.22k
        &self,
3312
7.22k
        ptr: T,
3313
7.22k
        int_type: <T::BaseType as PointerMathType<'ctx>>::PtrConvType,
3314
7.22k
        name: &str,
3315
7.22k
    ) -> Result<<<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType, BuilderError>
3316
    {
3317
7.22k
        if self.positioned.get() != PositionState::Set {
3318
0
            return Err(BuilderError::UnsetPosition);
3319
7.22k
        }
3320
7.22k
        let c_string = to_c_str(name);
3321
3322
7.22k
        let value = unsafe {
3323
7.22k
            LLVMBuildPtrToInt(
3324
7.22k
                self.builder,
3325
7.22k
                ptr.as_value_ref(),
3326
7.22k
                int_type.as_type_ref(),
3327
7.22k
                c_string.as_ptr(),
3328
            )
3329
        };
3330
3331
7.22k
        unsafe { Ok(<<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType::new(value)) }
3332
7.22k
    }
<inkwell::builder::Builder>::build_ptr_to_int::<inkwell::values::ptr_value::PointerValue>
Line
Count
Source
3310
7.22k
    pub fn build_ptr_to_int<T: PointerMathValue<'ctx>>(
3311
7.22k
        &self,
3312
7.22k
        ptr: T,
3313
7.22k
        int_type: <T::BaseType as PointerMathType<'ctx>>::PtrConvType,
3314
7.22k
        name: &str,
3315
7.22k
    ) -> Result<<<T::BaseType as PointerMathType<'ctx>>::PtrConvType as IntMathType<'ctx>>::ValueType, BuilderError>
3316
    {
3317
7.22k
        if self.positioned.get() != PositionState::Set {
3318
0
            return Err(BuilderError::UnsetPosition);
3319
7.22k
        }
3320
7.22k
        let c_string = to_c_str(name);
3321
3322
7.22k
        let value = unsafe {
3323
7.22k
            LLVMBuildPtrToInt(
3324
7.22k
                self.builder,
3325
7.22k
                ptr.as_value_ref(),
3326
7.22k
                int_type.as_type_ref(),
3327
7.22k
                c_string.as_ptr(),
3328
            )
3329
        };
3330
3331
7.22k
        unsafe { Ok(<<T::BaseType as PointerMathType>::PtrConvType as IntMathType>::ValueType::new(value)) }
3332
7.22k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_ptr_to_int::<_>
3333
3334
0
    pub fn clear_insertion_position(&self) {
3335
0
        self.positioned.set(PositionState::NotSet);
3336
0
        unsafe { LLVMClearInsertionPosition(self.builder) }
3337
0
    }
3338
3339
    // REVIEW: Returning InstructionValue is the safe move here; but if the value means something
3340
    // (IE the result of the switch) it should probably return BasicValueEnum?
3341
    // SubTypes: I think value and case values must be the same subtype (maybe). Case value might need to be constants
3342
96.6k
    pub fn build_switch(
3343
96.6k
        &self,
3344
96.6k
        value: IntValue<'ctx>,
3345
96.6k
        else_block: BasicBlock<'ctx>,
3346
96.6k
        cases: &[(IntValue<'ctx>, BasicBlock<'ctx>)],
3347
96.6k
    ) -> Result<InstructionValue<'ctx>, BuilderError> {
3348
96.6k
        if self.positioned.get() != PositionState::Set {
3349
0
            return Err(BuilderError::UnsetPosition);
3350
96.6k
        }
3351
96.6k
        let switch_value = unsafe {
3352
96.6k
            LLVMBuildSwitch(
3353
96.6k
                self.builder,
3354
96.6k
                value.as_value_ref(),
3355
96.6k
                else_block.basic_block,
3356
96.6k
                cases.len() as u32,
3357
            )
3358
        };
3359
3360
109k
        for &(value, basic_block) in cases {
3361
109k
            unsafe { LLVMAddCase(switch_value, value.as_value_ref(), basic_block.basic_block) }
3362
        }
3363
3364
96.6k
        unsafe { Ok(InstructionValue::new(switch_value)) }
3365
96.6k
    }
3366
3367
    // SubTypes: condition can only be IntValue<bool> or VectorValue<IntValue<Bool>>
3368
117k
    pub fn build_select<BV: BasicValue<'ctx>, IMV: IntMathValue<'ctx>>(
3369
117k
        &self,
3370
117k
        condition: IMV,
3371
117k
        then: BV,
3372
117k
        else_: BV,
3373
117k
        name: &str,
3374
117k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3375
117k
        if self.positioned.get() != PositionState::Set {
3376
0
            return Err(BuilderError::UnsetPosition);
3377
117k
        }
3378
117k
        let c_string = to_c_str(name);
3379
117k
        let value = unsafe {
3380
117k
            LLVMBuildSelect(
3381
117k
                self.builder,
3382
117k
                condition.as_value_ref(),
3383
117k
                then.as_value_ref(),
3384
117k
                else_.as_value_ref(),
3385
117k
                c_string.as_ptr(),
3386
            )
3387
        };
3388
3389
117k
        unsafe { Ok(BasicValueEnum::new(value)) }
3390
117k
    }
<inkwell::builder::Builder>::build_select::<inkwell::values::float_value::FloatValue, inkwell::values::int_value::IntValue>
Line
Count
Source
3368
33.4k
    pub fn build_select<BV: BasicValue<'ctx>, IMV: IntMathValue<'ctx>>(
3369
33.4k
        &self,
3370
33.4k
        condition: IMV,
3371
33.4k
        then: BV,
3372
33.4k
        else_: BV,
3373
33.4k
        name: &str,
3374
33.4k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3375
33.4k
        if self.positioned.get() != PositionState::Set {
3376
0
            return Err(BuilderError::UnsetPosition);
3377
33.4k
        }
3378
33.4k
        let c_string = to_c_str(name);
3379
33.4k
        let value = unsafe {
3380
33.4k
            LLVMBuildSelect(
3381
33.4k
                self.builder,
3382
33.4k
                condition.as_value_ref(),
3383
33.4k
                then.as_value_ref(),
3384
33.4k
                else_.as_value_ref(),
3385
33.4k
                c_string.as_ptr(),
3386
            )
3387
        };
3388
3389
33.4k
        unsafe { Ok(BasicValueEnum::new(value)) }
3390
33.4k
    }
<inkwell::builder::Builder>::build_select::<inkwell::values::enums::BasicValueEnum, inkwell::values::int_value::IntValue>
Line
Count
Source
3368
32.7k
    pub fn build_select<BV: BasicValue<'ctx>, IMV: IntMathValue<'ctx>>(
3369
32.7k
        &self,
3370
32.7k
        condition: IMV,
3371
32.7k
        then: BV,
3372
32.7k
        else_: BV,
3373
32.7k
        name: &str,
3374
32.7k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3375
32.7k
        if self.positioned.get() != PositionState::Set {
3376
0
            return Err(BuilderError::UnsetPosition);
3377
32.7k
        }
3378
32.7k
        let c_string = to_c_str(name);
3379
32.7k
        let value = unsafe {
3380
32.7k
            LLVMBuildSelect(
3381
32.7k
                self.builder,
3382
32.7k
                condition.as_value_ref(),
3383
32.7k
                then.as_value_ref(),
3384
32.7k
                else_.as_value_ref(),
3385
32.7k
                c_string.as_ptr(),
3386
            )
3387
        };
3388
3389
32.7k
        unsafe { Ok(BasicValueEnum::new(value)) }
3390
32.7k
    }
<inkwell::builder::Builder>::build_select::<inkwell::values::enums::BasicValueEnum, inkwell::values::vec_value::VectorValue>
Line
Count
Source
3368
2
    pub fn build_select<BV: BasicValue<'ctx>, IMV: IntMathValue<'ctx>>(
3369
2
        &self,
3370
2
        condition: IMV,
3371
2
        then: BV,
3372
2
        else_: BV,
3373
2
        name: &str,
3374
2
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3375
2
        if self.positioned.get() != PositionState::Set {
3376
0
            return Err(BuilderError::UnsetPosition);
3377
2
        }
3378
2
        let c_string = to_c_str(name);
3379
2
        let value = unsafe {
3380
2
            LLVMBuildSelect(
3381
2
                self.builder,
3382
2
                condition.as_value_ref(),
3383
2
                then.as_value_ref(),
3384
2
                else_.as_value_ref(),
3385
2
                c_string.as_ptr(),
3386
            )
3387
        };
3388
3389
2
        unsafe { Ok(BasicValueEnum::new(value)) }
3390
2
    }
<inkwell::builder::Builder>::build_select::<inkwell::values::int_value::IntValue, inkwell::values::int_value::IntValue>
Line
Count
Source
3368
44.3k
    pub fn build_select<BV: BasicValue<'ctx>, IMV: IntMathValue<'ctx>>(
3369
44.3k
        &self,
3370
44.3k
        condition: IMV,
3371
44.3k
        then: BV,
3372
44.3k
        else_: BV,
3373
44.3k
        name: &str,
3374
44.3k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3375
44.3k
        if self.positioned.get() != PositionState::Set {
3376
0
            return Err(BuilderError::UnsetPosition);
3377
44.3k
        }
3378
44.3k
        let c_string = to_c_str(name);
3379
44.3k
        let value = unsafe {
3380
44.3k
            LLVMBuildSelect(
3381
44.3k
                self.builder,
3382
44.3k
                condition.as_value_ref(),
3383
44.3k
                then.as_value_ref(),
3384
44.3k
                else_.as_value_ref(),
3385
44.3k
                c_string.as_ptr(),
3386
            )
3387
        };
3388
3389
44.3k
        unsafe { Ok(BasicValueEnum::new(value)) }
3390
44.3k
    }
<inkwell::builder::Builder>::build_select::<inkwell::values::vec_value::VectorValue, inkwell::values::vec_value::VectorValue>
Line
Count
Source
3368
6.54k
    pub fn build_select<BV: BasicValue<'ctx>, IMV: IntMathValue<'ctx>>(
3369
6.54k
        &self,
3370
6.54k
        condition: IMV,
3371
6.54k
        then: BV,
3372
6.54k
        else_: BV,
3373
6.54k
        name: &str,
3374
6.54k
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3375
6.54k
        if self.positioned.get() != PositionState::Set {
3376
0
            return Err(BuilderError::UnsetPosition);
3377
6.54k
        }
3378
6.54k
        let c_string = to_c_str(name);
3379
6.54k
        let value = unsafe {
3380
6.54k
            LLVMBuildSelect(
3381
6.54k
                self.builder,
3382
6.54k
                condition.as_value_ref(),
3383
6.54k
                then.as_value_ref(),
3384
6.54k
                else_.as_value_ref(),
3385
6.54k
                c_string.as_ptr(),
3386
            )
3387
        };
3388
3389
6.54k
        unsafe { Ok(BasicValueEnum::new(value)) }
3390
6.54k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_select::<_, _>
3391
3392
    // The unsafety of this function should be fixable with subtypes. See GH #32
3393
0
    pub unsafe fn build_global_string(&self, value: &str, name: &str) -> Result<GlobalValue<'ctx>, BuilderError> {
3394
0
        if self.positioned.get() != PositionState::Set {
3395
0
            return Err(BuilderError::UnsetPosition);
3396
0
        }
3397
0
        let c_string_value = to_c_str(value);
3398
0
        let c_string_name = to_c_str(name);
3399
0
        let value = LLVMBuildGlobalString(self.builder, c_string_value.as_ptr(), c_string_name.as_ptr());
3400
3401
0
        Ok(GlobalValue::new(value))
3402
0
    }
3403
3404
    // REVIEW: Does this similar fn have the same issue build_global_string does? If so, mark as unsafe
3405
    // and fix with subtypes.
3406
0
    pub fn build_global_string_ptr(&self, value: &str, name: &str) -> Result<GlobalValue<'ctx>, BuilderError> {
3407
0
        if self.positioned.get() != PositionState::Set {
3408
0
            return Err(BuilderError::UnsetPosition);
3409
0
        }
3410
0
        let c_string_value = to_c_str(value);
3411
0
        let c_string_name = to_c_str(name);
3412
0
        let value = unsafe { LLVMBuildGlobalStringPtr(self.builder, c_string_value.as_ptr(), c_string_name.as_ptr()) };
3413
3414
0
        unsafe { Ok(GlobalValue::new(value)) }
3415
0
    }
3416
3417
    // REVIEW: Do we need to constrain types here? subtypes?
3418
38.9k
    pub fn build_shuffle_vector<V: VectorBaseValue<'ctx>>(
3419
38.9k
        &self,
3420
38.9k
        left: V,
3421
38.9k
        right: V,
3422
38.9k
        mask: V,
3423
38.9k
        name: &str,
3424
38.9k
    ) -> Result<V, BuilderError> {
3425
38.9k
        if self.positioned.get() != PositionState::Set {
3426
0
            return Err(BuilderError::UnsetPosition);
3427
38.9k
        }
3428
38.9k
        let c_string = to_c_str(name);
3429
38.9k
        let value = unsafe {
3430
38.9k
            LLVMBuildShuffleVector(
3431
38.9k
                self.builder,
3432
38.9k
                left.as_value_ref(),
3433
38.9k
                right.as_value_ref(),
3434
38.9k
                mask.as_value_ref(),
3435
38.9k
                c_string.as_ptr(),
3436
            )
3437
        };
3438
3439
38.9k
        unsafe { Ok(V::new(value)) }
3440
38.9k
    }
<inkwell::builder::Builder>::build_shuffle_vector::<inkwell::values::vec_value::VectorValue>
Line
Count
Source
3418
38.9k
    pub fn build_shuffle_vector<V: VectorBaseValue<'ctx>>(
3419
38.9k
        &self,
3420
38.9k
        left: V,
3421
38.9k
        right: V,
3422
38.9k
        mask: V,
3423
38.9k
        name: &str,
3424
38.9k
    ) -> Result<V, BuilderError> {
3425
38.9k
        if self.positioned.get() != PositionState::Set {
3426
0
            return Err(BuilderError::UnsetPosition);
3427
38.9k
        }
3428
38.9k
        let c_string = to_c_str(name);
3429
38.9k
        let value = unsafe {
3430
38.9k
            LLVMBuildShuffleVector(
3431
38.9k
                self.builder,
3432
38.9k
                left.as_value_ref(),
3433
38.9k
                right.as_value_ref(),
3434
38.9k
                mask.as_value_ref(),
3435
38.9k
                c_string.as_ptr(),
3436
            )
3437
        };
3438
3439
38.9k
        unsafe { Ok(V::new(value)) }
3440
38.9k
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_shuffle_vector::<_>
3441
3442
    // REVIEW: Is return type correct?
3443
    // SubTypes: I think this should be type: BT -> BT::Value
3444
    // https://llvm.org/docs/LangRef.html#i-va-arg
3445
0
    pub fn build_va_arg<BT: BasicType<'ctx>>(
3446
0
        &self,
3447
0
        list: PointerValue<'ctx>,
3448
0
        type_: BT,
3449
0
        name: &str,
3450
0
    ) -> Result<BasicValueEnum<'ctx>, BuilderError> {
3451
0
        if self.positioned.get() != PositionState::Set {
3452
0
            return Err(BuilderError::UnsetPosition);
3453
0
        }
3454
0
        let c_string = to_c_str(name);
3455
3456
0
        let value = unsafe {
3457
0
            LLVMBuildVAArg(
3458
0
                self.builder,
3459
0
                list.as_value_ref(),
3460
0
                type_.as_type_ref(),
3461
0
                c_string.as_ptr(),
3462
            )
3463
        };
3464
3465
0
        unsafe { Ok(BasicValueEnum::new(value)) }
3466
0
    }
3467
3468
    /// Builds an atomicrmw instruction. It allows you to atomically modify memory.
3469
    ///
3470
    /// May return of the following errors:
3471
    /// - `Err(BuilderError::BitwidthError)` if the bitwidth of the value is not a power of 2 and less than 8
3472
    /// - `Err(BuilderError:PointeeTypeMismatch)` if the pointee type does not match the value's type
3473
    ///
3474
    /// # Example
3475
    ///
3476
    /// ```
3477
    /// use inkwell::context::Context;
3478
    /// use inkwell::{AddressSpace, AtomicOrdering, AtomicRMWBinOp};
3479
    /// let context = Context::create();
3480
    /// let module = context.create_module("rmw");
3481
    /// let void_type = context.void_type();
3482
    /// let i32_type = context.i32_type();
3483
    /// let i32_seven = i32_type.const_int(7, false);
3484
    /// #[cfg(feature = "typed-pointers")]
3485
    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
3486
    /// #[cfg(not(feature = "typed-pointers"))]
3487
    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
3488
    /// let fn_type = void_type.fn_type(&[i32_ptr_type.into()], false);
3489
    /// let fn_value = module.add_function("rmw", fn_type, None);
3490
    /// let entry = context.append_basic_block(fn_value, "entry");
3491
    /// let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value();
3492
    /// let builder = context.create_builder();
3493
    /// builder.position_at_end(entry);
3494
    /// #[cfg(feature = "llvm21-1")]
3495
    /// builder.build_atomicrmw(AtomicRMWBinOp::Add, i32_ptr_param, i32_seven, AtomicOrdering::Monotonic).unwrap();
3496
    /// #[cfg(not(feature = "llvm21-1"))]
3497
    /// builder.build_atomicrmw(AtomicRMWBinOp::Add, i32_ptr_param, i32_seven, AtomicOrdering::Unordered).unwrap();
3498
    /// builder.build_return(None).unwrap();
3499
    /// ```
3500
    // https://llvm.org/docs/LangRef.html#atomicrmw-instruction
3501
4.94k
    pub fn build_atomicrmw(
3502
4.94k
        &self,
3503
4.94k
        op: AtomicRMWBinOp,
3504
4.94k
        ptr: PointerValue<'ctx>,
3505
4.94k
        value: IntValue<'ctx>,
3506
4.94k
        ordering: AtomicOrdering,
3507
4.94k
    ) -> Result<IntValue<'ctx>, BuilderError> {
3508
4.94k
        if self.positioned.get() != PositionState::Set {
3509
0
            return Err(BuilderError::UnsetPosition);
3510
4.94k
        }
3511
        // TODO: add support for fadd, fsub and xchg on floating point types in LLVM 9+.
3512
3513
        // "The type of ‘<value>’ must be an integer type whose bit width is a power of two greater than or equal to eight and less than or equal to a target-specific size limit. The type of the ‘<pointer>’ operand must be a pointer to that type." -- https://releases.llvm.org/3.6.2/docs/LangRef.html#atomicrmw-instruction
3514
4.94k
        if value.get_type().get_bit_width() < 8 || !value.get_type().get_bit_width().is_power_of_two() {
3515
0
            return Err(BuilderError::BitwidthError);
3516
4.94k
        }
3517
3518
        #[cfg(feature = "typed-pointers")]
3519
        if ptr.get_type().get_element_type() != value.get_type().into() {
3520
            return Err(BuilderError::PointeeTypeMismatch);
3521
        }
3522
3523
4.94k
        let val = unsafe {
3524
4.94k
            LLVMBuildAtomicRMW(
3525
4.94k
                self.builder,
3526
4.94k
                op.into(),
3527
4.94k
                ptr.as_value_ref(),
3528
4.94k
                value.as_value_ref(),
3529
4.94k
                ordering.into(),
3530
4.94k
                false as i32,
3531
            )
3532
        };
3533
3534
4.94k
        unsafe { Ok(IntValue::new(val)) }
3535
4.94k
    }
3536
3537
    /// Builds a [`cmpxchg`](https://llvm.org/docs/LangRef.html#cmpxchg-instruction) instruction.
3538
    ///
3539
    /// This instruction allows to atomically compare and replace memory.
3540
    ///
3541
    /// May return one of the following errors:
3542
    /// - `Err(BuilderError::PointeeTypeMismatch)` if the pointer does not point to an element of the value type
3543
    /// - `Err(BuilderError::ValueTypeMismatch)` if the value to compare and the new values are not of the same type, or if
3544
    ///   the value does not have a pointer or integer type
3545
    /// - `Err(BuilderError::OrderingError)` if the following conditions are not satisfied:
3546
    ///     - Both success and failure orderings are not Monotonic or stronger
3547
    ///     - The failure ordering is stronger than the success ordering
3548
    ///     - The failure ordering is release or acquire release
3549
    ///
3550
    /// # Example
3551
    ///
3552
    /// ```
3553
    /// use inkwell::context::Context;
3554
    /// use inkwell::{AddressSpace, AtomicOrdering};
3555
    /// let context = Context::create();
3556
    /// let module = context.create_module("cmpxchg");
3557
    /// let void_type = context.void_type();
3558
    /// let i32_type = context.i32_type();
3559
    /// #[cfg(feature = "typed-pointers")]
3560
    /// let i32_ptr_type = i32_type.ptr_type(AddressSpace::default());
3561
    /// #[cfg(not(feature = "typed-pointers"))]
3562
    /// let i32_ptr_type = context.ptr_type(AddressSpace::default());
3563
    /// let fn_type = void_type.fn_type(&[i32_ptr_type.into()], false);
3564
    /// let fn_value = module.add_function("", fn_type, None);
3565
    /// let i32_ptr_param = fn_value.get_first_param().unwrap().into_pointer_value();
3566
    /// let i32_seven = i32_type.const_int(7, false);
3567
    /// let i32_eight = i32_type.const_int(8, false);
3568
    /// let entry = context.append_basic_block(fn_value, "entry");
3569
    /// let builder = context.create_builder();
3570
    /// builder.position_at_end(entry);
3571
    /// builder.build_cmpxchg(i32_ptr_param, i32_seven, i32_eight, AtomicOrdering::AcquireRelease, AtomicOrdering::Monotonic).unwrap();
3572
    /// builder.build_return(None).unwrap();
3573
    /// ```
3574
29
    pub fn build_cmpxchg<V: BasicValue<'ctx>>(
3575
29
        &self,
3576
29
        ptr: PointerValue<'ctx>,
3577
29
        cmp: V,
3578
29
        new: V,
3579
29
        success: AtomicOrdering,
3580
29
        failure: AtomicOrdering,
3581
29
    ) -> Result<StructValue<'ctx>, BuilderError> {
3582
29
        if self.positioned.get() != PositionState::Set {
3583
0
            return Err(BuilderError::UnsetPosition);
3584
29
        }
3585
29
        let cmp = cmp.as_basic_value_enum();
3586
29
        let new = new.as_basic_value_enum();
3587
29
        if cmp.get_type() != new.get_type() {
3588
0
            return Err(BuilderError::NotSameType);
3589
29
        }
3590
29
        if !cmp.is_int_value() && !cmp.is_pointer_value() {
3591
0
            return Err(BuilderError::NotPointerOrInteger);
3592
29
        }
3593
3594
        #[cfg(feature = "typed-pointers")]
3595
        if ptr.get_type().get_element_type().as_basic_type_enum() != cmp.get_type() {
3596
            return Err(BuilderError::PointeeTypeMismatch);
3597
        }
3598
3599
        // "Both ordering parameters must be at least monotonic, the ordering constraint on failure must be no stronger than that on success, and the failure ordering cannot be either release or acq_rel." -- https://llvm.org/docs/LangRef.html#cmpxchg-instruction
3600
29
        if success < AtomicOrdering::Monotonic || failure < AtomicOrdering::Monotonic {
3601
0
            return Err(BuilderError::OrderingError(OrderingError::WeakerThanMonotic));
3602
29
        }
3603
29
        if failure > success {
3604
0
            return Err(BuilderError::OrderingError(OrderingError::WeakerSuccessOrdering));
3605
29
        }
3606
29
        if failure == AtomicOrdering::Release || failure == AtomicOrdering::AcquireRelease {
3607
0
            return Err(BuilderError::OrderingError(OrderingError::ReleaseOrAcqRel));
3608
29
        }
3609
3610
29
        let val = unsafe {
3611
29
            LLVMBuildAtomicCmpXchg(
3612
29
                self.builder,
3613
29
                ptr.as_value_ref(),
3614
29
                cmp.as_value_ref(),
3615
29
                new.as_value_ref(),
3616
29
                success.into(),
3617
29
                failure.into(),
3618
29
                false as i32,
3619
            )
3620
        };
3621
3622
29
        unsafe { Ok(StructValue::new(val)) }
3623
29
    }
<inkwell::builder::Builder>::build_cmpxchg::<inkwell::values::int_value::IntValue>
Line
Count
Source
3574
29
    pub fn build_cmpxchg<V: BasicValue<'ctx>>(
3575
29
        &self,
3576
29
        ptr: PointerValue<'ctx>,
3577
29
        cmp: V,
3578
29
        new: V,
3579
29
        success: AtomicOrdering,
3580
29
        failure: AtomicOrdering,
3581
29
    ) -> Result<StructValue<'ctx>, BuilderError> {
3582
29
        if self.positioned.get() != PositionState::Set {
3583
0
            return Err(BuilderError::UnsetPosition);
3584
29
        }
3585
29
        let cmp = cmp.as_basic_value_enum();
3586
29
        let new = new.as_basic_value_enum();
3587
29
        if cmp.get_type() != new.get_type() {
3588
0
            return Err(BuilderError::NotSameType);
3589
29
        }
3590
29
        if !cmp.is_int_value() && !cmp.is_pointer_value() {
3591
0
            return Err(BuilderError::NotPointerOrInteger);
3592
29
        }
3593
3594
        #[cfg(feature = "typed-pointers")]
3595
        if ptr.get_type().get_element_type().as_basic_type_enum() != cmp.get_type() {
3596
            return Err(BuilderError::PointeeTypeMismatch);
3597
        }
3598
3599
        // "Both ordering parameters must be at least monotonic, the ordering constraint on failure must be no stronger than that on success, and the failure ordering cannot be either release or acq_rel." -- https://llvm.org/docs/LangRef.html#cmpxchg-instruction
3600
29
        if success < AtomicOrdering::Monotonic || failure < AtomicOrdering::Monotonic {
3601
0
            return Err(BuilderError::OrderingError(OrderingError::WeakerThanMonotic));
3602
29
        }
3603
29
        if failure > success {
3604
0
            return Err(BuilderError::OrderingError(OrderingError::WeakerSuccessOrdering));
3605
29
        }
3606
29
        if failure == AtomicOrdering::Release || failure == AtomicOrdering::AcquireRelease {
3607
0
            return Err(BuilderError::OrderingError(OrderingError::ReleaseOrAcqRel));
3608
29
        }
3609
3610
29
        let val = unsafe {
3611
29
            LLVMBuildAtomicCmpXchg(
3612
29
                self.builder,
3613
29
                ptr.as_value_ref(),
3614
29
                cmp.as_value_ref(),
3615
29
                new.as_value_ref(),
3616
29
                success.into(),
3617
29
                failure.into(),
3618
29
                false as i32,
3619
            )
3620
        };
3621
3622
29
        unsafe { Ok(StructValue::new(val)) }
3623
29
    }
Unexecuted instantiation: <inkwell::builder::Builder>::build_cmpxchg::<_>
3624
3625
    /// Set the debug info source location of the instruction currently pointed at by the builder
3626
0
    pub fn set_current_debug_location(&self, location: DILocation<'ctx>) {
3627
        use llvm_sys::core::LLVMSetCurrentDebugLocation2;
3628
0
        unsafe {
3629
0
            LLVMSetCurrentDebugLocation2(self.builder, location.metadata_ref);
3630
0
        }
3631
0
    }
3632
3633
    /// Get the debug info source location of the instruction currently pointed at by the builder,
3634
    /// if available.
3635
0
    pub fn get_current_debug_location(&self) -> Option<DILocation<'ctx>> {
3636
        use llvm_sys::core::LLVMGetCurrentDebugLocation;
3637
        use llvm_sys::core::LLVMValueAsMetadata;
3638
0
        let metadata_ref = unsafe { LLVMGetCurrentDebugLocation(self.builder) };
3639
0
        if metadata_ref.is_null() {
3640
0
            return None;
3641
0
        }
3642
0
        Some(DILocation {
3643
0
            metadata_ref: unsafe { LLVMValueAsMetadata(metadata_ref) },
3644
0
            _marker: PhantomData,
3645
0
        })
3646
0
    }
3647
3648
    /// Unset the debug info source location of the instruction currently pointed at by the
3649
    /// builder. If there isn't any debug info, this is a no-op.
3650
0
    pub fn unset_current_debug_location(&self) {
3651
        use llvm_sys::core::LLVMSetCurrentDebugLocation2;
3652
0
        unsafe {
3653
0
            LLVMSetCurrentDebugLocation2(self.builder, std::ptr::null_mut());
3654
0
        }
3655
0
    }
3656
}
3657
3658
/// Used by build_memcpy and build_memmove
3659
0
fn is_alignment_ok(align: u32) -> bool {
3660
    // This replicates the assertions LLVM runs.
3661
    //
3662
    // See https://github.com/TheDan64/inkwell/issues/168
3663
    // is_power_of_two returns false for 0.
3664
0
    align.is_power_of_two()
3665
0
}
3666
3667
impl Drop for Builder<'_> {
3668
338k
    fn drop(&mut self) {
3669
338k
        unsafe {
3670
338k
            LLVMDisposeBuilder(self.builder);
3671
338k
        }
3672
338k
    }
3673
}