Skip to content

Commit 5650064

Browse files
committed
Fixed FunctionValue::get_return_type() and moved it to FunctionType
1 parent e9c3620 commit 5650064

File tree

4 files changed

+43
-17
lines changed

4 files changed

+43
-17
lines changed

src/types/fn_type.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use llvm_sys::core::{LLVMGetParamTypes, LLVMIsFunctionVarArg, LLVMCountParamTypes};
1+
use llvm_sys::LLVMTypeKind;
2+
use llvm_sys::core::{LLVMGetParamTypes, LLVMIsFunctionVarArg, LLVMCountParamTypes, LLVMGetReturnType, LLVMGetTypeKind};
23
use llvm_sys::prelude::LLVMTypeRef;
34

45
use std::fmt;
@@ -10,7 +11,6 @@ use crate::support::LLVMString;
1011
use crate::types::traits::AsTypeRef;
1112
use crate::types::{PointerType, Type, BasicTypeEnum};
1213

13-
// REVIEW: Add a get_return_type() -> Option<BasicTypeEnum>?
1414
/// A `FunctionType` is the type of a function variable.
1515
#[derive(PartialEq, Eq, Clone, Copy)]
1616
pub struct FunctionType {
@@ -167,6 +167,35 @@ impl FunctionType {
167167
self.fn_type.print_to_stderr()
168168
}
169169

170+
/// Gets the return type of this `FunctionType`.
171+
///
172+
/// # Example
173+
///
174+
/// ```no_run
175+
/// use inkwell::context::Context;
176+
///
177+
/// let context = Context::create();
178+
/// let f32_type = context.f32_type();
179+
/// let fn_type = f32_type.fn_type(&[], true);
180+
///
181+
/// assert_eq!(fn_type.get_return_type().unwrap().into_float_type(), f32_type);
182+
/// ```
183+
pub fn get_return_type(&self) -> Option<BasicTypeEnum> {
184+
let ty = unsafe {
185+
LLVMGetReturnType(self.as_type_ref())
186+
};
187+
188+
let kind = unsafe {
189+
LLVMGetTypeKind(ty)
190+
};
191+
192+
if let LLVMTypeKind::LLVMVoidTypeKind = kind {
193+
return None;
194+
}
195+
196+
Some(BasicTypeEnum::new(ty))
197+
}
198+
170199
// REVIEW: Can you do undef for functions?
171200
// Seems to "work" - no UB or SF so far but fails
172201
// LLVMIsAFunction() check. Commenting out for further research

src/values/fn_value.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use llvm_sys::analysis::{LLVMVerifierFailureAction, LLVMVerifyFunction, LLVMViewFunctionCFG, LLVMViewFunctionCFGOnly};
2-
use llvm_sys::core::{LLVMIsAFunction, LLVMIsConstant, LLVMGetLinkage, LLVMTypeOf, LLVMGetPreviousFunction, LLVMGetNextFunction, LLVMGetParam, LLVMCountParams, LLVMGetLastParam, LLVMCountBasicBlocks, LLVMGetFirstParam, LLVMGetNextParam, LLVMGetBasicBlocks, LLVMGetReturnType, LLVMAppendBasicBlock, LLVMDeleteFunction, LLVMGetElementType, LLVMGetLastBasicBlock, LLVMGetFirstBasicBlock, LLVMGetEntryBasicBlock, LLVMGetIntrinsicID, LLVMGetFunctionCallConv, LLVMSetFunctionCallConv, LLVMGetGC, LLVMSetGC, LLVMSetLinkage, LLVMSetParamAlignment, LLVMGetParams};
2+
use llvm_sys::core::{LLVMIsAFunction, LLVMIsConstant, LLVMGetLinkage, LLVMGetPreviousFunction, LLVMGetNextFunction, LLVMGetParam, LLVMCountParams, LLVMGetLastParam, LLVMCountBasicBlocks, LLVMGetFirstParam, LLVMGetNextParam, LLVMGetBasicBlocks, LLVMAppendBasicBlock, LLVMDeleteFunction, LLVMGetLastBasicBlock, LLVMGetFirstBasicBlock, LLVMGetEntryBasicBlock, LLVMGetIntrinsicID, LLVMGetFunctionCallConv, LLVMSetFunctionCallConv, LLVMGetGC, LLVMSetGC, LLVMSetLinkage, LLVMSetParamAlignment, LLVMGetParams};
33
#[llvm_versions(3.7 => latest)]
44
use llvm_sys::core::{LLVMGetPersonalityFn, LLVMSetPersonalityFn};
55
#[llvm_versions(3.9 => latest)]
@@ -15,9 +15,9 @@ use crate::attributes::Attribute;
1515
use crate::basic_block::BasicBlock;
1616
use crate::module::Linkage;
1717
use crate::support::LLVMString;
18-
use crate::types::{BasicTypeEnum, FunctionType};
18+
use crate::types::{FunctionType, PointerType};
1919
use crate::values::traits::AsValueRef;
20-
use crate::values::{BasicValueEnum, GlobalValue, Value, MetadataValue};
20+
use crate::values::{BasicValueEnum, GlobalValue, MetadataValue, Value};
2121

2222
#[derive(PartialEq, Eq, Clone, Copy, Hash)]
2323
pub struct FunctionValue {
@@ -201,14 +201,6 @@ impl FunctionValue {
201201
raw_vec.iter().map(|val| BasicBlock::new(*val).unwrap()).collect()
202202
}
203203

204-
pub fn get_return_type(&self) -> BasicTypeEnum {
205-
let type_ = unsafe {
206-
LLVMGetReturnType(LLVMGetElementType(LLVMTypeOf(self.fn_value.value)))
207-
};
208-
209-
BasicTypeEnum::new(type_)
210-
}
211-
212204
pub fn get_param_iter(&self) -> ParamValueIter {
213205
ParamValueIter {
214206
param_iter_value: self.fn_value.value,
@@ -262,7 +254,9 @@ impl FunctionValue {
262254
}
263255

264256
pub fn get_type(&self) -> FunctionType {
265-
FunctionType::new(self.fn_value.get_type())
257+
let ptr_type = PointerType::new(self.fn_value.get_type());
258+
259+
ptr_type.get_element_type().into_function_type()
266260
}
267261

268262
pub fn has_metadata(&self) -> bool {

tests/all/test_basic_block.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ fn test_get_basic_blocks() {
9797
let function = module.add_function("testing", fn_type, None);
9898

9999
assert_eq!(function.get_name(), &*CString::new("testing").unwrap());
100-
assert_eq!(function.get_return_type().into_int_type().get_bit_width(), 1);
100+
assert_eq!(fn_type.get_return_type().unwrap().into_int_type().get_bit_width(), 1);
101101

102102
assert!(function.get_last_basic_block().is_none());
103103
assert_eq!(function.get_basic_blocks().len(), 0);

tests/all/test_values.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ fn test_linkage() {
2222

2323
let function = module.add_function("free_f32", fn_type, None);
2424

25+
assert_eq!(function.get_type(), fn_type);
26+
assert!(function.get_type().get_return_type().is_none());
27+
assert!(fn_type.get_return_type().is_none());
28+
2529
assert_eq!(function.get_linkage(), External);
2630
}
2731

@@ -686,8 +690,7 @@ fn test_function_value_no_params() {
686690
let fn_type = void_type.fn_type(&[], false);
687691
let fn_value = module.add_function("no_params", fn_type, None);
688692

689-
// REVIEW: According to this, fn_value.get_type() is a void ptr??
690-
// assert_eq!(fn_value.get_type(), fn_type);
693+
assert_eq!(fn_value.get_type(), fn_type);
691694
assert_eq!(fn_value.count_params(), 0);
692695
assert_eq!(fn_value.get_param_iter().collect::<Vec<_>>().len(), 0);
693696
assert_eq!(fn_value.get_params().len(), 0);

0 commit comments

Comments
 (0)