1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! `cxx` `extern "Rust"` opaque-visitor bridges for the ctree and tinfo walks (namespace
//! `bridge`).
//!
//! Two production walks each drive an [`extern "Rust"`] **opaque visitor** whose `&mut self`
//! methods `cxx` exposes to C++ as callable member functions, sharing one bridge module:
//!
//! - the ctree walk ([`CtreeVisitor`], driver `facade/ctree_bridge.cpp`'s `walker_t`) walks a
//! decompiled `cfunc_t` depth-first, calling one method per expression, statement, and local;
//! - the tinfo type walk ([`TypeWalkVisitor`], driver `facade/typewalk_bridge.cpp`'s `visit_walker_t`)
//! walks a `tinfo_t`, calling one method per node kind.
//!
//! Neither uses a function-pointer table or a `void*` context: each visitor forwards every C++ call
//! straight into a sink ([`CtreeSink`] / [`TypeWalkSink`]) the consumer supplies, so `idakit`
//! interns nodes into its own tables without a C-ABI shim layer. The ctree walk resolves node types
//! through the same type walker, handed [`cfunc_walk_ctree`]'s `type_visitor` address.
//!
//! Per-call data crosses borrowed for the duration of that one call, except names. Names, string
//! literals, and comments cross as owned `String` (`rust::String`), decoded leniently facade-side
//! (IDA emits UTF-8; any undecodable unit is U+FFFD), so the sink never re-decodes. Child-handle
//! arrays cross as `&[u32]`; struct members and enum constants cross as `&[MemberInfo]` /
//! `&[EnumConstInfo]`, plain POD shared structs with an owned `name: String`.
//!
//! The sink traits, opaque visitors, and the bridge module itself are generated by the
//! `idakit-sys-codegen` crate's `emit` engine from the declarative manifest in its
//! `visitors` module, so their signatures never drift out of sync across the trait, the
//! forwarding `impl`, and the `extern "Rust"` decl; only the hand-written constructors/drivers
//! below stay in this file.
//!
//! # Panic safety
//!
//! A `cxx` `extern "Rust"` function (including an opaque type's methods) that panics is caught at
//! the boundary: `cxx` logs and calls `std::process::abort`, so a panic never unwinds into C++.
//! The visitor methods here are panic-free in the normal path regardless; this is the contract if
//! one ever did.
// cxx::bridge auto-derives Clone/Debug/etc. for each shared struct it declares, and that
// generated code trips unused_qualifications on the struct's own name; scoped here since the
// generated module can't carry its own attribute.
use NonNull;
include!;
pub use ;
/// Walk the local type named `name` into `sink` via the `cxx` opaque visitor; returns the root
/// handle, or `None` when no such type exists (or a name was not valid UTF-8, surfaced as a thrown
/// `Err`).
/// Walk the local type at `ordinal` into `sink`; the ordinal twin of [`walk_type_named`].
/// Walk the prototype of the function at `ea` into `sink`; the function-address twin of
/// [`walk_type_named`]. `None` when the function has no type info.
/// Walk the stack frame of the function at `ea`, interning each variable's type into `sink`.
///
/// Returns the frame size and variables, or `None` when there is no function or frame at `ea`.
/// The returned [`FrameVar::ty`] handles index the table `sink` built.