1use super::*;
4use super::c_api::*;
5
6use llvm_sys::bit_writer::LLVMWriteBitcodeToFile;
7use std::path::Path;
8
9pub struct Module {
11 pub(crate) module: Option<LLVMModuleRef>,
12}
13
14impl Module {
15 pub fn add_function<S>(&self, name: S, ty: Type) -> Value where S: AsRef<str> {
17 Value {
18 value: unsafe {
19 LLVMAddFunction(self.module.unwrap(), into_c(name).as_ptr(), ty.ty)
20 }
21 }
22 }
23
24 pub fn add_global<S>(&self, name: S, ty: Type) -> Value where S: AsRef<str> {
26 Value {
27 value: unsafe {
28 LLVMAddGlobal(self.module.unwrap(), ty.ty, into_c(name).as_ptr())
29 }
30 }
31 }
32
33 pub fn get_function<S>(&self, name: S) -> Value where S: AsRef<str> {
35 Value {
36 value: unsafe {
37 LLVMGetNamedFunction(self.module.unwrap(), into_c(name).as_ptr())
38 }
39 }
40 }
41
42 pub fn get_global<S>(&self, name: S) -> Value where S: AsRef<str> {
44 Value {
45 value: unsafe {
46 LLVMGetNamedGlobal(self.module.unwrap(), into_c(name).as_ptr())
47 }
48 }
49 }
50
51 pub fn set_triple<S>(&self, triple: S) where S: AsRef<str> {
53 unsafe {
54 LLVMSetTarget(self.module.unwrap(), into_c(triple).as_ptr())
55 }
56 }
57
58 pub fn set_data_layout(&self, data: &target::TargetData) {
60 unsafe {
61 LLVMSetDataLayout(self.module.unwrap(), into_c(data.to_string()).as_ptr())
62 }
63 }
64
65 pub fn functions(&self) -> iter::Functions {
67 iter::Functions {
68 pointer: Value {
69 value: unsafe {
70 LLVMGetFirstFunction(self.module.unwrap())
71 }
72 }
73 }
74 }
75
76 pub fn globals(&self) -> iter::Globals {
78 iter::Globals {
79 pointer: Value {
80 value: unsafe {
81 LLVMGetFirstGlobal(self.module.unwrap())
82 }
83 }
84 }
85 }
86
87 pub fn dump(&self) {
89 unsafe {
90 LLVMDumpModule(self.module.unwrap());
91 }
92 }
93
94 pub fn write_llvm_ir<P>(&self, path: P) where P: AsRef<Path> {
96 unsafe {
97 if LLVMPrintModuleToFile(
98 self.module.unwrap(),
99 into_c(path.as_ref()
100 .to_str()
101 .expect("path could not be converted to string")
102 ).as_ptr(),
103 vec![into_c("could not output LLVM IR for module").as_ptr() as *mut i8].as_mut_ptr(),
104 ) != 0 {
105 panic!("failed to write LLVM IR to file");
106 }
107 }
108 }
109
110 pub fn write_bitcode<P>(&self, path: P) where P: AsRef<Path> {
112 unsafe {
113 if LLVMWriteBitcodeToFile(
114 self.module.unwrap(),
115 into_c(path.as_ref()
116 .to_str()
117 .expect("path could not be converted to string")
118 ).as_ptr()
119 ) != 0 {
120 panic!("failed to write bitcode to file");
121 }
122 }
123 }
124
125 pub fn inner(&self) -> LLVMModuleRef {
127 self.module.unwrap()
128 }
129
130 pub unsafe fn into_inner(mut self) -> LLVMModuleRef {
132 self.module.take().unwrap()
133 }
134}
135
136impl Deref for Module {
137 type Target = LLVMModuleRef;
138
139 fn deref(&self) -> &LLVMModuleRef {
140 self.module.as_ref().unwrap()
141 }
142}
143
144impl Drop for Module {
145 fn drop(&mut self) {
146 if let Some(module) = self.module {
147 unsafe {
148 LLVMDisposeModule(module);
149 }
150 }
151 }
152}
153
154impl Debug for Module {
155 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156 write!(f, "Module")
157 }
158}