ruby-llvm 18.1.8 → 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.
@@ -20,13 +20,13 @@ module LLVM
20
20
  when :instruction
21
21
  Instruction.from_ptr(ptr)
22
22
  when :const_int
23
- Int.from_ptr(ptr)
23
+ ConstantInt.from_ptr(ptr)
24
24
  when :const_fp
25
- Float.from_ptr(ptr)
25
+ ConstantReal.from_ptr(ptr)
26
26
  when :poison
27
27
  Poison.from_ptr(ptr)
28
28
  when :global_variable
29
- GlobalValue.from_ptr(ptr)
29
+ GlobalVariable.from_ptr(ptr)
30
30
  else
31
31
  raise "from_ptr_kind cannot handle: #{kind}"
32
32
  end
@@ -51,8 +51,35 @@ module LLVM
51
51
  C.get_value_kind(self)
52
52
  end
53
53
 
54
+ def allocated_type?
55
+ case self
56
+ when Instruction
57
+ true
58
+ else
59
+ false
60
+ end
61
+ end
62
+
63
+ # allocated type of alloca
64
+ # also works on geps of allocas
54
65
  def allocated_type
55
- Type.from_ptr(C.get_allocated_type(self), nil)
66
+ return if !allocated_type?
67
+
68
+ alloc_type = C.get_allocated_type(self)
69
+ return nil if alloc_type.nil?
70
+
71
+ Type.from_ptr(alloc_type, nil)
72
+ end
73
+
74
+ def gep_source_element_type?
75
+ is_a?(Instruction)
76
+ end
77
+
78
+ # element type of gep
79
+ def gep_source_element_type
80
+ return if !gep_source_element_type?
81
+
82
+ Type.from_ptr(C.get_gep_source_element_type(self))
56
83
  end
57
84
 
58
85
  # Returns the value's name.
@@ -63,12 +90,13 @@ module LLVM
63
90
  # Sets the value's name to str.
64
91
  def name=(str)
65
92
  C.set_value_name(self, str)
66
- str
67
93
  end
68
94
 
69
95
  # Print the value's IR to stdout.
70
96
  def dump
97
+ # :nocov:
71
98
  C.dump_value(self)
99
+ # :nocov:
72
100
  end
73
101
 
74
102
  def to_s
@@ -77,26 +105,22 @@ module LLVM
77
105
 
78
106
  # Returns whether the value is constant.
79
107
  def constant?
80
- case C.is_constant(self)
81
- when 0 then false
82
- when 1 then true
83
- end
108
+ C.is_constant(self)
84
109
  end
85
110
 
86
111
  # Returns whether the value is null.
87
112
  def null?
88
- case C.is_null(self)
89
- when 0 then false
90
- when 1 then true
91
- end
113
+ C.is_null(self)
92
114
  end
93
115
 
94
116
  # Returns whether the value is undefined.
95
- def undefined?
96
- case C.is_undef(self)
97
- when 0 then false
98
- when 1 then true
99
- end
117
+ def undef?
118
+ C.is_undef(self)
119
+ end
120
+ alias_method :undefined?, :undef?
121
+
122
+ def poison?
123
+ C.is_poison(self)
100
124
  end
101
125
 
102
126
  # Adds attr to this value's attributes.
@@ -144,7 +168,6 @@ module LLVM
144
168
  return if index.nil?
145
169
  index + 1
146
170
  end
147
-
148
171
  end
149
172
 
150
173
  class Argument < Value
@@ -213,11 +236,12 @@ module LLVM
213
236
  # Iterates through each Instruction in the collection.
214
237
  def each
215
238
  return to_enum :each unless block_given?
216
- inst, last = first, last
239
+ inst = first
240
+ final = last
217
241
 
218
242
  while inst
219
243
  yield inst
220
- break if inst == last
244
+ break if inst == final
221
245
  inst = inst.next
222
246
  end
223
247
 
@@ -288,6 +312,10 @@ module LLVM
288
312
  from_ptr(C.get_undef(type))
289
313
  end
290
314
 
315
+ def self.poison(type)
316
+ from_ptr(C.get_poison(type))
317
+ end
318
+
291
319
  # Creates a null pointer constant of Type.
292
320
  def self.null_ptr(type)
293
321
  from_ptr(C.const_pointer_null(type))
@@ -299,7 +327,7 @@ module LLVM
299
327
  end
300
328
 
301
329
  # @deprecated
302
- alias bit_cast bitcast_to
330
+ alias_method :bit_cast, :bitcast_to
303
331
 
304
332
  # Returns the element pointer at the given indices of the constant.
305
333
  # For more information on gep go to: http://llvm.org/docs/GetElementPtr.html
@@ -339,6 +367,10 @@ module LLVM
339
367
  from_ptr(C.const_string(str, str.length, null_terminate ? 0 : 1))
340
368
  end
341
369
 
370
+ def self.string_in_context(context, str, null_terminate = true)
371
+ from_ptr(C.const_string_in_context(context, str, str.length, null_terminate ? 0 : 1))
372
+ end
373
+
342
374
  # ConstantArray.const(type, 3) {|i| ... } or
343
375
  # ConstantArray.const(type, [...])
344
376
  def self.const(type, size_or_values, &block)
@@ -359,38 +391,44 @@ module LLVM
359
391
  end
360
392
 
361
393
  class ConstantInt < Constant
362
- def self.all_ones
363
- from_ptr(C.const_all_ones(type))
364
- end
365
-
366
- # Creates a ConstantInt from an integer.
367
- def self.from_i(int, signed = true)
368
- width = type.width
369
- return type.poison if !fits_width?(int, width, signed)
370
-
371
- from_ptr(C.const_int(type, int, signed ? 1 : 0))
372
- end
373
-
374
- # does int fit in width
375
- # allow 1 for signed i1 (though really it's -1 to 0)
376
- def self.fits_width?(int, width, signed)
377
- if signed
378
- int.bit_length < width || int == 1
379
- else
380
- int >= 0 && int.bit_length <= width
381
- end
382
- end
383
-
384
- def self.parse(str, radix = 10)
385
- from_ptr(C.const_int_of_string(type, str, radix))
386
- end
394
+ extend Gem::Deprecate
395
+
396
+ # def type
397
+ # super
398
+ # end
399
+ #
400
+ # def self.all_ones
401
+ # from_ptr(C.const_all_ones(type))
402
+ # end
403
+ #
404
+ # # Creates a ConstantInt from an integer.
405
+ # def self.from_i(int, signed = true)
406
+ # width = type.width
407
+ # return type.poison if !fits_width?(int, width, signed)
408
+ #
409
+ # from_ptr(C.const_int(type, int, signed ? 1 : 0))
410
+ # end
411
+ #
412
+ # # does int fit in width
413
+ # # allow 1 for signed i1 (though really it's -1 to 0)
414
+ # def self.fits_width?(int, width, signed)
415
+ # if signed
416
+ # int.bit_length < width || int == 1
417
+ # else
418
+ # int >= 0 && int.bit_length <= width
419
+ # end
420
+ # end
421
+ #
422
+ # def self.parse(str, radix = 10)
423
+ # from_ptr(C.const_int_of_string(type, str, radix))
424
+ # end
387
425
 
388
426
  # Negation.
389
427
  def -@
390
428
  self.class.from_ptr(C.const_neg(self))
391
429
  end
392
430
 
393
- alias neg -@
431
+ alias_method :neg, :-@
394
432
 
395
433
  # "No signed wrap" negation.
396
434
  def nsw_neg
@@ -398,16 +436,20 @@ module LLVM
398
436
  end
399
437
 
400
438
  # "No unsigned wrap" negation.
439
+ # @deprecated
401
440
  def nuw_neg
441
+ # :nocov:
402
442
  self.class.from_ptr(C.const_nuw_neg(self))
443
+ # :nocov:
403
444
  end
445
+ deprecate :nuw_neg, "neg", 2025, 3
404
446
 
405
447
  # Addition.
406
448
  def +(rhs)
407
449
  self.class.from_ptr(C.const_add(self, rhs))
408
450
  end
409
451
 
410
- alias add +
452
+ alias_method :add, :+
411
453
 
412
454
  # "No signed wrap" addition.
413
455
  def nsw_add(rhs)
@@ -424,7 +466,7 @@ module LLVM
424
466
  self.class.from_ptr(C.const_sub(self, rhs))
425
467
  end
426
468
 
427
- alias sub -
469
+ alias_method :sub, :-
428
470
 
429
471
  # "No signed wrap" subtraction.
430
472
  def nsw_sub(rhs)
@@ -441,7 +483,7 @@ module LLVM
441
483
  self.class.from_ptr(C.const_mul(self, rhs))
442
484
  end
443
485
 
444
- alias mul *
486
+ alias_method :mul, :*
445
487
 
446
488
  # "No signed wrap" multiplication.
447
489
  def nsw_mul(rhs)
@@ -455,22 +497,26 @@ module LLVM
455
497
 
456
498
  # Unsigned division.
457
499
  def udiv(rhs)
458
- self.class.from_i(to_ui / rhs.to_ui, false)
500
+ width = [type.width, rhs.type.width].max
501
+ LLVM::Type.integer(width).from_i(to_ui / rhs.to_ui, false)
459
502
  end
460
503
 
461
504
  # Signed division.
462
505
  def /(rhs)
463
- self.class.from_i(to_si / rhs.to_si, true)
506
+ width = [type.width, rhs.type.width].max
507
+ LLVM::Type.integer(width).from_i(to_si / rhs.to_si, true)
464
508
  end
465
509
 
466
510
  # Unsigned remainder.
467
511
  def urem(rhs)
468
- self.class.from_i(to_ui % rhs.to_ui, false)
512
+ width = [type.width, rhs.type.width].max
513
+ LLVM::Type.integer(width).from_i(to_ui % rhs.to_ui, false)
469
514
  end
470
515
 
471
516
  # Signed remainder.
472
517
  def rem(rhs)
473
- self.class.from_i(to_si % rhs.to_si, true)
518
+ width = [type.width, rhs.type.width].max
519
+ LLVM::Type.integer(width).from_i(to_si % rhs.to_si, true)
474
520
  end
475
521
 
476
522
  # Boolean negation.
@@ -478,47 +524,53 @@ module LLVM
478
524
  self.class.from_ptr(C.const_not(self))
479
525
  end
480
526
 
481
- alias not ~
527
+ alias_method :not, :~
482
528
 
483
529
  # Integer AND.
484
530
  # was: self.class.from_ptr(C.const_and(self, rhs))
485
531
  def &(rhs)
486
- self.class.from_i(to_i & rhs.to_i)
532
+ width = [type.width, rhs.type.width].max
533
+ LLVM::Type.integer(width).from_i(to_i & rhs.to_i)
487
534
  end
488
535
 
489
- alias and &
536
+ alias_method :and, :&
490
537
 
491
538
  # Integer OR.
492
539
  def |(rhs)
493
- self.class.from_i(to_i | rhs.to_i)
540
+ width = [type.width, rhs.type.width].max
541
+ LLVM::Type.integer(width).from_i(to_i | rhs.to_i)
494
542
  end
495
543
 
496
- alias or |
544
+ alias_method :or, :|
497
545
 
498
546
  # Integer XOR.
499
547
  def ^(rhs)
500
548
  self.class.from_ptr(C.const_xor(self, rhs))
501
549
  end
502
550
 
503
- alias xor ^
551
+ alias_method :xor, :^
504
552
 
505
553
  # Shift left.
506
554
  def <<(bits)
507
- self.class.from_ptr(C.const_shl(self, bits))
555
+ width = [type.width, bits.type.width].max
556
+ LLVM::Type.integer(width).from_i(to_i << bits.to_i)
508
557
  end
509
558
 
510
- alias shl <<
559
+ alias_method :shl, :<<
511
560
 
512
561
  # Shift right.
513
- def >>(bits)
514
- self.class.from_ptr(C.const_l_shr(self, bits))
562
+ def lshr(bits)
563
+ width = [type.width, bits.type.width].max
564
+ LLVM::Type.integer(width).from_i(to_ui >> bits.to_i)
515
565
  end
516
566
 
517
- alias shr >>
567
+ alias_method :shr, :lshr
568
+ alias_method :>>, :lshr
518
569
 
519
570
  # Arithmatic shift right.
520
571
  def ashr(bits)
521
- self.class.from_ptr(C.const_a_shr(self, bits))
572
+ width = [type.width, bits.type.width].max
573
+ LLVM::Type.integer(width).from_i(to_i >> bits.to_i)
522
574
  end
523
575
 
524
576
  # Integer comparison using the predicate specified via the first parameter.
@@ -533,12 +585,12 @@ module LLVM
533
585
  # :sge - signed greater than or equal to
534
586
  # :slt - signed less than
535
587
  # :sle - signed less than or equal to
536
- def icmp(pred, rhs)
537
- self.class.from_ptr(C.const_i_cmp(pred, self, rhs))
588
+ def icmp(_pred, _rhs)
589
+ raise DeprecationError
538
590
  end
539
591
 
540
592
  # Conversion to pointer.
541
- def int_to_ptr(type)
593
+ def int_to_ptr(type = LLVM.Pointer)
542
594
  ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
543
595
  end
544
596
 
@@ -584,19 +636,14 @@ module LLVM
584
636
  end
585
637
  end
586
638
 
639
+ # creates LLVM::Int1, LLVM::Int64, etc
587
640
  def self.const_missing(const)
588
641
  case const.to_s
589
642
  when /Int(\d+)/
590
643
  width = Regexp.last_match(1).to_i
591
- name = "Int#{width}"
592
- eval <<-KLASS
593
- class #{name} < ConstantInt
594
- def self.type
595
- Type.from_ptr(C.int_type(#{width}), :integer)
596
- end
597
- end
598
- KLASS
599
- const_get(name)
644
+ name = "Int#{width}"
645
+ value = LLVM::Type.integer(width).freeze
646
+ const_set(name, value)
600
647
  else
601
648
  super
602
649
  end
@@ -623,42 +670,39 @@ module LLVM
623
670
  ::LLVM::FALSE = ::LLVM::Int1.from_i(0)
624
671
 
625
672
  class ConstantReal < Constant
626
- # Creates a ConstantReal from a float of Type.
627
- def self.from_f(n)
628
- from_ptr(C.const_real(type, n))
629
- end
630
-
631
- def self.parse(type, str)
632
- from_ptr(C.const_real_of_string(type, str))
633
- end
634
-
635
673
  # Negation.
674
+ # fneg
636
675
  def -@
637
- self.class.from_f(-to_f)
676
+ type.from_f(-to_f)
638
677
  end
639
678
 
640
679
  # Returns the result of adding this ConstantReal to rhs.
641
680
  def +(rhs)
642
- self.class.from_f(to_f + rhs.to_f)
681
+ type = LLVM::RealType.fits([self.type, rhs.type])
682
+ type.from_f(to_f + rhs.to_f)
643
683
  end
644
684
 
645
685
  def -(rhs)
646
- self.class.from_f(to_f - rhs.to_f)
686
+ type = LLVM::RealType.fits([self.type, rhs.type])
687
+ type.from_f(to_f - rhs.to_f)
647
688
  end
648
689
 
649
690
  # Returns the result of multiplying this ConstantReal by rhs.
650
691
  def *(rhs)
651
- self.class.from_f(to_f * rhs.to_f)
692
+ type = LLVM::RealType.fits([self.type, rhs.type])
693
+ type.from_f(to_f * rhs.to_f)
652
694
  end
653
695
 
654
696
  # Returns the result of dividing this ConstantReal by rhs.
655
697
  def /(rhs)
656
- self.class.from_f(to_f / rhs.to_f) # rubocop:disable Style/FloatDivision
698
+ type = LLVM::RealType.fits([self.type, rhs.type])
699
+ type.from_f(to_f / rhs.to_f) # rubocop:disable Style/FloatDivision
657
700
  end
658
701
 
659
702
  # Remainder.
660
703
  def rem(rhs)
661
- self.class.from_f(to_f.divmod(rhs.to_f).last)
704
+ type = LLVM::RealType.fits([self.type, rhs.type])
705
+ type.from_f(to_f.divmod(rhs.to_f).last)
662
706
  end
663
707
 
664
708
  # Floating point comparison using the predicate specified via the first
@@ -679,8 +723,8 @@ module LLVM
679
723
  # :sle - unordered and less than or equal to
680
724
  # :true - always true
681
725
  # :false- always false
682
- def fcmp(pred, rhs)
683
- self.class.from_ptr(C.llmv_const_f_cmp(pred, self, rhs))
726
+ def fcmp(_pred, _rhs)
727
+ raise DeprecationError
684
728
  end
685
729
 
686
730
  # constant FPToSI
@@ -711,29 +755,6 @@ module LLVM
711
755
  end
712
756
  double
713
757
  end
714
-
715
- end
716
-
717
- class Float < ConstantReal
718
- # Return a Type representation of the float.
719
- def self.type
720
- Type.from_ptr(C.float_type, :float)
721
- end
722
- end
723
-
724
- # Create a LLVM::Float from a Ruby Float (val).
725
- def self.Float(val)
726
- Float.from_f(val)
727
- end
728
-
729
- class Double < ConstantReal
730
- def self.type
731
- Type.from_ptr(C.double_type, :double)
732
- end
733
- end
734
-
735
- def self.Double(val)
736
- Double.from_f(val)
737
758
  end
738
759
 
739
760
  class ConstantStruct < Constant
@@ -761,6 +782,11 @@ module LLVM
761
782
 
762
783
  def self.const(size_or_values, &block)
763
784
  vals = LLVM::Support.allocate_pointers(size_or_values, &block)
785
+
786
+ # size 0, or empty values
787
+ # this will segfault in const_vector
788
+ raise ArgumentError if vals.size.zero? # rubocop:disable Style/ZeroLengthPredicate
789
+
764
790
  from_ptr(C.const_vector(vals, vals.size / vals.type_size))
765
791
  end
766
792
 
@@ -810,27 +836,6 @@ module LLVM
810
836
  C.set_alignment(self, bytes)
811
837
  end
812
838
 
813
- def initializer
814
- Value.from_ptr(C.get_initializer(self))
815
- end
816
-
817
- def initializer=(val)
818
- C.set_initializer(self, val)
819
- end
820
-
821
- def global_constant?
822
- C.is_global_constant(self) != 0
823
- end
824
-
825
- def global_constant=(flag)
826
- if flag.kind_of?(Integer)
827
- warn 'Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.'
828
- flag = !flag.zero?
829
- end
830
-
831
- C.set_global_constant(self, flag ? 1 : 0)
832
- end
833
-
834
839
  def unnamed_addr?
835
840
  C.has_unnamed_addr(self) != 0
836
841
  end
@@ -852,7 +857,6 @@ module LLVM
852
857
  # Sets the function's calling convention and returns it.
853
858
  def call_conv=(conv)
854
859
  C.set_function_call_conv(self, conv)
855
- conv
856
860
  end
857
861
 
858
862
  # gets the calling convention of the function
@@ -873,7 +877,6 @@ module LLVM
873
877
  # @return self
874
878
  def personality_function=(personality_function)
875
879
  C.set_personality_fn(self, personality_function)
876
- self
877
880
  end
878
881
 
879
882
  # Returns an Enumerable of the BasicBlocks in this function.
@@ -937,7 +940,6 @@ module LLVM
937
940
  end
938
941
 
939
942
  class AttributeCollection
940
-
941
943
  def initialize(fun, index)
942
944
  @fun = fun
943
945
  @index = index
@@ -1017,7 +1019,6 @@ module LLVM
1017
1019
  LLVM::Attribute.memory(inaccessiblemem: :readwrite)
1018
1020
  end
1019
1021
  end
1020
-
1021
1022
  end
1022
1023
 
1023
1024
  # @private
@@ -1133,23 +1134,42 @@ module LLVM
1133
1134
  end
1134
1135
 
1135
1136
  def initializer=(val)
1137
+ raise ArgumentError unless val.is_a? Constant
1138
+
1136
1139
  C.set_initializer(self, val)
1137
1140
  end
1138
1141
 
1139
1142
  def thread_local?
1140
- case C.is_thread_local(self)
1141
- when 0 then false
1142
- else true
1143
- end
1143
+ C.is_thread_local(self)
1144
1144
  end
1145
1145
 
1146
1146
  def thread_local=(local)
1147
1147
  C.set_thread_local(self, local ? 1 : 0)
1148
1148
  end
1149
+
1150
+ def global_constant?
1151
+ C.is_global_constant(self)
1152
+ end
1153
+
1154
+ def global_constant=(flag)
1155
+ if flag.kind_of?(Integer)
1156
+ warn 'Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.'
1157
+ flag = !flag.zero?
1158
+ end
1159
+
1160
+ C.set_global_constant(self, flag ? 1 : 0)
1161
+ end
1162
+
1163
+ def externally_initialized?
1164
+ C.is_externally_initialized(self)
1165
+ end
1166
+
1167
+ def externally_initialized=(boolean)
1168
+ C.set_externally_initialized(self, boolean)
1169
+ end
1149
1170
  end
1150
1171
 
1151
1172
  class Instruction < User
1152
-
1153
1173
  def self.from_ptr(ptr)
1154
1174
  kind = C.get_value_kind(ptr)
1155
1175
  kind == :instruction ? super : LLVM::Value.from_ptr_kind(ptr)
@@ -1180,17 +1200,45 @@ module LLVM
1180
1200
  def inspect
1181
1201
  { self.class.name => { opcode: opcode, ptr: @ptr } }.to_s
1182
1202
  end
1203
+
1204
+ def nsw!
1205
+ C.set_nsw(self, true)
1206
+ self
1207
+ end
1208
+
1209
+ def clear_nsw!
1210
+ C.set_nsw(self, false)
1211
+ self
1212
+ end
1213
+
1214
+ def nuw!
1215
+ C.set_nuw(self, true)
1216
+ self
1217
+ end
1218
+
1219
+ def clear_nuw!
1220
+ C.set_nuw(self, false)
1221
+ self
1222
+ end
1223
+
1224
+ def exact!
1225
+ C.set_exact(self, true)
1226
+ self
1227
+ end
1228
+
1229
+ def clear_exact!
1230
+ C.set_exact(self, false)
1231
+ self
1232
+ end
1183
1233
  end
1184
1234
 
1185
1235
  class Poison < Value
1186
-
1187
1236
  end
1188
1237
 
1189
1238
  class CallInst < Instruction
1190
1239
  # Sets the call convention to conv.
1191
1240
  def call_conv=(conv)
1192
1241
  C.set_instruction_call_conv(self, conv)
1193
- conv
1194
1242
  end
1195
1243
 
1196
1244
  # Returns the call insatnce's call convention.
@@ -1233,7 +1281,6 @@ module LLVM
1233
1281
  end
1234
1282
  end
1235
1283
 
1236
-
1237
1284
  # @private
1238
1285
  class IndirectBr < Instruction
1239
1286
  # Adds a basic block reference as a destination for this indirect branch.
@@ -1241,6 +1288,6 @@ module LLVM
1241
1288
  C.add_destination(self, dest)
1242
1289
  end
1243
1290
 
1244
- alias :<< :add_dest
1291
+ alias_method :<<, :add_dest
1245
1292
  end
1246
1293
  end