mt-lang 0.2.0
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.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/AUTHORS +3 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +82 -0
- data/LICENSE +21 -0
- data/README.md +1208 -0
- data/Rakefile +332 -0
- data/bin/mtc +8 -0
- data/bin/profile-mtc-checks +133 -0
- data/bin/tracy-profiler +0 -0
- data/docs/build-guide.md +536 -0
- data/docs/index.html +2778 -0
- data/docs/language-design.md +1519 -0
- data/docs/language-manual.md +1534 -0
- data/lib/milk_tea/base.rb +49 -0
- data/lib/milk_tea/bindings/bindgen/ast_parser.rb +398 -0
- data/lib/milk_tea/bindings/bindgen/declaration.rb +319 -0
- data/lib/milk_tea/bindings/bindgen/emitter.rb +387 -0
- data/lib/milk_tea/bindings/bindgen/overrides.rb +134 -0
- data/lib/milk_tea/bindings/bindgen/type_mapper.rb +622 -0
- data/lib/milk_tea/bindings/bindgen.rb +207 -0
- data/lib/milk_tea/bindings/cli.rb +121 -0
- data/lib/milk_tea/bindings/imported_bindings/defaults.rb +210 -0
- data/lib/milk_tea/bindings/imported_bindings/generator.rb +1114 -0
- data/lib/milk_tea/bindings/imported_bindings/method_source.rb +190 -0
- data/lib/milk_tea/bindings/imported_bindings/naming.rb +286 -0
- data/lib/milk_tea/bindings/imported_bindings.rb +215 -0
- data/lib/milk_tea/bindings/opengl_registry.rb +547 -0
- data/lib/milk_tea/bindings/raw_bindings/defaults.rb +1338 -0
- data/lib/milk_tea/bindings/raw_bindings.rb +269 -0
- data/lib/milk_tea/bindings/steamworks.rb +629 -0
- data/lib/milk_tea/bindings/upstream_sources.rb +352 -0
- data/lib/milk_tea/bindings/vendored_box2d.rb +79 -0
- data/lib/milk_tea/bindings/vendored_c_library.rb +322 -0
- data/lib/milk_tea/bindings/vendored_cjson.rb +52 -0
- data/lib/milk_tea/bindings/vendored_flecs.rb +78 -0
- data/lib/milk_tea/bindings/vendored_glfw.rb +77 -0
- data/lib/milk_tea/bindings/vendored_libuv.rb +75 -0
- data/lib/milk_tea/bindings/vendored_pcre2.rb +84 -0
- data/lib/milk_tea/bindings/vendored_raylib.rb +131 -0
- data/lib/milk_tea/bindings/vendored_sdl3.rb +78 -0
- data/lib/milk_tea/bindings/vendored_steamworks.rb +71 -0
- data/lib/milk_tea/bindings/vendored_tool.rb +71 -0
- data/lib/milk_tea/bindings/vendored_tools.rb +23 -0
- data/lib/milk_tea/bindings/vendored_tracy.rb +37 -0
- data/lib/milk_tea/bindings.rb +23 -0
- data/lib/milk_tea/core/ast.rb +311 -0
- data/lib/milk_tea/core/async_runtime_installer.rb +28 -0
- data/lib/milk_tea/core/binding_types.rb +18 -0
- data/lib/milk_tea/core/bindings/attribute_binding.rb +58 -0
- data/lib/milk_tea/core/bindings/function_binding.rb +5 -0
- data/lib/milk_tea/core/bindings/module_binding.rb +58 -0
- data/lib/milk_tea/core/bindings/value_binding.rb +21 -0
- data/lib/milk_tea/core/c_backend/aggregate_utils.rb +103 -0
- data/lib/milk_tea/core/c_backend/control_flow_emission.rb +412 -0
- data/lib/milk_tea/core/c_backend/expressions.rb +468 -0
- data/lib/milk_tea/core/c_backend/feature_detection.rb +483 -0
- data/lib/milk_tea/core/c_backend/reachability.rb +398 -0
- data/lib/milk_tea/core/c_backend/reinterpret.rb +226 -0
- data/lib/milk_tea/core/c_backend/runtime_helpers.rb +1080 -0
- data/lib/milk_tea/core/c_backend/statements.rb +563 -0
- data/lib/milk_tea/core/c_backend/type_collectors.rb +1545 -0
- data/lib/milk_tea/core/c_backend/type_declaration.rb +223 -0
- data/lib/milk_tea/core/c_backend/type_system.rb +345 -0
- data/lib/milk_tea/core/c_backend.rb +287 -0
- data/lib/milk_tea/core/compatibility_helpers.rb +79 -0
- data/lib/milk_tea/core/compile_time/const_eval.rb +187 -0
- data/lib/milk_tea/core/compile_time.rb +329 -0
- data/lib/milk_tea/core/control_flow/builder.rb +582 -0
- data/lib/milk_tea/core/control_flow/constant_propagation.rb +143 -0
- data/lib/milk_tea/core/control_flow/dataflow.rb +74 -0
- data/lib/milk_tea/core/control_flow/definite_assignment.rb +79 -0
- data/lib/milk_tea/core/control_flow/graph.rb +90 -0
- data/lib/milk_tea/core/control_flow/liveness.rb +24 -0
- data/lib/milk_tea/core/control_flow/nullability_flow.rb +43 -0
- data/lib/milk_tea/core/control_flow/reachability.rb +22 -0
- data/lib/milk_tea/core/control_flow/termination.rb +31 -0
- data/lib/milk_tea/core/control_flow.rb +34 -0
- data/lib/milk_tea/core/cst.rb +48 -0
- data/lib/milk_tea/core/cst_builder.rb +19 -0
- data/lib/milk_tea/core/ir.rb +85 -0
- data/lib/milk_tea/core/keywords.rb +97 -0
- data/lib/milk_tea/core/lexer/character_classes.rb +60 -0
- data/lib/milk_tea/core/lexer/format_strings.rb +225 -0
- data/lib/milk_tea/core/lexer/heredocs.rb +199 -0
- data/lib/milk_tea/core/lexer/indentation.rb +62 -0
- data/lib/milk_tea/core/lexer/numbers.rb +96 -0
- data/lib/milk_tea/core/lexer/recovery.rb +32 -0
- data/lib/milk_tea/core/lexer/strings.rb +167 -0
- data/lib/milk_tea/core/lexer/symbols.rb +71 -0
- data/lib/milk_tea/core/lexer/trivia.rb +53 -0
- data/lib/milk_tea/core/lexer.rb +430 -0
- data/lib/milk_tea/core/lowering/artifacts.rb +26 -0
- data/lib/milk_tea/core/lowering/async/analysis.rb +245 -0
- data/lib/milk_tea/core/lowering/async/lowering.rb +1399 -0
- data/lib/milk_tea/core/lowering/async/normalization.rb +459 -0
- data/lib/milk_tea/core/lowering/async.rb +714 -0
- data/lib/milk_tea/core/lowering/block.rb +1052 -0
- data/lib/milk_tea/core/lowering/calls.rb +1565 -0
- data/lib/milk_tea/core/lowering/declarations.rb +214 -0
- data/lib/milk_tea/core/lowering/dyn.rb +206 -0
- data/lib/milk_tea/core/lowering/events.rb +1054 -0
- data/lib/milk_tea/core/lowering/expressions.rb +1645 -0
- data/lib/milk_tea/core/lowering/foreign_cstr.rb +206 -0
- data/lib/milk_tea/core/lowering/functions.rb +242 -0
- data/lib/milk_tea/core/lowering/loops.rb +1087 -0
- data/lib/milk_tea/core/lowering/lowering_context.rb +80 -0
- data/lib/milk_tea/core/lowering/proc.rb +419 -0
- data/lib/milk_tea/core/lowering/resolve.rb +2516 -0
- data/lib/milk_tea/core/lowering/scans.rb +220 -0
- data/lib/milk_tea/core/lowering/str_buffer.rb +125 -0
- data/lib/milk_tea/core/lowering/utils.rb +1453 -0
- data/lib/milk_tea/core/lowering.rb +378 -0
- data/lib/milk_tea/core/module_binder.rb +181 -0
- data/lib/milk_tea/core/module_loader/errors.rb +21 -0
- data/lib/milk_tea/core/module_loader.rb +479 -0
- data/lib/milk_tea/core/module_path_resolver.rb +153 -0
- data/lib/milk_tea/core/module_roots.rb +88 -0
- data/lib/milk_tea/core/parser/attributes.rb +71 -0
- data/lib/milk_tea/core/parser/blocks.rb +119 -0
- data/lib/milk_tea/core/parser/declarations.rb +749 -0
- data/lib/milk_tea/core/parser/expressions.rb +624 -0
- data/lib/milk_tea/core/parser/recovery.rb +131 -0
- data/lib/milk_tea/core/parser/statements.rb +756 -0
- data/lib/milk_tea/core/parser/types.rb +271 -0
- data/lib/milk_tea/core/parser.rb +400 -0
- data/lib/milk_tea/core/prelude_installer.rb +29 -0
- data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +917 -0
- data/lib/milk_tea/core/pretty_printer/base_formatter.rb +87 -0
- data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +300 -0
- data/lib/milk_tea/core/pretty_printer.rb +17 -0
- data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +314 -0
- data/lib/milk_tea/core/semantic_analyzer/attributes.rb +184 -0
- data/lib/milk_tea/core/semantic_analyzer/calls.rb +992 -0
- data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1735 -0
- data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +355 -0
- data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +155 -0
- data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +354 -0
- data/lib/milk_tea/core/semantic_analyzer/generics.rb +383 -0
- data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +78 -0
- data/lib/milk_tea/core/semantic_analyzer/module_context.rb +35 -0
- data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +1438 -0
- data/lib/milk_tea/core/semantic_analyzer/nullability.rb +421 -0
- data/lib/milk_tea/core/semantic_analyzer/statements.rb +1308 -0
- data/lib/milk_tea/core/semantic_analyzer/top_level.rb +588 -0
- data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +307 -0
- data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +851 -0
- data/lib/milk_tea/core/semantic_analyzer.rb +327 -0
- data/lib/milk_tea/core/token.rb +26 -0
- data/lib/milk_tea/core/token_stream.rb +30 -0
- data/lib/milk_tea/core/types/layout.rb +243 -0
- data/lib/milk_tea/core/types/predicates.rb +609 -0
- data/lib/milk_tea/core/types/registry.rb +83 -0
- data/lib/milk_tea/core/types/types.rb +1696 -0
- data/lib/milk_tea/core/types/visitor.rb +442 -0
- data/lib/milk_tea/core.rb +25 -0
- data/lib/milk_tea/dap/backends/lldb_dap.rb +158 -0
- data/lib/milk_tea/dap/protocol.rb +58 -0
- data/lib/milk_tea/dap/server/breakpoints.rb +66 -0
- data/lib/milk_tea/dap/server/debug_map.rb +291 -0
- data/lib/milk_tea/dap/server/handlers.rb +374 -0
- data/lib/milk_tea/dap/server/launch.rb +261 -0
- data/lib/milk_tea/dap/server/lldb_backend.rb +380 -0
- data/lib/milk_tea/dap/server/pause_diagnostics.rb +109 -0
- data/lib/milk_tea/dap/server/utilities.rb +160 -0
- data/lib/milk_tea/dap/server/wire.rb +55 -0
- data/lib/milk_tea/dap/server.rb +131 -0
- data/lib/milk_tea/dap/session.rb +152 -0
- data/lib/milk_tea/dap.rb +6 -0
- data/lib/milk_tea/lsp/dependency_resolution.rb +52 -0
- data/lib/milk_tea/lsp/diagnostics.rb +611 -0
- data/lib/milk_tea/lsp/protocol.rb +104 -0
- data/lib/milk_tea/lsp/server/call_hierarchy.rb +274 -0
- data/lib/milk_tea/lsp/server/code_actions.rb +446 -0
- data/lib/milk_tea/lsp/server/code_lens.rb +97 -0
- data/lib/milk_tea/lsp/server/completion.rb +1099 -0
- data/lib/milk_tea/lsp/server/configuration.rb +167 -0
- data/lib/milk_tea/lsp/server/debug_info.rb +45 -0
- data/lib/milk_tea/lsp/server/definition.rb +779 -0
- data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +239 -0
- data/lib/milk_tea/lsp/server/execute_command.rb +25 -0
- data/lib/milk_tea/lsp/server/folding_range.rb +153 -0
- data/lib/milk_tea/lsp/server/formatting.rb +575 -0
- data/lib/milk_tea/lsp/server/hover.rb +1465 -0
- data/lib/milk_tea/lsp/server/inlay_hints.rb +204 -0
- data/lib/milk_tea/lsp/server/lifecycle.rb +234 -0
- data/lib/milk_tea/lsp/server/linked_editing_range.rb +43 -0
- data/lib/milk_tea/lsp/server/on_type_formatting.rb +73 -0
- data/lib/milk_tea/lsp/server/progress.rb +47 -0
- data/lib/milk_tea/lsp/server/references.rb +433 -0
- data/lib/milk_tea/lsp/server/rename.rb +598 -0
- data/lib/milk_tea/lsp/server/selection_range.rb +130 -0
- data/lib/milk_tea/lsp/server/semantic_tokens.rb +1745 -0
- data/lib/milk_tea/lsp/server/signature_help.rb +200 -0
- data/lib/milk_tea/lsp/server/text_documents.rb +125 -0
- data/lib/milk_tea/lsp/server/type_hierarchy.rb +167 -0
- data/lib/milk_tea/lsp/server/utilities.rb +520 -0
- data/lib/milk_tea/lsp/server.rb +415 -0
- data/lib/milk_tea/lsp/workspace/analysis.rb +209 -0
- data/lib/milk_tea/lsp/workspace/caches.rb +260 -0
- data/lib/milk_tea/lsp/workspace/collection.rb +98 -0
- data/lib/milk_tea/lsp/workspace/definition_index.rb +184 -0
- data/lib/milk_tea/lsp/workspace/dependency_graph.rb +282 -0
- data/lib/milk_tea/lsp/workspace/store.rb +154 -0
- data/lib/milk_tea/lsp/workspace/utilities.rb +490 -0
- data/lib/milk_tea/lsp/workspace.rb +127 -0
- data/lib/milk_tea/lsp.rb +13 -0
- data/lib/milk_tea/packages/atomic_write.rb +63 -0
- data/lib/milk_tea/packages/dependency_solver.rb +194 -0
- data/lib/milk_tea/packages/graph.rb +139 -0
- data/lib/milk_tea/packages/lock.rb +421 -0
- data/lib/milk_tea/packages/manager_cli.rb +485 -0
- data/lib/milk_tea/packages/manifest.rb +356 -0
- data/lib/milk_tea/packages/manifest_editor.rb +134 -0
- data/lib/milk_tea/packages/registry_metadata_provider.rb +34 -0
- data/lib/milk_tea/packages/registry_store.rb +420 -0
- data/lib/milk_tea/packages/services.rb +41 -0
- data/lib/milk_tea/packages/source_cache.rb +71 -0
- data/lib/milk_tea/packages/source_fetcher.rb +124 -0
- data/lib/milk_tea/packages/source_resolver.rb +389 -0
- data/lib/milk_tea/packages/version.rb +164 -0
- data/lib/milk_tea/packages.rb +16 -0
- data/lib/milk_tea/tooling/asset_pack.rb +141 -0
- data/lib/milk_tea/tooling/build.rb +1124 -0
- data/lib/milk_tea/tooling/build_cache.rb +240 -0
- data/lib/milk_tea/tooling/cli.rb +2688 -0
- data/lib/milk_tea/tooling/cst_formatter.rb +13 -0
- data/lib/milk_tea/tooling/debug_info_formatter.rb +456 -0
- data/lib/milk_tea/tooling/debug_map.rb +248 -0
- data/lib/milk_tea/tooling/docs_app.rb +369 -0
- data/lib/milk_tea/tooling/error_formatter.rb +86 -0
- data/lib/milk_tea/tooling/formatter.rb +787 -0
- data/lib/milk_tea/tooling/linter/doc_tags.rb +212 -0
- data/lib/milk_tea/tooling/linter/fix_engine.rb +237 -0
- data/lib/milk_tea/tooling/linter/flow_rules.rb +380 -0
- data/lib/milk_tea/tooling/linter/imports_platform.rb +841 -0
- data/lib/milk_tea/tooling/linter/release_rules.rb +744 -0
- data/lib/milk_tea/tooling/linter/reserved_names.rb +199 -0
- data/lib/milk_tea/tooling/linter/rules.rb +593 -0
- data/lib/milk_tea/tooling/linter/source_helpers.rb +407 -0
- data/lib/milk_tea/tooling/linter/trailing_comma.rb +139 -0
- data/lib/milk_tea/tooling/linter/visitors.rb +1286 -0
- data/lib/milk_tea/tooling/linter.rb +798 -0
- data/lib/milk_tea/tooling/project_scaffold.rb +82 -0
- data/lib/milk_tea/tooling/public/css/docs.css +166 -0
- data/lib/milk_tea/tooling/public/js/docs.js +94 -0
- data/lib/milk_tea/tooling/run.rb +408 -0
- data/lib/milk_tea/tooling/templates/wasm_shell.html +48 -0
- data/lib/milk_tea/tooling/toolchain_cli.rb +157 -0
- data/lib/milk_tea/tooling/views/404.erb +7 -0
- data/lib/milk_tea/tooling/views/index.erb +87 -0
- data/lib/milk_tea/tooling/views/layout.erb +69 -0
- data/lib/milk_tea/tooling/views/module.erb +97 -0
- data/lib/milk_tea/tooling/views/stdlib.erb +21 -0
- data/lib/milk_tea/tooling.rb +20 -0
- data/lib/milk_tea.rb +8 -0
- metadata +426 -0
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MilkTea
|
|
4
|
+
module Bindgen
|
|
5
|
+
class Generator
|
|
6
|
+
module GeneratorTypeMapper
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def map_c_type(qual_type, context:)
|
|
10
|
+
normalized = normalize_c_type(qual_type)
|
|
11
|
+
raise BindgenError, "missing C type for #{context}" if normalized.empty?
|
|
12
|
+
normalized, nullability = extract_top_level_nullability(normalized)
|
|
13
|
+
mapped_type = if array_type?(normalized)
|
|
14
|
+
map_array_type(normalized, context:)
|
|
15
|
+
elsif function_pointer_type?(normalized)
|
|
16
|
+
map_function_pointer_type(normalized, context:)
|
|
17
|
+
else
|
|
18
|
+
pointer_candidate = strip_pointer_suffix_qualifiers(normalized)
|
|
19
|
+
if pointer_type?(pointer_candidate)
|
|
20
|
+
if va_list_pointer?(pointer_candidate)
|
|
21
|
+
synthesize_typedef_dependency("va_list")
|
|
22
|
+
"va_list"
|
|
23
|
+
elsif c_string_pointer?(pointer_candidate)
|
|
24
|
+
"cstr"
|
|
25
|
+
else
|
|
26
|
+
pointee = pointer_candidate.sub(/\s*\*\z/, "")
|
|
27
|
+
pointer_name = top_level_const_qualified?(pointee) ? "const_ptr" : "ptr"
|
|
28
|
+
"#{pointer_name}[#{map_c_type(pointee, context:)}]"
|
|
29
|
+
end
|
|
30
|
+
else
|
|
31
|
+
unqualified = strip_qualifiers(normalized)
|
|
32
|
+
if unqualified == "__va_list_tag" || unqualified == "struct __va_list_tag"
|
|
33
|
+
synthesize_typedef_dependency("__va_list_tag")
|
|
34
|
+
"__va_list_tag"
|
|
35
|
+
elsif standard_typedef_primitive(unqualified)
|
|
36
|
+
standard_typedef_primitive(unqualified)
|
|
37
|
+
elsif PRIMITIVE_TYPE_MAP.key?(unqualified)
|
|
38
|
+
PRIMITIVE_TYPE_MAP.fetch(unqualified)
|
|
39
|
+
elsif @type_overrides.key?(unqualified)
|
|
40
|
+
@type_overrides.fetch(unqualified)
|
|
41
|
+
elsif unqualified.start_with?("long") || unqualified.start_with?("unsigned long") || unqualified.start_with?("signed long")
|
|
42
|
+
map_long_type(unqualified, context:)
|
|
43
|
+
elsif unqualified.start_with?("struct ") || unqualified.start_with?("union ") || unqualified.start_with?("enum ")
|
|
44
|
+
tag_name = unqualified.split.last
|
|
45
|
+
@type_overrides.fetch(tag_name) do
|
|
46
|
+
if unqualified.start_with?("struct ")
|
|
47
|
+
record_name_for(unqualified)
|
|
48
|
+
elsif unqualified.start_with?("union ")
|
|
49
|
+
record_name_for(unqualified)
|
|
50
|
+
else
|
|
51
|
+
enum_name_for(unqualified)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
elsif unqualified.match?(/\A[A-Za-z_][A-Za-z0-9_]*\z/)
|
|
55
|
+
if known_generated_type_name?(unqualified, @visible_typedef_names)
|
|
56
|
+
visible_type_name(unqualified)
|
|
57
|
+
else
|
|
58
|
+
raise BindgenError, "unknown referenced C type #{unqualified.inspect} for #{context}"
|
|
59
|
+
end
|
|
60
|
+
else
|
|
61
|
+
raise BindgenError, "unsupported C type #{qual_type.inspect} for #{context}"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
apply_nullability(mapped_type, nullability)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def array_type?(qual_type)
|
|
70
|
+
qual_type.match?(/\[[0-9]+\]\z/)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def map_array_type(qual_type, context:)
|
|
74
|
+
match = qual_type.match(/\A(.+)\[([0-9]+)\]\z/)
|
|
75
|
+
raise BindgenError, "unsupported array type #{qual_type.inspect} for #{context}" unless match
|
|
76
|
+
|
|
77
|
+
element_type = map_c_type(match[1], context: "element type of #{context}")
|
|
78
|
+
length = Integer(match[2], 10)
|
|
79
|
+
"array[#{element_type}, #{length}]"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def va_list_pointer?(qual_type)
|
|
83
|
+
stripped = strip_qualifiers(qual_type)
|
|
84
|
+
stripped == "struct __va_list_tag *" || stripped == "__va_list_tag *"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def function_pointer_type?(qual_type)
|
|
88
|
+
qual_type.match?(/\A.+\(\s*\*.*\)\s*\(.*\)\z/)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def map_function_pointer_typedef(node, context:)
|
|
92
|
+
function_proto = extract_function_proto(node)
|
|
93
|
+
raise BindgenError, "unsupported function pointer type #{node.dig("type", "qualType").inspect} for #{context}" unless function_proto
|
|
94
|
+
|
|
95
|
+
map_function_proto_node(function_proto, context:, nullability: function_pointer_surface_nullability(type_qual_type(node)))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def map_function_proto_node(function_proto, context:, nullability: nil)
|
|
99
|
+
inner_types = Array(function_proto["inner"])
|
|
100
|
+
raise BindgenError, "unsupported function pointer type #{function_proto.inspect} for #{context}" if inner_types.empty?
|
|
101
|
+
|
|
102
|
+
return_type = map_type_node(inner_types.first, context: "return type of #{context}")
|
|
103
|
+
param_types = inner_types.drop(1)
|
|
104
|
+
params = if param_types.empty? || (param_types.length == 1 && void_type_node?(param_types.first))
|
|
105
|
+
[]
|
|
106
|
+
else
|
|
107
|
+
param_types.each_with_index.map do |param_type, index|
|
|
108
|
+
"arg#{index}: #{map_type_node(param_type, context: "parameter #{index} of #{context}")}"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
apply_nullability("fn(#{params.join(', ')}) -> #{return_type}", nullability)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def map_function_pointer_type(qual_type, context:)
|
|
115
|
+
return_type_source, declarator_source, params_source = parse_function_pointer_signature(qual_type, context:)
|
|
116
|
+
|
|
117
|
+
# Handles C forms like `void (*)(...)` and pointer-wrapped variants like `void (**)(...)`.
|
|
118
|
+
pointer_depth_match = declarator_source.match(/\A((?:\*\s*)+)((?:_Nullable|_Nonnull|_Null_unspecified|_Nullable_result)?)\s*\z/)
|
|
119
|
+
if pointer_depth_match
|
|
120
|
+
pointer_depth = pointer_depth_match[1].count("*")
|
|
121
|
+
base_nullability = nullability_for_token(pointer_depth_match[2])
|
|
122
|
+
function_type = build_function_type(
|
|
123
|
+
return_type_source:,
|
|
124
|
+
params_source:,
|
|
125
|
+
nullability: base_nullability,
|
|
126
|
+
context:,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
wrapped_type = function_type
|
|
130
|
+
(pointer_depth - 1).times do
|
|
131
|
+
wrapped_type = "ptr[#{wrapped_type}]"
|
|
132
|
+
end
|
|
133
|
+
return wrapped_type
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Handles C forms like `void (*(*)(...))(...)` (function pointer returning function pointer).
|
|
137
|
+
nested_match = declarator_source.match(/\A\*\s*((?:_Nullable|_Nonnull|_Null_unspecified|_Nullable_result)?)\s*\(\s*\*\s*((?:_Nullable|_Nonnull|_Null_unspecified|_Nullable_result)?)\s*\)\s*\((.*)\)\s*\z/)
|
|
138
|
+
if nested_match
|
|
139
|
+
outer_nullability = nullability_for_token(nested_match[1])
|
|
140
|
+
returned_fn_nullability = nullability_for_token(nested_match[2])
|
|
141
|
+
outer_params_source = nested_match[3]
|
|
142
|
+
|
|
143
|
+
returned_fn_type = build_function_type(
|
|
144
|
+
return_type_source:,
|
|
145
|
+
params_source:,
|
|
146
|
+
nullability: returned_fn_nullability,
|
|
147
|
+
context: "return type of #{context}",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
outer_params = function_params_from_source(outer_params_source, context:)
|
|
151
|
+
return apply_nullability("fn(#{outer_params.join(', ')}) -> #{returned_fn_type}", outer_nullability)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
raise BindgenError, "unsupported function pointer type #{qual_type.inspect} for #{context}"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def parse_function_pointer_signature(qual_type, context:)
|
|
158
|
+
source = qual_type.strip
|
|
159
|
+
raise BindgenError, "unsupported function pointer type #{qual_type.inspect} for #{context}" unless source.end_with?(")")
|
|
160
|
+
|
|
161
|
+
params_start = matching_open_paren_index(source, source.length - 1)
|
|
162
|
+
raise BindgenError, "unsupported function pointer type #{qual_type.inspect} for #{context}" unless params_start
|
|
163
|
+
|
|
164
|
+
params_source = source[(params_start + 1)...-1]
|
|
165
|
+
prefix = source[0...params_start].rstrip
|
|
166
|
+
raise BindgenError, "unsupported function pointer type #{qual_type.inspect} for #{context}" unless prefix.end_with?(")")
|
|
167
|
+
|
|
168
|
+
declarator_end = prefix.length - 1
|
|
169
|
+
declarator_start = matching_open_paren_index(prefix, declarator_end)
|
|
170
|
+
raise BindgenError, "unsupported function pointer type #{qual_type.inspect} for #{context}" unless declarator_start
|
|
171
|
+
|
|
172
|
+
declarator_source = prefix[(declarator_start + 1)...declarator_end].strip
|
|
173
|
+
return_type_source = prefix[0...declarator_start].rstrip
|
|
174
|
+
raise BindgenError, "unsupported function pointer type #{qual_type.inspect} for #{context}" if return_type_source.empty?
|
|
175
|
+
|
|
176
|
+
[return_type_source, declarator_source, params_source]
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def matching_open_paren_index(source, close_index)
|
|
180
|
+
depth = 0
|
|
181
|
+
index = close_index
|
|
182
|
+
|
|
183
|
+
while index >= 0
|
|
184
|
+
char = source[index]
|
|
185
|
+
if char == ")"
|
|
186
|
+
depth += 1
|
|
187
|
+
elsif char == "("
|
|
188
|
+
depth -= 1
|
|
189
|
+
return index if depth.zero?
|
|
190
|
+
end
|
|
191
|
+
index -= 1
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
nil
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def function_params_from_source(params_source, context:)
|
|
198
|
+
param_list = split_top_level_csv(params_source)
|
|
199
|
+
return [] if param_list.empty? || (param_list.length == 1 && strip_qualifiers(param_list.first) == "void")
|
|
200
|
+
|
|
201
|
+
param_list.each_with_index.map do |param_type, index|
|
|
202
|
+
"arg#{index}: #{map_c_type(param_type, context: "parameter #{index} of #{context}")}"
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def build_function_type(return_type_source:, params_source:, nullability:, context:)
|
|
207
|
+
return_type = map_c_type(return_type_source, context: "return type of #{context}")
|
|
208
|
+
params = function_params_from_source(params_source, context:)
|
|
209
|
+
apply_nullability("fn(#{params.join(', ')}) -> #{return_type}", nullability)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def split_top_level_csv(source)
|
|
213
|
+
return [] if source.strip.empty?
|
|
214
|
+
|
|
215
|
+
parts = []
|
|
216
|
+
current = +""
|
|
217
|
+
depth = 0
|
|
218
|
+
|
|
219
|
+
source.each_char do |char|
|
|
220
|
+
case char
|
|
221
|
+
when "(", "["
|
|
222
|
+
depth += 1
|
|
223
|
+
current << char
|
|
224
|
+
when ")", "]"
|
|
225
|
+
depth -= 1 if depth.positive?
|
|
226
|
+
current << char
|
|
227
|
+
when ","
|
|
228
|
+
if depth.zero?
|
|
229
|
+
parts << current.strip
|
|
230
|
+
current = +""
|
|
231
|
+
else
|
|
232
|
+
current << char
|
|
233
|
+
end
|
|
234
|
+
else
|
|
235
|
+
current << char
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
parts << current.strip unless current.strip.empty?
|
|
240
|
+
parts
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def extract_function_proto(node)
|
|
244
|
+
queue = Array(node["inner"]).dup
|
|
245
|
+
until queue.empty?
|
|
246
|
+
current = queue.shift
|
|
247
|
+
next unless current.is_a?(Hash)
|
|
248
|
+
return current if current["kind"] == "FunctionProtoType"
|
|
249
|
+
|
|
250
|
+
queue.concat(Array(current["inner"]))
|
|
251
|
+
end
|
|
252
|
+
nil
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def map_type_node(node, context:)
|
|
256
|
+
alias_name = typedef_name_from_type_node(node)
|
|
257
|
+
return @type_overrides.fetch(alias_name) if alias_name && @type_overrides.key?(alias_name)
|
|
258
|
+
|
|
259
|
+
if alias_name && preserve_typedef_name?(alias_name) && direct_typedef_surface?(node, alias_name)
|
|
260
|
+
synthesize_typedef_dependency(alias_name)
|
|
261
|
+
return visible_type_name(alias_name)
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
qual_type = type_qual_type(node)
|
|
265
|
+
if function_pointer_type?(qual_type)
|
|
266
|
+
function_proto = extract_function_proto(node)
|
|
267
|
+
return map_function_proto_node(function_proto, context:, nullability: function_pointer_surface_nullability(qual_type)) if function_proto
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
map_c_type(qual_type, context:)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def preserve_typedef_name?(name)
|
|
274
|
+
name == "va_list" || @visible_typedef_names.include?(name)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def direct_typedef_surface?(node, alias_name)
|
|
278
|
+
spelled_type = normalize_c_type(node.dig("type", "qualType"))
|
|
279
|
+
strip_qualifiers(spelled_type) == alias_name
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def unresolved_alias_target?(mapped_type, alias_names)
|
|
283
|
+
match = mapped_type.match(/\A([A-Za-z_][A-Za-z0-9_]*)\z/)
|
|
284
|
+
return false unless match
|
|
285
|
+
|
|
286
|
+
name = match[1]
|
|
287
|
+
return false unless name.start_with?("__")
|
|
288
|
+
|
|
289
|
+
!known_generated_type_name?(name, alias_names)
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
def known_generated_type_name?(name, alias_names)
|
|
293
|
+
return true if PRIMITIVE_TYPE_MAP.value?(name)
|
|
294
|
+
return true if alias_names.include?(name)
|
|
295
|
+
return true if @record_visible_names.value?(name)
|
|
296
|
+
return true if @enum_visible_names.value?(name)
|
|
297
|
+
return true if @synthetic_declarations.any? { |declaration| declaration[:name] == name }
|
|
298
|
+
|
|
299
|
+
false
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def typedef_name_from_type_node(node)
|
|
303
|
+
queue = [node]
|
|
304
|
+
until queue.empty?
|
|
305
|
+
current = queue.shift
|
|
306
|
+
next unless current.is_a?(Hash)
|
|
307
|
+
|
|
308
|
+
if current["kind"] == "TypedefType"
|
|
309
|
+
name = current.dig("decl", "name")
|
|
310
|
+
return name if name && name != "__builtin_va_list"
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
queue.concat(Array(current["inner"]))
|
|
314
|
+
end
|
|
315
|
+
nil
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def void_type_node?(node)
|
|
319
|
+
node["kind"] == "BuiltinType" && normalize_c_type(node.dig("type", "qualType")) == "void"
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def synthesize_typedef_dependency(name)
|
|
323
|
+
case name
|
|
324
|
+
when "va_list"
|
|
325
|
+
return if @synthetic_declarations.any? { |declaration| declaration[:name] == "va_list" }
|
|
326
|
+
|
|
327
|
+
@synthetic_declarations << { kind: "opaque", name: "va_list", linkage_name: "va_list" }
|
|
328
|
+
when "__va_list_tag"
|
|
329
|
+
return if @synthetic_declarations.any? { |declaration| declaration[:name] == "__va_list_tag" }
|
|
330
|
+
|
|
331
|
+
@synthetic_declarations << { kind: "opaque", name: "__va_list_tag", linkage_name: "__va_list_tag" }
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
def record_c_name(node)
|
|
336
|
+
return unless node
|
|
337
|
+
|
|
338
|
+
typedef_name = @record_aliases[node["id"]]
|
|
339
|
+
typedef_name ||= @record_aliases_by_tag_name[node["name"]] if node["name"]
|
|
340
|
+
return typedef_name if typedef_name
|
|
341
|
+
|
|
342
|
+
tag_name = node["name"]
|
|
343
|
+
return "#{node["tagUsed"]} #{tag_name}" if tag_name && !tag_name.empty?
|
|
344
|
+
|
|
345
|
+
nil
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def aggregate_explicit_c_name(name, node)
|
|
349
|
+
c_name = record_c_name(node)
|
|
350
|
+
return if c_name.nil? || c_name == name
|
|
351
|
+
|
|
352
|
+
c_name
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
def synthetic_declarations_for(declarations)
|
|
356
|
+
existing_names = declarations.filter_map { |declaration| declaration[:name] }.to_h { |name| [name, true] }
|
|
357
|
+
@synthetic_declarations.reject { |declaration| existing_names.key?(declaration[:name]) }
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
def normalize_c_type(qual_type)
|
|
361
|
+
qual_type.to_s.gsub(/\s+/, " ").strip
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def extract_top_level_nullability(qual_type)
|
|
365
|
+
result = qual_type
|
|
366
|
+
nullability = nil
|
|
367
|
+
qualifier_pattern = NULLABILITY_QUALIFIERS.join("|")
|
|
368
|
+
|
|
369
|
+
loop do
|
|
370
|
+
match = result.match(/\s*(#{qualifier_pattern})\z/)
|
|
371
|
+
break unless match
|
|
372
|
+
|
|
373
|
+
nullability ||= nullability_for_token(match[1])
|
|
374
|
+
result = result[0...match.begin(0)].rstrip
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
[result, nullability]
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def function_pointer_surface_nullability(qual_type)
|
|
381
|
+
match = normalize_c_type(qual_type).match(/\(\s*\*\s*(_Nullable|_Nonnull|_Null_unspecified|_Nullable_result)?\s*\)\s*\(/)
|
|
382
|
+
nullability_for_token(match && match[1])
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def nullability_for_token(token)
|
|
386
|
+
return :nullable if token == "_Nullable" || token == "_Nullable_result"
|
|
387
|
+
return :nonnull if token == "_Nonnull"
|
|
388
|
+
return :unspecified if token == "_Null_unspecified"
|
|
389
|
+
|
|
390
|
+
nil
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def apply_nullability(mapped_type, nullability)
|
|
394
|
+
return mapped_type unless nullability == :nullable
|
|
395
|
+
return mapped_type if mapped_type.end_with?("?")
|
|
396
|
+
|
|
397
|
+
"#{mapped_type}?"
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def nullable_policy_type?(type)
|
|
401
|
+
type.include?("?")
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
def record_nullable_param_override(function_name, param_name, param_node, override_type)
|
|
405
|
+
return unless nullable_policy_type?(override_type)
|
|
406
|
+
|
|
407
|
+
auto_type, auto_error = infer_bindgen_type do
|
|
408
|
+
map_type_node(param_node, context: "parameter #{param_name} of #{function_name}")
|
|
409
|
+
end
|
|
410
|
+
return if auto_error.nil? && auto_type == override_type
|
|
411
|
+
|
|
412
|
+
@manual_nullable_param_overrides << {
|
|
413
|
+
function: function_name,
|
|
414
|
+
parameter: param_name,
|
|
415
|
+
override_type: override_type,
|
|
416
|
+
auto_type: auto_type,
|
|
417
|
+
c_type: type_qual_type(param_node),
|
|
418
|
+
auto_error: auto_error,
|
|
419
|
+
}.compact
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def record_nullable_return_override(node, override_type)
|
|
423
|
+
return unless nullable_policy_type?(override_type)
|
|
424
|
+
|
|
425
|
+
auto_type, auto_error = infer_bindgen_type do
|
|
426
|
+
map_c_type(function_return_type(node), context: "return type of #{node["name"]}")
|
|
427
|
+
end
|
|
428
|
+
return if auto_error.nil? && auto_type == override_type
|
|
429
|
+
|
|
430
|
+
@manual_nullable_return_overrides << {
|
|
431
|
+
function: node["name"],
|
|
432
|
+
override_type: override_type,
|
|
433
|
+
auto_type: auto_type,
|
|
434
|
+
c_type: function_return_type(node),
|
|
435
|
+
auto_error: auto_error,
|
|
436
|
+
}.compact
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
def infer_bindgen_type
|
|
440
|
+
[yield, nil]
|
|
441
|
+
rescue BindgenError => e
|
|
442
|
+
[nil, e.message]
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def strip_pointer_suffix_qualifiers(qual_type)
|
|
446
|
+
result = qual_type
|
|
447
|
+
qualifier_pattern = QUALIFIERS.join("|")
|
|
448
|
+
|
|
449
|
+
loop do
|
|
450
|
+
updated = result.sub(/\s*(?:#{qualifier_pattern})\z/, "")
|
|
451
|
+
break if updated == result
|
|
452
|
+
|
|
453
|
+
result = updated
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
result
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def top_level_const_qualified?(qual_type)
|
|
460
|
+
normalized = normalize_c_type(qual_type)
|
|
461
|
+
pointer_candidate = strip_pointer_suffix_qualifiers(normalized)
|
|
462
|
+
if pointer_type?(pointer_candidate)
|
|
463
|
+
return pointer_suffix_qualifiers(normalized).include?("const")
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
normalized.split.include?("const")
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
def pointer_suffix_qualifiers(qual_type)
|
|
470
|
+
result = qual_type
|
|
471
|
+
qualifier_pattern = QUALIFIERS.join("|")
|
|
472
|
+
qualifiers = []
|
|
473
|
+
|
|
474
|
+
loop do
|
|
475
|
+
match = result.match(/\s*(#{qualifier_pattern})\z/)
|
|
476
|
+
break unless match
|
|
477
|
+
|
|
478
|
+
qualifiers << match[1]
|
|
479
|
+
result = result[0...match.begin(0)]
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
qualifiers
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
def standard_typedef_primitive(unqualified)
|
|
486
|
+
return "ptr_uint" if unqualified == "size_t"
|
|
487
|
+
return "ptr_int" if unqualified == "ssize_t" || unqualified == "ptrdiff_t"
|
|
488
|
+
return "int" if unqualified == "wchar_t"
|
|
489
|
+
|
|
490
|
+
integer_typedef_primitive(unqualified)
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
def integer_typedef_primitive(unqualified)
|
|
494
|
+
match = unqualified.match(/\A(?:__)?(u_?)?int(8|16|32|64)_t\z/)
|
|
495
|
+
return unless match
|
|
496
|
+
|
|
497
|
+
signed_prefix = match[1]
|
|
498
|
+
width = match[2]
|
|
499
|
+
if signed_prefix
|
|
500
|
+
{
|
|
501
|
+
"8" => "ubyte",
|
|
502
|
+
"16" => "ushort",
|
|
503
|
+
"32" => "uint",
|
|
504
|
+
"64" => "ulong",
|
|
505
|
+
}.fetch(width)
|
|
506
|
+
else
|
|
507
|
+
{
|
|
508
|
+
"8" => "byte",
|
|
509
|
+
"16" => "short",
|
|
510
|
+
"32" => "int",
|
|
511
|
+
"64" => "long",
|
|
512
|
+
}.fetch(width)
|
|
513
|
+
end
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def pointer_type?(qual_type)
|
|
517
|
+
qual_type.end_with?("*")
|
|
518
|
+
end
|
|
519
|
+
|
|
520
|
+
def c_string_pointer?(qual_type)
|
|
521
|
+
pointee = qual_type.sub(/\s*\*\z/, "")
|
|
522
|
+
unqualified = strip_qualifiers(pointee)
|
|
523
|
+
unqualified == "char" && pointee.split.include?("const")
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
def string_literal_macro_compatible_c_type?(qual_type)
|
|
527
|
+
pointer_candidate = strip_pointer_suffix_qualifiers(qual_type)
|
|
528
|
+
return true if c_string_pointer?(pointer_candidate)
|
|
529
|
+
|
|
530
|
+
match = qual_type.match(/\A(.+)\[[0-9]+\]\z/)
|
|
531
|
+
return false unless match
|
|
532
|
+
|
|
533
|
+
strip_qualifiers(match[1]) == "char"
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
def strip_qualifiers(qual_type)
|
|
537
|
+
qual_type.split.reject { |token| QUALIFIERS.include?(token) }.join(" ")
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def map_long_type(unqualified, context:)
|
|
541
|
+
case unqualified
|
|
542
|
+
when "long", "long int", "signed long", "signed long int"
|
|
543
|
+
long_width_type(signed: true)
|
|
544
|
+
when "unsigned long", "unsigned long int"
|
|
545
|
+
long_width_type(signed: false)
|
|
546
|
+
else
|
|
547
|
+
raise BindgenError, "unsupported C type #{context}: #{unqualified.inspect}"
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
def long_width_type(signed:)
|
|
552
|
+
width = long_width_bytes
|
|
553
|
+
mapping = signed ? { 4 => "int", 8 => "long" } : { 4 => "uint", 8 => "ulong" }
|
|
554
|
+
mapping.fetch(width) do
|
|
555
|
+
raise BindgenError, "unsupported C long width #{width} bytes"
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
def long_width_bytes
|
|
560
|
+
return @long_width_bytes if defined?(@long_width_bytes)
|
|
561
|
+
|
|
562
|
+
stdout, stderr, status = Open3.capture3(@clang, "-x", "c", "-dM", "-E", "-", *@clang_args, stdin_data: "")
|
|
563
|
+
unless status.success?
|
|
564
|
+
details = [stdout, stderr].reject(&:empty?).join
|
|
565
|
+
raise BindgenError, details.empty? ? "failed to query clang target macros" : "failed to query clang target macros:\n#{details}"
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
define = stdout.lines.find { |line| line.start_with?("#define __SIZEOF_LONG__ ") }
|
|
569
|
+
raise BindgenError, "clang did not report __SIZEOF_LONG__" unless define
|
|
570
|
+
|
|
571
|
+
@long_width_bytes = Integer(define.split.last, 10)
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
def record_name_for(unqualified)
|
|
575
|
+
synthesize_record_dependency(unqualified)
|
|
576
|
+
tag_name = unqualified.split.last
|
|
577
|
+
@record_visible_names[tag_name] || tag_name
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def enum_name_for(unqualified)
|
|
581
|
+
tag_name = unqualified.split.last
|
|
582
|
+
@enum_visible_names[tag_name] || tag_name
|
|
583
|
+
end
|
|
584
|
+
|
|
585
|
+
def synthesize_record_dependency(unqualified)
|
|
586
|
+
kind, tag_name = unqualified.split(" ", 2)
|
|
587
|
+
return unless %w[struct union].include?(kind)
|
|
588
|
+
return if tag_name.nil? || tag_name.empty?
|
|
589
|
+
return if @record_visible_names.key?(tag_name) || @record_visible_names.value?(tag_name)
|
|
590
|
+
|
|
591
|
+
record_node = @referenceable_record_declarations[tag_name]
|
|
592
|
+
original_name = record_node ? (@record_aliases[record_node["id"]] || tag_name) : tag_name
|
|
593
|
+
visible_name = visible_type_name(original_name)
|
|
594
|
+
return if @synthetic_declarations.any? { |declaration| declaration[:name] == visible_name }
|
|
595
|
+
|
|
596
|
+
@record_visible_names[tag_name] = visible_name
|
|
597
|
+
@record_visible_names[visible_name] = visible_name
|
|
598
|
+
|
|
599
|
+
if record_node && record_complete_definition?(record_node)
|
|
600
|
+
@synthetic_declarations << {
|
|
601
|
+
kind: record_node.fetch("tagUsed"),
|
|
602
|
+
name: visible_name,
|
|
603
|
+
node: record_node,
|
|
604
|
+
}
|
|
605
|
+
@aggregate_declarations[visible_name] = record_node
|
|
606
|
+
return
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
@synthetic_declarations << {
|
|
610
|
+
kind: "opaque",
|
|
611
|
+
name: visible_name,
|
|
612
|
+
linkage_name: "#{kind} #{tag_name}",
|
|
613
|
+
}
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
def visible_type_name(name)
|
|
617
|
+
@type_name_overrides.fetch(name, name)
|
|
618
|
+
end
|
|
619
|
+
end
|
|
620
|
+
end
|
|
621
|
+
end
|
|
622
|
+
end
|