Line data Source code
1 : use lief_ffi as ffi;
2 :
3 : use crate::common::{into_optional, FromFFI};
4 : use crate::declare_fwd_iterator;
5 : use crate::dwarf::types::DwarfType;
6 : use crate::to_result;
7 : use std::marker::PhantomData;
8 : use crate::Error;
9 : use super::Type;
10 :
11 : /// Trait shared by [`Structure`], [`Class`] or [`Union`]
12 : pub trait ClassLike {
13 : #[doc(hidden)]
14 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike;
15 :
16 : /// Return this list of all the attributes defined in this class-like type
17 0 : fn members(&self) -> Members {
18 0 : Members::new(self.get_classlike().members())
19 0 : }
20 : }
21 :
22 : pub struct Member<'a> {
23 : ptr: cxx::UniquePtr<ffi::DWARF_types_ClassLike_Member>,
24 : _owner: PhantomData<&'a ()>,
25 : }
26 :
27 : impl Member<'_> {
28 : /// Name of the member
29 0 : pub fn name(&self) -> String {
30 0 : self.ptr.name().to_string()
31 0 : }
32 :
33 : /// Offset of the current member in the struct/union/class
34 0 : pub fn offset(&self) -> Result<u64, Error> {
35 0 : to_result!(ffi::DWARF_types_ClassLike_Member::offset, self);
36 0 : }
37 :
38 : /// Offset of the current member in **bits** the struct/union/class
39 : ///
40 : /// This function differs from [`Member::offset`] for aggregates using bit-field
41 : /// declaration:
42 : ///
43 : /// ```cpp
44 : /// struct S {
45 : /// int flag : 4;
46 : /// int opt : 1
47 : /// };
48 : /// ```
49 : ///
50 : /// Usually, `offset() * 8 == bit_offset()`
51 0 : pub fn bit_offset(&self) -> Result<u64, Error> {
52 0 : to_result!(ffi::DWARF_types_ClassLike_Member::offset, self);
53 0 : }
54 :
55 : /// Type of the current member
56 0 : pub fn get_type(&self) -> Option<Type> {
57 0 : into_optional(self.ptr.get_type())
58 0 : }
59 :
60 0 : pub fn is_external(&self) -> bool {
61 0 : self.ptr.is_external()
62 0 : }
63 :
64 0 : pub fn is_declaration(&self) -> bool {
65 0 : self.ptr.is_declaration()
66 0 : }
67 : }
68 :
69 : impl FromFFI<ffi::DWARF_types_ClassLike_Member> for Member<'_> {
70 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_ClassLike_Member>) -> Self {
71 0 : Self {
72 0 : ptr: cmd,
73 0 : _owner: PhantomData,
74 0 : }
75 0 : }
76 : }
77 :
78 : /// This structure represents a `DW_TAG_structure_type` DWARF type
79 : pub struct Structure<'a> {
80 : ptr: cxx::UniquePtr<ffi::DWARF_types_Structure>,
81 : _owner: PhantomData<&'a ()>,
82 : }
83 :
84 : impl FromFFI<ffi::DWARF_types_Structure> for Structure<'_> {
85 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Structure>) -> Self {
86 0 : Self {
87 0 : ptr: cmd,
88 0 : _owner: PhantomData,
89 0 : }
90 0 : }
91 : }
92 :
93 : impl DwarfType for Structure<'_> {
94 0 : fn get_base(&self) -> &ffi::DWARF_Type {
95 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
96 0 : }
97 : }
98 :
99 : impl ClassLike for Structure<'_> {
100 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
101 0 : self.ptr.as_ref().unwrap().as_ref()
102 0 : }
103 : }
104 :
105 : /// This structure represents a `DW_TAG_union_type` DWARF type
106 : pub struct Union<'a> {
107 : ptr: cxx::UniquePtr<ffi::DWARF_types_Union>,
108 : _owner: PhantomData<&'a ()>,
109 : }
110 :
111 : impl FromFFI<ffi::DWARF_types_Union> for Union<'_> {
112 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Union>) -> Self {
113 0 : Self {
114 0 : ptr: cmd,
115 0 : _owner: PhantomData,
116 0 : }
117 0 : }
118 : }
119 :
120 : impl DwarfType for Union<'_> {
121 0 : fn get_base(&self) -> &ffi::DWARF_Type {
122 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
123 0 : }
124 : }
125 :
126 : impl ClassLike for Union<'_> {
127 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
128 0 : self.ptr.as_ref().unwrap().as_ref()
129 0 : }
130 : }
131 :
132 :
133 : /// This structure represents a `DW_TAG_class_type` DWARF type
134 : pub struct Class<'a> {
135 : ptr: cxx::UniquePtr<ffi::DWARF_types_Class>,
136 : _owner: PhantomData<&'a ()>,
137 : }
138 :
139 : impl FromFFI<ffi::DWARF_types_Class> for Class<'_> {
140 0 : fn from_ffi(cmd: cxx::UniquePtr<ffi::DWARF_types_Class>) -> Self {
141 0 : Self {
142 0 : ptr: cmd,
143 0 : _owner: PhantomData,
144 0 : }
145 0 : }
146 : }
147 :
148 : impl DwarfType for Class<'_> {
149 0 : fn get_base(&self) -> &ffi::DWARF_Type {
150 0 : self.ptr.as_ref().unwrap().as_ref().as_ref()
151 0 : }
152 : }
153 :
154 : impl ClassLike for Class<'_> {
155 0 : fn get_classlike(&self) -> &ffi::DWARF_types_ClassLike {
156 0 : self.ptr.as_ref().unwrap().as_ref()
157 0 : }
158 : }
159 :
160 0 : declare_fwd_iterator!(
161 0 : Members,
162 0 : Member<'a>,
163 0 : ffi::DWARF_types_ClassLike_Member,
164 0 : ffi::DWARF_types_ClassLike,
165 0 : ffi::DWARF_types_ClassLike_it_members
166 0 : );
|