vicis_core/ir/function/
mod.rs

1pub mod basic_block;
2pub mod builder;
3pub mod data;
4pub mod instruction;
5pub mod layout;
6pub mod param_attrs;
7pub mod parser;
8pub mod print;
9
10pub use parser::parse;
11
12use super::{
13    module::{
14        attributes::Attribute, linkage::Linkage, name::Name,
15        preemption_specifier::PreemptionSpecifier, unnamed_addr::UnnamedAddr,
16        visibility::Visibility,
17    },
18    types::{Type, Types},
19    value::ConstantData,
20};
21use crate::traits::basic_block::{BasicBlockData, BasicBlockLayout};
22use basic_block::BasicBlock;
23use id_arena::Id;
24use instruction::InstructionId;
25use param_attrs::ParameterAttribute;
26use std::fmt;
27
28pub type FunctionId = Id<Function>;
29
30pub type PersonalityFunc = (Type, ConstantData);
31
32pub struct Function {
33    pub name: String,
34    pub is_var_arg: bool,
35    pub result_ty: Type,
36    pub params: Vec<Parameter>,
37    pub linkage: Linkage,
38    pub preemption_specifier: PreemptionSpecifier,
39    pub visibility: Visibility,
40    pub unnamed_addr: Option<UnnamedAddr>,
41    pub func_attrs: Vec<Attribute>,
42    pub ret_attrs: Vec<param_attrs::ParameterAttribute>,
43    pub personality: Option<PersonalityFunc>,
44    pub data: data::Data,
45    pub layout: layout::Layout,
46    pub types: Types,
47    // pub is_prototype: bool,
48}
49
50#[derive(Debug, Clone)]
51pub struct Parameter {
52    pub name: Name,
53    pub ty: Type,
54    pub attrs: Vec<ParameterAttribute>,
55}
56
57impl Function {
58    pub fn new<T: AsRef<str>>(
59        name: T,
60        result_ty: Type,
61        params: Vec<Parameter>,
62        is_var_arg: bool,
63        types: Types,
64    ) -> Self {
65        Self {
66            name: name.as_ref().to_string(),
67            is_var_arg,
68            result_ty,
69            params,
70            linkage: Linkage::Common,
71            preemption_specifier: PreemptionSpecifier::DsoLocal,
72            visibility: Visibility::Default,
73            unnamed_addr: None,
74            func_attrs: vec![],
75            ret_attrs: vec![],
76            personality: None,
77            data: data::Data::default(),
78            layout: layout::Layout::default(),
79            types,
80        }
81    }
82
83    pub fn name(&self) -> &String {
84        &self.name
85    }
86
87    pub fn params(&self) -> &[Parameter] {
88        &self.params
89    }
90
91    pub fn is_var_arg(&self) -> bool {
92        self.is_var_arg
93    }
94
95    pub fn is_prototype(&self) -> bool {
96        self.layout.is_empty()
97    }
98
99    pub fn remove_inst(&mut self, inst: InstructionId) -> Option<()> {
100        self.data.remove_uses(inst);
101        self.layout.remove_inst(inst)
102    }
103}
104
105impl fmt::Debug for Function {
106    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107        print::FunctionAsmPrinter::new(f).print(self)
108    }
109}
110
111impl Parameter {
112    pub fn new(ty: Type) -> Self {
113        Self {
114            name: Name::Number(0),
115            ty,
116            attrs: vec![],
117        }
118    }
119
120    pub fn to_string(&self, types: &Types) -> String {
121        format!("{} %{:?}", types.to_string(self.ty), self.name)
122    }
123}
124
125impl BasicBlockData<BasicBlock> for Function {
126    fn get(&self, id: Id<BasicBlock>) -> &BasicBlock {
127        &self.data.basic_blocks[id]
128    }
129}
130
131impl BasicBlockLayout<BasicBlock> for Function {
132    fn order(&self) -> Box<dyn Iterator<Item = Id<BasicBlock>> + '_> {
133        Box::new(self.layout.block_iter())
134    }
135}