1pub mod archive;
28pub mod container;
29pub mod enumeration;
30pub mod library;
31pub mod parser;
32pub mod printer;
33pub mod structure;
34
35use binaryninjacore_sys::*;
36
37use crate::{
38 architecture::Architecture,
39 binary_view::{BinaryView, BinaryViewExt},
40 calling_convention::CoreCallingConvention,
41 rc::*,
42 string::{BnString, IntoCStr},
43};
44
45use crate::confidence::{Conf, MAX_CONFIDENCE, MIN_CONFIDENCE};
46use crate::string::raw_to_string;
47use crate::variable::{Variable, VariableSourceType};
48use std::num::NonZeroUsize;
49use std::{
50 collections::HashSet,
51 fmt::{Debug, Display, Formatter},
52 hash::{Hash, Hasher},
53 iter::IntoIterator,
54};
55
56pub use archive::{TypeArchive, TypeArchiveId, TypeArchiveSnapshotId};
57pub use container::TypeContainer;
58pub use enumeration::{Enumeration, EnumerationBuilder, EnumerationMember};
59pub use library::TypeLibrary;
60pub use parser::{
61 CoreTypeParser, ParsedType, TypeParser, TypeParserError, TypeParserErrorSeverity,
62 TypeParserResult,
63};
64pub use printer::{CoreTypePrinter, TypePrinter};
65pub use structure::{
66 BaseStructure, InheritedStructureMember, Structure, StructureBuilder, StructureMember,
67};
68
69#[deprecated(note = "Use crate::qualified_name::QualifiedName instead")]
70pub use crate::qualified_name::QualifiedName;
72
73pub type StructureType = BNStructureVariant;
74pub type ReferenceType = BNReferenceType;
75pub type TypeClass = BNTypeClass;
76pub type NamedTypeReferenceClass = BNNamedTypeReferenceClass;
77pub type MemberAccess = BNMemberAccess;
78pub type MemberScope = BNMemberScope;
79pub type IntegerDisplayType = BNIntegerDisplayType;
80pub type PointerBaseType = BNPointerBaseType;
81
82#[derive(PartialEq, Eq, Hash)]
83pub struct TypeBuilder {
84 pub(crate) handle: *mut BNTypeBuilder,
85}
86
87impl TypeBuilder {
88 pub fn new(t: &Type) -> Self {
89 unsafe { Self::from_raw(BNCreateTypeBuilderFromType(t.handle)) }
90 }
91
92 pub(crate) unsafe fn from_raw(handle: *mut BNTypeBuilder) -> Self {
93 debug_assert!(!handle.is_null());
94 Self { handle }
95 }
96
97 pub fn finalize(&self) -> Ref<Type> {
99 unsafe { Type::ref_from_raw(BNFinalizeTypeBuilder(self.handle)) }
100 }
101
102 pub fn set_can_return<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
103 let mut bool_with_confidence = value.into().into();
104 unsafe { BNSetFunctionTypeBuilderCanReturn(self.handle, &mut bool_with_confidence) };
105 self
106 }
107
108 pub fn set_pure<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
109 let mut bool_with_confidence = value.into().into();
110 unsafe { BNSetTypeBuilderPure(self.handle, &mut bool_with_confidence) };
111 self
112 }
113
114 pub fn set_const<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
115 let mut bool_with_confidence = value.into().into();
116 unsafe { BNTypeBuilderSetConst(self.handle, &mut bool_with_confidence) };
117 self
118 }
119
120 pub fn set_volatile<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
121 let mut bool_with_confidence = value.into().into();
122 unsafe { BNTypeBuilderSetVolatile(self.handle, &mut bool_with_confidence) };
123 self
124 }
125
126 pub fn set_width(&self, width: usize) -> &Self {
130 unsafe { BNTypeBuilderSetWidth(self.handle, width) }
131 self
132 }
133
134 pub fn set_alignment(&self, alignment: usize) -> &Self {
138 unsafe { BNTypeBuilderSetAlignment(self.handle, alignment) }
139 self
140 }
141
142 pub fn set_pointer_base(&self, base_type: PointerBaseType, base_offset: i64) -> &Self {
143 unsafe { BNSetTypeBuilderPointerBase(self.handle, base_type, base_offset) }
144 self
145 }
146
147 pub fn set_child_type<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
148 let mut type_with_confidence = Conf::<&Type>::into_raw(ty.into());
149 unsafe { BNTypeBuilderSetChildType(self.handle, &mut type_with_confidence) };
150 self
151 }
152
153 pub fn set_target<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
155 self.set_child_type(ty)
156 }
157
158 pub fn set_element_type<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
160 self.set_child_type(ty)
161 }
162
163 pub fn set_return_value<'a, T: Into<Conf<&'a Type>>>(&self, ty: T) -> &Self {
165 self.set_child_type(ty)
166 }
167
168 pub fn set_signed<T: Into<Conf<bool>>>(&self, value: T) -> &Self {
169 let mut bool_with_confidence = value.into().into();
170 unsafe { BNTypeBuilderSetSigned(self.handle, &mut bool_with_confidence) };
171 self
172 }
173
174 pub fn type_class(&self) -> TypeClass {
177 unsafe { BNGetTypeBuilderClass(self.handle) }
178 }
179
180 pub fn width(&self) -> u64 {
181 unsafe { BNGetTypeBuilderWidth(self.handle) }
182 }
183
184 pub fn alignment(&self) -> usize {
185 unsafe { BNGetTypeBuilderAlignment(self.handle) }
186 }
187
188 pub fn is_signed(&self) -> Conf<bool> {
189 unsafe { BNIsTypeBuilderSigned(self.handle).into() }
190 }
191
192 pub fn is_const(&self) -> Conf<bool> {
193 unsafe { BNIsTypeBuilderConst(self.handle).into() }
194 }
195
196 pub fn is_volatile(&self) -> Conf<bool> {
197 unsafe { BNIsTypeBuilderVolatile(self.handle).into() }
198 }
199
200 pub fn is_floating_point(&self) -> bool {
201 unsafe { BNIsTypeBuilderFloatingPoint(self.handle) }
202 }
203
204 pub fn child_type(&self) -> Option<Conf<Ref<Type>>> {
205 let raw_target = unsafe { BNGetTypeBuilderChildType(self.handle) };
206 match raw_target.type_.is_null() {
207 false => Some(Conf::<Ref<Type>>::from_owned_raw(raw_target)),
208 true => None,
209 }
210 }
211
212 pub fn target(&self) -> Option<Conf<Ref<Type>>> {
214 self.child_type()
215 }
216
217 pub fn element_type(&self) -> Option<Conf<Ref<Type>>> {
219 self.child_type()
220 }
221
222 pub fn return_value(&self) -> Option<Conf<Ref<Type>>> {
224 self.child_type()
225 }
226
227 pub fn calling_convention(&self) -> Option<Conf<Ref<CoreCallingConvention>>> {
228 let raw_convention_confidence = unsafe { BNGetTypeBuilderCallingConvention(self.handle) };
229 match raw_convention_confidence.convention.is_null() {
230 false => Some(Conf::<Ref<CoreCallingConvention>>::from_owned_raw(
231 raw_convention_confidence,
232 )),
233 true => None,
234 }
235 }
236
237 pub fn parameters(&self) -> Option<Vec<FunctionParameter>> {
238 unsafe {
239 let mut count = 0;
240 let raw_parameters_ptr = BNGetTypeBuilderParameters(self.handle, &mut count);
241 match raw_parameters_ptr.is_null() {
242 false => {
243 let raw_parameters = std::slice::from_raw_parts(raw_parameters_ptr, count);
244 let parameters = raw_parameters
245 .iter()
246 .map(FunctionParameter::from_raw)
247 .collect();
248 BNFreeTypeParameterList(raw_parameters_ptr, count);
249 Some(parameters)
250 }
251 true => None,
252 }
253 }
254 }
255
256 pub fn has_variable_arguments(&self) -> Conf<bool> {
257 unsafe { BNTypeBuilderHasVariableArguments(self.handle).into() }
258 }
259
260 pub fn can_return(&self) -> Conf<bool> {
261 unsafe { BNFunctionTypeBuilderCanReturn(self.handle).into() }
262 }
263
264 pub fn pure(&self) -> Conf<bool> {
265 unsafe { BNIsTypeBuilderPure(self.handle).into() }
266 }
267
268 pub fn get_structure(&self) -> Option<Ref<Structure>> {
271 let raw_struct_ptr = unsafe { BNGetTypeBuilderStructure(self.handle) };
272 match raw_struct_ptr.is_null() {
273 false => Some(unsafe { Structure::ref_from_raw(raw_struct_ptr) }),
274 true => None,
275 }
276 }
277
278 pub fn get_enumeration(&self) -> Option<Ref<Enumeration>> {
281 let raw_enum_ptr = unsafe { BNGetTypeBuilderEnumeration(self.handle) };
282 match raw_enum_ptr.is_null() {
283 false => Some(unsafe { Enumeration::ref_from_raw(raw_enum_ptr) }),
284 true => None,
285 }
286 }
287
288 pub fn get_named_type_reference(&self) -> Option<Ref<NamedTypeReference>> {
291 let raw_type_ref_ptr = unsafe { BNGetTypeBuilderNamedTypeReference(self.handle) };
292 match raw_type_ref_ptr.is_null() {
293 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
294 true => None,
295 }
296 }
297
298 pub fn count(&self) -> u64 {
299 unsafe { BNGetTypeBuilderElementCount(self.handle) }
300 }
301
302 pub fn offset(&self) -> u64 {
303 unsafe { BNGetTypeBuilderOffset(self.handle) }
304 }
305
306 pub fn stack_adjustment(&self) -> Conf<i64> {
307 unsafe { BNGetTypeBuilderStackAdjustment(self.handle).into() }
308 }
309
310 pub fn pointer_base_type(&self) -> PointerBaseType {
311 unsafe { BNTypeBuilderGetPointerBaseType(self.handle) }
312 }
313
314 pub fn pointer_base_offset(&self) -> i64 {
315 unsafe { BNTypeBuilderGetPointerBaseOffset(self.handle) }
316 }
317
318 pub fn void() -> Self {
323 unsafe { Self::from_raw(BNCreateVoidTypeBuilder()) }
324 }
325
326 pub fn bool() -> Self {
328 unsafe { Self::from_raw(BNCreateBoolTypeBuilder()) }
329 }
330
331 pub fn char() -> Self {
333 Self::int(1, true)
334 }
335
336 pub fn int(width: usize, is_signed: bool) -> Self {
338 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
339
340 unsafe {
341 Self::from_raw(BNCreateIntegerTypeBuilder(
342 width,
343 &mut is_signed,
344 c"".as_ptr() as _,
345 ))
346 }
347 }
348
349 pub fn named_int(width: usize, is_signed: bool, alt_name: &str) -> Self {
352 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
353 let alt_name = alt_name.to_cstr();
354
355 unsafe {
356 Self::from_raw(BNCreateIntegerTypeBuilder(
357 width,
358 &mut is_signed,
359 alt_name.as_ref().as_ptr() as _,
360 ))
361 }
362 }
363
364 pub fn float(width: usize) -> Self {
366 unsafe { Self::from_raw(BNCreateFloatTypeBuilder(width, c"".as_ptr())) }
367 }
368
369 pub fn named_float(width: usize, alt_name: &str) -> Self {
371 let alt_name = alt_name.to_cstr();
372 unsafe { Self::from_raw(BNCreateFloatTypeBuilder(width, alt_name.as_ptr())) }
373 }
374
375 pub fn array<'a, T: Into<Conf<&'a Type>>>(ty: T, count: u64) -> Self {
377 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
378 unsafe { Self::from_raw(BNCreateArrayTypeBuilder(&owned_raw_ty, count)) }
379 }
380
381 pub fn enumeration<T: Into<Conf<bool>>>(
389 enumeration: &Enumeration,
390 width: NonZeroUsize,
391 is_signed: T,
392 ) -> Self {
393 unsafe {
394 Self::from_raw(BNCreateEnumerationTypeBuilder(
395 std::ptr::null_mut(),
397 enumeration.handle,
398 width.get(),
399 &mut is_signed.into().into(),
400 ))
401 }
402 }
403
404 pub fn structure(structure_type: &Structure) -> Self {
406 unsafe { Self::from_raw(BNCreateStructureTypeBuilder(structure_type.handle)) }
407 }
408
409 pub fn named_type(type_reference: &NamedTypeReference) -> Self {
411 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
412 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
413 unsafe {
414 Self::from_raw(BNCreateNamedTypeReferenceBuilder(
415 type_reference.handle,
416 0,
417 1,
418 &mut is_const,
419 &mut is_volatile,
420 ))
421 }
422 }
423
424 pub fn named_type_from_type<T: Into<QualifiedName>>(name: T, t: &Type) -> Self {
426 let mut raw_name = QualifiedName::into_raw(name.into());
427 let id = c"";
428
429 let result = unsafe {
430 Self::from_raw(BNCreateNamedTypeReferenceBuilderFromTypeAndId(
431 id.as_ptr() as *mut _,
432 &mut raw_name,
433 t.handle,
434 ))
435 };
436 QualifiedName::free_raw(raw_name);
437 result
438 }
439
440 pub fn function<'a, T: Into<Conf<&'a Type>>>(
444 return_type: T,
445 parameters: Vec<FunctionParameter>,
446 variable_arguments: bool,
447 ) -> Self {
448 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
449 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
450 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
451 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
452
453 let mut raw_calling_convention: BNCallingConventionWithConfidence =
454 BNCallingConventionWithConfidence {
455 convention: std::ptr::null_mut(),
456 confidence: MIN_CONFIDENCE,
457 };
458
459 let mut stack_adjust = Conf::new(0, MIN_CONFIDENCE).into();
460 let mut raw_parameters = parameters
461 .into_iter()
462 .map(FunctionParameter::into_raw)
463 .collect::<Vec<_>>();
464 let reg_stack_adjust_regs = std::ptr::null_mut();
465 let reg_stack_adjust_values = std::ptr::null_mut();
466
467 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
468 regs: std::ptr::null_mut(),
469 count: 0,
470 confidence: 0,
471 };
472
473 let result = unsafe {
474 Self::from_raw(BNCreateFunctionTypeBuilder(
475 &mut owned_raw_return_type,
476 &mut raw_calling_convention,
477 raw_parameters.as_mut_ptr(),
478 raw_parameters.len(),
479 &mut variable_arguments,
480 &mut can_return,
481 &mut stack_adjust,
482 reg_stack_adjust_regs,
483 reg_stack_adjust_values,
484 0,
485 &mut return_regs,
486 BNNameType::NoNameType,
487 &mut pure,
488 ))
489 };
490
491 for raw_param in raw_parameters {
492 FunctionParameter::free_raw(raw_param);
493 }
494
495 result
496 }
497
498 pub fn function_with_opts<
502 'a,
503 T: Into<Conf<&'a Type>>,
504 C: Into<Conf<Ref<CoreCallingConvention>>>,
505 >(
506 return_type: T,
507 parameters: &[FunctionParameter],
508 variable_arguments: bool,
509 calling_convention: C,
510 stack_adjust: Conf<i64>,
511 ) -> Self {
512 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
513 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
514 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
515 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
516
517 let mut owned_raw_calling_convention =
518 Conf::<Ref<CoreCallingConvention>>::into_owned_raw(&calling_convention.into());
519
520 let mut stack_adjust = stack_adjust.into();
521 let mut raw_parameters = parameters
522 .iter()
523 .cloned()
524 .map(FunctionParameter::into_raw)
525 .collect::<Vec<_>>();
526
527 let reg_stack_adjust_regs = std::ptr::null_mut();
529 let reg_stack_adjust_values = std::ptr::null_mut();
530
531 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
532 regs: std::ptr::null_mut(),
533 count: 0,
534 confidence: 0,
535 };
536
537 let result = unsafe {
538 Self::from_raw(BNCreateFunctionTypeBuilder(
539 &mut owned_raw_return_type,
540 &mut owned_raw_calling_convention,
541 raw_parameters.as_mut_ptr(),
542 raw_parameters.len(),
543 &mut variable_arguments,
544 &mut can_return,
545 &mut stack_adjust,
546 reg_stack_adjust_regs,
547 reg_stack_adjust_values,
548 0,
549 &mut return_regs,
550 BNNameType::NoNameType,
551 &mut pure,
552 ))
553 };
554
555 for raw_param in raw_parameters {
556 FunctionParameter::free_raw(raw_param);
557 }
558
559 result
560 }
561
562 pub fn pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Self {
564 Self::pointer_with_options(arch, ty, false, false, None)
565 }
566
567 pub fn const_pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Self {
569 Self::pointer_with_options(arch, ty, true, false, None)
570 }
571
572 pub fn pointer_with_options<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
573 arch: &A,
574 ty: T,
575 is_const: bool,
576 is_volatile: bool,
577 ref_type: Option<ReferenceType>,
578 ) -> Self {
579 let arch_ptr_size = arch.address_size();
580 Self::pointer_of_width(ty, arch_ptr_size, is_const, is_volatile, ref_type)
581 }
582
583 pub fn pointer_of_width<'a, T: Into<Conf<&'a Type>>>(
584 ty: T,
585 size: usize,
586 is_const: bool,
587 is_volatile: bool,
588 ref_type: Option<ReferenceType>,
589 ) -> Self {
590 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
591 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
592 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
593 unsafe {
594 Self::from_raw(BNCreatePointerTypeBuilderOfWidth(
595 size,
596 &owned_raw_ty,
597 &mut is_const,
598 &mut is_volatile,
599 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
600 ))
601 }
602 }
603}
604
605impl Display for TypeBuilder {
606 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
607 write!(f, "{}", unsafe {
608 BnString::into_string(BNGetTypeBuilderString(self.handle, std::ptr::null_mut()))
609 })
610 }
611}
612
613impl Drop for TypeBuilder {
614 fn drop(&mut self) {
615 unsafe { BNFreeTypeBuilder(self.handle) };
616 }
617}
618
619#[repr(transparent)]
655pub struct Type {
656 pub handle: *mut BNType,
657}
658
659impl Type {
660 pub unsafe fn from_raw(handle: *mut BNType) -> Self {
661 debug_assert!(!handle.is_null());
662 Self { handle }
663 }
664
665 pub unsafe fn ref_from_raw(handle: *mut BNType) -> Ref<Self> {
666 debug_assert!(!handle.is_null());
667 Ref::new(Self { handle })
668 }
669
670 pub fn to_builder(&self) -> TypeBuilder {
671 TypeBuilder::new(self)
672 }
673
674 pub fn type_class(&self) -> TypeClass {
675 unsafe { BNGetTypeClass(self.handle) }
676 }
677
678 pub fn width(&self) -> u64 {
682 unsafe { BNGetTypeWidth(self.handle) }
683 }
684
685 pub fn alignment(&self) -> usize {
686 unsafe { BNGetTypeAlignment(self.handle) }
687 }
688
689 pub fn is_signed(&self) -> Conf<bool> {
690 unsafe { BNIsTypeSigned(self.handle).into() }
691 }
692
693 pub fn is_const(&self) -> Conf<bool> {
694 unsafe { BNIsTypeConst(self.handle).into() }
695 }
696
697 pub fn is_volatile(&self) -> Conf<bool> {
698 unsafe { BNIsTypeVolatile(self.handle).into() }
699 }
700
701 pub fn is_floating_point(&self) -> bool {
702 unsafe { BNIsTypeFloatingPoint(self.handle) }
703 }
704
705 pub fn child_type(&self) -> Option<Conf<Ref<Type>>> {
706 let raw_target = unsafe { BNGetChildType(self.handle) };
707 match raw_target.type_.is_null() {
708 false => Some(Conf::<Ref<Type>>::from_owned_raw(raw_target)),
709 true => None,
710 }
711 }
712
713 pub fn target(&self) -> Option<Conf<Ref<Type>>> {
715 self.child_type()
716 }
717
718 pub fn element_type(&self) -> Option<Conf<Ref<Type>>> {
720 self.child_type()
721 }
722
723 pub fn return_value(&self) -> Option<Conf<Ref<Type>>> {
725 self.child_type()
726 }
727
728 pub fn calling_convention(&self) -> Option<Conf<Ref<CoreCallingConvention>>> {
729 let convention_confidence = unsafe { BNGetTypeCallingConvention(self.handle) };
730 match convention_confidence.convention.is_null() {
731 false => Some(Conf::<Ref<CoreCallingConvention>>::from_owned_raw(
732 convention_confidence,
733 )),
734 true => None,
735 }
736 }
737
738 pub fn parameters(&self) -> Option<Vec<FunctionParameter>> {
739 unsafe {
740 let mut count = 0;
741 let raw_parameters_ptr = BNGetTypeParameters(self.handle, &mut count);
742 match raw_parameters_ptr.is_null() {
743 false => {
744 let raw_parameters = std::slice::from_raw_parts(raw_parameters_ptr, count);
745 let parameters = raw_parameters
746 .iter()
747 .map(FunctionParameter::from_raw)
748 .collect();
749 BNFreeTypeParameterList(raw_parameters_ptr, count);
750 Some(parameters)
751 }
752 true => None,
753 }
754 }
755 }
756
757 pub fn has_variable_arguments(&self) -> Conf<bool> {
758 unsafe { BNTypeHasVariableArguments(self.handle).into() }
759 }
760
761 pub fn can_return(&self) -> Conf<bool> {
762 unsafe { BNFunctionTypeCanReturn(self.handle).into() }
763 }
764
765 pub fn pure(&self) -> Conf<bool> {
766 unsafe { BNIsTypePure(self.handle).into() }
767 }
768
769 pub fn get_structure(&self) -> Option<Ref<Structure>> {
772 let raw_struct_ptr = unsafe { BNGetTypeStructure(self.handle) };
773 match raw_struct_ptr.is_null() {
774 false => Some(unsafe { Structure::ref_from_raw(raw_struct_ptr) }),
775 true => None,
776 }
777 }
778
779 pub fn get_enumeration(&self) -> Option<Ref<Enumeration>> {
782 let raw_enum_ptr = unsafe { BNGetTypeEnumeration(self.handle) };
783 match raw_enum_ptr.is_null() {
784 false => Some(unsafe { Enumeration::ref_from_raw(raw_enum_ptr) }),
785 true => None,
786 }
787 }
788
789 pub fn get_named_type_reference(&self) -> Option<Ref<NamedTypeReference>> {
792 let raw_type_ref_ptr = unsafe { BNGetTypeNamedTypeReference(self.handle) };
793 match raw_type_ref_ptr.is_null() {
794 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
795 true => None,
796 }
797 }
798
799 pub fn count(&self) -> u64 {
800 unsafe { BNGetTypeElementCount(self.handle) }
801 }
802
803 pub fn offset(&self) -> u64 {
804 unsafe { BNGetTypeOffset(self.handle) }
805 }
806
807 pub fn stack_adjustment(&self) -> Conf<i64> {
808 unsafe { BNGetTypeStackAdjustment(self.handle).into() }
809 }
810
811 pub fn registered_name(&self) -> Option<Ref<NamedTypeReference>> {
812 let raw_type_ref_ptr = unsafe { BNGetRegisteredTypeName(self.handle) };
813 match raw_type_ref_ptr.is_null() {
814 false => Some(unsafe { NamedTypeReference::ref_from_raw(raw_type_ref_ptr) }),
815 true => None,
816 }
817 }
818
819 pub fn pointer_base_type(&self) -> BNPointerBaseType {
820 unsafe { BNTypeGetPointerBaseType(self.handle) }
821 }
822
823 pub fn pointer_base_offset(&self) -> i64 {
824 unsafe { BNTypeGetPointerBaseOffset(self.handle) }
825 }
826
827 pub fn void() -> Ref<Self> {
831 unsafe { Self::ref_from_raw(BNCreateVoidType()) }
832 }
833
834 pub fn bool() -> Ref<Self> {
835 unsafe { Self::ref_from_raw(BNCreateBoolType()) }
836 }
837
838 pub fn char() -> Ref<Self> {
839 Self::int(1, true)
840 }
841
842 pub fn wide_char(width: usize) -> Ref<Self> {
843 unsafe { Self::ref_from_raw(BNCreateWideCharType(width, c"".as_ptr())) }
844 }
845
846 pub fn int(width: usize, is_signed: bool) -> Ref<Self> {
847 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
848 unsafe { Self::ref_from_raw(BNCreateIntegerType(width, &mut is_signed, c"".as_ptr())) }
849 }
850
851 pub fn named_int(width: usize, is_signed: bool, alt_name: &str) -> Ref<Self> {
852 let mut is_signed = Conf::new(is_signed, MAX_CONFIDENCE).into();
853 let alt_name = alt_name.to_cstr();
854
855 unsafe {
856 Self::ref_from_raw(BNCreateIntegerType(
857 width,
858 &mut is_signed,
859 alt_name.as_ptr(),
860 ))
861 }
862 }
863
864 pub fn float(width: usize) -> Ref<Self> {
865 unsafe { Self::ref_from_raw(BNCreateFloatType(width, c"".as_ptr())) }
866 }
867
868 pub fn named_float(width: usize, alt_name: &str) -> Ref<Self> {
869 let alt_name = alt_name.to_cstr();
870 unsafe { Self::ref_from_raw(BNCreateFloatType(width, alt_name.as_ptr())) }
871 }
872
873 pub fn array<'a, T: Into<Conf<&'a Type>>>(ty: T, count: u64) -> Ref<Self> {
874 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
875 unsafe { Self::ref_from_raw(BNCreateArrayType(&owned_raw_ty, count)) }
876 }
877
878 pub fn enumeration<T: Into<Conf<bool>>>(
884 enumeration: &Enumeration,
885 width: NonZeroUsize,
886 is_signed: T,
887 ) -> Ref<Self> {
888 unsafe {
889 Self::ref_from_raw(BNCreateEnumerationType(
890 std::ptr::null_mut(),
892 enumeration.handle,
893 width.get(),
894 &mut is_signed.into().into(),
895 ))
896 }
897 }
898
899 pub fn structure(structure: &Structure) -> Ref<Self> {
900 unsafe { Self::ref_from_raw(BNCreateStructureType(structure.handle)) }
901 }
902
903 pub fn named_type(type_reference: &NamedTypeReference) -> Ref<Self> {
904 let mut is_const = Conf::new(false, MIN_CONFIDENCE).into();
905 let mut is_volatile = Conf::new(false, MIN_CONFIDENCE).into();
906 unsafe {
907 Self::ref_from_raw(BNCreateNamedTypeReference(
908 type_reference.handle,
909 0,
910 1,
911 &mut is_const,
912 &mut is_volatile,
913 ))
914 }
915 }
916
917 pub fn named_type_from_type<T: Into<QualifiedName>>(name: T, t: &Type) -> Ref<Self> {
918 let mut raw_name = QualifiedName::into_raw(name.into());
919 let id = c"";
921
922 let result = unsafe {
923 Self::ref_from_raw(BNCreateNamedTypeReferenceFromTypeAndId(
924 id.as_ptr(),
925 &mut raw_name,
926 t.handle,
927 ))
928 };
929 QualifiedName::free_raw(raw_name);
930 result
931 }
932
933 pub fn function<'a, T: Into<Conf<&'a Type>>>(
935 return_type: T,
936 parameters: Vec<FunctionParameter>,
937 variable_arguments: bool,
938 ) -> Ref<Self> {
939 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
940 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
941 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
942 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
943
944 let mut raw_calling_convention: BNCallingConventionWithConfidence =
945 BNCallingConventionWithConfidence {
946 convention: std::ptr::null_mut(),
947 confidence: MIN_CONFIDENCE,
948 };
949
950 let mut stack_adjust = Conf::new(0, MIN_CONFIDENCE).into();
951 let mut raw_parameters = parameters
952 .into_iter()
953 .map(FunctionParameter::into_raw)
954 .collect::<Vec<_>>();
955 let reg_stack_adjust_regs = std::ptr::null_mut();
956 let reg_stack_adjust_values = std::ptr::null_mut();
957
958 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
959 regs: std::ptr::null_mut(),
960 count: 0,
961 confidence: 0,
962 };
963
964 let result = unsafe {
965 Self::ref_from_raw(BNCreateFunctionType(
966 &mut owned_raw_return_type,
967 &mut raw_calling_convention,
968 raw_parameters.as_mut_ptr(),
969 raw_parameters.len(),
970 &mut variable_arguments,
971 &mut can_return,
972 &mut stack_adjust,
973 reg_stack_adjust_regs,
974 reg_stack_adjust_values,
975 0,
976 &mut return_regs,
977 BNNameType::NoNameType,
978 &mut pure,
979 ))
980 };
981
982 for raw_param in raw_parameters {
983 FunctionParameter::free_raw(raw_param);
984 }
985
986 result
987 }
988
989 pub fn function_with_opts<
991 'a,
992 T: Into<Conf<&'a Type>>,
993 C: Into<Conf<Ref<CoreCallingConvention>>>,
994 >(
995 return_type: T,
996 parameters: &[FunctionParameter],
997 variable_arguments: bool,
998 calling_convention: C,
999 stack_adjust: Conf<i64>,
1000 ) -> Ref<Self> {
1001 let mut owned_raw_return_type = Conf::<&Type>::into_raw(return_type.into());
1002 let mut variable_arguments = Conf::new(variable_arguments, MAX_CONFIDENCE).into();
1003 let mut can_return = Conf::new(true, MIN_CONFIDENCE).into();
1004 let mut pure = Conf::new(false, MIN_CONFIDENCE).into();
1005
1006 let mut owned_raw_calling_convention =
1007 Conf::<Ref<CoreCallingConvention>>::into_owned_raw(&calling_convention.into());
1008
1009 let mut stack_adjust = stack_adjust.into();
1010 let mut raw_parameters = parameters
1011 .iter()
1012 .cloned()
1013 .map(FunctionParameter::into_raw)
1014 .collect::<Vec<_>>();
1015
1016 let reg_stack_adjust_regs = std::ptr::null_mut();
1018 let reg_stack_adjust_values = std::ptr::null_mut();
1019
1020 let mut return_regs: BNRegisterSetWithConfidence = BNRegisterSetWithConfidence {
1021 regs: std::ptr::null_mut(),
1022 count: 0,
1023 confidence: 0,
1024 };
1025
1026 let result = unsafe {
1027 Self::ref_from_raw(BNCreateFunctionType(
1028 &mut owned_raw_return_type,
1029 &mut owned_raw_calling_convention,
1030 raw_parameters.as_mut_ptr(),
1031 raw_parameters.len(),
1032 &mut variable_arguments,
1033 &mut can_return,
1034 &mut stack_adjust,
1035 reg_stack_adjust_regs,
1036 reg_stack_adjust_values,
1037 0,
1038 &mut return_regs,
1039 BNNameType::NoNameType,
1040 &mut pure,
1041 ))
1042 };
1043
1044 for raw_param in raw_parameters {
1045 FunctionParameter::free_raw(raw_param);
1046 }
1047
1048 result
1049 }
1050
1051 pub fn pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(arch: &A, ty: T) -> Ref<Self> {
1052 Self::pointer_with_options(arch, ty, false, false, None)
1053 }
1054
1055 pub fn const_pointer<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
1056 arch: &A,
1057 ty: T,
1058 ) -> Ref<Self> {
1059 Self::pointer_with_options(arch, ty, true, false, None)
1060 }
1061
1062 pub fn pointer_with_options<'a, A: Architecture, T: Into<Conf<&'a Type>>>(
1063 arch: &A,
1064 ty: T,
1065 is_const: bool,
1066 is_volatile: bool,
1067 ref_type: Option<ReferenceType>,
1068 ) -> Ref<Self> {
1069 let arch_pointer_size = arch.address_size();
1070 Self::pointer_of_width(ty, arch_pointer_size, is_const, is_volatile, ref_type)
1071 }
1072
1073 pub fn pointer_of_width<'a, T: Into<Conf<&'a Type>>>(
1074 ty: T,
1075 size: usize,
1076 is_const: bool,
1077 is_volatile: bool,
1078 ref_type: Option<ReferenceType>,
1079 ) -> Ref<Self> {
1080 let mut is_const = Conf::new(is_const, MAX_CONFIDENCE).into();
1081 let mut is_volatile = Conf::new(is_volatile, MAX_CONFIDENCE).into();
1082 let owned_raw_ty = Conf::<&Type>::into_raw(ty.into());
1083 unsafe {
1084 Self::ref_from_raw(BNCreatePointerTypeOfWidth(
1085 size,
1086 &owned_raw_ty,
1087 &mut is_const,
1088 &mut is_volatile,
1089 ref_type.unwrap_or(ReferenceType::PointerReferenceType),
1090 ))
1091 }
1092 }
1093
1094 pub fn generate_auto_demangled_type_id<T: Into<QualifiedName>>(name: T) -> String {
1095 let mut raw_name = QualifiedName::into_raw(name.into());
1096 let type_id =
1097 unsafe { BnString::into_string(BNGenerateAutoDemangledTypeId(&mut raw_name)) };
1098 QualifiedName::free_raw(raw_name);
1099 type_id
1100 }
1101}
1102
1103impl Display for Type {
1104 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1105 write!(f, "{}", unsafe {
1106 BnString::into_string(BNGetTypeString(
1107 self.handle,
1108 std::ptr::null_mut(),
1109 BNTokenEscapingType::NoTokenEscapingType,
1110 ))
1111 })
1112 }
1113}
1114
1115impl Debug for Type {
1116 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1117 f.debug_struct("Type")
1122 .field("type_class", &self.type_class())
1123 .field("width", &self.width())
1124 .field("alignment", &self.alignment())
1125 .field("is_signed", &self.is_signed())
1126 .field("is_const", &self.is_const())
1127 .field("is_volatile", &self.is_volatile())
1128 .field("child_type", &self.child_type())
1129 .field("calling_convention", &self.calling_convention())
1130 .field("parameters", &self.parameters())
1131 .field("has_variable_arguments", &self.has_variable_arguments())
1132 .field("can_return", &self.can_return())
1133 .field("pure", &self.pure())
1134 .field("get_structure", &self.get_structure())
1135 .field("get_enumeration", &self.get_enumeration())
1136 .field("get_named_type_reference", &self.get_named_type_reference())
1137 .field("count", &self.count())
1138 .field("offset", &self.offset())
1139 .field("stack_adjustment", &self.stack_adjustment())
1140 .field("registered_name", &self.registered_name())
1141 .finish()
1142 }
1143}
1144
1145impl PartialEq for Type {
1146 fn eq(&self, other: &Self) -> bool {
1147 unsafe { BNTypesEqual(self.handle, other.handle) }
1148 }
1149}
1150
1151impl Eq for Type {}
1152
1153impl Hash for Type {
1154 fn hash<H: Hasher>(&self, state: &mut H) {
1155 self.handle.hash(state);
1156 }
1157}
1158
1159unsafe impl Send for Type {}
1160unsafe impl Sync for Type {}
1161
1162unsafe impl RefCountable for Type {
1163 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1164 Self::ref_from_raw(BNNewTypeReference(handle.handle))
1165 }
1166
1167 unsafe fn dec_ref(handle: &Self) {
1168 BNFreeType(handle.handle);
1169 }
1170}
1171
1172impl ToOwned for Type {
1173 type Owned = Ref<Self>;
1174
1175 fn to_owned(&self) -> Self::Owned {
1176 unsafe { RefCountable::inc_ref(self) }
1177 }
1178}
1179
1180impl CoreArrayProvider for Type {
1181 type Raw = *mut BNType;
1182 type Context = ();
1183 type Wrapped<'a> = &'a Self;
1184}
1185
1186unsafe impl CoreArrayProviderInner for Type {
1187 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1188 BNFreeTypeList(raw, count)
1189 }
1190
1191 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1192 std::mem::transmute(raw)
1194 }
1195}
1196
1197#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1198pub struct FunctionParameter {
1199 pub ty: Conf<Ref<Type>>,
1200 pub name: String,
1201 pub location: Option<Variable>,
1202}
1203
1204impl FunctionParameter {
1205 pub(crate) fn from_raw(value: &BNFunctionParameter) -> Self {
1206 let name = if value.name.is_null() {
1209 if value.location.type_ == VariableSourceType::RegisterVariableSourceType {
1210 format!("reg_{}", value.location.storage)
1211 } else if value.location.type_ == VariableSourceType::StackVariableSourceType {
1212 format!("arg_{}", value.location.storage)
1213 } else {
1214 String::new()
1215 }
1216 } else {
1217 raw_to_string(value.name as *const _).unwrap()
1218 };
1219
1220 Self {
1221 ty: Conf::new(
1222 unsafe { Type::from_raw(value.type_).to_owned() },
1223 value.typeConfidence,
1224 ),
1225 name,
1226 location: match value.defaultLocation {
1227 false => Some(Variable::from(value.location)),
1228 true => None,
1229 },
1230 }
1231 }
1232
1233 #[allow(unused)]
1234 pub(crate) fn from_owned_raw(value: BNFunctionParameter) -> Self {
1235 let owned = Self::from_raw(&value);
1236 Self::free_raw(value);
1237 owned
1238 }
1239
1240 pub(crate) fn into_raw(value: Self) -> BNFunctionParameter {
1241 let bn_name = BnString::new(value.name);
1242 BNFunctionParameter {
1243 name: BnString::into_raw(bn_name),
1244 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
1245 typeConfidence: value.ty.confidence,
1246 defaultLocation: value.location.is_none(),
1247 location: value.location.map(Into::into).unwrap_or_default(),
1248 }
1249 }
1250
1251 pub(crate) fn free_raw(value: BNFunctionParameter) {
1252 unsafe { BnString::free_raw(value.name) };
1253 let _ = unsafe { Type::ref_from_raw(value.type_) };
1254 }
1255
1256 pub fn new<T: Into<Conf<Ref<Type>>>>(ty: T, name: String, location: Option<Variable>) -> Self {
1257 Self {
1258 ty: ty.into(),
1259 name,
1260 location,
1261 }
1262 }
1263}
1264
1265#[derive(PartialEq, Eq, Hash)]
1266pub struct NamedTypeReference {
1267 pub(crate) handle: *mut BNNamedTypeReference,
1268}
1269
1270impl NamedTypeReference {
1271 pub(crate) unsafe fn from_raw(handle: *mut BNNamedTypeReference) -> Self {
1272 debug_assert!(!handle.is_null());
1273 Self { handle }
1274 }
1275
1276 pub(crate) unsafe fn ref_from_raw(handle: *mut BNNamedTypeReference) -> Ref<Self> {
1277 debug_assert!(!handle.is_null());
1278 Ref::new(Self { handle })
1279 }
1280
1281 pub fn new<T: Into<QualifiedName>>(type_class: NamedTypeReferenceClass, name: T) -> Ref<Self> {
1287 let mut raw_name = QualifiedName::into_raw(name.into());
1288 let result = unsafe {
1289 Self::ref_from_raw(BNCreateNamedType(
1290 type_class,
1291 std::ptr::null(),
1292 &mut raw_name,
1293 ))
1294 };
1295 QualifiedName::free_raw(raw_name);
1296 result
1297 }
1298
1299 pub fn new_with_id<T: Into<QualifiedName>>(
1305 type_class: NamedTypeReferenceClass,
1306 type_id: &str,
1307 name: T,
1308 ) -> Ref<Self> {
1309 let type_id = type_id.to_cstr();
1310 let mut raw_name = QualifiedName::into_raw(name.into());
1311 let result = unsafe {
1312 Self::ref_from_raw(BNCreateNamedType(
1313 type_class,
1314 type_id.as_ref().as_ptr() as _,
1315 &mut raw_name,
1316 ))
1317 };
1318 QualifiedName::free_raw(raw_name);
1319 result
1320 }
1321
1322 pub fn name(&self) -> QualifiedName {
1323 let raw_name = unsafe { BNGetTypeReferenceName(self.handle) };
1324 QualifiedName::from_owned_raw(raw_name)
1325 }
1326
1327 pub fn id(&self) -> String {
1328 unsafe { BnString::into_string(BNGetTypeReferenceId(self.handle)) }
1329 }
1330
1331 pub fn class(&self) -> NamedTypeReferenceClass {
1332 unsafe { BNGetTypeReferenceClass(self.handle) }
1333 }
1334
1335 fn target_helper(&self, bv: &BinaryView, visited: &mut HashSet<String>) -> Option<Ref<Type>> {
1336 let ty = bv.type_by_id(&self.id())?;
1337 match ty.type_class() {
1338 TypeClass::NamedTypeReferenceClass => {
1339 let ntr = ty
1341 .get_named_type_reference()
1342 .expect("NTR type class should always have a valid NTR");
1343 match visited.insert(ntr.id()) {
1344 true => ntr.target_helper(bv, visited),
1345 false => None,
1347 }
1348 }
1349 _ => Some(ty),
1351 }
1352 }
1353
1354 pub fn target(&self, bv: &BinaryView) -> Option<Ref<Type>> {
1358 self.target_helper(bv, &mut HashSet::new())
1359 }
1360}
1361
1362impl ToOwned for NamedTypeReference {
1363 type Owned = Ref<Self>;
1364
1365 fn to_owned(&self) -> Self::Owned {
1366 unsafe { RefCountable::inc_ref(self) }
1367 }
1368}
1369
1370unsafe impl RefCountable for NamedTypeReference {
1371 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
1372 Self::ref_from_raw(BNNewNamedTypeReference(handle.handle))
1373 }
1374
1375 unsafe fn dec_ref(handle: &Self) {
1376 BNFreeNamedTypeReference(handle.handle)
1377 }
1378}
1379
1380impl Debug for NamedTypeReference {
1381 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1382 write!(f, "{} (id: {})", self.name(), self.id())
1383 }
1384}
1385
1386#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1387pub struct QualifiedNameAndType {
1388 pub name: QualifiedName,
1389 pub ty: Ref<Type>,
1390}
1391
1392impl QualifiedNameAndType {
1393 pub(crate) fn from_raw(value: &BNQualifiedNameAndType) -> Self {
1394 Self {
1395 name: QualifiedName::from_raw(&value.name),
1396 ty: unsafe { Type::from_raw(value.type_).to_owned() },
1397 }
1398 }
1399
1400 pub(crate) fn from_owned_raw(value: BNQualifiedNameAndType) -> Self {
1401 let owned = Self::from_raw(&value);
1402 Self::free_raw(value);
1403 owned
1404 }
1405
1406 pub(crate) fn into_raw(value: Self) -> BNQualifiedNameAndType {
1407 BNQualifiedNameAndType {
1408 name: QualifiedName::into_raw(value.name),
1409 type_: unsafe { Ref::into_raw(value.ty).handle },
1410 }
1411 }
1412
1413 pub(crate) fn free_raw(value: BNQualifiedNameAndType) {
1414 QualifiedName::free_raw(value.name);
1415 let _ = unsafe { Type::ref_from_raw(value.type_) };
1416 }
1417
1418 pub fn new(name: QualifiedName, ty: Ref<Type>) -> Self {
1419 Self { name, ty }
1420 }
1421}
1422
1423impl<T> From<(T, Ref<Type>)> for QualifiedNameAndType
1424where
1425 T: Into<QualifiedName>,
1426{
1427 fn from(value: (T, Ref<Type>)) -> Self {
1428 Self {
1429 name: value.0.into(),
1430 ty: value.1,
1431 }
1432 }
1433}
1434
1435impl<T> From<(T, &Type)> for QualifiedNameAndType
1436where
1437 T: Into<QualifiedName>,
1438{
1439 fn from(value: (T, &Type)) -> Self {
1440 let ty = value.1.to_owned();
1441 Self {
1442 name: value.0.into(),
1443 ty,
1444 }
1445 }
1446}
1447
1448impl CoreArrayProvider for QualifiedNameAndType {
1449 type Raw = BNQualifiedNameAndType;
1450 type Context = ();
1451 type Wrapped<'a> = Self;
1452}
1453
1454unsafe impl CoreArrayProviderInner for QualifiedNameAndType {
1455 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1456 BNFreeTypeAndNameList(raw, count);
1457 }
1458
1459 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1460 QualifiedNameAndType::from_raw(raw)
1461 }
1462}
1463
1464#[derive(Debug, Clone, Hash, PartialEq, Eq)]
1465pub struct QualifiedNameTypeAndId {
1466 pub name: QualifiedName,
1467 pub ty: Ref<Type>,
1468 pub id: String,
1469}
1470
1471impl QualifiedNameTypeAndId {
1472 pub(crate) fn from_raw(value: &BNQualifiedNameTypeAndId) -> Self {
1473 Self {
1474 name: QualifiedName::from_raw(&value.name),
1475 ty: unsafe { Type::from_raw(value.type_) }.to_owned(),
1476 id: raw_to_string(value.id).unwrap(),
1477 }
1478 }
1479
1480 #[allow(unused)]
1481 pub(crate) fn from_owned_raw(value: BNQualifiedNameTypeAndId) -> Self {
1482 let owned = Self::from_raw(&value);
1483 Self::free_raw(value);
1484 owned
1485 }
1486
1487 pub(crate) fn into_raw(value: Self) -> BNQualifiedNameTypeAndId {
1488 let bn_id = BnString::new(value.id);
1489 BNQualifiedNameTypeAndId {
1490 name: QualifiedName::into_raw(value.name),
1491 id: BnString::into_raw(bn_id),
1492 type_: unsafe { Ref::into_raw(value.ty) }.handle,
1493 }
1494 }
1495
1496 pub(crate) fn free_raw(value: BNQualifiedNameTypeAndId) {
1497 QualifiedName::free_raw(value.name);
1498 let _ = unsafe { Type::ref_from_raw(value.type_) };
1499 let _ = unsafe { BnString::from_raw(value.id) };
1500 }
1501}
1502
1503impl CoreArrayProvider for QualifiedNameTypeAndId {
1504 type Raw = BNQualifiedNameTypeAndId;
1505 type Context = ();
1506 type Wrapped<'a> = QualifiedNameTypeAndId;
1507}
1508
1509unsafe impl CoreArrayProviderInner for QualifiedNameTypeAndId {
1510 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1511 BNFreeTypeIdList(raw, count);
1512 }
1513
1514 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1515 QualifiedNameTypeAndId::from_raw(raw)
1516 }
1517}
1518
1519#[derive(Debug, Clone, Eq, PartialEq, Hash)]
1524pub struct NameAndType {
1525 pub name: String,
1526 pub ty: Conf<Ref<Type>>,
1527}
1528
1529impl NameAndType {
1530 pub(crate) fn from_raw(value: &BNNameAndType) -> Self {
1531 Self {
1532 name: raw_to_string(value.name as *mut _).unwrap(),
1534 ty: Conf::new(
1535 unsafe { Type::from_raw(value.type_).to_owned() },
1536 value.typeConfidence,
1537 ),
1538 }
1539 }
1540
1541 #[allow(unused)]
1542 pub(crate) fn from_owned_raw(value: BNNameAndType) -> Self {
1543 let owned = Self::from_raw(&value);
1544 Self::free_raw(value);
1545 owned
1546 }
1547
1548 pub(crate) fn into_raw(value: Self) -> BNNameAndType {
1549 let bn_name = BnString::new(value.name);
1550 BNNameAndType {
1551 name: BnString::into_raw(bn_name),
1552 type_: unsafe { Ref::into_raw(value.ty.contents) }.handle,
1553 typeConfidence: value.ty.confidence,
1554 }
1555 }
1556
1557 pub(crate) fn free_raw(value: BNNameAndType) {
1558 unsafe { BnString::free_raw(value.name) };
1559 let _ = unsafe { Type::ref_from_raw(value.type_) };
1560 }
1561
1562 pub fn new(name: impl Into<String>, ty: Conf<Ref<Type>>) -> Self {
1563 Self {
1564 name: name.into(),
1565 ty,
1566 }
1567 }
1568}
1569
1570impl CoreArrayProvider for NameAndType {
1571 type Raw = BNNameAndType;
1572 type Context = ();
1573 type Wrapped<'a> = Self;
1574}
1575
1576unsafe impl CoreArrayProviderInner for NameAndType {
1577 unsafe fn free(raw: *mut Self::Raw, count: usize, _context: &Self::Context) {
1578 BNFreeNameAndTypeList(raw, count);
1579 }
1580
1581 unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, _context: &'a Self::Context) -> Self::Wrapped<'a> {
1582 NameAndType::from_raw(raw)
1583 }
1584}