vicis_core/ir/function/
mod.rs1pub 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 }
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}