Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use super::Type;
4 : use crate::common::into_optional;
5 : use crate::common::FromFFI;
6 : use crate::DebugLocation;
7 : use crate::{declare_fwd_iterator, to_result, Error};
8 : use std::marker::PhantomData;
9 : use crate::dwarf::Scope;
10 :
11 : /// This class represents a DWARF variable which can be owned by a
12 : /// [`crate::dwarf::Function`] or a [`crate::dwarf::CompilationUnit`]
13 : pub struct Variable<'a> {
14 : ptr: cxx::UniquePtr<ffi::DWARF_Variable>,
15 : _owner: PhantomData<&'a ()>,
16 : }
17 :
18 : impl FromFFI<ffi::DWARF_Variable> for Variable<'_> {
19 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::DWARF_Variable>) -> Self {
20 0 : Self {
21 0 : ptr,
22 0 : _owner: PhantomData,
23 0 : }
24 0 : }
25 : }
26 :
27 : impl Variable<'_> {
28 : /// Name of the variable (usually demangled)
29 0 : pub fn name(&self) -> String {
30 0 : self.ptr.name().to_string()
31 0 : }
32 :
33 : /// The name of the variable which is used for linking (`DW_AT_linkage_name`).
34 : ///
35 : /// This name differs from [`Variable::name`] as it is usually mangled.
36 0 : pub fn linkage_name(&self) -> Option<String> {
37 0 : let name = self.ptr.name().to_string();
38 0 : if !name.is_empty() {
39 0 : return Some(name);
40 0 : }
41 0 : None
42 0 : }
43 :
44 : /// Address of the variable.
45 : ///
46 : /// If the variable is **static**, it returns the **virtual address**
47 : /// where it is defined.
48 : /// If the variable is stack-based, it returns the **relative offset** from
49 : /// the frame based register.
50 : ///
51 : /// If the address can't be resolved, it returns an [`Error`].
52 0 : pub fn address(&self) -> Result<i64, Error> {
53 0 : to_result!(ffi::DWARF_Variable::address, self);
54 0 : }
55 :
56 : /// Return the size of the variable (or an [`Error`] if it can't be
57 : /// resolved).
58 : ///
59 : /// This size is defined by its type.
60 0 : pub fn size(&self) -> Result<u64, Error> {
61 0 : to_result!(ffi::DWARF_Variable::size, self);
62 0 : }
63 :
64 : /// Whether it's a `constexpr` variable
65 0 : pub fn is_constexpr(&self) -> bool {
66 0 : self.ptr.is_constexpr()
67 0 : }
68 :
69 : /// The original source location where the variable is defined.
70 0 : pub fn debug_location(&self) -> DebugLocation {
71 0 : DebugLocation::from_ffi(self.ptr.debug_location())
72 0 : }
73 :
74 : /// Return the type of this variable
75 0 : pub fn get_type(&self) -> Option<Type> {
76 0 : into_optional(self.ptr.get_type())
77 0 : }
78 :
79 : /// The scope in which this variable is defined
80 0 : pub fn scope(&self) -> Option<Scope> {
81 0 : into_optional(self.ptr.scope())
82 0 : }
83 :
84 : /// Description (`DW_AT_description`) of the variable or an empty string
85 0 : pub fn description(&self) -> String {
86 0 : self.ptr.description().to_string()
87 0 : }
88 : }
89 :
90 0 : declare_fwd_iterator!(
91 0 : Variables,
92 0 : Variable<'a>,
93 0 : ffi::DWARF_Variable,
94 0 : ffi::DWARF_Function,
95 0 : ffi::DWARF_Function_it_variables
96 0 : );
97 :
98 0 : declare_fwd_iterator!(
99 0 : CompilationUnitVariables,
100 0 : Variable<'a>,
101 0 : ffi::DWARF_Variable,
102 0 : ffi::DWARF_CompilationUnit,
103 0 : ffi::DWARF_CompilationUnit_it_variables
104 0 : );
|