ruby-llvm 18.1.7 → 18.2.0

Sign up to get free protection for your applications and to get access to all the features.
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