1use std::ffi::CStr;
2use std::fmt::{Debug, Formatter};
3use std::ptr::null_mut;
4
5use llvm_sys::core::*;
6use llvm_sys::*;
7
8use crate::core::Message;
9use crate::owning::{OpaqueClone, OpaqueDrop, Owning};
10use crate::type_tag::*;
11use crate::*;
12
13impl<'c> Debug for Module<'c> {
14 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
15 f.write_str(self.print_to_string().to_str().unwrap())
16 }
17}
18
19impl Context {
20 pub fn create_module(&self, name: &CStr) -> Owning<Module> {
22 unsafe {
23 let ptr = LLVMModuleCreateWithNameInContext(name.as_ptr(), self.as_raw());
24 Owning::from_raw(ptr)
25 }
26 }
27}
28
29impl OpaqueClone for LLVMModule {
30 unsafe fn clone_raw(ptr: *mut Self) -> *mut Self {
31 unsafe { LLVMCloneModule(ptr) }
32 }
33}
34
35impl OpaqueDrop for LLVMModule {
36 unsafe fn drop_raw(ptr: *mut Self) {
37 unsafe { LLVMDisposeModule(ptr) }
38 }
39}
40
41impl<'c> Module<'c> {
42 pub fn get_identifier(&self) -> &[u8] {
43 unsafe {
44 let mut len = 0;
45 let ptr = LLVMGetModuleIdentifier(self.as_raw(), &mut len);
46 std::slice::from_raw_parts(ptr as _, len)
47 }
48 }
49
50 pub fn set_identifier(&self, ident: &[u8]) {
51 unsafe { LLVMSetModuleIdentifier(self.as_raw(), ident.as_ptr() as _, ident.len()) }
52 }
53
54 pub fn get_source_file_name(&self) -> &[u8] {
55 unsafe {
56 let mut len = 0;
57 let ptr = LLVMGetSourceFileName(self.as_raw(), &mut len);
58 std::slice::from_raw_parts(ptr as _, len)
59 }
60 }
61
62 pub fn set_source_file_name(&self, ident: &[u8]) {
63 unsafe { LLVMSetSourceFileName(self.as_raw(), ident.as_ptr() as _, ident.len()) }
64 }
65
66 pub fn get_data_layout_str(&self) -> &CStr {
67 unsafe { CStr::from_ptr(LLVMGetDataLayoutStr(self.as_raw())) }
68 }
69
70 pub fn set_data_layout_str(&self, data_layout_str: &CStr) {
71 unsafe { LLVMSetDataLayout(self.as_raw(), data_layout_str.as_ptr()) }
72 }
73
74 pub fn get_target(&self) -> &CStr {
75 unsafe { CStr::from_ptr(LLVMGetTarget(self.as_raw())) }
76 }
77
78 pub fn set_target(&self, triple: &CStr) {
79 unsafe { LLVMSetTarget(self.as_raw(), triple.as_ptr()) }
80 }
81
82 pub fn copy_flags_metadata(&self) -> ModuleFlagsMetadata {
83 unsafe {
84 let mut len = 0;
85 let ptr = LLVMCopyModuleFlagsMetadata(self.as_raw(), &mut len);
86 ModuleFlagsMetadata::from_raw(ptr, len)
87 }
88 }
89}
90
91impl<'m> Drop for ModuleFlagsMetadata<'m> {
92 fn drop(&mut self) {
93 unsafe { LLVMDisposeModuleFlagsMetadata(self.as_raw()) }
94 }
95}
96
97impl<'m> ModuleFlagsMetadata<'m> {
98 pub fn get_flag_behavior(&self, index: u32) -> LLVMModuleFlagBehavior {
99 assert!((index as usize) < self.len);
100 unsafe { LLVMModuleFlagEntriesGetFlagBehavior(self.as_raw() as _, index) }
101 }
102
103 pub fn get_key(&self, index: u32) -> &[u8] {
104 assert!((index as usize) < self.len);
105 unsafe {
106 let mut len = 0;
107 let ptr = LLVMModuleFlagEntriesGetKey(self.as_raw() as _, index, &mut len);
108 std::slice::from_raw_parts(ptr as _, len)
109 }
110 }
111
112 pub fn get_metadata(&self, index: u32) -> &Metadata {
113 assert!((index as usize) < self.len);
114 unsafe { Metadata::from_raw(LLVMModuleFlagEntriesGetMetadata(self.as_raw() as _, index)) }
115 }
116}
117
118impl<'c> Module<'c> {
119 pub fn get_flag(&self, key: &[u8]) -> &Metadata {
120 unsafe {
121 Metadata::from_raw(LLVMGetModuleFlag(
122 self.as_raw(),
123 key.as_ptr() as _,
124 key.len(),
125 ))
126 }
127 }
128
129 pub fn add_flag(&self, behavior: LLVMModuleFlagBehavior, key: &[u8], val: &Metadata) {
130 unsafe {
131 LLVMAddModuleFlag(
132 self.as_raw(),
133 behavior,
134 key.as_ptr() as _,
135 key.len(),
136 val.as_raw(),
137 )
138 }
139 }
140
141 pub fn dump(&self) {
142 unsafe { LLVMDumpModule(self.as_raw()) }
143 }
144
145 pub fn print_to_file(&self, filename: &CStr) -> Result<(), Message> {
146 unsafe {
147 let mut error = null_mut();
148 if LLVMPrintModuleToFile(self.as_raw(), filename.as_ptr(), &mut error) != 0 {
149 Err(Message::from_raw(error))
150 } else {
151 Ok(())
152 }
153 }
154 }
155
156 pub fn print_to_string(&self) -> Message {
157 unsafe { Message::from_raw(LLVMPrintModuleToString(self.as_raw())) }
158 }
159
160 pub fn get_inline_asm_raw(&self) -> *const [u8] {
161 unsafe {
162 let mut len = 0;
163 let ptr = LLVMGetModuleInlineAsm(self.as_raw(), &mut len);
164 std::ptr::slice_from_raw_parts(ptr as _, len)
165 }
166 }
167
168 pub fn get_inline_asm(&self) -> Vec<u8> {
169 unsafe { Vec::from(&*self.get_inline_asm_raw()) }
170 }
171
172 pub fn set_inline_asm(&self, asm: &[u8]) {
173 unsafe { LLVMSetModuleInlineAsm2(self.as_raw(), asm.as_ptr() as _, asm.len()) }
174 }
175
176 pub fn append_inline_asm(&self, asm: &[u8]) {
177 unsafe { LLVMAppendModuleInlineAsm(self.as_raw(), asm.as_ptr() as _, asm.len()) }
178 }
179}
180
181impl<T: TypeTag> Type<T> {
182 pub fn get_inline_asm(
183 &self,
184 asm_string: &[u8],
185 constraints: &[u8],
186 has_side_effects: bool,
187 is_align_stack: bool,
188 dialect: LLVMInlineAsmDialect,
189 can_throw: bool,
190 ) -> &Value<T> {
191 unsafe {
192 Value::from_raw(LLVMGetInlineAsm(
193 self.as_raw(),
194 asm_string.as_ptr() as _,
195 asm_string.len(),
196 constraints.as_ptr() as _,
197 constraints.len(),
198 has_side_effects as _,
199 is_align_stack as _,
200 dialect,
201 can_throw as _,
202 ))
203 }
204 }
205}
206
207impl<T: TypeTag> Value<T> {
208 pub fn get_inline_asm_constrain_string(&self) -> &[u8] {
209 unsafe {
210 let mut len = 0;
211 let ptr = LLVMGetInlineAsmConstraintString(self.as_raw(), &mut len);
212 std::slice::from_raw_parts(ptr as _, len)
213 }
214 }
215
216 pub fn get_inline_asm_dialect(&self) -> LLVMInlineAsmDialect {
217 unsafe { LLVMGetInlineAsmDialect(self.as_raw()) }
218 }
219
220 pub fn get_inline_asm_function_type(&self) -> &Type<T> {
221 unsafe { Type::from_raw(LLVMGetInlineAsmFunctionType(self.as_raw())) }
222 }
223
224 pub fn get_inline_asm_has_side_effects(&self) -> bool {
225 unsafe { LLVMGetInlineAsmHasSideEffects(self.as_raw()) != 0 }
226 }
227
228 pub fn get_inline_asm_needs_aligned_stack(&self) -> bool {
229 unsafe { LLVMGetInlineAsmNeedsAlignedStack(self.as_raw()) != 0 }
230 }
231
232 pub fn get_inline_asm_can_unwind(&self) -> bool {
233 unsafe { LLVMGetInlineAsmCanUnwind(self.as_raw()) != 0 }
234 }
235}
236
237impl<'c> Module<'c> {
238 pub fn context(&self) -> &'c Context {
240 unsafe { Context::from_raw(LLVMGetModuleContext(self.as_raw())) }
241 }
242
243 pub fn get_first_named_metadata(&self) -> &NamedMDNode {
244 unsafe { NamedMDNode::from_raw(LLVMGetFirstNamedMetadata(self.as_raw())) }
245 }
246
247 pub fn get_last_named_metadata(&self) -> &NamedMDNode {
248 unsafe { NamedMDNode::from_raw(LLVMGetLastNamedMetadata(self.as_raw())) }
249 }
250}
251
252impl NamedMDNode {
253 pub fn get_next(&self) -> &NamedMDNode {
254 unsafe { NamedMDNode::from_raw(LLVMGetNextNamedMetadata(self.as_raw())) }
255 }
256
257 pub fn get_previous(&self) -> &NamedMDNode {
258 unsafe { NamedMDNode::from_raw(LLVMGetPreviousNamedMetadata(self.as_raw())) }
259 }
260}
261
262impl<'c> Module<'c> {
263 pub fn get_named_metadata(&self, name: &[u8]) -> &NamedMDNode {
264 unsafe {
265 NamedMDNode::from_raw(LLVMGetNamedMetadata(
266 self.as_raw(),
267 name.as_ptr() as _,
268 name.len(),
269 ))
270 }
271 }
272
273 pub fn get_or_insert_named_metadata(&self, name: &[u8]) -> &NamedMDNode {
274 unsafe {
275 NamedMDNode::from_raw(LLVMGetOrInsertNamedMetadata(
276 self.as_raw(),
277 name.as_ptr() as _,
278 name.len(),
279 ))
280 }
281 }
282}
283
284impl NamedMDNode {
285 pub fn get_name(&self) -> &[u8] {
286 unsafe {
287 let mut len = 0;
288 let ptr = LLVMGetNamedMetadataName(self.as_raw(), &mut len);
289 std::slice::from_raw_parts(ptr as _, len)
290 }
291 }
292}
293
294impl<'c> Module<'c> {
295 pub fn get_named_metadata_num_operands(&self, name: &CStr) -> u32 {
296 unsafe { LLVMGetNamedMetadataNumOperands(self.as_raw(), name.as_ptr()) }
297 }
298
299 pub fn get_named_metadata_operands<'s>(
300 &self,
301 name: &CStr,
302 slice: &'s mut [Option<&'c Value<metadata>>],
303 ) -> &'s mut [&'c Value<metadata>] {
304 assert_eq!(
305 slice.len(),
306 self.get_named_metadata_num_operands(name) as usize
307 );
308 unsafe {
309 LLVMGetNamedMetadataOperands(self.as_raw(), name.as_ptr(), slice.as_mut_ptr() as _);
310 std::mem::transmute(slice)
311 }
312 }
313
314 pub fn add_named_metadata_operand(&self, name: &CStr, val: &Value<metadata>) {
315 unsafe { LLVMAddNamedMetadataOperand(self.as_raw(), name.as_ptr(), val.as_raw()) }
316 }
317}
318
319impl<T: TypeTag> Value<T> {
320 pub fn get_debug_loc_director(&self) -> &[u8] {
321 unsafe {
322 let mut len = 0;
323 let ptr = LLVMGetDebugLocDirectory(self.as_raw(), &mut len);
324 std::slice::from_raw_parts(ptr as _, len as _)
325 }
326 }
327
328 pub fn get_debug_loc_filename(&self) -> &[u8] {
329 unsafe {
330 let mut len = 0;
331 let ptr = LLVMGetDebugLocFilename(self.as_raw(), &mut len);
332 std::slice::from_raw_parts(ptr as _, len as _)
333 }
334 }
335
336 pub fn get_debug_loc_line(&self) -> u32 {
337 unsafe { LLVMGetDebugLocLine(self.as_raw()) }
338 }
339
340 pub fn get_debug_loc_column(&self) -> u32 {
341 unsafe { LLVMGetDebugLocColumn(self.as_raw()) }
342 }
343}
344
345impl<'c> Module<'c> {
346 pub fn add_function<T: FunTypeTag>(&self, name: &CStr, ty: &'c Type<T>) -> &'c Function<T> {
348 unsafe { Function::from_raw(LLVMAddFunction(self.as_raw(), name.as_ptr(), ty.as_raw())) }
349 }
350
351 pub fn get_named_function<T: FunTypeTag>(&self, name: &CStr) -> &'c Function<T> {
353 unsafe {
354 Function::<fun_any>::from_raw(LLVMGetNamedFunction(self.as_raw(), name.as_ptr())).cast()
355 }
356 }
357
358 pub fn get_first_function(&self) -> &'c Function<fun_any> {
359 unsafe { Function::from_raw(LLVMGetFirstFunction(self.as_raw())) }
360 }
361
362 pub fn get_last_function(&self) -> &'c Function<fun_any> {
363 unsafe { Function::from_raw(LLVMGetLastFunction(self.as_raw())) }
364 }
365}
366
367impl<T: FunTypeTag> Function<T> {
368 pub fn get_next_function(&self) -> &Function<fun_any> {
369 unsafe { Function::from_raw(LLVMGetNextFunction(self.as_raw())) }
370 }
371
372 pub fn get_previous_function(&self) -> &Function<fun_any> {
373 unsafe { Function::from_raw(LLVMGetPreviousFunction(self.as_raw())) }
374 }
375}