mt-lang 0.3.8 → 0.3.10

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.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/lib/milk_tea/base.rb +1 -2
  3. data/lib/milk_tea/bindings/bindgen/ast_parser.rb +0 -2
  4. data/lib/milk_tea/bindings/bindgen/declaration.rb +0 -2
  5. data/lib/milk_tea/bindings/bindgen/emitter.rb +0 -2
  6. data/lib/milk_tea/bindings/bindgen/overrides.rb +0 -2
  7. data/lib/milk_tea/bindings/bindgen/type_mapper.rb +51 -53
  8. data/lib/milk_tea/bindings/imported_bindings/generator.rb +7 -9
  9. data/lib/milk_tea/bindings/imported_bindings/method_source.rb +0 -2
  10. data/lib/milk_tea/bindings/imported_bindings/naming.rb +6 -8
  11. data/lib/milk_tea/bindings/imported_bindings.rb +0 -2
  12. data/lib/milk_tea/bindings/opengl_registry.rb +3 -7
  13. data/lib/milk_tea/bindings/steamworks.rb +12 -16
  14. data/lib/milk_tea/bindings/upstream_sources.rb +10 -14
  15. data/lib/milk_tea/bindings/vendored_box2d.rb +10 -12
  16. data/lib/milk_tea/bindings/vendored_cjson.rb +6 -8
  17. data/lib/milk_tea/bindings/vendored_flecs.rb +10 -12
  18. data/lib/milk_tea/bindings/vendored_glfw.rb +11 -13
  19. data/lib/milk_tea/bindings/vendored_libuv.rb +11 -13
  20. data/lib/milk_tea/bindings/vendored_pcre2.rb +11 -13
  21. data/lib/milk_tea/bindings/vendored_raylib.rb +6 -10
  22. data/lib/milk_tea/bindings/vendored_sdl3.rb +11 -13
  23. data/lib/milk_tea/bindings/vendored_steamworks.rb +1 -5
  24. data/lib/milk_tea/core/ast.rb +103 -45
  25. data/lib/milk_tea/core/async_runtime_installer.rb +0 -2
  26. data/lib/milk_tea/core/bindings/attribute_binding.rb +1 -3
  27. data/lib/milk_tea/core/c_backend/aggregate_utils.rb +147 -84
  28. data/lib/milk_tea/core/c_backend/control_flow_emission.rb +394 -396
  29. data/lib/milk_tea/core/c_backend/expressions.rb +489 -476
  30. data/lib/milk_tea/core/c_backend/feature_detection.rb +446 -437
  31. data/lib/milk_tea/core/c_backend/format_helpers.rb +0 -2
  32. data/lib/milk_tea/core/c_backend/reachability.rb +339 -341
  33. data/lib/milk_tea/core/c_backend/reinterpret.rb +231 -217
  34. data/lib/milk_tea/core/c_backend/runtime_helpers.rb +531 -526
  35. data/lib/milk_tea/core/c_backend/statements.rb +528 -530
  36. data/lib/milk_tea/core/c_backend/type_collectors.rb +1344 -1346
  37. data/lib/milk_tea/core/c_backend/type_declaration.rb +215 -213
  38. data/lib/milk_tea/core/c_backend/type_system.rb +347 -349
  39. data/lib/milk_tea/core/c_backend.rb +17 -9
  40. data/lib/milk_tea/core/compatibility_helpers.rb +0 -2
  41. data/lib/milk_tea/core/compile_time/const_eval.rb +7 -12
  42. data/lib/milk_tea/core/compile_time.rb +32 -38
  43. data/lib/milk_tea/core/control_flow/builder.rb +3 -5
  44. data/lib/milk_tea/core/control_flow/constant_propagation.rb +14 -17
  45. data/lib/milk_tea/core/control_flow/definite_assignment.rb +0 -1
  46. data/lib/milk_tea/core/ir.rb +10 -10
  47. data/lib/milk_tea/core/lexer/character_classes.rb +5 -7
  48. data/lib/milk_tea/core/lexer/format_strings.rb +7 -9
  49. data/lib/milk_tea/core/lexer/heredocs.rb +22 -22
  50. data/lib/milk_tea/core/lexer/indentation.rb +0 -2
  51. data/lib/milk_tea/core/lexer/numbers.rb +0 -2
  52. data/lib/milk_tea/core/lexer/recovery.rb +0 -2
  53. data/lib/milk_tea/core/lexer/strings.rb +0 -2
  54. data/lib/milk_tea/core/lexer/symbols.rb +0 -2
  55. data/lib/milk_tea/core/lexer/trivia.rb +0 -2
  56. data/lib/milk_tea/core/lexer.rb +0 -2
  57. data/lib/milk_tea/core/lowering/async/analysis.rb +0 -2
  58. data/lib/milk_tea/core/lowering/async/lowering.rb +1264 -1265
  59. data/lib/milk_tea/core/lowering/async/normalization.rb +0 -2
  60. data/lib/milk_tea/core/lowering/async.rb +627 -630
  61. data/lib/milk_tea/core/lowering/block.rb +413 -416
  62. data/lib/milk_tea/core/lowering/calls.rb +1381 -1384
  63. data/lib/milk_tea/core/lowering/declarations.rb +180 -183
  64. data/lib/milk_tea/core/lowering/dyn.rb +48 -50
  65. data/lib/milk_tea/core/lowering/events.rb +983 -985
  66. data/lib/milk_tea/core/lowering/expressions.rb +1513 -1518
  67. data/lib/milk_tea/core/lowering/foreign_cstr.rb +181 -184
  68. data/lib/milk_tea/core/lowering/functions.rb +185 -188
  69. data/lib/milk_tea/core/lowering/loops.rb +1028 -1031
  70. data/lib/milk_tea/core/lowering/proc.rb +363 -366
  71. data/lib/milk_tea/core/lowering/resolve.rb +2133 -2135
  72. data/lib/milk_tea/core/lowering/scans.rb +179 -181
  73. data/lib/milk_tea/core/lowering/str_buffer.rb +102 -105
  74. data/lib/milk_tea/core/lowering/utils.rb +1040 -1044
  75. data/lib/milk_tea/core/lowering.rb +5 -7
  76. data/lib/milk_tea/core/module_binder.rb +0 -2
  77. data/lib/milk_tea/core/module_loader/errors.rb +4 -2
  78. data/lib/milk_tea/core/module_loader.rb +113 -20
  79. data/lib/milk_tea/core/module_path_resolver.rb +0 -2
  80. data/lib/milk_tea/core/module_roots.rb +6 -8
  81. data/lib/milk_tea/core/parser/attributes.rb +0 -2
  82. data/lib/milk_tea/core/parser/blocks.rb +0 -2
  83. data/lib/milk_tea/core/parser/declarations.rb +0 -2
  84. data/lib/milk_tea/core/parser/expressions.rb +31 -14
  85. data/lib/milk_tea/core/parser/recovery.rb +0 -2
  86. data/lib/milk_tea/core/parser/statements.rb +0 -2
  87. data/lib/milk_tea/core/parser/types.rb +8 -10
  88. data/lib/milk_tea/core/parser.rb +1 -3
  89. data/lib/milk_tea/core/pretty_printer/ast_formatter.rb +31 -33
  90. data/lib/milk_tea/core/pretty_printer/base_formatter.rb +0 -2
  91. data/lib/milk_tea/core/pretty_printer/ir_formatter.rb +0 -2
  92. data/lib/milk_tea/core/semantic_analyzer/analysis_context.rb +0 -2
  93. data/lib/milk_tea/core/semantic_analyzer/attributes.rb +14 -16
  94. data/lib/milk_tea/core/semantic_analyzer/calls.rb +0 -2
  95. data/lib/milk_tea/core/semantic_analyzer/expressions.rb +1 -14
  96. data/lib/milk_tea/core/semantic_analyzer/flow_refinement.rb +18 -21
  97. data/lib/milk_tea/core/semantic_analyzer/foreign_functions.rb +0 -3
  98. data/lib/milk_tea/core/semantic_analyzer/function_binding.rb +12 -15
  99. data/lib/milk_tea/core/semantic_analyzer/generics.rb +57 -59
  100. data/lib/milk_tea/core/semantic_analyzer/interface_conformance.rb +0 -2
  101. data/lib/milk_tea/core/semantic_analyzer/name_resolution.rb +5 -9
  102. data/lib/milk_tea/core/semantic_analyzer/nullability.rb +0 -3
  103. data/lib/milk_tea/core/semantic_analyzer/statements.rb +35 -40
  104. data/lib/milk_tea/core/semantic_analyzer/top_level.rb +10 -12
  105. data/lib/milk_tea/core/semantic_analyzer/type_compatibility.rb +0 -6
  106. data/lib/milk_tea/core/semantic_analyzer/type_declaration.rb +102 -105
  107. data/lib/milk_tea/core/semantic_analyzer.rb +17 -8
  108. data/lib/milk_tea/core/types/layout.rb +21 -22
  109. data/lib/milk_tea/core/types/predicates.rb +0 -2
  110. data/lib/milk_tea/core/types/registry.rb +16 -18
  111. data/lib/milk_tea/core/types/visitor.rb +0 -4
  112. data/lib/milk_tea/dap/backends/lldb_dap.rb +0 -2
  113. data/lib/milk_tea/dap/protocol.rb +1 -1
  114. data/lib/milk_tea/dap/server/breakpoints.rb +0 -2
  115. data/lib/milk_tea/dap/server/debug_map.rb +0 -2
  116. data/lib/milk_tea/dap/server/handlers.rb +0 -2
  117. data/lib/milk_tea/dap/server/launch.rb +0 -2
  118. data/lib/milk_tea/dap/server/lldb_backend.rb +8 -10
  119. data/lib/milk_tea/dap/server/pause_diagnostics.rb +14 -16
  120. data/lib/milk_tea/dap/server/utilities.rb +0 -2
  121. data/lib/milk_tea/dap/server/wire.rb +0 -2
  122. data/lib/milk_tea/dap/server.rb +0 -2
  123. data/lib/milk_tea/lsp/diagnostics.rb +16 -16
  124. data/lib/milk_tea/lsp/server/call_hierarchy.rb +11 -12
  125. data/lib/milk_tea/lsp/server/code_actions.rb +355 -357
  126. data/lib/milk_tea/lsp/server/code_lens.rb +23 -25
  127. data/lib/milk_tea/lsp/server/completion.rb +873 -875
  128. data/lib/milk_tea/lsp/server/configuration.rb +129 -131
  129. data/lib/milk_tea/lsp/server/debug_info.rb +0 -2
  130. data/lib/milk_tea/lsp/server/definition.rb +564 -565
  131. data/lib/milk_tea/lsp/server/diagnostics_scheduling.rb +191 -193
  132. data/lib/milk_tea/lsp/server/execute_command.rb +0 -2
  133. data/lib/milk_tea/lsp/server/folding_range.rb +0 -4
  134. data/lib/milk_tea/lsp/server/formatting.rb +478 -480
  135. data/lib/milk_tea/lsp/server/hover.rb +1282 -1284
  136. data/lib/milk_tea/lsp/server/inlay_hints.rb +179 -181
  137. data/lib/milk_tea/lsp/server/lifecycle.rb +192 -194
  138. data/lib/milk_tea/lsp/server/linked_editing_range.rb +0 -2
  139. data/lib/milk_tea/lsp/server/on_type_formatting.rb +0 -2
  140. data/lib/milk_tea/lsp/server/progress.rb +0 -2
  141. data/lib/milk_tea/lsp/server/references.rb +316 -318
  142. data/lib/milk_tea/lsp/server/rename.rb +445 -447
  143. data/lib/milk_tea/lsp/server/selection_range.rb +0 -4
  144. data/lib/milk_tea/lsp/server/semantic_tokens.rb +1318 -1320
  145. data/lib/milk_tea/lsp/server/signature_help.rb +146 -148
  146. data/lib/milk_tea/lsp/server/text_documents.rb +99 -101
  147. data/lib/milk_tea/lsp/server/type_hierarchy.rb +2 -4
  148. data/lib/milk_tea/lsp/server/utilities.rb +397 -399
  149. data/lib/milk_tea/lsp/server.rb +0 -3
  150. data/lib/milk_tea/lsp/workspace/analysis.rb +40 -42
  151. data/lib/milk_tea/lsp/workspace/dependency_graph.rb +4 -10
  152. data/lib/milk_tea/lsp/workspace/utilities.rb +19 -19
  153. data/lib/milk_tea/packages/atomic_write.rb +4 -5
  154. data/lib/milk_tea/packages/dependency_solver.rb +15 -15
  155. data/lib/milk_tea/packages/lock.rb +4 -4
  156. data/lib/milk_tea/packages/manager_cli.rb +1 -1
  157. data/lib/milk_tea/packages/manifest.rb +3 -3
  158. data/lib/milk_tea/packages/registry_store.rb +4 -6
  159. data/lib/milk_tea/packages/services.rb +16 -16
  160. data/lib/milk_tea/packages/source_cache.rb +4 -6
  161. data/lib/milk_tea/packages/source_resolver.rb +44 -44
  162. data/lib/milk_tea/packages/version.rb +8 -8
  163. data/lib/milk_tea/tooling/build.rb +3 -7
  164. data/lib/milk_tea/tooling/build_cache.rb +0 -2
  165. data/lib/milk_tea/tooling/debug_info_formatter.rb +31 -33
  166. data/lib/milk_tea/tooling/debug_map.rb +8 -10
  167. data/lib/milk_tea/tooling/docs_app.rb +0 -2
  168. data/lib/milk_tea/tooling/linter/doc_tags.rb +25 -27
  169. data/lib/milk_tea/tooling/linter/fix_engine.rb +87 -24
  170. data/lib/milk_tea/tooling/linter/flow_rules.rb +44 -46
  171. data/lib/milk_tea/tooling/linter/imports_platform.rb +14 -16
  172. data/lib/milk_tea/tooling/linter/release_rules.rb +3 -5
  173. data/lib/milk_tea/tooling/linter/reserved_names.rb +23 -25
  174. data/lib/milk_tea/tooling/linter/rules.rb +87 -89
  175. data/lib/milk_tea/tooling/linter/source_helpers.rb +40 -42
  176. data/lib/milk_tea/tooling/linter/trailing_comma.rb +17 -19
  177. data/lib/milk_tea/tooling/linter/visitors.rb +162 -50
  178. data/lib/milk_tea/tooling/linter.rb +0 -2
  179. data/lib/milk_tea/tooling/project_scaffold.rb +0 -2
  180. data/lib/milk_tea/tooling/run.rb +0 -2
  181. data/lib/milk_tea/tooling/toolchain_cli.rb +0 -2
  182. data/std/cli.mt +13 -32
  183. data/std/color.mt +28 -28
  184. data/std/encoding.mt +4 -4
  185. data/std/graph.mt +1 -2
  186. data/std/hash.mt +14 -14
  187. data/std/http/server.mt +3 -3
  188. data/std/input.mt +1 -1
  189. data/std/json.mt +1 -1
  190. data/std/linear_algebra.mt +6 -6
  191. data/std/net/mux.mt +1 -1
  192. data/std/noise.mt +23 -23
  193. data/std/parse.mt +2 -2
  194. data/std/process.mt +3 -4
  195. data/std/sparse_set.mt +1 -1
  196. data/std/steering.mt +5 -5
  197. data/std/str.mt +1 -1
  198. data/std/tween.mt +4 -4
  199. data/std/utility.mt +3 -3
  200. metadata +2 -2
@@ -3,453 +3,462 @@
3
3
  module MilkTea
4
4
  class CBackend
5
5
  module FeatureDetection
6
- private
7
-
8
- def uses_fmt_builder?
9
- return @uses_fmt_builder if defined?(@uses_fmt_builder)
10
-
11
- @uses_fmt_builder = emitted_functions.any? do |function|
12
- function_uses_named_call?(function, %w[mt_fmt_begin])
13
- end
14
- end
15
-
16
- def uses_string_view?
17
- return @uses_string_view if defined?(@uses_string_view)
18
- @uses_string_view = begin
19
- uses_fatal_helper? || uses_format_helpers? || uses_str_buffer_helpers? ||
20
- uses_entrypoint_argv_helpers? || uses_str_equality_helper? ||
21
- uses_foreign_temp_cstr_helpers? ||
22
- emitted_functions.any? do |function|
23
- type_contains_string_view?(function.return_type) ||
24
- function.params.any? { |param| type_contains_string_view?(param.type) }
25
- end ||
26
- emitted_aggregate_structs.any? { |s| s.fields.any? { |f| type_contains_string_view?(f.type) } } ||
27
- emitted_aggregate_unions.any? { |u| u.fields.any? { |f| type_contains_string_view?(f.type) } } ||
28
- emitted_aggregate_variants.any? { |v| v.arms.any? { |a| a.fields.any? { |f| type_contains_string_view?(f.type) } } } ||
29
- emitted_constants.any? { |c| type_contains_string_view?(c.type) } ||
30
- emitted_globals.any? { |g| type_contains_string_view?(g.type) } ||
31
- !collect_str_literals.empty?
32
- end
33
- end
34
-
35
- def type_contains_string_view?(type)
36
- return false unless type
37
- return true if type.is_a?(Types::StringView)
38
- case type
39
- when Types::Nullable
40
- type_contains_string_view?(type.base)
41
- when Types::Span
42
- type_contains_string_view?(type.element_type)
43
- when Types::GenericInstance
44
- type.arguments.any? { |a| type_contains_string_view?(a) }
45
- else
46
- false
47
- end
48
- end
49
-
50
- def uses_vector_math_types?
51
- return @uses_vector_math_types if defined?(@uses_vector_math_types)
52
- @uses_vector_math_types = begin
53
- emitted_functions.any? do |function|
54
- type_contains_vector_math?(function.return_type) ||
55
- function.params.any? { |param| type_contains_vector_math?(param.type) } ||
56
- function.body.any? { |stmt| statement_uses_vector_math?(stmt) }
57
- end ||
58
- emitted_aggregate_structs.any? { |s| s.fields.any? { |f| type_contains_vector_math?(f.type) } } ||
59
- emitted_aggregate_unions.any? { |u| u.fields.any? { |f| type_contains_vector_math?(f.type) } } ||
60
- emitted_aggregate_variants.any? { |v| v.arms.any? { |a| a.fields.any? { |f| type_contains_vector_math?(f.type) } } } ||
61
- emitted_constants.any? { |c| type_contains_vector_math?(c.type) } ||
62
- emitted_globals.any? { |g| type_contains_vector_math?(g.type) }
63
- end
64
- @uses_vector_math_types
65
- end
66
-
67
- def statement_uses_vector_math?(stmt)
68
- case stmt
69
- when IR::LocalDecl
70
- type_contains_vector_math?(stmt.type)
71
- when IR::Assignment
72
- type_contains_vector_math?(stmt.target.type) || expression_uses_vector_math?(stmt.value)
73
- when IR::ExpressionStmt
74
- expression_uses_vector_math?(stmt.expression)
75
- when IR::ReturnStmt
76
- stmt.value && expression_uses_vector_math?(stmt.value)
77
- when IR::BlockStmt
78
- stmt.body.any? { |s| statement_uses_vector_math?(s) }
79
- when IR::WhileStmt
80
- stmt.body.any? { |s| statement_uses_vector_math?(s) }
81
- when IR::ForStmt
82
- stmt.body.any? { |s| statement_uses_vector_math?(s) }
83
- when IR::IfStmt
84
- stmt.then_body.any? { |s| statement_uses_vector_math?(s) } ||
85
- (stmt.else_body && stmt.else_body.any? { |s| statement_uses_vector_math?(s) })
86
- when IR::SwitchStmt
87
- stmt.cases.any? { |c| c.body.any? { |s| statement_uses_vector_math?(s) } }
88
- else
89
- false
90
- end
91
- end
92
-
93
- def expression_uses_vector_math?(expr)
94
- return false unless expr
95
- return true if expr.respond_to?(:type) && type_contains_vector_math?(expr.type)
96
- case expr
97
- when IR::Assignment
98
- expression_uses_vector_math?(expr.target) || expression_uses_vector_math?(expr.value)
99
- when IR::AggregateLiteral
100
- expr.fields.any? { |f| expression_uses_vector_math?(f.value) }
101
- when IR::Binary
102
- expression_uses_vector_math?(expr.left) || expression_uses_vector_math?(expr.right)
103
- when IR::Unary
104
- expression_uses_vector_math?(expr.operand)
105
- when IR::Call
106
- expr.arguments.any? { |a| expression_uses_vector_math?(a) }
107
- when IR::Member
108
- expression_uses_vector_math?(expr.receiver)
109
- when IR::Index
110
- expression_uses_vector_math?(expr.receiver)
111
- when IR::Conditional
112
- expression_uses_vector_math?(expr.then_expression) || expression_uses_vector_math?(expr.else_expression)
113
- else
114
- false
6
+ def uses_fmt_builder?
7
+ return @uses_fmt_builder if defined?(@uses_fmt_builder)
8
+
9
+ @uses_fmt_builder = emitted_functions.any? do |function|
10
+ function_uses_named_call?(function, %w[mt_fmt_begin])
11
+ end
12
+ end
13
+
14
+ def uses_string_view?
15
+ return @uses_string_view if defined?(@uses_string_view)
16
+ @uses_string_view = begin
17
+ uses_fatal_helper? || uses_format_helpers? || uses_str_buffer_helpers? ||
18
+ uses_entrypoint_argv_helpers? || uses_str_equality_helper? ||
19
+ uses_foreign_temp_cstr_helpers? ||
20
+ emitted_functions.any? do |function|
21
+ type_contains_string_view?(function.return_type) ||
22
+ function.params.any? { |param| type_contains_string_view?(param.type) }
23
+ end ||
24
+ emitted_aggregate_structs.any? { |s| s.fields.any? { |f| type_contains_string_view?(f.type) } } ||
25
+ emitted_aggregate_unions.any? { |u| u.fields.any? { |f| type_contains_string_view?(f.type) } } ||
26
+ emitted_aggregate_variants.any? { |v| v.arms.any? { |a| a.fields.any? { |f| type_contains_string_view?(f.type) } } } ||
27
+ emitted_constants.any? { |c| type_contains_string_view?(c.type) } ||
28
+ emitted_globals.any? { |g| type_contains_string_view?(g.type) } ||
29
+ !collect_str_literals.empty?
30
+ end
31
+ end
32
+
33
+ def type_contains_string_view?(type)
34
+ return false unless type
35
+ return true if type.is_a?(Types::StringView)
36
+ case type
37
+ when Types::Nullable
38
+ type_contains_string_view?(type.base)
39
+ when Types::Span
40
+ type_contains_string_view?(type.element_type)
41
+ when Types::GenericInstance
42
+ type.arguments.any? { |a| type_contains_string_view?(a) }
43
+ else
44
+ false
45
+ end
46
+ end
47
+
48
+ def uses_vector_math_types?
49
+ return @uses_vector_math_types if defined?(@uses_vector_math_types)
50
+ @uses_vector_math_types = begin
51
+ emitted_functions.any? do |function|
52
+ type_contains_vector_math?(function.return_type) ||
53
+ function.params.any? { |param| type_contains_vector_math?(param.type) } ||
54
+ function.body.any? { |stmt| statement_uses_vector_math?(stmt) }
55
+ end ||
56
+ emitted_aggregate_structs.any? { |s| s.fields.any? { |f| type_contains_vector_math?(f.type) } } ||
57
+ emitted_aggregate_unions.any? { |u| u.fields.any? { |f| type_contains_vector_math?(f.type) } } ||
58
+ emitted_aggregate_variants.any? { |v| v.arms.any? { |a| a.fields.any? { |f| type_contains_vector_math?(f.type) } } } ||
59
+ emitted_constants.any? { |c| type_contains_vector_math?(c.type) } ||
60
+ emitted_globals.any? { |g| type_contains_vector_math?(g.type) }
61
+ end
62
+ @uses_vector_math_types
63
+ end
64
+
65
+ def statement_uses_vector_math?(stmt)
66
+ case stmt
67
+ when IR::LocalDecl
68
+ type_contains_vector_math?(stmt.type)
69
+ when IR::Assignment
70
+ type_contains_vector_math?(stmt.target.type) || expression_uses_vector_math?(stmt.value)
71
+ when IR::ExpressionStmt
72
+ expression_uses_vector_math?(stmt.expression)
73
+ when IR::ReturnStmt
74
+ stmt.value && expression_uses_vector_math?(stmt.value)
75
+ when IR::BlockStmt
76
+ stmt.body.any? { |s| statement_uses_vector_math?(s) }
77
+ when IR::WhileStmt
78
+ stmt.body.any? { |s| statement_uses_vector_math?(s) }
79
+ when IR::ForStmt
80
+ stmt.body.any? { |s| statement_uses_vector_math?(s) }
81
+ when IR::IfStmt
82
+ stmt.then_body.any? { |s| statement_uses_vector_math?(s) } ||
83
+ (stmt.else_body && stmt.else_body.any? { |s| statement_uses_vector_math?(s) })
84
+ when IR::SwitchStmt
85
+ stmt.cases.any? { |c| c.body.any? { |s| statement_uses_vector_math?(s) } }
86
+ else
87
+ false
88
+ end
89
+ end
90
+
91
+ def expression_uses_vector_math?(expr)
92
+ return false unless expr
93
+ return true if expr.respond_to?(:type) && type_contains_vector_math?(expr.type)
94
+ case expr
95
+ when IR::Assignment
96
+ expression_uses_vector_math?(expr.target) || expression_uses_vector_math?(expr.value)
97
+ when IR::AggregateLiteral
98
+ expr.fields.any? { |f| expression_uses_vector_math?(f.value) }
99
+ when IR::Binary
100
+ expression_uses_vector_math?(expr.left) || expression_uses_vector_math?(expr.right)
101
+ when IR::Unary
102
+ expression_uses_vector_math?(expr.operand)
103
+ when IR::Call
104
+ expr.arguments.any? { |a| expression_uses_vector_math?(a) }
105
+ when IR::Member
106
+ expression_uses_vector_math?(expr.receiver)
107
+ when IR::Index
108
+ expression_uses_vector_math?(expr.receiver)
109
+ when IR::Conditional
110
+ expression_uses_vector_math?(expr.then_expression) || expression_uses_vector_math?(expr.else_expression)
111
+ else
112
+ false
113
+ end
114
+ end
115
+
116
+ def type_contains_vector_math?(type)
117
+ return false unless type
118
+ return true if type.is_a?(Types::Vector) || type.is_a?(Types::Matrix) || type.is_a?(Types::Quaternion)
119
+ case type
120
+ when Types::Nullable
121
+ type_contains_vector_math?(type.base)
122
+ when Types::Span
123
+ type_contains_vector_math?(type.element_type)
124
+ when Types::GenericInstance
125
+ type.arguments.any? { |a| type_contains_vector_math?(a) }
126
+ else
127
+ false
128
+ end
129
+ end
130
+
131
+ def uses_fatal_helper?
132
+ uses_mt_fatal_helper? || uses_mt_fatal_str_helper?
133
+ end
134
+
135
+ def uses_mt_fatal_helper?
136
+ return true if @debug_guards
137
+
138
+ collect_checked_array_index_types.any? || collect_checked_span_index_types.any? ||
139
+ uses_format_helpers? ||
140
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_fatal mt_str_buffer_len mt_str_buffer_as_cstr mt_str_buffer_assign mt_str_buffer_append mt_foreign_str_to_cstr_temp mt_foreign_strs_to_cstrs_temp]) }
141
+ end
142
+
143
+ def uses_mt_fatal_str_helper?
144
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_fatal_str]) }
145
+ end
146
+
147
+ def uses_foreign_temp_cstr_helpers?
148
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_foreign_str_to_cstr_temp mt_free_foreign_cstr_temp mt_foreign_strs_to_cstrs_temp mt_free_foreign_cstrs_temp]) }
149
+ end
150
+
151
+ def uses_entrypoint_argv_helpers?
152
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_entry_argv_to_span_str mt_free_entry_argv_strs]) }
153
+ end
154
+
155
+ def uses_text_buffer_helpers?
156
+ uses_str_buffer_helpers?
157
+ end
158
+
159
+ def uses_str_buffer_helpers?
160
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_str_buffer_len mt_str_buffer_as_cstr mt_str_buffer_clear mt_str_buffer_assign mt_str_buffer_append mt_str_buffer_prepare_write]) }
161
+ end
162
+
163
+ def uses_async_memory_helpers?
164
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_async_alloc mt_async_free]) }
165
+ end
166
+
167
+ def uses_cyclic_variant_heap_copy?
168
+ all_variants = emitted_aggregate_variants + collect_generic_variant_decls
169
+ all_variants.any? do |v|
170
+ v.arms.any? do |arm|
171
+ arm.fields.any? do |f|
172
+ aggregate_field_creates_cycle?(f.type, v.linkage_name)
115
173
  end
116
174
  end
117
-
118
- def type_contains_vector_math?(type)
119
- return false unless type
120
- return true if type.is_a?(Types::Vector) || type.is_a?(Types::Matrix) || type.is_a?(Types::Quaternion)
121
- case type
122
- when Types::Nullable
123
- type_contains_vector_math?(type.base)
124
- when Types::Span
125
- type_contains_vector_math?(type.element_type)
126
- when Types::GenericInstance
127
- type.arguments.any? { |a| type_contains_vector_math?(a) }
128
- else
129
- false
175
+ end
176
+ end
177
+
178
+ def uses_parallel_for_helper?
179
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_parallel_for]) }
180
+ end
181
+
182
+ def uses_spawn_all_helper?
183
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_spawn_all]) }
184
+ end
185
+
186
+ def uses_detach_helper?
187
+ emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_detach_run mt_detach_join]) }
188
+ end
189
+
190
+ def format_helper_callees
191
+ %w[
192
+ mt_format_str_make
193
+ mt_format_str_release
194
+ mt_format_cstr_len
195
+ mt_format_bool_len
196
+ mt_format_ptr_uint_len
197
+ mt_format_ulong_len
198
+ mt_format_uint_len
199
+ mt_format_long_len
200
+ mt_format_int_len
201
+ mt_format_ulong_hex_len
202
+ mt_format_long_hex_len
203
+ mt_format_float_len
204
+ mt_format_double_len
205
+ mt_format_double_precision_len
206
+ mt_format_ulong_oct_len
207
+ mt_format_long_oct_len
208
+ mt_format_ulong_bin_len
209
+ mt_format_long_bin_len
210
+ mt_format_append_str
211
+ mt_format_append_cstr
212
+ mt_format_append_bool
213
+ mt_format_append_ptr_uint
214
+ mt_format_append_ulong
215
+ mt_format_append_uint
216
+ mt_format_append_long
217
+ mt_format_append_int
218
+ mt_format_append_ulong_hex
219
+ mt_format_append_ulong_hex_upper
220
+ mt_format_append_long_hex
221
+ mt_format_append_long_hex_upper
222
+ mt_format_append_float
223
+ mt_format_append_double
224
+ mt_format_append_double_precision
225
+ mt_format_append_ulong_oct
226
+ mt_format_append_long_oct
227
+ mt_format_append_ulong_bin
228
+ mt_format_append_long_bin
229
+ ]
230
+ end
231
+
232
+ def used_format_helpers
233
+ @used_format_helpers ||= begin
234
+ helpers = {}
235
+
236
+ emitted_functions.each do |function|
237
+ format_helper_callees.each do |callee|
238
+ helpers[callee] = true if function_uses_named_call?(function, [callee])
130
239
  end
131
240
  end
132
241
 
133
- def uses_fatal_helper?
134
- uses_mt_fatal_helper? || uses_mt_fatal_str_helper?
135
- end
136
-
137
- def uses_mt_fatal_helper?
138
- return true if @debug_guards
139
-
140
- collect_checked_array_index_types.any? || collect_checked_span_index_types.any? ||
141
- uses_format_helpers? ||
142
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_fatal mt_str_buffer_len mt_str_buffer_as_cstr mt_str_buffer_assign mt_str_buffer_append mt_foreign_str_to_cstr_temp mt_foreign_strs_to_cstrs_temp]) }
143
- end
144
-
145
- def uses_mt_fatal_str_helper?
146
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_fatal_str]) }
147
- end
148
-
149
- def uses_foreign_temp_cstr_helpers?
150
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_foreign_str_to_cstr_temp mt_free_foreign_cstr_temp mt_foreign_strs_to_cstrs_temp mt_free_foreign_cstrs_temp]) }
151
- end
152
-
153
- def uses_entrypoint_argv_helpers?
154
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_entry_argv_to_span_str mt_free_entry_argv_strs]) }
155
- end
156
-
157
- def uses_text_buffer_helpers?
158
- uses_str_buffer_helpers?
159
- end
160
-
161
- def uses_str_buffer_helpers?
162
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_str_buffer_len mt_str_buffer_as_cstr mt_str_buffer_clear mt_str_buffer_assign mt_str_buffer_append mt_str_buffer_prepare_write]) }
163
- end
164
-
165
- def uses_async_memory_helpers?
166
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_async_alloc mt_async_free]) }
167
- end
168
-
169
- def uses_parallel_for_helper?
170
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_parallel_for]) }
171
- end
172
-
173
- def uses_spawn_all_helper?
174
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_spawn_all]) }
175
- end
176
-
177
- def uses_detach_helper?
178
- emitted_functions.any? { |function| function_uses_named_call?(function, %w[mt_detach_run mt_detach_join]) }
179
- end
180
-
181
- def format_helper_callees
182
- %w[
183
- mt_format_str_make
184
- mt_format_str_release
185
- mt_format_cstr_len
186
- mt_format_bool_len
187
- mt_format_ptr_uint_len
188
- mt_format_ulong_len
189
- mt_format_uint_len
190
- mt_format_long_len
191
- mt_format_int_len
192
- mt_format_ulong_hex_len
193
- mt_format_long_hex_len
194
- mt_format_float_len
195
- mt_format_double_len
196
- mt_format_double_precision_len
197
- mt_format_ulong_oct_len
198
- mt_format_long_oct_len
199
- mt_format_ulong_bin_len
200
- mt_format_long_bin_len
201
- mt_format_append_str
202
- mt_format_append_cstr
203
- mt_format_append_bool
204
- mt_format_append_ptr_uint
205
- mt_format_append_ulong
206
- mt_format_append_uint
207
- mt_format_append_long
208
- mt_format_append_int
209
- mt_format_append_ulong_hex
210
- mt_format_append_ulong_hex_upper
211
- mt_format_append_long_hex
212
- mt_format_append_long_hex_upper
213
- mt_format_append_float
214
- mt_format_append_double
215
- mt_format_append_double_precision
216
- mt_format_append_ulong_oct
217
- mt_format_append_long_oct
218
- mt_format_append_ulong_bin
219
- mt_format_append_long_bin
220
- ]
221
- end
222
-
223
- def used_format_helpers
224
- @used_format_helpers ||= begin
225
- helpers = {}
226
-
227
- emitted_functions.each do |function|
228
- format_helper_callees.each do |callee|
229
- helpers[callee] = true if function_uses_named_call?(function, [callee])
230
- end
231
- end
232
-
233
- loop do
234
- changed = false
235
-
236
- helpers.keys.each do |helper|
237
- (FORMAT_HELPER_DEPENDENCIES[helper] || []).each do |dependency|
238
- next if helpers[dependency]
242
+ loop do
243
+ changed = false
239
244
 
240
- helpers[dependency] = true
241
- changed = true
242
- end
243
- end
245
+ helpers.keys.each do |helper|
246
+ (FORMAT_HELPER_DEPENDENCIES[helper] || []).each do |dependency|
247
+ next if helpers[dependency]
244
248
 
245
- break unless changed
249
+ helpers[dependency] = true
250
+ changed = true
246
251
  end
247
-
248
- helpers
249
252
  end
250
- end
251
253
 
252
- FORMAT_HELPER_DEPENDENCIES = {
253
- 'mt_format_append_str' => %w[mt_format_append_bytes mt_format_check_capacity],
254
- 'mt_format_append_cstr' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_cstr_len],
255
- 'mt_format_append_bool' => %w[mt_format_append_bytes mt_format_check_capacity],
256
- 'mt_format_append_ptr_uint' => %w[mt_format_check_capacity mt_format_ptr_uint_len],
257
- 'mt_format_append_ulong' => %w[mt_format_check_capacity mt_format_ulong_len],
258
- 'mt_format_append_uint' => %w[mt_format_append_ptr_uint mt_format_check_capacity mt_format_ptr_uint_len],
259
- 'mt_format_append_long' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong mt_format_ulong_len],
260
- 'mt_format_append_int' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ptr_uint mt_format_ptr_uint_len],
261
- 'mt_format_append_ulong_hex' => %w[mt_format_check_capacity mt_format_ulong_hex_len],
262
- 'mt_format_append_ulong_hex_upper' => %w[mt_format_check_capacity mt_format_ulong_hex_len],
263
- 'mt_format_append_long_hex' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_hex mt_format_ulong_hex_len],
264
- 'mt_format_append_long_hex_upper' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_hex_upper mt_format_ulong_hex_len],
265
- 'mt_format_append_ulong_oct' => %w[mt_format_check_capacity mt_format_ulong_oct_len],
266
- 'mt_format_append_long_oct' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_oct mt_format_ulong_oct_len],
267
- 'mt_format_append_ulong_bin' => %w[mt_format_check_capacity mt_format_ulong_bin_len],
268
- 'mt_format_append_long_bin' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_bin mt_format_ulong_bin_len],
269
- 'mt_format_append_float' => %w[mt_format_check_capacity mt_format_float_len],
270
- 'mt_format_append_double' => %w[mt_format_check_capacity mt_format_double_len],
271
- 'mt_format_append_double_precision' => %w[mt_format_check_capacity mt_format_double_precision_len],
272
- 'mt_format_int_len' => %w[mt_format_ptr_uint_len],
273
- 'mt_format_long_len' => %w[mt_format_ulong_len],
274
- 'mt_format_long_hex_len' => %w[mt_format_ulong_hex_len],
275
- 'mt_format_long_oct_len' => %w[mt_format_ulong_oct_len],
276
- 'mt_format_long_bin_len' => %w[mt_format_ulong_bin_len],
277
- }.freeze
278
-
279
- def uses_format_helpers?
280
- !used_format_helpers.empty?
281
- end
282
-
283
- def uses_str_equality_helper?
284
- emitted_functions.any? { |function| function_uses_str_equality?(function) }
285
- end
286
-
287
- def uses_variant_equality_helper?
288
- emitted_functions.any? { |function| function_uses_variant_equality?(function) }
289
- end
290
-
291
- def function_uses_variant_equality?(function)
292
- function.body.any? { |statement| statement_uses_variant_equality?(statement) }
293
- end
294
-
295
- def statement_uses_variant_equality?(statement)
296
- case statement
297
- when IR::LocalDecl
298
- expression_uses_variant_equality?(statement.value)
299
- when IR::ExpressionStmt
300
- expression_uses_variant_equality?(statement.expression)
301
- when IR::ReturnStmt
302
- statement.value && expression_uses_variant_equality?(statement.value)
303
- when IR::Assignment
304
- expression_uses_variant_equality?(statement.value)
305
- when IR::IfStmt
306
- expression_uses_variant_equality?(statement.condition)
307
- when IR::WhileStmt
308
- expression_uses_variant_equality?(statement.condition)
309
- else
310
- false
311
- end
312
- end
313
-
314
- def expression_uses_variant_equality?(expression)
315
- return false unless expression
316
-
317
- case expression
318
- when IR::Binary
319
- EQUALITY_OPERATORS.include?(expression.operator) &&
320
- (expression.left.type.is_a?(Types::Variant) || expression.left.type.is_a?(Types::VariantArmPayload))
321
- when IR::Call
322
- expression.arguments.any? { |arg| expression_uses_variant_equality?(arg) }
323
- else
324
- false
325
- end
326
- end
327
-
328
- def function_uses_named_call?(function, callees)
329
- function.body.any? { |statement| statement_uses_named_call?(statement, callees) }
330
- end
331
-
332
- def function_uses_str_equality?(function)
333
- function.body.any? { |statement| statement_uses_str_equality?(statement) }
334
- end
335
-
336
- def statement_uses_named_call?(statement, callees)
337
- case statement
338
- when IR::LocalDecl
339
- expression_uses_named_call?(statement.value, callees)
340
- when IR::Assignment
341
- expression_uses_named_call?(statement.target, callees) || expression_uses_named_call?(statement.value, callees)
342
- when IR::BlockStmt
343
- statement.body.any? { |inner| statement_uses_named_call?(inner, callees) }
344
- when IR::WhileStmt
345
- expression_uses_named_call?(statement.condition, callees) || statement.body.any? { |inner| statement_uses_named_call?(inner, callees) }
346
- when IR::ForStmt
347
- statement_uses_named_call?(statement.init, callees) ||
348
- expression_uses_named_call?(statement.condition, callees) ||
349
- statement.body.any? { |inner| statement_uses_named_call?(inner, callees) } ||
350
- statement_uses_named_call?(statement.post, callees)
351
- when IR::IfStmt
352
- expression_uses_named_call?(statement.condition, callees) ||
353
- statement.then_body.any? { |inner| statement_uses_named_call?(inner, callees) } ||
354
- (statement.else_body && statement.else_body.any? { |inner| statement_uses_named_call?(inner, callees) })
355
- when IR::SwitchStmt
356
- expression_uses_named_call?(statement.expression, callees) || statement.cases.any? { |switch_case| switch_case.body.any? { |inner| statement_uses_named_call?(inner, callees) } }
357
- when IR::StaticAssert
358
- expression_uses_named_call?(statement.condition, callees) || expression_uses_named_call?(statement.message, callees)
359
- when IR::ReturnStmt
360
- statement.value && expression_uses_named_call?(statement.value, callees)
361
- when IR::ExpressionStmt
362
- expression_uses_named_call?(statement.expression, callees)
363
- end
364
- end
365
-
366
- def statement_uses_str_equality?(statement)
367
- case statement
368
- when IR::LocalDecl
369
- expression_uses_str_equality?(statement.value)
370
- when IR::Assignment
371
- expression_uses_str_equality?(statement.target) || expression_uses_str_equality?(statement.value)
372
- when IR::BlockStmt
373
- statement.body.any? { |inner| statement_uses_str_equality?(inner) }
374
- when IR::WhileStmt
375
- expression_uses_str_equality?(statement.condition) || statement.body.any? { |inner| statement_uses_str_equality?(inner) }
376
- when IR::ForStmt
377
- statement_uses_str_equality?(statement.init) ||
378
- expression_uses_str_equality?(statement.condition) ||
379
- statement.body.any? { |inner| statement_uses_str_equality?(inner) } ||
380
- statement_uses_str_equality?(statement.post)
381
- when IR::IfStmt
382
- expression_uses_str_equality?(statement.condition) ||
383
- statement.then_body.any? { |inner| statement_uses_str_equality?(inner) } ||
384
- (statement.else_body && statement.else_body.any? { |inner| statement_uses_str_equality?(inner) })
385
- when IR::SwitchStmt
386
- expression_uses_str_equality?(statement.expression) || statement.cases.any? { |switch_case| switch_case.body.any? { |inner| statement_uses_str_equality?(inner) } }
387
- when IR::StaticAssert
388
- expression_uses_str_equality?(statement.condition) || expression_uses_str_equality?(statement.message)
389
- when IR::ReturnStmt
390
- statement.value && expression_uses_str_equality?(statement.value)
391
- when IR::ExpressionStmt
392
- expression_uses_str_equality?(statement.expression)
393
- else
394
- false
395
- end
396
- end
397
-
398
- def expression_uses_named_call?(expression, callees)
399
- case expression
400
- when IR::Call
401
- callees.include?(expression.callee) ||
402
- (!expression.callee.is_a?(String) && expression_uses_named_call?(expression.callee, callees)) ||
403
- expression.arguments.any? { |argument| expression_uses_named_call?(argument, callees) }
404
- when IR::Member
405
- expression_uses_named_call?(expression.receiver, callees)
406
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
407
- expression_uses_named_call?(expression.receiver, callees) || expression_uses_named_call?(expression.index, callees)
408
- when IR::Unary
409
- expression_uses_named_call?(expression.operand, callees)
410
- when IR::Binary
411
- expression_uses_named_call?(expression.left, callees) || expression_uses_named_call?(expression.right, callees)
412
- when IR::Conditional
413
- expression_uses_named_call?(expression.condition, callees) || expression_uses_named_call?(expression.then_expression, callees) || expression_uses_named_call?(expression.else_expression, callees)
414
- when IR::ReinterpretExpr, IR::Cast, IR::AddressOf
415
- expression_uses_named_call?(expression.expression, callees)
416
- when IR::AggregateLiteral
417
- expression.fields.any? { |field| expression_uses_named_call?(field.value, callees) }
418
- when IR::ArrayLiteral
419
- expression.elements.any? { |element| expression_uses_named_call?(element, callees) }
420
- when IR::VariantLiteral
421
- expression.fields.any? { |field| expression_uses_named_call?(field.value, callees) }
422
- else
423
- false
424
- end
425
- end
426
-
427
- def expression_uses_str_equality?(expression)
428
- case expression
429
- when IR::Binary
430
- str_equality_expression?(expression) || expression_uses_str_equality?(expression.left) || expression_uses_str_equality?(expression.right)
431
- when IR::Call
432
- (!expression.callee.is_a?(String) && expression_uses_str_equality?(expression.callee)) || expression.arguments.any? { |argument| expression_uses_str_equality?(argument) }
433
- when IR::Member
434
- expression_uses_str_equality?(expression.receiver)
435
- when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
436
- expression_uses_str_equality?(expression.receiver) || expression_uses_str_equality?(expression.index)
437
- when IR::Unary
438
- expression_uses_str_equality?(expression.operand)
439
- when IR::Conditional
440
- expression_uses_str_equality?(expression.condition) || expression_uses_str_equality?(expression.then_expression) || expression_uses_str_equality?(expression.else_expression)
441
- when IR::ReinterpretExpr, IR::Cast, IR::AddressOf
442
- expression_uses_str_equality?(expression.expression)
443
- when IR::AggregateLiteral
444
- expression.fields.any? { |field| expression_uses_str_equality?(field.value) }
445
- when IR::ArrayLiteral
446
- expression.elements.any? { |element| expression_uses_str_equality?(element) }
447
- when IR::VariantLiteral
448
- expression.fields.any? { |field| expression_uses_str_equality?(field.value) }
449
- else
450
- false
451
- end
452
- end
254
+ break unless changed
255
+ end
256
+
257
+ helpers
258
+ end
259
+ end
260
+
261
+ FORMAT_HELPER_DEPENDENCIES = {
262
+ 'mt_format_append_str' => %w[mt_format_append_bytes mt_format_check_capacity],
263
+ 'mt_format_append_cstr' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_cstr_len],
264
+ 'mt_format_append_bool' => %w[mt_format_append_bytes mt_format_check_capacity],
265
+ 'mt_format_append_ptr_uint' => %w[mt_format_check_capacity mt_format_ptr_uint_len],
266
+ 'mt_format_append_ulong' => %w[mt_format_check_capacity mt_format_ulong_len],
267
+ 'mt_format_append_uint' => %w[mt_format_append_ptr_uint mt_format_check_capacity mt_format_ptr_uint_len],
268
+ 'mt_format_append_long' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong mt_format_ulong_len],
269
+ 'mt_format_append_int' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ptr_uint mt_format_ptr_uint_len],
270
+ 'mt_format_append_ulong_hex' => %w[mt_format_check_capacity mt_format_ulong_hex_len],
271
+ 'mt_format_append_ulong_hex_upper' => %w[mt_format_check_capacity mt_format_ulong_hex_len],
272
+ 'mt_format_append_long_hex' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_hex mt_format_ulong_hex_len],
273
+ 'mt_format_append_long_hex_upper' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_hex_upper mt_format_ulong_hex_len],
274
+ 'mt_format_append_ulong_oct' => %w[mt_format_check_capacity mt_format_ulong_oct_len],
275
+ 'mt_format_append_long_oct' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_oct mt_format_ulong_oct_len],
276
+ 'mt_format_append_ulong_bin' => %w[mt_format_check_capacity mt_format_ulong_bin_len],
277
+ 'mt_format_append_long_bin' => %w[mt_format_append_bytes mt_format_check_capacity mt_format_append_ulong_bin mt_format_ulong_bin_len],
278
+ 'mt_format_append_float' => %w[mt_format_check_capacity mt_format_float_len],
279
+ 'mt_format_append_double' => %w[mt_format_check_capacity mt_format_double_len],
280
+ 'mt_format_append_double_precision' => %w[mt_format_check_capacity mt_format_double_precision_len],
281
+ 'mt_format_int_len' => %w[mt_format_ptr_uint_len],
282
+ 'mt_format_long_len' => %w[mt_format_ulong_len],
283
+ 'mt_format_long_hex_len' => %w[mt_format_ulong_hex_len],
284
+ 'mt_format_long_oct_len' => %w[mt_format_ulong_oct_len],
285
+ 'mt_format_long_bin_len' => %w[mt_format_ulong_bin_len],
286
+ }.freeze
287
+
288
+ def uses_format_helpers?
289
+ !used_format_helpers.empty?
290
+ end
291
+
292
+ def uses_str_equality_helper?
293
+ emitted_functions.any? { |function| function_uses_str_equality?(function) }
294
+ end
295
+
296
+ def uses_variant_equality_helper?
297
+ emitted_functions.any? { |function| function_uses_variant_equality?(function) }
298
+ end
299
+
300
+ def function_uses_variant_equality?(function)
301
+ function.body.any? { |statement| statement_uses_variant_equality?(statement) }
302
+ end
303
+
304
+ def statement_uses_variant_equality?(statement)
305
+ case statement
306
+ when IR::LocalDecl
307
+ expression_uses_variant_equality?(statement.value)
308
+ when IR::ExpressionStmt
309
+ expression_uses_variant_equality?(statement.expression)
310
+ when IR::ReturnStmt
311
+ statement.value && expression_uses_variant_equality?(statement.value)
312
+ when IR::Assignment
313
+ expression_uses_variant_equality?(statement.value)
314
+ when IR::IfStmt
315
+ expression_uses_variant_equality?(statement.condition)
316
+ when IR::WhileStmt
317
+ expression_uses_variant_equality?(statement.condition)
318
+ else
319
+ false
320
+ end
321
+ end
322
+
323
+ def expression_uses_variant_equality?(expression)
324
+ return false unless expression
325
+
326
+ case expression
327
+ when IR::Binary
328
+ EQUALITY_OPERATORS.include?(expression.operator) &&
329
+ (expression.left.type.is_a?(Types::Variant) || expression.left.type.is_a?(Types::VariantArmPayload))
330
+ when IR::Call
331
+ expression.arguments.any? { |arg| expression_uses_variant_equality?(arg) }
332
+ else
333
+ false
334
+ end
335
+ end
336
+
337
+ def function_uses_named_call?(function, callees)
338
+ function.body.any? { |statement| statement_uses_named_call?(statement, callees) }
339
+ end
340
+
341
+ def function_uses_str_equality?(function)
342
+ function.body.any? { |statement| statement_uses_str_equality?(statement) }
343
+ end
344
+
345
+ def statement_uses_named_call?(statement, callees)
346
+ case statement
347
+ when IR::LocalDecl
348
+ expression_uses_named_call?(statement.value, callees)
349
+ when IR::Assignment
350
+ expression_uses_named_call?(statement.target, callees) || expression_uses_named_call?(statement.value, callees)
351
+ when IR::BlockStmt
352
+ statement.body.any? { |inner| statement_uses_named_call?(inner, callees) }
353
+ when IR::WhileStmt
354
+ expression_uses_named_call?(statement.condition, callees) || statement.body.any? { |inner| statement_uses_named_call?(inner, callees) }
355
+ when IR::ForStmt
356
+ statement_uses_named_call?(statement.init, callees) ||
357
+ expression_uses_named_call?(statement.condition, callees) ||
358
+ statement.body.any? { |inner| statement_uses_named_call?(inner, callees) } ||
359
+ statement_uses_named_call?(statement.post, callees)
360
+ when IR::IfStmt
361
+ expression_uses_named_call?(statement.condition, callees) ||
362
+ statement.then_body.any? { |inner| statement_uses_named_call?(inner, callees) } ||
363
+ (statement.else_body && statement.else_body.any? { |inner| statement_uses_named_call?(inner, callees) })
364
+ when IR::SwitchStmt
365
+ expression_uses_named_call?(statement.expression, callees) || statement.cases.any? { |switch_case| switch_case.body.any? { |inner| statement_uses_named_call?(inner, callees) } }
366
+ when IR::StaticAssert
367
+ expression_uses_named_call?(statement.condition, callees) || expression_uses_named_call?(statement.message, callees)
368
+ when IR::ReturnStmt
369
+ statement.value && expression_uses_named_call?(statement.value, callees)
370
+ when IR::ExpressionStmt
371
+ expression_uses_named_call?(statement.expression, callees)
372
+ end
373
+ end
374
+
375
+ def statement_uses_str_equality?(statement)
376
+ case statement
377
+ when IR::LocalDecl
378
+ expression_uses_str_equality?(statement.value)
379
+ when IR::Assignment
380
+ expression_uses_str_equality?(statement.target) || expression_uses_str_equality?(statement.value)
381
+ when IR::BlockStmt
382
+ statement.body.any? { |inner| statement_uses_str_equality?(inner) }
383
+ when IR::WhileStmt
384
+ expression_uses_str_equality?(statement.condition) || statement.body.any? { |inner| statement_uses_str_equality?(inner) }
385
+ when IR::ForStmt
386
+ statement_uses_str_equality?(statement.init) ||
387
+ expression_uses_str_equality?(statement.condition) ||
388
+ statement.body.any? { |inner| statement_uses_str_equality?(inner) } ||
389
+ statement_uses_str_equality?(statement.post)
390
+ when IR::IfStmt
391
+ expression_uses_str_equality?(statement.condition) ||
392
+ statement.then_body.any? { |inner| statement_uses_str_equality?(inner) } ||
393
+ (statement.else_body && statement.else_body.any? { |inner| statement_uses_str_equality?(inner) })
394
+ when IR::SwitchStmt
395
+ expression_uses_str_equality?(statement.expression) || statement.cases.any? { |switch_case| switch_case.body.any? { |inner| statement_uses_str_equality?(inner) } }
396
+ when IR::StaticAssert
397
+ expression_uses_str_equality?(statement.condition) || expression_uses_str_equality?(statement.message)
398
+ when IR::ReturnStmt
399
+ statement.value && expression_uses_str_equality?(statement.value)
400
+ when IR::ExpressionStmt
401
+ expression_uses_str_equality?(statement.expression)
402
+ else
403
+ false
404
+ end
405
+ end
406
+
407
+ def expression_uses_named_call?(expression, callees)
408
+ case expression
409
+ when IR::Call
410
+ callees.include?(expression.callee) ||
411
+ (!expression.callee.is_a?(String) && expression_uses_named_call?(expression.callee, callees)) ||
412
+ expression.arguments.any? { |argument| expression_uses_named_call?(argument, callees) }
413
+ when IR::Member
414
+ expression_uses_named_call?(expression.receiver, callees)
415
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
416
+ expression_uses_named_call?(expression.receiver, callees) || expression_uses_named_call?(expression.index, callees)
417
+ when IR::Unary
418
+ expression_uses_named_call?(expression.operand, callees)
419
+ when IR::Binary
420
+ expression_uses_named_call?(expression.left, callees) || expression_uses_named_call?(expression.right, callees)
421
+ when IR::Conditional
422
+ expression_uses_named_call?(expression.condition, callees) || expression_uses_named_call?(expression.then_expression, callees) || expression_uses_named_call?(expression.else_expression, callees)
423
+ when IR::ReinterpretExpr, IR::Cast, IR::AddressOf
424
+ expression_uses_named_call?(expression.expression, callees)
425
+ when IR::AggregateLiteral
426
+ expression.fields.any? { |field| expression_uses_named_call?(field.value, callees) }
427
+ when IR::ArrayLiteral
428
+ expression.elements.any? { |element| expression_uses_named_call?(element, callees) }
429
+ when IR::VariantLiteral
430
+ expression.fields.any? { |field| expression_uses_named_call?(field.value, callees) }
431
+ else
432
+ false
433
+ end
434
+ end
435
+
436
+ def expression_uses_str_equality?(expression)
437
+ case expression
438
+ when IR::Binary
439
+ str_equality_expression?(expression) || expression_uses_str_equality?(expression.left) || expression_uses_str_equality?(expression.right)
440
+ when IR::Call
441
+ (!expression.callee.is_a?(String) && expression_uses_str_equality?(expression.callee)) || expression.arguments.any? { |argument| expression_uses_str_equality?(argument) }
442
+ when IR::Member
443
+ expression_uses_str_equality?(expression.receiver)
444
+ when IR::Index, IR::CheckedIndex, IR::CheckedSpanIndex, IR::NullableIndex, IR::NullableSpanIndex
445
+ expression_uses_str_equality?(expression.receiver) || expression_uses_str_equality?(expression.index)
446
+ when IR::Unary
447
+ expression_uses_str_equality?(expression.operand)
448
+ when IR::Conditional
449
+ expression_uses_str_equality?(expression.condition) || expression_uses_str_equality?(expression.then_expression) || expression_uses_str_equality?(expression.else_expression)
450
+ when IR::ReinterpretExpr, IR::Cast, IR::AddressOf
451
+ expression_uses_str_equality?(expression.expression)
452
+ when IR::AggregateLiteral
453
+ expression.fields.any? { |field| expression_uses_str_equality?(field.value) }
454
+ when IR::ArrayLiteral
455
+ expression.elements.any? { |element| expression_uses_str_equality?(element) }
456
+ when IR::VariantLiteral
457
+ expression.fields.any? { |field| expression_uses_str_equality?(field.value) }
458
+ else
459
+ false
460
+ end
461
+ end
453
462
  end
454
463
  end
455
464
  end