|
| 1 | +/// 为以后codegen逻辑完全分离作准备,此包代码应该遵循以下原则: |
| 2 | +/// 1. 所有Builder的字段都应该private,不应该被外部直接访问 |
| 3 | +/// 2. 所有涉及llvm类型的函数(包括参数或返回值)都应该是private的 |
| 4 | +pub mod llvmbuilder; |
| 5 | +use std::{ |
| 6 | + cell::{Cell, RefCell}, |
| 7 | + path::Path, |
| 8 | + rc::Rc, |
| 9 | +}; |
| 10 | + |
| 11 | +use inkwell::{ |
| 12 | + basic_block::BasicBlock, |
| 13 | + builder::Builder, |
| 14 | + context::Context, |
| 15 | + debug_info::*, |
| 16 | + module::{Linkage, Module}, |
| 17 | + targets::TargetMachine, |
| 18 | + types::{ArrayType, BasicType, BasicTypeEnum, StructType}, |
| 19 | + values::{ |
| 20 | + AnyValue, AnyValueEnum, BasicMetadataValueEnum, BasicValue, BasicValueEnum, FunctionValue, |
| 21 | + PointerValue, |
| 22 | + }, |
| 23 | + AddressSpace, FloatPredicate, IntPredicate, |
| 24 | +}; |
| 25 | +use rustc_hash::FxHashMap; |
| 26 | + |
| 27 | +use super::{ |
| 28 | + ctx::{Ctx, MemberType, PLDiag}, |
| 29 | + diag::ErrorCode, |
| 30 | + node::{types::TypedIdentifierNode, TypeNode, TypeNodeEnum}, |
| 31 | + pltype::{ARRType, FNType, Field, PLType, PriType, RetTypeEnum, STType}, |
| 32 | + range::{Pos, Range}, |
| 33 | +}; |
| 34 | + |
| 35 | + |
| 36 | +pub trait IRBuilder<'a, 'ctx> { |
| 37 | + fn get_global_var_handle(&self, name: &str) -> Option<ValueHandle>; |
| 38 | + fn new_subscope(&self, start: Pos); |
| 39 | + fn add_global( |
| 40 | + &self, |
| 41 | + name: &str, |
| 42 | + pltype: Rc<RefCell<PLType>>, |
| 43 | + ctx: &mut Ctx<'a>, |
| 44 | + line: u32, |
| 45 | + pltp: &PLType, |
| 46 | + ) -> ValueHandle; |
| 47 | + fn alloc_vtp(&self, name: &str, v: ValueHandle) -> ValueHandle; |
| 48 | + fn alloc(&self, name: &str, pltype: &PLType, ctx: &mut Ctx<'a>) -> ValueHandle; |
| 49 | + fn build_conditional_branch( |
| 50 | + &self, |
| 51 | + cond: ValueHandle, |
| 52 | + then_bb: BlockHandle, |
| 53 | + else_bb: BlockHandle, |
| 54 | + ); |
| 55 | + fn build_const_in_bounds_gep(&self, ptr: ValueHandle, index: &[u64], name: &str) |
| 56 | + -> ValueHandle; |
| 57 | + fn build_dbg_location(&self, pos: Pos); |
| 58 | + fn build_in_bounds_gep( |
| 59 | + &self, |
| 60 | + ptr: ValueHandle, |
| 61 | + index: &[ValueHandle], |
| 62 | + name: &str, |
| 63 | + ) -> ValueHandle; |
| 64 | + fn build_return(&self, v: Option<ValueHandle>); |
| 65 | + fn build_store(&self, ptr: ValueHandle, value: ValueHandle); |
| 66 | + fn build_struct_gep( |
| 67 | + &self, |
| 68 | + structv: ValueHandle, |
| 69 | + index: u32, |
| 70 | + name: &str, |
| 71 | + ) -> Result<ValueHandle, ()>; |
| 72 | + fn build_sub_program( |
| 73 | + &self, |
| 74 | + paralist: Vec<Box<TypedIdentifierNode>>, |
| 75 | + ret: Box<TypeNodeEnum>, |
| 76 | + fntype: &FNType, |
| 77 | + fnvalue: ValueHandle, |
| 78 | + child: &mut Ctx<'a>, |
| 79 | + ) -> Result<(), PLDiag>; |
| 80 | + fn clear_insertion_position(&self); |
| 81 | + fn const_string(&self, s: &str) -> ValueHandle; |
| 82 | + fn create_parameter_variable( |
| 83 | + &self, |
| 84 | + fntype: &FNType, |
| 85 | + pos: Pos, |
| 86 | + i: usize, |
| 87 | + child: &mut Ctx<'a>, |
| 88 | + fnvalue: ValueHandle, |
| 89 | + alloca: ValueHandle, |
| 90 | + allocab: BlockHandle, |
| 91 | + ); |
| 92 | + fn delete_block(&self, b: BlockHandle); |
| 93 | + fn finalize_debug(&self); |
| 94 | + fn float_value(&self, ty: &PriType, v: f64) -> ValueHandle; |
| 95 | + fn get_first_basic_block(&self, v: ValueHandle) -> BlockHandle; |
| 96 | + fn get_first_instruction(&self, bb: BlockHandle) -> Option<ValueHandle>; |
| 97 | + fn get_last_basic_block(&self, v: ValueHandle) -> BlockHandle; |
| 98 | + fn insert_var_declare( |
| 99 | + &self, |
| 100 | + name: &str, |
| 101 | + pos: Pos, |
| 102 | + pltype: &PLType, |
| 103 | + v: ValueHandle, |
| 104 | + ctx: &mut Ctx<'a>, |
| 105 | + ); |
| 106 | + fn int_value(&self, ty: &PriType, v: u64, sign_ext: bool) -> ValueHandle; |
| 107 | + fn position_at(&self, v: ValueHandle); |
| 108 | + fn print_to_file(&self, file: &Path) -> Result<(), String>; |
| 109 | + fn rm_curr_debug_location(&self); |
| 110 | + fn try_set_fn_dbg(&self, pos: Pos, f: ValueHandle); |
| 111 | + fn write_bitcode_to_path(&self, path: &Path) -> bool; |
| 112 | + fn build_unconditional_branch(&self, bb: BlockHandle); |
| 113 | + fn position_at_end_block(&self, block: BlockHandle); |
| 114 | + fn add_body_to_struct_type(&self, name: &str, order_fields: &[Field], ctx: &mut Ctx<'a>); |
| 115 | + fn get_or_insert_fn_handle(&self, pltp: &FNType, ctx: &mut Ctx<'a>) -> ValueHandle; |
| 116 | + fn mv2heap(&self, val: ValueHandle, ctx: &mut Ctx<'a>) -> ValueHandle; |
| 117 | + fn gc_add_root(&self, stackptr: BasicValueEnum<'ctx>, ctx: &mut Ctx<'a>); |
| 118 | + fn gc_rm_root(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>); |
| 119 | + fn gc_rm_root_current(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>); |
| 120 | + fn gc_collect(&self, ctx: &mut Ctx<'a>); |
| 121 | + fn get_or_add_global( |
| 122 | + &self, |
| 123 | + name: &str, |
| 124 | + pltype: Rc<RefCell<PLType>>, |
| 125 | + ctx: &mut Ctx<'a>, |
| 126 | + ) -> ValueHandle; |
| 127 | + fn build_load(&self, ptr: ValueHandle, name: &str) -> ValueHandle; |
| 128 | + fn try_load2var( |
| 129 | + &self, |
| 130 | + range: Range, |
| 131 | + v: ValueHandle, |
| 132 | + tp: Rc<RefCell<PLType>>, |
| 133 | + ctx: &mut Ctx<'a>, |
| 134 | + ) -> Result<(ValueHandle, Rc<RefCell<PLType>>), PLDiag>; |
| 135 | + fn get_function(&self, name: &str) -> Option<ValueHandle>; |
| 136 | + fn build_call(&self, f: ValueHandle, args: &[ValueHandle]) -> Option<ValueHandle>; |
| 137 | + fn add_function( |
| 138 | + &self, |
| 139 | + name: &str, |
| 140 | + paramtps: &[PLType], |
| 141 | + ret: PLType, |
| 142 | + ctx: &mut Ctx<'a>, |
| 143 | + ) -> ValueHandle; |
| 144 | + fn opaque_struct_type(&self, name: &str); |
| 145 | + fn build_int_z_extend(&self, v: ValueHandle, ty: &PriType, name: &str) -> ValueHandle; |
| 146 | + fn build_or(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 147 | + fn build_and(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 148 | + fn build_float_compare( |
| 149 | + &self, |
| 150 | + op: FloatPredicate, |
| 151 | + lhs: ValueHandle, |
| 152 | + rhs: ValueHandle, |
| 153 | + name: &str, |
| 154 | + ) -> ValueHandle; |
| 155 | + fn build_int_compare( |
| 156 | + &self, |
| 157 | + op: IntPredicate, |
| 158 | + lhs: ValueHandle, |
| 159 | + rhs: ValueHandle, |
| 160 | + name: &str, |
| 161 | + ) -> ValueHandle; |
| 162 | + fn build_int_add(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 163 | + fn build_int_sub(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 164 | + fn build_int_mul(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 165 | + fn build_int_signed_div(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 166 | + fn build_float_neg(&self, v: ValueHandle, name: &str) -> ValueHandle; |
| 167 | + fn build_float_add(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 168 | + fn build_float_sub(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 169 | + fn build_float_mul(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 170 | + fn build_float_div(&self, lhs: ValueHandle, rhs: ValueHandle, name: &str) -> ValueHandle; |
| 171 | + fn append_basic_block(&self, func: ValueHandle, name: &str) -> BlockHandle; |
| 172 | + fn build_int_truncate(&self, v: ValueHandle, dest_ty: &PriType, name: &str) -> ValueHandle; |
| 173 | + fn build_int_neg(&self, v: ValueHandle, name: &str) -> ValueHandle; |
| 174 | +} |
| 175 | + |
| 176 | + |
| 177 | +pub type ValueHandle = usize; |
| 178 | +pub type BlockHandle = usize; |
| 179 | + |
0 commit comments