ruby-llvm 18.1.7 → 18.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4bda8c1e9b39947ab7023efaaca880f460712765bed7db90f13671f4604642f7
4
- data.tar.gz: e1a7aefc5e08bb131c9bec9bfd5f2c11ae41e42385be00eea4acc16507d1c723
3
+ metadata.gz: e48eb7aeebc6f8fb6de9c900065168d2b2ed555ca4e294bf1a96e47959344069
4
+ data.tar.gz: c61c5cbf456724538e18cbc9b70660fba586e9af8cc5811a98e74f589166e808
5
5
  SHA512:
6
- metadata.gz: eb8286217d9f1c92f0c52f41112279113c1bd255ce5eac5342bd044d99cd3d642f4f5509d8e7e2eaa17fac0e91e6a89f1c114b21fec0501040cd01f3d1ad6689
7
- data.tar.gz: 372f498dcbbb775191badd8eca79ac993d5ee44a665438baba1097443d4ed0185150beced4af7a72a7105bd0048048ec9ae2e170d43be67bf6791f6c0d2c8319
6
+ metadata.gz: faac90c796d9eab92633734c0c323a1b959118ae4558c7ac2dbffbe3f019dc64b876de72a678ced189a31b2fa34cd04fe7d3352cb3571638618c181844186f33
7
+ data.tar.gz: 7a3549ffad064a6aedfe6a84146ab4be41434d093c5856315d49ca854bd8ba17bd0bd543e9c396b292b399ddcfd230d35cbfbb302c6cdde2642532b923bc7ea9
@@ -31,7 +31,6 @@ def find_llvm_config
31
31
  check_for('llvm-config',
32
32
  %W(llvm-config-#{LLVM_VERSION} llvm-config),
33
33
  'LLVM_CONFIG') do |llvm_config|
34
-
35
34
  begin
36
35
  actual_version = `#{llvm_config} --version`.strip
37
36
  actual_maj, actual_min, _ = actual_version.split('.')
data/lib/llvm/config.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  # Generated by ruby-llvm. Please do not change this file by hand.
2
2
  module LLVM
3
3
  module CONFIG
4
- VERSION = "18.1.0"
5
- COMPONENTS = ["aarch64", "aarch64asmparser", "aarch64codegen", "aarch64desc", "aarch64disassembler", "aarch64info", "aarch64utils", "aggressiveinstcombine", "all", "all-targets", "amdgpu", "amdgpuasmparser", "amdgpucodegen", "amdgpudesc", "amdgpudisassembler", "amdgpuinfo", "amdgputargetmca", "amdgpuutils", "analysis", "arm", "armasmparser", "armcodegen", "armdesc", "armdisassembler", "arminfo", "armutils", "asmparser", "asmprinter", "avr", "avrasmparser", "avrcodegen", "avrdesc", "avrdisassembler", "avrinfo", "binaryformat", "bitreader", "bitstreamreader", "bitwriter", "bpf", "bpfasmparser", "bpfcodegen", "bpfdesc", "bpfdisassembler", "bpfinfo", "cfguard", "codegen", "codegentypes", "core", "coroutines", "coverage", "debuginfobtf", "debuginfocodeview", "debuginfodwarf", "debuginfogsym", "debuginfologicalview", "debuginfomsf", "debuginfopdb", "demangle", "dlltooldriver", "dwarflinker", "dwarflinkerclassic", "dwarflinkerparallel", "dwp", "engine", "executionengine", "extensions", "filecheck", "frontenddriver", "frontendhlsl", "frontendoffloading", "frontendopenacc", "frontendopenmp", "fuzzercli", "fuzzmutate", "globalisel", "hexagon", "hexagonasmparser", "hexagoncodegen", "hexagondesc", "hexagondisassembler", "hexagoninfo", "hipstdpar", "instcombine", "instrumentation", "interfacestub", "interpreter", "ipo", "irprinter", "irreader", "jitlink", "lanai", "lanaiasmparser", "lanaicodegen", "lanaidesc", "lanaidisassembler", "lanaiinfo", "libdriver", "lineeditor", "linker", "loongarch", "loongarchasmparser", "loongarchcodegen", "loongarchdesc", "loongarchdisassembler", "loongarchinfo", "lto", "m68k", "m68kasmparser", "m68kcodegen", "m68kdesc", "m68kdisassembler", "m68kinfo", "mc", "mca", "mcdisassembler", "mcjit", "mcparser", "mips", "mipsasmparser", "mipscodegen", "mipsdesc", "mipsdisassembler", "mipsinfo", "mirparser", "msp430", "msp430asmparser", "msp430codegen", "msp430desc", "msp430disassembler", "msp430info", "native", "nativecodegen", "nvptx", "nvptxcodegen", "nvptxdesc", "nvptxinfo", "objcarcopts", "objcopy", "object", "objectyaml", "option", "orcdebugging", "orcjit", "orcshared", "orctargetprocess", "passes", "perfjitevents", "powerpc", "powerpcasmparser", "powerpccodegen", "powerpcdesc", "powerpcdisassembler", "powerpcinfo", "profiledata", "remarks", "riscv", "riscvasmparser", "riscvcodegen", "riscvdesc", "riscvdisassembler", "riscvinfo", "riscvtargetmca", "runtimedyld", "scalaropts", "selectiondag", "sparc", "sparcasmparser", "sparccodegen", "sparcdesc", "sparcdisassembler", "sparcinfo", "support", "symbolize", "systemz", "systemzasmparser", "systemzcodegen", "systemzdesc", "systemzdisassembler", "systemzinfo", "tablegen", "target", "targetparser", "textapi", "textapibinaryreader", "transformutils", "ve", "veasmparser", "vecodegen", "vectorize", "vedesc", "vedisassembler", "veinfo", "webassembly", "webassemblyasmparser", "webassemblycodegen", "webassemblydesc", "webassemblydisassembler", "webassemblyinfo", "webassemblyutils", "windowsdriver", "windowsmanifest", "x86", "x86asmparser", "x86codegen", "x86desc", "x86disassembler", "x86info", "x86targetmca", "xcore", "xcorecodegen", "xcoredesc", "xcoredisassembler", "xcoreinfo", "xray", "xtensa", "xtensaasmparser", "xtensacodegen", "xtensadesc", "xtensadisassembler", "xtensainfo"]
4
+ VERSION = "19.1.0"
5
+ COMPONENTS = ["aarch64", "aarch64asmparser", "aarch64codegen", "aarch64desc", "aarch64disassembler", "aarch64info", "aarch64utils", "aggressiveinstcombine", "all", "all-targets", "amdgpu", "amdgpuasmparser", "amdgpucodegen", "amdgpudesc", "amdgpudisassembler", "amdgpuinfo", "amdgputargetmca", "amdgpuutils", "analysis", "arm", "armasmparser", "armcodegen", "armdesc", "armdisassembler", "arminfo", "armutils", "asmparser", "asmprinter", "avr", "avrasmparser", "avrcodegen", "avrdesc", "avrdisassembler", "avrinfo", "binaryformat", "bitreader", "bitstreamreader", "bitwriter", "bpf", "bpfasmparser", "bpfcodegen", "bpfdesc", "bpfdisassembler", "bpfinfo", "cfguard", "codegen", "codegendata", "codegentypes", "core", "coroutines", "coverage", "debuginfobtf", "debuginfocodeview", "debuginfodwarf", "debuginfogsym", "debuginfologicalview", "debuginfomsf", "debuginfopdb", "demangle", "dlltooldriver", "dwarflinker", "dwarflinkerclassic", "dwarflinkerparallel", "dwp", "engine", "executionengine", "extensions", "filecheck", "frontenddriver", "frontendhlsl", "frontendoffloading", "frontendopenacc", "frontendopenmp", "fuzzercli", "fuzzmutate", "globalisel", "hexagon", "hexagonasmparser", "hexagoncodegen", "hexagondesc", "hexagondisassembler", "hexagoninfo", "hipstdpar", "instcombine", "instrumentation", "interfacestub", "interpreter", "ipo", "irprinter", "irreader", "jitlink", "lanai", "lanaiasmparser", "lanaicodegen", "lanaidesc", "lanaidisassembler", "lanaiinfo", "libdriver", "lineeditor", "linker", "loongarch", "loongarchasmparser", "loongarchcodegen", "loongarchdesc", "loongarchdisassembler", "loongarchinfo", "lto", "m68k", "m68kasmparser", "m68kcodegen", "m68kdesc", "m68kdisassembler", "m68kinfo", "mc", "mca", "mcdisassembler", "mcjit", "mcparser", "mips", "mipsasmparser", "mipscodegen", "mipsdesc", "mipsdisassembler", "mipsinfo", "mirparser", "msp430", "msp430asmparser", "msp430codegen", "msp430desc", "msp430disassembler", "msp430info", "native", "nativecodegen", "nvptx", "nvptxcodegen", "nvptxdesc", "nvptxinfo", "objcarcopts", "objcopy", "object", "objectyaml", "option", "orcdebugging", "orcjit", "orcshared", "orctargetprocess", "passes", "perfjitevents", "powerpc", "powerpcasmparser", "powerpccodegen", "powerpcdesc", "powerpcdisassembler", "powerpcinfo", "profiledata", "remarks", "riscv", "riscvasmparser", "riscvcodegen", "riscvdesc", "riscvdisassembler", "riscvinfo", "riscvtargetmca", "runtimedyld", "sandboxir", "scalaropts", "selectiondag", "sparc", "sparcasmparser", "sparccodegen", "sparcdesc", "sparcdisassembler", "sparcinfo", "support", "symbolize", "systemz", "systemzasmparser", "systemzcodegen", "systemzdesc", "systemzdisassembler", "systemzinfo", "tablegen", "target", "targetparser", "textapi", "textapibinaryreader", "transformutils", "ve", "veasmparser", "vecodegen", "vectorize", "vedesc", "vedisassembler", "veinfo", "webassembly", "webassemblyasmparser", "webassemblycodegen", "webassemblydesc", "webassemblydisassembler", "webassemblyinfo", "webassemblyutils", "windowsdriver", "windowsmanifest", "x86", "x86asmparser", "x86codegen", "x86desc", "x86disassembler", "x86info", "x86targetmca", "xcore", "xcorecodegen", "xcoredesc", "xcoredisassembler", "xcoreinfo", "xray", "xtensa", "xtensaasmparser", "xtensacodegen", "xtensadesc", "xtensadisassembler", "xtensainfo"]
6
6
  TARGETS_BUILT = ["AArch64", "AMDGPU", "ARM", "AVR", "BPF", "Hexagon", "Lanai", "LoongArch", "Mips", "MSP430", "NVPTX", "PowerPC", "RISCV", "Sparc", "SystemZ", "VE", "WebAssembly", "X86", "XCore", "M68k", "Xtensa"]
7
7
  HOST_TARGET = "x86_64-pc-linux-gnu"
8
8
  BUILD_MODE = "RelWithDebInfo"
9
- CFLAGS = "-I/usr/lib/llvm-18/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
10
- CXXFLAGS = "-I/usr/lib/llvm-18/include -std=c++17 -fno-exceptions -funwind-tables -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
11
- LDFLAGS = "-L/usr/lib/llvm-18/lib"
9
+ CFLAGS = "-I/usr/lib/llvm-19/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
10
+ CXXFLAGS = "-I/usr/lib/llvm-19/include -std=c++17 -fno-exceptions -funwind-tables -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS"
11
+ LDFLAGS = "-L/usr/lib/llvm-19/lib"
12
+ LIBS = "-lLLVM-19"
12
13
  end
13
14
  end
@@ -3,11 +3,9 @@
3
3
  module LLVM
4
4
  # wrapper for LLVMAttributeRef
5
5
  class Attribute
6
-
7
6
  include PointerIdentity
8
7
 
9
8
  class << self
10
-
11
9
  def new(from)
12
10
  case from
13
11
  when String, Symbol
@@ -89,7 +87,6 @@ module LLVM
89
87
  0
90
88
  end
91
89
  end
92
-
93
90
  end
94
91
 
95
92
  def kind
@@ -188,6 +185,5 @@ module LLVM
188
185
  return C.get_string_attribute_value(self, size_ptr)
189
186
  end
190
187
  end
191
-
192
188
  end
193
189
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module LLVM
4
4
  class Builder
5
+ extend Gem::Deprecate
6
+
5
7
  # Important: Call #dispose to free backend memory after use.
6
8
  def initialize
7
9
  @ptr = C.create_builder()
@@ -173,17 +175,32 @@ module LLVM
173
175
  end
174
176
 
175
177
  def invoke2(type, fun, args, normal, exception, name = "")
176
- raise ArgumentError, "Trying to build LLVM call with non-function: #{fun.inspect}" if !fun.is_a?(LLVM::Function)
177
-
178
- type ||= fun.return_type
179
- must_be_type!(type)
178
+ type, fun = call2_infer_function_and_type(type, fun)
180
179
 
181
- s = args.size
182
- FFI::MemoryPointer.new(FFI.type_size(:pointer) * s) do |args_ptr|
180
+ arg_count = args.size
181
+ invoke_ins = nil
182
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_count) do |args_ptr|
183
183
  args_ptr.write_array_of_pointer(args)
184
- ins = C.build_invoke2(self, type, fun, args_ptr, s, normal, exception, name)
185
- return Instruction.from_ptr(ins)
184
+ ins = C.build_invoke2(self, type, fun, args_ptr, arg_count, normal, exception, name)
185
+ invoke_ins = InvokeInst.from_ptr(ins)
186
186
  end
187
+
188
+ if fun.is_a?(Function)
189
+ invoke_ins.call_conv = fun.call_conv
190
+ end
191
+
192
+ invoke_ins
193
+ end
194
+
195
+ # @return LLVM::Value
196
+ def landing_pad(type, personality_function, num_clauses, name = '')
197
+ C.build_landing_pad(self, type, personality_function, num_clauses, name)
198
+ end
199
+
200
+ def landing_pad_cleanup(type, personality_function, num_clauses, name = '')
201
+ lp = landing_pad(type, personality_function, num_clauses, name)
202
+ C.set_cleanup(lp, 1)
203
+ lp
187
204
  end
188
205
 
189
206
  # Builds an unwind Instruction.
@@ -479,9 +496,11 @@ module LLVM
479
496
  # @param [String] name Name of the result in LLVM IR
480
497
  # @return [LLVM::Instruction] The negated operand
481
498
  # @LLVMinst sub
499
+ # @deprecated
482
500
  def nuw_neg(arg, name = "")
483
501
  Instruction.from_ptr(C.build_nuw_neg(self, arg, name))
484
502
  end
503
+ deprecate :nuw_neg, "neg", 2025, 3
485
504
 
486
505
  # Boolean negation.
487
506
  # @param [LLVM::Value] arg Integer or vector of integers
@@ -505,7 +524,15 @@ module LLVM
505
524
  # @param [String] name The name of the result in LLVM IR
506
525
  # @return [LLVM::Instruction] A pointer to the malloced array
507
526
  def array_malloc(ty, sz, name = "")
508
- Instruction.from_ptr(C.build_array_malloc(self, LLVM::Type(ty), sz, name))
527
+ size = case sz
528
+ when LLVM::Value
529
+ sz
530
+ when Integer
531
+ LLVM.i(32, sz)
532
+ else
533
+ raise ArgumentError, "Unknown size parameter for array_malloc: #{sz}"
534
+ end
535
+ Instruction.from_ptr(C.build_array_malloc(self, LLVM::Type(ty), size, name))
509
536
  end
510
537
 
511
538
  # Stack allocation.
@@ -588,7 +615,7 @@ module LLVM
588
615
  # @LLVMinst gep2
589
616
  # @see http://llvm.org/docs/GetElementPtr.html
590
617
  # may return Instruction or GlobalVariable
591
- def gep2(type, ptr, indices, name)
618
+ def gep2(type, ptr, indices, name = '')
592
619
  must_be_value!(ptr)
593
620
 
594
621
  type ||= must_infer_type!(ptr)
@@ -618,7 +645,7 @@ module LLVM
618
645
  def inbounds_gep2(type, ptr, indices, name = "")
619
646
  must_be_value!(ptr)
620
647
 
621
- type = must_infer_type!(ptr)
648
+ type ||= must_infer_type!(ptr)
622
649
  must_be_type!(type)
623
650
 
624
651
  indices = Array(indices)
@@ -642,13 +669,13 @@ module LLVM
642
669
  struct_gep2(nil, ptr, idx, name)
643
670
  end
644
671
 
645
- def struct_gep2(type, ptr, idx, name)
672
+ def struct_gep2(type, ptr, idx, name = "")
646
673
  must_be_value!(ptr)
647
674
 
648
675
  type ||= must_infer_type!(ptr)
649
676
  must_be_type!(type)
650
677
 
651
- ins = C.build_struct_gep2(self, type, ptr, idx, name)
678
+ ins = C.build_struct_gep2(self, type, ptr, idx.to_i, name)
652
679
  Instruction.from_ptr(ins)
653
680
  end
654
681
 
@@ -838,6 +865,7 @@ module LLVM
838
865
  # @param [LLVM::Type, #ty] ty
839
866
  # @param [String] name The name of the result in LLVM IR
840
867
  # @return [LLVM::Instruction]
868
+ # Cast pointer to other type
841
869
  def pointer_cast(val, ty, name = "")
842
870
  Instruction.from_ptr(C.build_pointer_cast(self, val, LLVM::Type(ty), name))
843
871
  end
@@ -850,6 +878,15 @@ module LLVM
850
878
  Instruction.from_ptr(C.build_int_cast(self, val, LLVM::Type(ty), name))
851
879
  end
852
880
 
881
+ # @param [LLVM::Value] val
882
+ # @param [LLVM::Type, #ty] ty
883
+ # @param [String] name The name of the result in LLVM IR
884
+ # @param [bool] signed whether to sign or zero extend
885
+ # @return [LLVM::Instruction]
886
+ def int_cast2(val, ty, signed, name = "")
887
+ Instruction.from_ptr(C.build_int_cast2(self, val, LLVM::Type(ty), signed, name))
888
+ end
889
+
853
890
  # @param [LLVM::Value] val
854
891
  # @param [LLVM::Type, #ty] ty
855
892
  # @param [String] name The name of the result in LLVM IR
@@ -998,6 +1035,8 @@ module LLVM
998
1035
  # @return [LLVM::Instruction] The extracted element
999
1036
  # @LLVMinst extractelement
1000
1037
  def extract_element(vector, idx, name = "")
1038
+ must_be_value!(vector)
1039
+ must_be_value!(idx)
1001
1040
  error = element_error(vector, idx)
1002
1041
 
1003
1042
  raise ArgumentError, "Error building extract_element with #{error}" if error
@@ -1014,12 +1053,11 @@ module LLVM
1014
1053
  # @return [LLVM::Instruction] A vector the same type as 'vector'
1015
1054
  # @LLVMinst insertelement
1016
1055
  def insert_element(vector, elem, idx, name = "")
1056
+ must_be_value!(vector)
1057
+ must_be_value!(elem)
1058
+ must_be_value!(idx)
1017
1059
  error = element_error(vector, idx)
1018
1060
 
1019
- error ||= if !elem.is_a?(LLVM::Value)
1020
- "elem: #{elem.inspect}"
1021
- end
1022
-
1023
1061
  raise ArgumentError, "Error building insert_element with #{error}" if error
1024
1062
 
1025
1063
  ins = C.build_insert_element(self, vector, elem, idx, name)
@@ -1045,6 +1083,7 @@ module LLVM
1045
1083
  # @return [LLVM::Instruction] The extracted value
1046
1084
  # @LLVMinst extractvalue
1047
1085
  def extract_value(aggregate, idx, name = "")
1086
+ must_be_value!(aggregate)
1048
1087
  error = value_error(aggregate, idx)
1049
1088
 
1050
1089
  raise ArgumentError, "Error building extract_value with #{error}" if error
@@ -1061,12 +1100,10 @@ module LLVM
1061
1100
  # @return [LLVM::Instruction] An aggregate value of the same type as 'aggregate'
1062
1101
  # @LLVMinst insertvalue
1063
1102
  def insert_value(aggregate, elem, idx, name = "")
1103
+ must_be_value!(aggregate)
1104
+ must_be_value!(elem)
1064
1105
  error = value_error(aggregate, idx)
1065
1106
 
1066
- error ||= if !elem.is_a?(LLVM::Value)
1067
- "elem: #{elem.inspect}"
1068
- end
1069
-
1070
1107
  raise ArgumentError, "Error building insert_value with #{error}" if error
1071
1108
 
1072
1109
  ins = C.build_insert_value(self, aggregate, elem, idx, name)
@@ -1096,18 +1133,34 @@ module LLVM
1096
1133
  # @return [LLVM::Instruction] The integer difference between the two
1097
1134
  # pointers
1098
1135
  def ptr_diff(lhs, rhs, name = "")
1099
- Instruction.from_ptr(C.build_ptr_diff(lhs, rhs, name))
1136
+ ptr_diff2(nil, lhs, rhs, name)
1137
+ end
1138
+
1139
+ def ptr_diff2(type, lhs, rhs, name = "")
1140
+ must_be_value!(lhs)
1141
+ must_be_value!(rhs)
1142
+
1143
+ type ||= begin
1144
+ lhs_type = must_infer_type!(lhs)
1145
+ rhs_type = must_infer_type!(lhs)
1146
+ raise ArgumentError, "ptr_diff types must match: [#{lhs_type}] [#{rhs_type}]" if lhs_type != rhs_type
1147
+
1148
+ lhs_type
1149
+ end
1150
+ must_be_type!(type)
1151
+
1152
+ Instruction.from_ptr(C.build_ptr_diff2(self, type, lhs, rhs, name))
1100
1153
  end
1101
1154
 
1102
1155
  private
1103
1156
 
1104
1157
  def must_be_value!(value)
1105
- raise "must be a Value, got #{value.class.name}" unless Value === value
1158
+ raise ArgumentError, "must be a Value, got #{value.class.name}" unless Value === value
1106
1159
  end
1107
1160
 
1108
1161
  def must_be_type!(type)
1109
1162
  type2 = LLVM.Type(type)
1110
- raise "must be a Type (LLVMTypeRef), got #{type2.class.name}" unless Type === type2
1163
+ raise ArgumentError, "must be a Type (LLVMTypeRef), got #{type2.class.name}" unless Type === type2
1111
1164
  end
1112
1165
 
1113
1166
  def must_infer_type!(value)
@@ -1121,7 +1174,7 @@ module LLVM
1121
1174
  when Instruction
1122
1175
  must_infer_instruction_type!(ptr)
1123
1176
  else
1124
- raise "#{ptr.class.name} #{ptr}"
1177
+ raise ArgumentError, "Cannot infer type from [#{ptr}] with type [#{ptr.type}]"
1125
1178
  end
1126
1179
  end
1127
1180
 
@@ -1130,7 +1183,7 @@ module LLVM
1130
1183
  when :get_element_ptr
1131
1184
  must_infer_gep!(ptr)
1132
1185
  when :alloca
1133
- Type.from_ptr(C.get_allocated_type(ptr))
1186
+ ptr.allocated_type
1134
1187
  when :load
1135
1188
  ptr.type
1136
1189
  else
@@ -1148,23 +1201,32 @@ module LLVM
1148
1201
  when :array, :vector
1149
1202
  source_type.element_type
1150
1203
  else
1151
- debugger
1204
+ raise ArgumentError
1152
1205
  end
1153
1206
  end
1154
1207
 
1155
1208
  def element_error(vector, idx)
1156
1209
  if !vector.is_a?(LLVM::Value)
1210
+ # :nocov:
1211
+ # already handled
1157
1212
  "non-value: #{vector.inspect}"
1213
+ # :nocov:
1158
1214
  elsif vector.type.kind != :vector
1159
1215
  "non-vector: #{vector.type.kind}"
1160
1216
  elsif !idx.is_a?(LLVM::Value)
1217
+ # :nocov:
1218
+ # already handled
1161
1219
  "index: #{idx}"
1220
+ # :nocov:
1162
1221
  end
1163
1222
  end
1164
1223
 
1165
1224
  def value_error(aggregate, idx)
1166
1225
  if !aggregate.is_a?(LLVM::Value)
1226
+ # :nocov:
1227
+ # already handled
1167
1228
  "non-value: #{aggregate.inspect}"
1229
+ # :nocov:
1168
1230
  # TODO: fix this
1169
1231
  elsif !aggregate.type.aggregate?
1170
1232
  "non-aggregate: #{aggregate.type.kind}"
@@ -81,7 +81,7 @@ module LLVM
81
81
  Type.from_ptr(C.get_type_by_name(@module, name.to_s), nil)
82
82
  end
83
83
 
84
- alias [] named
84
+ alias_method :[], :named
85
85
  end
86
86
 
87
87
  # Returns an Enumerable of all the GlobalVariables in the module.
@@ -251,6 +251,5 @@ module LLVM
251
251
  def dump
252
252
  C.dump_module(self)
253
253
  end
254
-
255
254
  end
256
255
  end
@@ -11,6 +11,8 @@ module LLVM
11
11
  ty = case kind
12
12
  when :integer
13
13
  IntType.allocate
14
+ when :float, :double
15
+ RealType.allocate
14
16
  when :function
15
17
  FunctionType.allocate
16
18
  when :struct
@@ -24,9 +26,7 @@ module LLVM
24
26
  end
25
27
 
26
28
  # Returns a symbol representation of the types kind (ex. :pointer, :vector, :array.)
27
- def kind
28
- @kind
29
- end
29
+ attr_reader :kind
30
30
 
31
31
  # Returns the size of the type.
32
32
  def size
@@ -46,7 +46,7 @@ module LLVM
46
46
  when :pointer
47
47
  LLVM.Void
48
48
  else
49
- raise "element_type not supported for kind: #{kind}"
49
+ raise ArgumentError, "element_type not supported for kind: #{kind}"
50
50
  end
51
51
  end
52
52
 
@@ -57,11 +57,18 @@ module LLVM
57
57
 
58
58
  # Returns a null ConstantExpr of this type.
59
59
  def null
60
- ConstantExpr.from_ptr(C.const_null(self))
60
+ # ConstantExpr.from_ptr(C.const_null(self))
61
+ Constant.null(self)
61
62
  end
62
63
 
63
64
  def poison
64
- ConstantExpr.from_ptr(C.get_poison(self))
65
+ # ConstantExpr.from_ptr(C.get_poison(self))
66
+ Constant.poison(self)
67
+ end
68
+
69
+ def undef
70
+ # ConstantExpr.from_ptr(C.get_undef(self))
71
+ Constant.undef(self)
65
72
  end
66
73
 
67
74
  # Creates a pointer type with this type and the given address space.
@@ -71,7 +78,9 @@ module LLVM
71
78
 
72
79
  # Print the type's representation to stdout.
73
80
  def dump
81
+ # :nocov:
74
82
  C.dump_type(self)
83
+ # :nocov:
75
84
  end
76
85
 
77
86
  # Build string of LLVM type representation.
@@ -95,6 +104,14 @@ module LLVM
95
104
  C.is_literal_struct(self)
96
105
  end
97
106
 
107
+ def ===(other)
108
+ if other.is_a?(LLVM::Value)
109
+ return self == other.type
110
+ end
111
+
112
+ super
113
+ end
114
+
98
115
  # Creates an array type of Type with the given size.
99
116
  # arrays can be size >= 0, https://llvm.org/docs/LangRef.html#array-type
100
117
  def self.array(ty, sz = 0)
@@ -178,18 +195,98 @@ module LLVM
178
195
  # from_ptr(C.opaque_type, :pointer)
179
196
  # end
180
197
 
181
- def self.rec
182
- h = opaque
183
- ty = yield h
184
- h.refine(ty)
185
- ty
198
+ # def self.rec
199
+ # h = opaque
200
+ # ty = yield h
201
+ # h.refine(ty)
202
+ # ty
203
+ # end
204
+
205
+ def self.integer(width)
206
+ IntType.from_ptr(C.int_type(width), :integer)
207
+ end
208
+
209
+ class << self
210
+ alias_method :i, :integer
211
+ end
212
+
213
+ def self.float
214
+ RealType.from_ptr(C.float_type, kind: :float)
215
+ end
216
+
217
+ def self.double
218
+ RealType.from_ptr(C.double_type, kind: :double)
186
219
  end
187
220
  end
188
221
 
189
222
  class IntType < Type
223
+ def all_ones
224
+ from_ptr(C.const_all_ones(self))
225
+ end
226
+
190
227
  def width
191
228
  C.get_int_type_width(self)
192
229
  end
230
+
231
+ def from_i(int, options = {})
232
+ signed = case options
233
+ when true, false
234
+ options
235
+ when Hash
236
+ options.fetch(:signed, true)
237
+ else
238
+ raise ArgumentError
239
+ end
240
+ # return poison if !fits_width?(int, width, signed)
241
+
242
+ ptr = C.const_int(self, int, signed ? 1 : 0)
243
+ val = from_ptr(ptr)
244
+ val.to_i(signed) == int ? val : poison
245
+ end
246
+
247
+ # unused
248
+ private def fits_width?(int, width, signed)
249
+ # :nocov:
250
+ if signed
251
+ int.bit_length < width || int == 1
252
+ else
253
+ int >= 0 && int.bit_length <= width
254
+ end
255
+ # :nocov:
256
+ end
257
+
258
+ def from_ptr(ptr)
259
+ ConstantInt.from_ptr(ptr)
260
+ end
261
+
262
+ def parse(str, radix = 10)
263
+ # from_ptr(C.const_int_of_string(self, str, radix))
264
+ from_i(str.to_i(radix))
265
+ end
266
+
267
+ def type
268
+ self
269
+ end
270
+ end
271
+
272
+ class RealType < Type
273
+ # given an array of values, return the type that will fit all of them
274
+ # currently only works for floats and doubles
275
+ def self.fits(values)
276
+ values.detect { |v| v.type.to_s == 'double' } ? double : float
277
+ end
278
+
279
+ def from_f(value)
280
+ ConstantReal.from_ptr(C.const_real(self, value))
281
+ end
282
+
283
+ def parse(str)
284
+ ConstantReal.from_ptr(C.const_real_of_string(self, str))
285
+ end
286
+
287
+ def type
288
+ self
289
+ end
193
290
  end
194
291
 
195
292
  class FunctionType < Type
@@ -247,8 +344,10 @@ module LLVM
247
344
  # Creates a Type from the given object.
248
345
  def Type(ty)
249
346
  case ty
250
- when LLVM::Type then ty
251
- else ty.type
347
+ when LLVM::Type
348
+ ty
349
+ else
350
+ ty.type
252
351
  end
253
352
  end
254
353
 
@@ -287,4 +386,42 @@ module LLVM
287
386
  LLVM::Type.void
288
387
  end
289
388
 
389
+ def void
390
+ LLVM::Type.void
391
+ end
392
+
393
+ def i(width, value = nil)
394
+ type = LLVM::Type.i(width)
395
+ value ? type.from_i(value) : type
396
+ end
397
+
398
+ def double(value = nil)
399
+ type = LLVM::Type.double
400
+ value ? type.from_f(value) : type
401
+ end
402
+
403
+ def float(value = nil)
404
+ type = LLVM::Type.float
405
+ value ? type.from_f(value) : type
406
+ end
407
+
408
+ def ptr
409
+ LLVM::Type.pointer
410
+ end
411
+
412
+ # for compatibility
413
+ # Create a float LLVM::ContantReal from a Ruby Float (value).
414
+ def Float(value)
415
+ float(value)
416
+ end
417
+
418
+ # for compatibility
419
+ # Create a double LLVM::ContantReal from a Ruby Float (value).
420
+ def Double(value)
421
+ double(value)
422
+ end
423
+
424
+ # for compatibility
425
+ Float = float.freeze
426
+ Double = double.freeze
290
427
  end