Coverage Report

Created: 2024-10-16 07:58

/rust/registry/src/index.crates.io-6f17d22bba15001f/inkwell-0.1.1/src/values/fn_value.rs
Line
Count
Source (jump to first uncovered line)
1
use llvm_sys::analysis::{LLVMVerifierFailureAction, LLVMVerifyFunction, LLVMViewFunctionCFG, LLVMViewFunctionCFGOnly};
2
use llvm_sys::core::{
3
    LLVMAddAttributeAtIndex, LLVMGetAttributeCountAtIndex, LLVMGetEnumAttributeAtIndex, LLVMGetStringAttributeAtIndex,
4
    LLVMRemoveEnumAttributeAtIndex, LLVMRemoveStringAttributeAtIndex,
5
};
6
use llvm_sys::core::{
7
    LLVMCountBasicBlocks, LLVMCountParams, LLVMDeleteFunction, LLVMGetBasicBlocks, LLVMGetFirstBasicBlock,
8
    LLVMGetFirstParam, LLVMGetFunctionCallConv, LLVMGetGC, LLVMGetIntrinsicID, LLVMGetLastBasicBlock, LLVMGetLastParam,
9
    LLVMGetLinkage, LLVMGetNextFunction, LLVMGetNextParam, LLVMGetParam, LLVMGetParams, LLVMGetPreviousFunction,
10
    LLVMIsAFunction, LLVMIsConstant, LLVMSetFunctionCallConv, LLVMSetGC, LLVMSetLinkage, LLVMSetParamAlignment,
11
};
12
use llvm_sys::core::{LLVMGetPersonalityFn, LLVMSetPersonalityFn};
13
#[llvm_versions(7.0..=latest)]
14
use llvm_sys::debuginfo::{LLVMGetSubprogram, LLVMSetSubprogram};
15
use llvm_sys::prelude::{LLVMBasicBlockRef, LLVMValueRef};
16
17
use std::ffi::CStr;
18
use std::fmt::{self, Display};
19
use std::marker::PhantomData;
20
use std::mem::forget;
21
22
use crate::attributes::{Attribute, AttributeLoc};
23
use crate::basic_block::BasicBlock;
24
#[llvm_versions(7.0..=latest)]
25
use crate::debug_info::DISubprogram;
26
use crate::module::Linkage;
27
use crate::support::to_c_str;
28
use crate::types::FunctionType;
29
use crate::values::traits::{AnyValue, AsValueRef};
30
use crate::values::{BasicValueEnum, GlobalValue, Value};
31
32
#[derive(PartialEq, Eq, Clone, Copy, Hash)]
33
pub struct FunctionValue<'ctx> {
34
    fn_value: Value<'ctx>,
35
}
36
37
impl<'ctx> FunctionValue<'ctx> {
38
15.4M
    pub(crate) unsafe fn new(value: LLVMValueRef) -> Option<Self> {
39
15.4M
        if value.is_null() {
40
0
            return None;
41
15.4M
        }
42
15.4M
43
15.4M
        assert!(!LLVMIsAFunction(value).is_null());
44
45
15.4M
        Some(FunctionValue {
46
15.4M
            fn_value: Value::new(value),
47
15.4M
        })
48
15.4M
    }
49
50
0
    pub fn get_linkage(self) -> Linkage {
51
0
        unsafe { LLVMGetLinkage(self.as_value_ref()).into() }
52
0
    }
53
54
425k
    pub fn set_linkage(self, linkage: Linkage) {
55
425k
        unsafe { LLVMSetLinkage(self.as_value_ref(), linkage.into()) }
56
425k
    }
57
58
0
    pub fn is_null(self) -> bool {
59
0
        self.fn_value.is_null()
60
0
    }
61
62
0
    pub fn is_undef(self) -> bool {
63
0
        self.fn_value.is_undef()
64
0
    }
65
66
0
    pub fn print_to_stderr(self) {
67
0
        self.fn_value.print_to_stderr()
68
0
    }
69
70
    // FIXME: Better error returns, code 1 is error
71
0
    pub fn verify(self, print: bool) -> bool {
72
0
        let action = if print {
73
0
            LLVMVerifierFailureAction::LLVMPrintMessageAction
74
        } else {
75
0
            LLVMVerifierFailureAction::LLVMReturnStatusAction
76
        };
77
78
0
        let code = unsafe { LLVMVerifyFunction(self.fn_value.value, action) };
79
0
80
0
        code != 1
81
0
    }
82
83
    // REVIEW: If there's a demand, could easily create a module.get_functions() -> Iterator
84
0
    pub fn get_next_function(self) -> Option<Self> {
85
0
        unsafe { FunctionValue::new(LLVMGetNextFunction(self.as_value_ref())) }
86
0
    }
87
88
0
    pub fn get_previous_function(self) -> Option<Self> {
89
0
        unsafe { FunctionValue::new(LLVMGetPreviousFunction(self.as_value_ref())) }
90
0
    }
91
92
9.76k
    pub fn get_first_param(self) -> Option<BasicValueEnum<'ctx>> {
93
9.76k
        let param = unsafe { LLVMGetFirstParam(self.as_value_ref()) };
94
9.76k
95
9.76k
        if param.is_null() {
96
0
            return None;
97
9.76k
        }
98
9.76k
99
9.76k
        unsafe { Some(BasicValueEnum::new(param)) }
100
9.76k
    }
101
102
0
    pub fn get_last_param(self) -> Option<BasicValueEnum<'ctx>> {
103
0
        let param = unsafe { LLVMGetLastParam(self.as_value_ref()) };
104
0
105
0
        if param.is_null() {
106
0
            return None;
107
0
        }
108
0
109
0
        unsafe { Some(BasicValueEnum::new(param)) }
110
0
    }
111
112
0
    pub fn get_first_basic_block(self) -> Option<BasicBlock<'ctx>> {
113
0
        unsafe { BasicBlock::new(LLVMGetFirstBasicBlock(self.as_value_ref())) }
114
0
    }
115
116
514k
    pub fn get_nth_param(self, nth: u32) -> Option<BasicValueEnum<'ctx>> {
117
514k
        let count = self.count_params();
118
514k
119
514k
        if nth + 1 > count {
120
0
            return None;
121
514k
        }
122
514k
123
514k
        unsafe { Some(BasicValueEnum::new(LLVMGetParam(self.as_value_ref(), nth))) }
124
514k
    }
125
126
572k
    pub fn count_params(self) -> u32 {
127
572k
        unsafe { LLVMCountParams(self.fn_value.value) }
128
572k
    }
129
130
0
    pub fn count_basic_blocks(self) -> u32 {
131
0
        unsafe { LLVMCountBasicBlocks(self.as_value_ref()) }
132
0
    }
133
134
0
    pub fn get_basic_blocks(self) -> Vec<BasicBlock<'ctx>> {
135
0
        let count = self.count_basic_blocks();
136
0
        let mut raw_vec: Vec<LLVMBasicBlockRef> = Vec::with_capacity(count as usize);
137
0
        let ptr = raw_vec.as_mut_ptr();
138
0
139
0
        forget(raw_vec);
140
0
141
0
        let raw_vec = unsafe {
142
0
            LLVMGetBasicBlocks(self.as_value_ref(), ptr);
143
0
144
0
            Vec::from_raw_parts(ptr, count as usize, count as usize)
145
0
        };
146
0
147
0
        raw_vec
148
0
            .iter()
149
0
            .map(|val| unsafe { BasicBlock::new(*val).unwrap() })
150
0
            .collect()
151
0
    }
152
153
0
    pub fn get_param_iter(self) -> ParamValueIter<'ctx> {
154
0
        ParamValueIter {
155
0
            param_iter_value: self.fn_value.value,
156
0
            start: true,
157
0
            _marker: PhantomData,
158
0
        }
159
0
    }
160
161
57.2k
    pub fn get_params(self) -> Vec<BasicValueEnum<'ctx>> {
162
57.2k
        let count = self.count_params();
163
57.2k
        let mut raw_vec: Vec<LLVMValueRef> = Vec::with_capacity(count as usize);
164
57.2k
        let ptr = raw_vec.as_mut_ptr();
165
57.2k
166
57.2k
        forget(raw_vec);
167
57.2k
168
57.2k
        let raw_vec = unsafe {
169
57.2k
            LLVMGetParams(self.as_value_ref(), ptr);
170
57.2k
171
57.2k
            Vec::from_raw_parts(ptr, count as usize, count as usize)
172
57.2k
        };
173
57.2k
174
171k
        raw_vec.iter().map(|val| unsafe { BasicValueEnum::new(*val) }).collect()
175
57.2k
    }
176
177
0
    pub fn get_last_basic_block(self) -> Option<BasicBlock<'ctx>> {
178
0
        unsafe { BasicBlock::new(LLVMGetLastBasicBlock(self.fn_value.value)) }
179
0
    }
180
181
    /// Gets the name of a `FunctionValue`.
182
0
    pub fn get_name(&self) -> &CStr {
183
0
        self.fn_value.get_name()
184
0
    }
185
186
    /// View the control flow graph and produce a .dot file
187
0
    pub fn view_function_cfg(self) {
188
0
        unsafe { LLVMViewFunctionCFG(self.as_value_ref()) }
189
0
    }
190
191
    /// Only view the control flow graph
192
0
    pub fn view_function_cfg_only(self) {
193
0
        unsafe { LLVMViewFunctionCFGOnly(self.as_value_ref()) }
194
0
    }
195
196
    // TODO: Look for ways to prevent use after delete but maybe not possible
197
0
    pub unsafe fn delete(self) {
198
0
        LLVMDeleteFunction(self.as_value_ref())
199
0
    }
200
201
    #[llvm_versions(4.0..=7.0)]
202
    pub fn get_type(self) -> FunctionType<'ctx> {
203
        use crate::types::PointerType;
204
205
        let ptr_type = unsafe { PointerType::new(self.fn_value.get_type()) };
206
207
        ptr_type.get_element_type().into_function_type()
208
    }
209
210
    #[llvm_versions(8.0..=latest)]
211
661k
    pub fn get_type(self) -> FunctionType<'ctx> {
212
661k
        unsafe { FunctionType::new(llvm_sys::core::LLVMGlobalGetValueType(self.as_value_ref())) }
213
661k
    }
214
215
    // TODOC: How this works as an exception handler
216
0
    pub fn has_personality_function(self) -> bool {
217
0
        use llvm_sys::core::LLVMHasPersonalityFn;
218
0
219
0
        unsafe { LLVMHasPersonalityFn(self.as_value_ref()) == 1 }
220
0
    }
221
222
0
    pub fn get_personality_function(self) -> Option<FunctionValue<'ctx>> {
223
0
        // This prevents a segfault when not having a pfn
224
0
        if !self.has_personality_function() {
225
0
            return None;
226
0
        }
227
0
228
0
        unsafe { FunctionValue::new(LLVMGetPersonalityFn(self.as_value_ref())) }
229
0
    }
230
231
101k
    pub fn set_personality_function(self, personality_fn: FunctionValue<'ctx>) {
232
101k
        unsafe { LLVMSetPersonalityFn(self.as_value_ref(), personality_fn.as_value_ref()) }
233
101k
    }
234
235
0
    pub fn get_intrinsic_id(self) -> u32 {
236
0
        unsafe { LLVMGetIntrinsicID(self.as_value_ref()) }
237
0
    }
238
239
0
    pub fn get_call_conventions(self) -> u32 {
240
0
        unsafe { LLVMGetFunctionCallConv(self.as_value_ref()) }
241
0
    }
242
243
0
    pub fn set_call_conventions(self, call_conventions: u32) {
244
0
        unsafe { LLVMSetFunctionCallConv(self.as_value_ref(), call_conventions) }
245
0
    }
246
247
0
    pub fn get_gc(&self) -> &CStr {
248
0
        unsafe { CStr::from_ptr(LLVMGetGC(self.as_value_ref())) }
249
0
    }
250
251
0
    pub fn set_gc(self, gc: &str) {
252
0
        let c_string = to_c_str(gc);
253
0
254
0
        unsafe { LLVMSetGC(self.as_value_ref(), c_string.as_ptr()) }
255
0
    }
256
257
0
    pub fn replace_all_uses_with(self, other: FunctionValue<'ctx>) {
258
0
        self.fn_value.replace_all_uses_with(other.as_value_ref())
259
0
    }
260
261
    /// Adds an `Attribute` to a particular location in this `FunctionValue`.
262
    ///
263
    /// # Example
264
    ///
265
    /// ```no_run
266
    /// use inkwell::attributes::AttributeLoc;
267
    /// use inkwell::context::Context;
268
    ///
269
    /// let context = Context::create();
270
    /// let module = context.create_module("my_mod");
271
    /// let void_type = context.void_type();
272
    /// let fn_type = void_type.fn_type(&[], false);
273
    /// let fn_value = module.add_function("my_fn", fn_type, None);
274
    /// let string_attribute = context.create_string_attribute("my_key", "my_val");
275
    /// let enum_attribute = context.create_enum_attribute(1, 1);
276
    ///
277
    /// fn_value.add_attribute(AttributeLoc::Return, string_attribute);
278
    /// fn_value.add_attribute(AttributeLoc::Return, enum_attribute);
279
    /// ```
280
754k
    pub fn add_attribute(self, loc: AttributeLoc, attribute: Attribute) {
281
754k
        unsafe { LLVMAddAttributeAtIndex(self.as_value_ref(), loc.get_index(), attribute.attribute) }
282
754k
    }
283
284
    /// Counts the number of `Attribute`s belonging to the specified location in this `FunctionValue`.
285
    ///
286
    /// # Example
287
    ///
288
    /// ```no_run
289
    /// use inkwell::attributes::AttributeLoc;
290
    /// use inkwell::context::Context;
291
    ///
292
    /// let context = Context::create();
293
    /// let module = context.create_module("my_mod");
294
    /// let void_type = context.void_type();
295
    /// let fn_type = void_type.fn_type(&[], false);
296
    /// let fn_value = module.add_function("my_fn", fn_type, None);
297
    /// let string_attribute = context.create_string_attribute("my_key", "my_val");
298
    /// let enum_attribute = context.create_enum_attribute(1, 1);
299
    ///
300
    /// fn_value.add_attribute(AttributeLoc::Return, string_attribute);
301
    /// fn_value.add_attribute(AttributeLoc::Return, enum_attribute);
302
    ///
303
    /// assert_eq!(fn_value.count_attributes(AttributeLoc::Return), 2);
304
    /// ```
305
0
    pub fn count_attributes(self, loc: AttributeLoc) -> u32 {
306
0
        unsafe { LLVMGetAttributeCountAtIndex(self.as_value_ref(), loc.get_index()) }
307
0
    }
308
309
    /// Get all `Attribute`s belonging to the specified location in this `FunctionValue`.
310
    ///
311
    /// # Example
312
    ///
313
    /// ```no_run
314
    /// use inkwell::attributes::AttributeLoc;
315
    /// use inkwell::context::Context;
316
    ///
317
    /// let context = Context::create();
318
    /// let module = context.create_module("my_mod");
319
    /// let void_type = context.void_type();
320
    /// let fn_type = void_type.fn_type(&[], false);
321
    /// let fn_value = module.add_function("my_fn", fn_type, None);
322
    /// let string_attribute = context.create_string_attribute("my_key", "my_val");
323
    /// let enum_attribute = context.create_enum_attribute(1, 1);
324
    ///
325
    /// fn_value.add_attribute(AttributeLoc::Return, string_attribute);
326
    /// fn_value.add_attribute(AttributeLoc::Return, enum_attribute);
327
    ///
328
    /// assert_eq!(fn_value.attributes(AttributeLoc::Return), vec![string_attribute, enum_attribute]);
329
    /// ```
330
0
    pub fn attributes(self, loc: AttributeLoc) -> Vec<Attribute> {
331
0
        use llvm_sys::core::LLVMGetAttributesAtIndex;
332
0
        use std::mem::{ManuallyDrop, MaybeUninit};
333
0
334
0
        let count = self.count_attributes(loc) as usize;
335
0
336
0
        // initialize a vector, but leave each element uninitialized
337
0
        let mut attribute_refs: Vec<MaybeUninit<Attribute>> = vec![MaybeUninit::uninit(); count];
338
0
339
0
        // Safety: relies on `Attribute` having the same in-memory representation as `LLVMAttributeRef`
340
0
        unsafe {
341
0
            LLVMGetAttributesAtIndex(
342
0
                self.as_value_ref(),
343
0
                loc.get_index(),
344
0
                attribute_refs.as_mut_ptr() as *mut _,
345
0
            )
346
0
        }
347
0
348
0
        // Safety: all elements are initialized
349
0
        unsafe {
350
0
            // ensure the vector is not dropped
351
0
            let mut attribute_refs = ManuallyDrop::new(attribute_refs);
352
0
353
0
            Vec::from_raw_parts(
354
0
                attribute_refs.as_mut_ptr() as *mut Attribute,
355
0
                attribute_refs.len(),
356
0
                attribute_refs.capacity(),
357
0
            )
358
0
        }
359
0
    }
360
361
    /// Removes a string `Attribute` belonging to the specified location in this `FunctionValue`.
362
    ///
363
    /// # Example
364
    ///
365
    /// ```no_run
366
    /// use inkwell::attributes::AttributeLoc;
367
    /// use inkwell::context::Context;
368
    ///
369
    /// let context = Context::create();
370
    /// let module = context.create_module("my_mod");
371
    /// let void_type = context.void_type();
372
    /// let fn_type = void_type.fn_type(&[], false);
373
    /// let fn_value = module.add_function("my_fn", fn_type, None);
374
    /// let string_attribute = context.create_string_attribute("my_key", "my_val");
375
    ///
376
    /// fn_value.add_attribute(AttributeLoc::Return, string_attribute);
377
    /// fn_value.remove_string_attribute(AttributeLoc::Return, "my_key");
378
    /// ```
379
0
    pub fn remove_string_attribute(self, loc: AttributeLoc, key: &str) {
380
0
        unsafe {
381
0
            LLVMRemoveStringAttributeAtIndex(
382
0
                self.as_value_ref(),
383
0
                loc.get_index(),
384
0
                key.as_ptr() as *const ::libc::c_char,
385
0
                key.len() as u32,
386
0
            )
387
0
        }
388
0
    }
389
390
    /// Removes an enum `Attribute` belonging to the specified location in this `FunctionValue`.
391
    ///
392
    /// # Example
393
    ///
394
    /// ```no_run
395
    /// use inkwell::attributes::AttributeLoc;
396
    /// use inkwell::context::Context;
397
    ///
398
    /// let context = Context::create();
399
    /// let module = context.create_module("my_mod");
400
    /// let void_type = context.void_type();
401
    /// let fn_type = void_type.fn_type(&[], false);
402
    /// let fn_value = module.add_function("my_fn", fn_type, None);
403
    /// let enum_attribute = context.create_enum_attribute(1, 1);
404
    ///
405
    /// fn_value.add_attribute(AttributeLoc::Return, enum_attribute);
406
    /// fn_value.remove_enum_attribute(AttributeLoc::Return, 1);
407
    /// ```
408
0
    pub fn remove_enum_attribute(self, loc: AttributeLoc, kind_id: u32) {
409
0
        unsafe { LLVMRemoveEnumAttributeAtIndex(self.as_value_ref(), loc.get_index(), kind_id) }
410
0
    }
411
412
    /// Gets an enum `Attribute` belonging to the specified location in this `FunctionValue`.
413
    ///
414
    /// # Example
415
    ///
416
    /// ```no_run
417
    /// use inkwell::attributes::AttributeLoc;
418
    /// use inkwell::context::Context;
419
    ///
420
    /// let context = Context::create();
421
    /// let module = context.create_module("my_mod");
422
    /// let void_type = context.void_type();
423
    /// let fn_type = void_type.fn_type(&[], false);
424
    /// let fn_value = module.add_function("my_fn", fn_type, None);
425
    /// let enum_attribute = context.create_enum_attribute(1, 1);
426
    ///
427
    /// fn_value.add_attribute(AttributeLoc::Return, enum_attribute);
428
    ///
429
    /// assert_eq!(fn_value.get_enum_attribute(AttributeLoc::Return, 1), Some(enum_attribute));
430
    /// ```
431
    // SubTypes: -> Option<Attribute<Enum>>
432
101k
    pub fn get_enum_attribute(self, loc: AttributeLoc, kind_id: u32) -> Option<Attribute> {
433
101k
        let ptr = unsafe { LLVMGetEnumAttributeAtIndex(self.as_value_ref(), loc.get_index(), kind_id) };
434
101k
435
101k
        if ptr.is_null() {
436
92.2k
            return None;
437
9.76k
        }
438
9.76k
439
9.76k
        unsafe { Some(Attribute::new(ptr)) }
440
101k
    }
441
442
    /// Gets a string `Attribute` belonging to the specified location in this `FunctionValue`.
443
    ///
444
    /// # Example
445
    ///
446
    /// ```no_run
447
    /// use inkwell::attributes::AttributeLoc;
448
    /// use inkwell::context::Context;
449
    ///
450
    /// let context = Context::create();
451
    /// let module = context.create_module("my_mod");
452
    /// let void_type = context.void_type();
453
    /// let fn_type = void_type.fn_type(&[], false);
454
    /// let fn_value = module.add_function("my_fn", fn_type, None);
455
    /// let string_attribute = context.create_string_attribute("my_key", "my_val");
456
    ///
457
    /// fn_value.add_attribute(AttributeLoc::Return, string_attribute);
458
    ///
459
    /// assert_eq!(fn_value.get_string_attribute(AttributeLoc::Return, "my_key"), Some(string_attribute));
460
    /// ```
461
    // SubTypes: -> Option<Attribute<String>>
462
0
    pub fn get_string_attribute(self, loc: AttributeLoc, key: &str) -> Option<Attribute> {
463
0
        let ptr = unsafe {
464
0
            LLVMGetStringAttributeAtIndex(
465
0
                self.as_value_ref(),
466
0
                loc.get_index(),
467
0
                key.as_ptr() as *const ::libc::c_char,
468
0
                key.len() as u32,
469
0
            )
470
0
        };
471
0
472
0
        if ptr.is_null() {
473
0
            return None;
474
0
        }
475
0
476
0
        unsafe { Some(Attribute::new(ptr)) }
477
0
    }
478
479
0
    pub fn set_param_alignment(self, param_index: u32, alignment: u32) {
480
0
        if let Some(param) = self.get_nth_param(param_index) {
481
0
            unsafe { LLVMSetParamAlignment(param.as_value_ref(), alignment) }
482
0
        }
483
0
    }
484
485
    /// Gets the `GlobalValue` version of this `FunctionValue`. This allows
486
    /// you to further inspect its global properties or even convert it to
487
    /// a `PointerValue`.
488
483k
    pub fn as_global_value(self) -> GlobalValue<'ctx> {
489
483k
        unsafe { GlobalValue::new(self.as_value_ref()) }
490
483k
    }
491
492
    /// Set the debug info descriptor
493
    #[llvm_versions(7.0..=latest)]
494
0
    pub fn set_subprogram(self, subprogram: DISubprogram<'ctx>) {
495
0
        unsafe { LLVMSetSubprogram(self.as_value_ref(), subprogram.metadata_ref) }
496
0
    }
497
498
    /// Get the debug info descriptor
499
    #[llvm_versions(7.0..=latest)]
500
0
    pub fn get_subprogram(self) -> Option<DISubprogram<'ctx>> {
501
0
        let metadata_ref = unsafe { LLVMGetSubprogram(self.as_value_ref()) };
502
0
503
0
        if metadata_ref.is_null() {
504
0
            None
505
        } else {
506
0
            Some(DISubprogram {
507
0
                metadata_ref,
508
0
                _marker: PhantomData,
509
0
            })
510
        }
511
0
    }
512
513
    /// Get the section to which this function belongs
514
0
    pub fn get_section(&self) -> Option<&CStr> {
515
0
        self.fn_value.get_section()
516
0
    }
517
518
    /// Set the section to which this function should belong
519
0
    pub fn set_section(self, section: Option<&str>) {
520
0
        self.fn_value.set_section(section)
521
0
    }
522
}
523
524
unsafe impl AsValueRef for FunctionValue<'_> {
525
4.55M
    fn as_value_ref(&self) -> LLVMValueRef {
526
4.55M
        self.fn_value.value
527
4.55M
    }
528
}
529
530
impl Display for FunctionValue<'_> {
531
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
532
0
        write!(f, "{}", self.print_to_string())
533
0
    }
534
}
535
536
impl fmt::Debug for FunctionValue<'_> {
537
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
538
0
        let llvm_value = self.print_to_string();
539
0
        let llvm_type = self.get_type();
540
0
        let name = self.get_name();
541
0
        let is_const = unsafe { LLVMIsConstant(self.fn_value.value) == 1 };
542
0
        let is_null = self.is_null();
543
0
544
0
        f.debug_struct("FunctionValue")
545
0
            .field("name", &name)
546
0
            .field("address", &self.as_value_ref())
547
0
            .field("is_const", &is_const)
548
0
            .field("is_null", &is_null)
549
0
            .field("llvm_value", &llvm_value)
550
0
            .field("llvm_type", &llvm_type.print_to_string())
551
0
            .finish()
552
0
    }
553
}
554
555
#[derive(Debug)]
556
pub struct ParamValueIter<'ctx> {
557
    param_iter_value: LLVMValueRef,
558
    start: bool,
559
    _marker: PhantomData<&'ctx ()>,
560
}
561
562
impl<'ctx> Iterator for ParamValueIter<'ctx> {
563
    type Item = BasicValueEnum<'ctx>;
564
565
0
    fn next(&mut self) -> Option<Self::Item> {
566
0
        if self.start {
567
0
            let first_value = unsafe { LLVMGetFirstParam(self.param_iter_value) };
568
0
569
0
            if first_value.is_null() {
570
0
                return None;
571
0
            }
572
0
573
0
            self.start = false;
574
0
575
0
            self.param_iter_value = first_value;
576
0
577
0
            return unsafe { Some(Self::Item::new(first_value)) };
578
0
        }
579
0
580
0
        let next_value = unsafe { LLVMGetNextParam(self.param_iter_value) };
581
0
582
0
        if next_value.is_null() {
583
0
            return None;
584
0
        }
585
0
586
0
        self.param_iter_value = next_value;
587
0
588
0
        unsafe { Some(Self::Item::new(next_value)) }
589
0
    }
590
}