pipeline_script/llvm/
global.rs

1use crate::context::Context;
2use crate::llvm::builder::ir::IRBuilder;
3use crate::llvm::types::LLVMType;
4use crate::llvm::value::array::ArrayValue;
5use crate::llvm::value::bool::BoolValue;
6use crate::llvm::value::double::DoubleValue;
7use crate::llvm::value::float::FloatValue;
8use crate::llvm::value::int::{Int16Value, Int32Value, Int64Value, Int8Value};
9use crate::llvm::value::LLVMValue;
10use llvm_sys::core::{
11    LLVMArrayType2, LLVMConstArray2, LLVMConstInt, LLVMConstReal, LLVMConstString,
12    LLVMCreateBuilder, LLVMDoubleType, LLVMFloatType, LLVMFunctionType, LLVMInt16Type,
13    LLVMInt1Type, LLVMInt32Type, LLVMInt64Type, LLVMInt8Type, LLVMPointerType, LLVMSizeOf,
14    LLVMStructType, LLVMVoidType,
15};
16use llvm_sys::prelude::{LLVMTypeRef, LLVMValueRef};
17use std::ffi::{c_uint, CString};
18
19pub struct Global;
20
21impl Global {
22    #[allow(unused)]
23    pub fn const_array(ctx: &Context, array: &[LLVMValue]) -> LLVMValue {
24        // 获取类型
25        let ty = array[0].get_llvm_type(ctx);
26        // 转换成LLVMValueRef
27        let mut llvm_values: Vec<LLVMValueRef> =
28            array.iter().map(|v| v.as_llvm_value_ref()).collect();
29        let a = unsafe {
30            LLVMConstArray2(
31                ty.as_llvm_type_ref(),
32                llvm_values.as_mut_ptr(),
33                llvm_values.len() as u64,
34            )
35        };
36        LLVMValue::Array(ArrayValue::new(a, ty, array.len()))
37    }
38    #[allow(unused)]
39    pub fn const_unit() -> LLVMValue {
40        LLVMValue::Unit
41    }
42    #[allow(unused)]
43    pub fn const_double(value: f64) -> DoubleValue {
44        let v = unsafe { LLVMConstReal(LLVMDoubleType(), value) };
45        DoubleValue::new(v)
46    }
47    pub fn const_float(value: f32) -> FloatValue {
48        let v = unsafe { LLVMConstReal(LLVMFloatType(), value as f64) };
49        FloatValue::new(v)
50    }
51    pub fn const_i8(value: i8) -> Int8Value {
52        let v = unsafe { LLVMConstInt(LLVMInt8Type(), value as u64, 0) };
53        Int8Value::new(v)
54    }
55    #[allow(unused)]
56    pub fn const_bool(value: bool) -> BoolValue {
57        let v = unsafe { LLVMConstInt(LLVMInt1Type(), value as u64, 0) };
58        BoolValue::new(v)
59    }
60    pub fn sizeof(ty: LLVMType) -> LLVMValue {
61        unsafe { LLVMSizeOf(ty.as_llvm_type_ref()) }.into()
62    }
63    pub fn const_i16(value: i16) -> Int16Value {
64        let v = unsafe { LLVMConstInt(LLVMInt16Type(), value as u64, 0) };
65        Int16Value::new(v)
66    }
67    pub fn const_i32(value: i32) -> Int32Value {
68        let v = unsafe { LLVMConstInt(LLVMInt32Type(), value as u64, 0) };
69        Int32Value::new(v)
70    }
71    pub fn const_i64(value: i64) -> Int64Value {
72        let v = unsafe { LLVMConstInt(LLVMInt64Type(), value as u64, 0) };
73        Int64Value::new(v)
74    }
75    pub fn i8_type() -> LLVMType {
76        let t = unsafe { LLVMInt8Type() };
77        LLVMType::Int8(t)
78    }
79    pub fn i1_type() -> LLVMType {
80        let t = unsafe { LLVMInt1Type() };
81        LLVMType::Int1(t)
82    }
83    pub fn i16_type() -> LLVMType {
84        let t = unsafe { LLVMInt16Type() };
85        LLVMType::Int16(t)
86    }
87    pub fn i32_type() -> LLVMType {
88        let t = unsafe { LLVMInt32Type() };
89        LLVMType::Int32(t)
90    }
91    pub fn i64_type() -> LLVMType {
92        let t = unsafe { LLVMInt64Type() };
93        LLVMType::Int64(t)
94    }
95    pub fn struct_type(name: String, element_type: Vec<(String, LLVMType)>) -> LLVMType {
96        let mut t = element_type
97            .iter()
98            .map(|t| t.1.as_llvm_type_ref())
99            .collect::<Vec<LLVMTypeRef>>();
100        let t = unsafe { LLVMStructType(t.as_mut_ptr(), element_type.len() as c_uint, 0) };
101        LLVMType::Struct(name, element_type, t)
102    }
103    // #[allow(unused)]
104    // pub fn const_struct(element_type: Vec<LLVMValue>) -> LLVMValue {
105    //     let mut t = element_type
106    //         .iter()
107    //         .map(|t| t.as_llvm_value_ref())
108    //         .collect::<Vec<LLVMValueRef>>();
109    //     let t = unsafe { LLVMConstStruct(t.as_mut_ptr(), element_type.len() as c_uint, 0) };
110    //     LLVMValue::Struct(t)
111    // }
112    // pub fn undef(ty: LLVMType) -> LLVMValue {
113    //     let t = unsafe { LLVMGetUndef(ty.as_llvm_type_ref()) };
114    //     LLVMValue::Undef(t)
115    // }
116    #[allow(unused)]
117    pub fn array_type(element_type: LLVMType) -> LLVMType {
118        let t = unsafe { LLVMArrayType2(element_type.as_llvm_type_ref(), 2) };
119        LLVMType::Array(Box::new(element_type), t)
120    }
121    pub fn unit_type() -> LLVMType {
122        let t = unsafe { LLVMVoidType() };
123        LLVMType::Unit(t)
124    }
125    #[allow(unused)]
126    pub fn float_type() -> LLVMType {
127        let t = unsafe { LLVMFloatType() };
128        LLVMType::Float(t)
129    }
130    #[allow(unused)]
131    pub fn double_type() -> LLVMType {
132        let t = unsafe { LLVMDoubleType() };
133        LLVMType::Double(t)
134    }
135    pub fn function_type(return_type: LLVMType, param_types: Vec<(String, LLVMType)>) -> LLVMType {
136        let mut t = param_types
137            .iter()
138            .map(|t| t.1.as_llvm_type_ref())
139            .collect::<Vec<LLVMTypeRef>>();
140        let t = unsafe {
141            LLVMFunctionType(
142                return_type.as_llvm_type_ref(),
143                t.as_mut_ptr(),
144                t.len() as c_uint,
145                0,
146            )
147        };
148        LLVMType::Function(Box::new(return_type), param_types, t)
149    }
150    pub fn function_type_with_var_arg(
151        return_type: LLVMType,
152        param_types: Vec<(String, LLVMType)>,
153    ) -> LLVMType {
154        let mut t = param_types
155            .iter()
156            .map(|t| t.1.as_llvm_type_ref())
157            .collect::<Vec<LLVMTypeRef>>();
158        let t = unsafe {
159            LLVMFunctionType(
160                return_type.as_llvm_type_ref(),
161                t.as_mut_ptr(),
162                t.len() as c_uint,
163                1,
164            )
165        };
166        LLVMType::Function(Box::new(return_type), param_types, t)
167    }
168    pub fn pointer_type(element_type: LLVMType) -> LLVMType {
169        let t = unsafe { LLVMPointerType(element_type.as_llvm_type_ref(), 0) };
170        LLVMType::Pointer(Box::new(element_type), t)
171    }
172    pub fn ref_type(element_type: LLVMType) -> LLVMType {
173        let t = unsafe { LLVMPointerType(element_type.as_llvm_type_ref(), 0) };
174        LLVMType::Ref(Box::new(element_type), t)
175    }
176    pub fn string_type() -> LLVMType {
177        let t = unsafe { LLVMPointerType(Global::i8_type().as_llvm_type_ref(), 0) };
178        LLVMType::String(t)
179    }
180    #[allow(unused)]
181    pub fn const_string(str: impl AsRef<str>) -> LLVMValue {
182        let str0 = str.as_ref();
183        let str = CString::new(str0).unwrap();
184        let c = unsafe { LLVMConstString(str.as_ptr(), str0.len() as c_uint, 0) };
185        c.into()
186    }
187    pub fn create_builder() -> IRBuilder {
188        let builder = unsafe { LLVMCreateBuilder() };
189        IRBuilder::new(builder)
190    }
191    #[allow(unused)]
192    pub fn type_of_string(s: &str) -> LLVMType {
193        match s {
194            "Int32" => Global::i32_type(),
195            "Float" => Global::float_type(),
196            "Double" => Global::double_type(),
197            // "Any"=> Global::struct_type(),
198            _ => panic!("unknown type"),
199        }
200    }
201}