|
1 | 1 | //! A `Builder` enables you to build instructions.
|
2 | 2 |
|
3 |
| -use either::{Either, Left, Right}; |
4 |
| -use llvm_sys::core::{LLVMBuildAdd, LLVMBuildAlloca, LLVMBuildAnd, LLVMBuildArrayAlloca, LLVMBuildArrayMalloc, LLVMBuildAtomicRMW, LLVMBuildBr, LLVMBuildCall, LLVMBuildCast, LLVMBuildCondBr, LLVMBuildExtractValue, LLVMBuildFAdd, LLVMBuildFCmp, LLVMBuildFDiv, LLVMBuildFence, LLVMBuildFMul, LLVMBuildFNeg, LLVMBuildFree, LLVMBuildFSub, LLVMBuildGEP, LLVMBuildICmp, LLVMBuildInsertValue, LLVMBuildIsNotNull, LLVMBuildIsNull, LLVMBuildLoad, LLVMBuildMalloc, LLVMBuildMul, LLVMBuildNeg, LLVMBuildNot, LLVMBuildOr, LLVMBuildPhi, LLVMBuildPointerCast, LLVMBuildRet, LLVMBuildRetVoid, LLVMBuildStore, LLVMBuildSub, LLVMBuildUDiv, LLVMBuildUnreachable, LLVMBuildXor, LLVMDisposeBuilder, LLVMGetElementType, LLVMGetInsertBlock, LLVMGetReturnType, LLVMGetTypeKind, LLVMInsertIntoBuilder, LLVMPositionBuilderAtEnd, LLVMTypeOf, LLVMBuildExtractElement, LLVMBuildInsertElement, LLVMBuildIntToPtr, LLVMBuildPtrToInt, LLVMInsertIntoBuilderWithName, LLVMClearInsertionPosition, LLVMPositionBuilder, LLVMPositionBuilderBefore, LLVMBuildAggregateRet, LLVMBuildStructGEP, LLVMBuildInBoundsGEP, LLVMBuildPtrDiff, LLVMBuildNSWAdd, LLVMBuildNUWAdd, LLVMBuildNSWSub, LLVMBuildNUWSub, LLVMBuildNSWMul, LLVMBuildNUWMul, LLVMBuildSDiv, LLVMBuildSRem, LLVMBuildURem, LLVMBuildFRem, LLVMBuildNSWNeg, LLVMBuildNUWNeg, LLVMBuildFPToUI, LLVMBuildFPToSI, LLVMBuildSIToFP, LLVMBuildUIToFP, LLVMBuildFPTrunc, LLVMBuildFPExt, LLVMBuildIntCast, LLVMBuildFPCast, LLVMBuildSExtOrBitCast, LLVMBuildZExtOrBitCast, LLVMBuildTruncOrBitCast, LLVMBuildSwitch, LLVMAddCase, LLVMBuildShl, LLVMBuildAShr, LLVMBuildLShr, LLVMBuildGlobalString, LLVMBuildGlobalStringPtr, LLVMBuildExactSDiv, LLVMBuildTrunc, LLVMBuildSExt, LLVMBuildZExt, LLVMBuildSelect, LLVMBuildAddrSpaceCast, LLVMBuildBitCast, LLVMBuildShuffleVector, LLVMBuildVAArg, LLVMBuildIndirectBr, LLVMAddDestination}; |
| 3 | +use llvm_sys::core::{LLVMBuildAdd, LLVMBuildAlloca, LLVMBuildAnd, LLVMBuildArrayAlloca, LLVMBuildArrayMalloc, LLVMBuildAtomicRMW, LLVMBuildBr, LLVMBuildCall, LLVMBuildCast, LLVMBuildCondBr, LLVMBuildExtractValue, LLVMBuildFAdd, LLVMBuildFCmp, LLVMBuildFDiv, LLVMBuildFence, LLVMBuildFMul, LLVMBuildFNeg, LLVMBuildFree, LLVMBuildFSub, LLVMBuildGEP, LLVMBuildICmp, LLVMBuildInsertValue, LLVMBuildIsNotNull, LLVMBuildIsNull, LLVMBuildLoad, LLVMBuildMalloc, LLVMBuildMul, LLVMBuildNeg, LLVMBuildNot, LLVMBuildOr, LLVMBuildPhi, LLVMBuildPointerCast, LLVMBuildRet, LLVMBuildRetVoid, LLVMBuildStore, LLVMBuildSub, LLVMBuildUDiv, LLVMBuildUnreachable, LLVMBuildXor, LLVMDisposeBuilder, LLVMGetInsertBlock, LLVMInsertIntoBuilder, LLVMPositionBuilderAtEnd, LLVMBuildExtractElement, LLVMBuildInsertElement, LLVMBuildIntToPtr, LLVMBuildPtrToInt, LLVMInsertIntoBuilderWithName, LLVMClearInsertionPosition, LLVMPositionBuilder, LLVMPositionBuilderBefore, LLVMBuildAggregateRet, LLVMBuildStructGEP, LLVMBuildInBoundsGEP, LLVMBuildPtrDiff, LLVMBuildNSWAdd, LLVMBuildNUWAdd, LLVMBuildNSWSub, LLVMBuildNUWSub, LLVMBuildNSWMul, LLVMBuildNUWMul, LLVMBuildSDiv, LLVMBuildSRem, LLVMBuildURem, LLVMBuildFRem, LLVMBuildNSWNeg, LLVMBuildNUWNeg, LLVMBuildFPToUI, LLVMBuildFPToSI, LLVMBuildSIToFP, LLVMBuildUIToFP, LLVMBuildFPTrunc, LLVMBuildFPExt, LLVMBuildIntCast, LLVMBuildFPCast, LLVMBuildSExtOrBitCast, LLVMBuildZExtOrBitCast, LLVMBuildTruncOrBitCast, LLVMBuildSwitch, LLVMAddCase, LLVMBuildShl, LLVMBuildAShr, LLVMBuildLShr, LLVMBuildGlobalString, LLVMBuildGlobalStringPtr, LLVMBuildExactSDiv, LLVMBuildTrunc, LLVMBuildSExt, LLVMBuildZExt, LLVMBuildSelect, LLVMBuildAddrSpaceCast, LLVMBuildBitCast, LLVMBuildShuffleVector, LLVMBuildVAArg, LLVMBuildIndirectBr, LLVMAddDestination}; |
5 | 4 | #[llvm_versions(3.9..=latest)]
|
6 | 5 | use llvm_sys::core::LLVMBuildAtomicCmpXchg;
|
7 | 6 | #[llvm_versions(8.0..=latest)]
|
8 | 7 | use llvm_sys::core::{LLVMBuildMemCpy, LLVMBuildMemMove};
|
9 | 8 | use llvm_sys::prelude::{LLVMBuilderRef, LLVMValueRef};
|
10 |
| -use llvm_sys::{LLVMTypeKind}; |
11 | 9 |
|
12 | 10 | use crate::{AtomicOrdering, AtomicRMWBinOp, IntPredicate, FloatPredicate};
|
13 | 11 | use crate::basic_block::BasicBlock;
|
14 | 12 | use crate::support::to_c_str;
|
15 |
| -use crate::values::{AggregateValue, AggregateValueEnum, AsValueRef, BasicValue, BasicValueEnum, PhiValue, FunctionValue, IntValue, PointerValue, VectorValue, InstructionValue, GlobalValue, IntMathValue, FloatMathValue, PointerMathValue, InstructionOpcode, CallSiteValue}; |
| 13 | +use crate::values::{AggregateValue, AggregateValueEnum, AsValueRef, BasicValue, BasicValueEnum, PhiValue, IntValue, PointerValue, VectorValue, InstructionValue, GlobalValue, IntMathValue, FloatMathValue, PointerMathValue, InstructionOpcode, CallSiteValue}; |
16 | 14 | #[llvm_versions(7.0..=latest)]
|
17 | 15 | use crate::debug_info::DILocation;
|
18 | 16 | #[llvm_versions(3.9..=latest)]
|
19 | 17 | use crate::values::StructValue;
|
| 18 | +use crate::values::CallableValue; |
20 | 19 | use crate::types::{AsTypeRef, BasicType, IntMathType, FloatMathType, PointerType, PointerMathType};
|
21 | 20 |
|
22 | 21 | use std::marker::PhantomData;
|
@@ -107,9 +106,11 @@ impl<'ctx> Builder<'ctx> {
|
107 | 106 | }
|
108 | 107 | }
|
109 | 108 |
|
110 |
| - /// Builds a function call instruction. It can take either a `FunctionValue` or a `PointerValue` |
111 |
| - /// which is a function pointer. It will panic if the `PointerValue` is not a function pointer. |
112 |
| - /// This may be turned into a Result in the future, however. |
| 109 | + /// Builds a function call instruction. |
| 110 | + /// [`FunctionValue`]s can be implicitly converted into a [`CallableValue`]. |
| 111 | + /// See [`CallableValue`] for details on calling a [`PointerValue`] that points to a function. |
| 112 | + /// |
| 113 | + /// [`FunctionValue`]: crate::values::FunctionValue |
113 | 114 | ///
|
114 | 115 | /// # Example
|
115 | 116 | ///
|
@@ -137,32 +138,16 @@ impl<'ctx> Builder<'ctx> {
|
137 | 138 | /// ```
|
138 | 139 | pub fn build_call<F>(&self, function: F, args: &[BasicValueEnum<'ctx>], name: &str) -> CallSiteValue<'ctx>
|
139 | 140 | where
|
140 |
| - F: Into<FunctionOrPointerValue<'ctx>>, |
| 141 | + F: Into<CallableValue<'ctx>>, |
141 | 142 | {
|
142 |
| - let fn_val_ref = match function.into() { |
143 |
| - Left(val) => val.as_value_ref(), |
144 |
| - Right(val) => { |
145 |
| - // If using a pointer value, we must validate it's a valid function ptr |
146 |
| - let value_ref = val.as_value_ref(); |
147 |
| - let ty_kind = unsafe { LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(value_ref))) }; |
148 |
| - let is_a_fn_ptr = match ty_kind { |
149 |
| - LLVMTypeKind::LLVMFunctionTypeKind => true, |
150 |
| - _ => false, |
151 |
| - }; |
152 |
| - |
153 |
| - // REVIEW: We should probably turn this into a Result? |
154 |
| - assert!(is_a_fn_ptr, "build_call called with a pointer which is not a function pointer"); |
155 |
| - |
156 |
| - value_ref |
157 |
| - }, |
158 |
| - }; |
| 143 | + let callable_value = function.into(); |
| 144 | + let fn_val_ref = callable_value.as_value_ref(); |
159 | 145 |
|
160 | 146 | // LLVM gets upset when void return calls are named because they don't return anything
|
161 |
| - let name = unsafe { |
162 |
| - match LLVMGetTypeKind(LLVMGetReturnType(LLVMGetElementType(LLVMTypeOf(fn_val_ref)))) { |
163 |
| - LLVMTypeKind::LLVMVoidTypeKind => "", |
164 |
| - _ => name, |
165 |
| - } |
| 147 | + let name = if callable_value.returns_void() { |
| 148 | + "" |
| 149 | + } else { |
| 150 | + name |
166 | 151 | };
|
167 | 152 |
|
168 | 153 | let c_string = to_c_str(name);
|
@@ -1892,17 +1877,3 @@ impl Drop for Builder<'_> {
|
1892 | 1877 | }
|
1893 | 1878 | }
|
1894 | 1879 | }
|
1895 |
| - |
1896 |
| -type FunctionOrPointerValue<'ctx> = Either<FunctionValue<'ctx>, PointerValue<'ctx>>; |
1897 |
| - |
1898 |
| -impl<'ctx> Into<FunctionOrPointerValue<'ctx>> for FunctionValue<'ctx> { |
1899 |
| - fn into(self) -> FunctionOrPointerValue<'ctx> { |
1900 |
| - Left(self) |
1901 |
| - } |
1902 |
| -} |
1903 |
| - |
1904 |
| -impl<'ctx> Into<FunctionOrPointerValue<'ctx>> for PointerValue<'ctx> { |
1905 |
| - fn into(self) -> FunctionOrPointerValue<'ctx> { |
1906 |
| - Right(self) |
1907 |
| - } |
1908 |
| -} |
0 commit comments