pipeline_script/llvm/
function.rs

1use crate::llvm::types::LLVMType;
2use crate::llvm::value::LLVMValue;
3use llvm_sys::core::{LLVMAppendBasicBlock, LLVMGetParam, LLVMSetGC};
4use llvm_sys::prelude::{LLVMBasicBlockRef, LLVMValueRef};
5use std::ffi::CString;
6
7#[derive(Clone, Debug)]
8pub struct Function {
9    function_ref: LLVMValueRef,
10    declaration: LLVMType,
11    param_names: Vec<String>,
12}
13
14impl Function {
15    pub(crate) fn new(
16        declaration: LLVMType,
17        function_ref: LLVMValueRef,
18        param_names: Vec<String>,
19    ) -> Self {
20        Self {
21            function_ref,
22            declaration,
23            param_names,
24        }
25    }
26    pub fn set_gc(&self, name: impl AsRef<str>) {
27        let cstr = CString::new(name.as_ref()).unwrap();
28        unsafe {
29            LLVMSetGC(self.function_ref, cstr.as_ptr());
30        }
31    }
32    pub fn has_param_name(&self, name: &str) -> bool {
33        self.param_names.contains(&name.to_string())
34    }
35
36    pub fn get_param_index(&self, name: &str) -> Option<usize> {
37        for (index, param_name) in self.param_names.iter().enumerate() {
38            if param_name == name {
39                return Some(index);
40            }
41        }
42        None
43    }
44    pub fn append_basic_block(&self, name: impl AsRef<str>) -> LLVMBasicBlockRef {
45        let name = name.as_ref();
46        let name = CString::new(name).unwrap();
47        unsafe { LLVMAppendBasicBlock(self.function_ref, name.as_ptr()) }
48    }
49    pub fn get_param(&self, name: &str) -> Option<LLVMValue> {
50        let index = self.get_param_index(name);
51        index.map(|index| unsafe { LLVMGetParam(self.function_ref, index as u32) }.into())
52    }
53    pub fn get_function_ref(&self) -> LLVMValueRef {
54        self.function_ref
55    }
56    pub fn get_declaration(&self) -> LLVMType {
57        self.declaration.clone()
58    }
59    pub fn as_ref(&self) -> LLVMValueRef {
60        self.function_ref
61    }
62}