mojo-bindgen 0.3.2__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/CHANGELOG.md +17 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/PKG-INFO +1 -1
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/record_policies.py +144 -15
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/cli.py +18 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/record_lowering.py +36 -2
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/pyproject.toml +1 -1
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/.gitignore +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/LICENSE +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/README.md +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/cir/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/cir/cir_canonicalizer.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/cir/reachability.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/cir/reference_validation.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/cir/validate_ir.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/common.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/alias_classification.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/bitfield_layout.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/context.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/dependency_graph.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/indexes.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/record_layout.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/record_storage.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/type_layout.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/alias_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/const_expr_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/const_value_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/decl_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/macro_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/mapping_support.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/mojo_emit_options.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/struct_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/type_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/union_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/mojo/unit_mapping.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/pipeline.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/traversal.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/type_walk.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/codegen/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/codegen/mojo_ir_printer.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/codegen/mojo_support_templates.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/codegen/normalize_mojo_module.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/ir.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/layout_tests/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/layout_tests/generator.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/orchestrator.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/diagnostics.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/doc_comments.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/frontend.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/__init__.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/const_expr.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/decl_lowering.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/literal_resolver.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/macro_env.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/primitive.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/lowering/type_lowering.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/parser.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/registry.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/parsing/target_abi.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/py.typed +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/serde.py +0 -0
- {mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/utils.py +0 -0
|
@@ -2,10 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.3.3] - 2026-06-27
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Add `mojo-bindgen --version` so scripts and users can inspect the installed
|
|
10
|
+
package version directly from the CLI.
|
|
11
|
+
- Make `mojo-bindgen` with no arguments print the help message instead of
|
|
12
|
+
failing on the missing header argument.
|
|
13
|
+
|
|
5
14
|
## [0.3.2] - 2026-06-23
|
|
6
15
|
|
|
7
16
|
### Changed
|
|
8
17
|
|
|
18
|
+
- Split struct trait inference from register-passability inference so generated
|
|
19
|
+
records now derive `Copyable` and `Movable` recursively through named types,
|
|
20
|
+
fixed arrays, and `UnsafeUnion` arms, keep atomics and flexible-tail records
|
|
21
|
+
non-copyable/non-movable, and document opaque-storage transfer traits as an
|
|
22
|
+
experimental default.
|
|
23
|
+
- Preserve typedef-backed integer bitfields such as `uint32_t flags:3` during
|
|
24
|
+
record lowering, keep their typedef surface names in generated accessors, and
|
|
25
|
+
stop silently dropping them before bitfield layout/codegen.
|
|
9
26
|
- Simplify and clarify the CLI surface: keep `--public-header` and
|
|
10
27
|
`--clang-arg`, add conventional `-o`, `-I`, `-D`, and `-U` forms, make
|
|
11
28
|
layout-test output explicit with `--layout-tests PATH`, and hide maintainer
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mojo-bindgen
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Generate Mojo FFI bindings from C headers using libclang
|
|
5
5
|
Project-URL: Homepage, https://github.com/MoSafi2/mojo_bindgen
|
|
6
6
|
Project-URL: Repository, https://github.com/MoSafi2/mojo_bindgen
|
|
@@ -27,6 +27,7 @@ from mojo_bindgen.ir import (
|
|
|
27
27
|
StructMember,
|
|
28
28
|
StructTraits,
|
|
29
29
|
Type,
|
|
30
|
+
TypeArg,
|
|
30
31
|
)
|
|
31
32
|
|
|
32
33
|
|
|
@@ -34,6 +35,14 @@ class AssignRecordPoliciesError(ValueError):
|
|
|
34
35
|
"""Raised when late record policy derivation cannot complete safely."""
|
|
35
36
|
|
|
36
37
|
|
|
38
|
+
@dataclass(frozen=True)
|
|
39
|
+
class TransferTraits:
|
|
40
|
+
"""Copy and move capability inferred separately from register passability."""
|
|
41
|
+
|
|
42
|
+
copyable: bool
|
|
43
|
+
movable: bool
|
|
44
|
+
|
|
45
|
+
|
|
37
46
|
_TRIVIAL_BUILTINS = frozenset(
|
|
38
47
|
builtin for builtin in MojoBuiltin if builtin != MojoBuiltin.UNSUPPORTED
|
|
39
48
|
)
|
|
@@ -68,8 +77,10 @@ class PolicyInferencePass:
|
|
|
68
77
|
def run(self, module: MojoModule) -> MojoModule:
|
|
69
78
|
self._structs = {decl.name: decl for decl in module.decls if isinstance(decl, StructDecl)}
|
|
70
79
|
self._aliases = {decl.name: decl for decl in module.decls if isinstance(decl, AliasDecl)}
|
|
71
|
-
self.
|
|
72
|
-
self.
|
|
80
|
+
self._passability_cache: dict[str, MojoPassability] = {}
|
|
81
|
+
self._passability_computing: set[str] = set()
|
|
82
|
+
self._transfer_cache: dict[str, TransferTraits] = {}
|
|
83
|
+
self._transfer_computing: set[str] = set()
|
|
73
84
|
|
|
74
85
|
return replace(
|
|
75
86
|
module,
|
|
@@ -80,7 +91,8 @@ class PolicyInferencePass:
|
|
|
80
91
|
if not isinstance(decl, StructDecl):
|
|
81
92
|
return decl
|
|
82
93
|
passability = self._record_passability(decl.name)
|
|
83
|
-
|
|
94
|
+
transfer_traits = self._record_transfer_traits(decl.name)
|
|
95
|
+
if self._has_representable_atomic_storage(decl) or decl.flexible_tail is not None:
|
|
84
96
|
return replace(
|
|
85
97
|
decl,
|
|
86
98
|
passability=passability,
|
|
@@ -91,7 +103,7 @@ class PolicyInferencePass:
|
|
|
91
103
|
return replace(
|
|
92
104
|
decl,
|
|
93
105
|
passability=passability,
|
|
94
|
-
traits=self.
|
|
106
|
+
traits=self._traits_for_decl(decl, passability, transfer_traits),
|
|
95
107
|
fieldwise_init=self._is_fieldwise_init_eligible(decl),
|
|
96
108
|
)
|
|
97
109
|
|
|
@@ -109,27 +121,27 @@ class PolicyInferencePass:
|
|
|
109
121
|
return True
|
|
110
122
|
|
|
111
123
|
def _record_passability(self, name: str) -> MojoPassability:
|
|
112
|
-
if name in self.
|
|
113
|
-
return self.
|
|
114
|
-
if name in self.
|
|
124
|
+
if name in self._passability_cache:
|
|
125
|
+
return self._passability_cache[name]
|
|
126
|
+
if name in self._passability_computing:
|
|
115
127
|
return MojoPassability.MEMORY_ONLY
|
|
116
128
|
|
|
117
129
|
decl = self._structs.get(name)
|
|
118
130
|
if decl is None or decl.kind != StructKind.PLAIN:
|
|
119
|
-
self.
|
|
131
|
+
self._passability_cache[name] = MojoPassability.MEMORY_ONLY
|
|
120
132
|
return MojoPassability.MEMORY_ONLY
|
|
121
133
|
if decl.flexible_tail is not None:
|
|
122
|
-
self.
|
|
134
|
+
self._passability_cache[name] = MojoPassability.MEMORY_ONLY
|
|
123
135
|
return MojoPassability.MEMORY_ONLY
|
|
124
136
|
if self._has_representable_atomic_storage(decl):
|
|
125
|
-
self.
|
|
137
|
+
self._passability_cache[name] = MojoPassability.MEMORY_ONLY
|
|
126
138
|
return MojoPassability.MEMORY_ONLY
|
|
127
139
|
|
|
128
|
-
self.
|
|
140
|
+
self._passability_computing.add(name)
|
|
129
141
|
try:
|
|
130
142
|
member_passabilities = [self._member_passability(member) for member in decl.members]
|
|
131
143
|
finally:
|
|
132
|
-
self.
|
|
144
|
+
self._passability_computing.remove(name)
|
|
133
145
|
|
|
134
146
|
if all(
|
|
135
147
|
passability == MojoPassability.TRIVIAL_REGISTER_PASSABLE
|
|
@@ -148,7 +160,46 @@ class PolicyInferencePass:
|
|
|
148
160
|
else:
|
|
149
161
|
result = MojoPassability.MEMORY_ONLY
|
|
150
162
|
|
|
151
|
-
self.
|
|
163
|
+
self._passability_cache[name] = result
|
|
164
|
+
return result
|
|
165
|
+
|
|
166
|
+
def _record_transfer_traits(self, name: str) -> TransferTraits:
|
|
167
|
+
if name in self._transfer_cache:
|
|
168
|
+
return self._transfer_cache[name]
|
|
169
|
+
if name in self._transfer_computing:
|
|
170
|
+
return TransferTraits(copyable=True, movable=True)
|
|
171
|
+
|
|
172
|
+
decl = self._structs.get(name)
|
|
173
|
+
if decl is None:
|
|
174
|
+
return TransferTraits(copyable=False, movable=False)
|
|
175
|
+
if decl.flexible_tail is not None or self._has_representable_atomic_storage(decl):
|
|
176
|
+
result = TransferTraits(copyable=False, movable=False)
|
|
177
|
+
self._transfer_cache[name] = result
|
|
178
|
+
return result
|
|
179
|
+
if decl.kind != StructKind.PLAIN:
|
|
180
|
+
result = TransferTraits(copyable=True, movable=True)
|
|
181
|
+
self._transfer_cache[name] = result
|
|
182
|
+
return result
|
|
183
|
+
|
|
184
|
+
if self._has_opaque_storage(decl):
|
|
185
|
+
# Experimental default: byte-backed fallback storage stays movable/copyable
|
|
186
|
+
# so generated wrappers remain usable while opaque record semantics are still
|
|
187
|
+
# being validated across real headers.
|
|
188
|
+
result = TransferTraits(copyable=True, movable=True)
|
|
189
|
+
self._transfer_cache[name] = result
|
|
190
|
+
return result
|
|
191
|
+
|
|
192
|
+
self._transfer_computing.add(name)
|
|
193
|
+
try:
|
|
194
|
+
member_traits = [self._member_transfer_traits(member) for member in decl.members]
|
|
195
|
+
finally:
|
|
196
|
+
self._transfer_computing.remove(name)
|
|
197
|
+
|
|
198
|
+
result = TransferTraits(
|
|
199
|
+
copyable=all(traits.copyable for traits in member_traits),
|
|
200
|
+
movable=all(traits.movable for traits in member_traits),
|
|
201
|
+
)
|
|
202
|
+
self._transfer_cache[name] = result
|
|
152
203
|
return result
|
|
153
204
|
|
|
154
205
|
def _member_passability(self, member: StructMember) -> MojoPassability:
|
|
@@ -164,6 +215,19 @@ class PolicyInferencePass:
|
|
|
164
215
|
f"unsupported StructMember for passability: {type(member).__name__!r}"
|
|
165
216
|
)
|
|
166
217
|
|
|
218
|
+
def _member_transfer_traits(self, member: StructMember) -> TransferTraits:
|
|
219
|
+
if isinstance(member, StoredMember):
|
|
220
|
+
return self._type_transfer_traits(member.type)
|
|
221
|
+
if isinstance(member, BitfieldGroupMember):
|
|
222
|
+
return self._type_transfer_traits(member.storage_type)
|
|
223
|
+
if isinstance(member, PaddingMember):
|
|
224
|
+
return TransferTraits(copyable=True, movable=True)
|
|
225
|
+
if isinstance(member, OpaqueStorageMember):
|
|
226
|
+
return TransferTraits(copyable=True, movable=True)
|
|
227
|
+
raise AssignRecordPoliciesError(
|
|
228
|
+
f"unsupported StructMember for transfer traits: {type(member).__name__!r}"
|
|
229
|
+
)
|
|
230
|
+
|
|
167
231
|
def _type_passability(self, t: Type) -> MojoPassability:
|
|
168
232
|
if isinstance(t, BuiltinType):
|
|
169
233
|
if t.name in _TRIVIAL_BUILTINS:
|
|
@@ -202,12 +266,77 @@ class PolicyInferencePass:
|
|
|
202
266
|
raise AssignRecordPoliciesError(f"unsupported Type for passability: {type(t).__name__!r}")
|
|
203
267
|
|
|
204
268
|
@staticmethod
|
|
205
|
-
def
|
|
269
|
+
def _passability_traits(passability: MojoPassability) -> list[StructTraits]:
|
|
206
270
|
if passability == MojoPassability.TRIVIAL_REGISTER_PASSABLE:
|
|
207
271
|
return [StructTraits.TRIVIAL_REGISTER_PASSABLE]
|
|
208
272
|
if passability == MojoPassability.REGISTER_PASSABLE:
|
|
209
273
|
return [StructTraits.REGISTER_PASSABLE]
|
|
210
|
-
return [
|
|
274
|
+
return []
|
|
275
|
+
|
|
276
|
+
def _type_transfer_traits(self, t: Type) -> TransferTraits:
|
|
277
|
+
if isinstance(t, BuiltinType):
|
|
278
|
+
supported = t.name in _TRIVIAL_BUILTINS
|
|
279
|
+
return TransferTraits(copyable=supported, movable=supported)
|
|
280
|
+
if isinstance(t, FunctionPtr):
|
|
281
|
+
return TransferTraits(copyable=True, movable=True)
|
|
282
|
+
if isinstance(t, Pointer):
|
|
283
|
+
return TransferTraits(copyable=True, movable=True)
|
|
284
|
+
if isinstance(t, Array):
|
|
285
|
+
if t.array_kind != "fixed" or t.size is None:
|
|
286
|
+
return TransferTraits(copyable=False, movable=False)
|
|
287
|
+
return self._type_transfer_traits(t.element)
|
|
288
|
+
if isinstance(t, ParametricType):
|
|
289
|
+
if t.base == ParametricBase.ATOMIC:
|
|
290
|
+
return TransferTraits(copyable=False, movable=False)
|
|
291
|
+
if t.base in (ParametricBase.SIMD, ParametricBase.COMPLEX_SIMD):
|
|
292
|
+
return TransferTraits(copyable=True, movable=True)
|
|
293
|
+
if t.base == ParametricBase.UNSAFE_UNION:
|
|
294
|
+
arg_traits = [self._transfer_traits_for_parametric_arg(arg) for arg in t.args]
|
|
295
|
+
return TransferTraits(
|
|
296
|
+
copyable=all(traits.copyable for traits in arg_traits),
|
|
297
|
+
movable=all(traits.movable for traits in arg_traits),
|
|
298
|
+
)
|
|
299
|
+
return TransferTraits(copyable=False, movable=False)
|
|
300
|
+
if isinstance(t, NamedType):
|
|
301
|
+
if t.name in _TRIVIAL_NAMED_TYPES:
|
|
302
|
+
return TransferTraits(copyable=True, movable=True)
|
|
303
|
+
|
|
304
|
+
struct_decl = self._structs.get(t.name)
|
|
305
|
+
if struct_decl is not None:
|
|
306
|
+
return self._record_transfer_traits(struct_decl.name)
|
|
307
|
+
|
|
308
|
+
alias_decl = self._aliases.get(t.name)
|
|
309
|
+
if alias_decl is None:
|
|
310
|
+
return TransferTraits(copyable=False, movable=False)
|
|
311
|
+
if alias_decl.kind == AliasKind.CALLBACK_SIGNATURE:
|
|
312
|
+
return TransferTraits(copyable=True, movable=True)
|
|
313
|
+
if alias_decl.kind in (AliasKind.TYPE_ALIAS, AliasKind.UNION_LAYOUT):
|
|
314
|
+
if alias_decl.type_value is None:
|
|
315
|
+
return TransferTraits(copyable=False, movable=False)
|
|
316
|
+
return self._type_transfer_traits(alias_decl.type_value)
|
|
317
|
+
return TransferTraits(copyable=False, movable=False)
|
|
318
|
+
raise AssignRecordPoliciesError(
|
|
319
|
+
f"unsupported Type for transfer traits: {type(t).__name__!r}"
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
def _transfer_traits_for_parametric_arg(self, arg) -> TransferTraits:
|
|
323
|
+
if isinstance(arg, TypeArg):
|
|
324
|
+
return self._type_transfer_traits(arg.type)
|
|
325
|
+
return TransferTraits(copyable=True, movable=True)
|
|
326
|
+
|
|
327
|
+
def _traits_for_decl(
|
|
328
|
+
self,
|
|
329
|
+
decl: StructDecl,
|
|
330
|
+
passability: MojoPassability,
|
|
331
|
+
transfer_traits: TransferTraits,
|
|
332
|
+
) -> list[StructTraits]:
|
|
333
|
+
traits = list(self._passability_traits(passability))
|
|
334
|
+
if decl.flexible_tail is None and not self._has_representable_atomic_storage(decl):
|
|
335
|
+
if transfer_traits.copyable:
|
|
336
|
+
traits.append(StructTraits.COPYABLE)
|
|
337
|
+
if transfer_traits.movable:
|
|
338
|
+
traits.append(StructTraits.MOVABLE)
|
|
339
|
+
return traits
|
|
211
340
|
|
|
212
341
|
@staticmethod
|
|
213
342
|
def _has_opaque_storage(decl: StructDecl) -> bool:
|
|
@@ -10,6 +10,7 @@ from typing import Annotated, Literal
|
|
|
10
10
|
import typer
|
|
11
11
|
from rich.console import Console
|
|
12
12
|
|
|
13
|
+
from mojo_bindgen import __version__
|
|
13
14
|
from mojo_bindgen.orchestrator import BindgenOptions, BindgenOrchestrator
|
|
14
15
|
from mojo_bindgen.parsing.frontend import ClangOptions
|
|
15
16
|
from mojo_bindgen.parsing.parser import ParseError
|
|
@@ -20,6 +21,12 @@ LinkModeOption = Literal["external-call", "owned-dl-handle"]
|
|
|
20
21
|
DiagnosticsMode = Literal["text", "json", "silent"]
|
|
21
22
|
|
|
22
23
|
|
|
24
|
+
def _version_callback(value: bool) -> None:
|
|
25
|
+
if value:
|
|
26
|
+
sys.stdout.write(f"mojo-bindgen {__version__}\n")
|
|
27
|
+
raise typer.Exit()
|
|
28
|
+
|
|
29
|
+
|
|
23
30
|
def run(
|
|
24
31
|
header: Annotated[
|
|
25
32
|
Path,
|
|
@@ -237,6 +244,15 @@ def run(
|
|
|
237
244
|
rich_help_panel="Output",
|
|
238
245
|
),
|
|
239
246
|
] = False,
|
|
247
|
+
version: Annotated[
|
|
248
|
+
bool,
|
|
249
|
+
typer.Option(
|
|
250
|
+
"--version",
|
|
251
|
+
callback=_version_callback,
|
|
252
|
+
is_eager=True,
|
|
253
|
+
help="Show the mojo-bindgen version and exit.",
|
|
254
|
+
),
|
|
255
|
+
] = False,
|
|
240
256
|
) -> int:
|
|
241
257
|
"""Generate Mojo FFI from a C header using libclang.
|
|
242
258
|
|
|
@@ -373,6 +389,8 @@ def _format_diagnostic(d) -> str:
|
|
|
373
389
|
|
|
374
390
|
def main(argv: list[str] | None = None) -> int:
|
|
375
391
|
cli_args = argv if argv is not None else sys.argv[1:]
|
|
392
|
+
if not cli_args:
|
|
393
|
+
cli_args = ["--help"]
|
|
376
394
|
previous_argv = sys.argv[:]
|
|
377
395
|
sys.argv = ["mojo-bindgen", *cli_args]
|
|
378
396
|
try:
|
|
@@ -12,7 +12,18 @@ from typing import cast
|
|
|
12
12
|
|
|
13
13
|
import clang.cindex as cx
|
|
14
14
|
|
|
15
|
-
from mojo_bindgen.ir import
|
|
15
|
+
from mojo_bindgen.ir import (
|
|
16
|
+
Array,
|
|
17
|
+
AtomicType,
|
|
18
|
+
FamPattern,
|
|
19
|
+
Field,
|
|
20
|
+
IntType,
|
|
21
|
+
QualifiedType,
|
|
22
|
+
Struct,
|
|
23
|
+
StructRef,
|
|
24
|
+
Type,
|
|
25
|
+
TypeRef,
|
|
26
|
+
)
|
|
16
27
|
from mojo_bindgen.parsing.diagnostics import ParserDiagnosticSink
|
|
17
28
|
from mojo_bindgen.parsing.doc_comments import cursor_doc_comment
|
|
18
29
|
from mojo_bindgen.parsing.lowering.type_lowering import TypeContext, TypeLowerer
|
|
@@ -307,7 +318,14 @@ class RecordLowerer:
|
|
|
307
318
|
"""Lower one normalized field site into one IR field."""
|
|
308
319
|
if site.is_bitfield:
|
|
309
320
|
backing = self.type_lowerer.lower(site.field_type, TypeContext.FIELD)
|
|
310
|
-
|
|
321
|
+
integer_backing = self._peel_bitfield_backing(backing)
|
|
322
|
+
if integer_backing is None:
|
|
323
|
+
if site.field_cursor is not None:
|
|
324
|
+
self.diagnostics.add_cursor_diag(
|
|
325
|
+
"warning",
|
|
326
|
+
site.field_cursor,
|
|
327
|
+
"bitfield backing type is not an integer after typedef/cv/atomic peeling; field skipped",
|
|
328
|
+
)
|
|
311
329
|
return None
|
|
312
330
|
return Field(
|
|
313
331
|
name=site.name,
|
|
@@ -353,6 +371,22 @@ class RecordLowerer:
|
|
|
353
371
|
),
|
|
354
372
|
)
|
|
355
373
|
|
|
374
|
+
@staticmethod
|
|
375
|
+
def _peel_bitfield_backing(field_type: Type) -> IntType | None:
|
|
376
|
+
"""Unwrap layout-transparent wrappers to find the integer bitfield backing type."""
|
|
377
|
+
while True:
|
|
378
|
+
if isinstance(field_type, TypeRef):
|
|
379
|
+
field_type = field_type.canonical
|
|
380
|
+
continue
|
|
381
|
+
if isinstance(field_type, QualifiedType):
|
|
382
|
+
field_type = field_type.unqualified
|
|
383
|
+
continue
|
|
384
|
+
if isinstance(field_type, AtomicType):
|
|
385
|
+
field_type = field_type.value_type
|
|
386
|
+
continue
|
|
387
|
+
break
|
|
388
|
+
return field_type if isinstance(field_type, IntType) else None
|
|
389
|
+
|
|
356
390
|
def _lower_field_site_type(self, site: FieldSite) -> Type:
|
|
357
391
|
"""Lower the type of one normalized field site."""
|
|
358
392
|
if site.attached_record is not None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mojo_bindgen-0.3.2 → mojo_bindgen-0.3.3}/mojo_bindgen/analysis/facts/alias_classification.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|