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.
@@ -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
@@ -860,6 +864,21 @@ module LLVM
860
864
  C.get_function_call_conv(self)
861
865
  end
862
866
 
867
+ # Get personality function of function
868
+ # @note Experimental and unsupported
869
+ # @return LLVM::Function
870
+ def personality_function
871
+ ptr = C.get_personality_fn(self)
872
+ LLVM::Function.from_ptr(ptr)
873
+ end
874
+
875
+ # Set personality function of function
876
+ # @note Experimental and unsupported
877
+ # @return self
878
+ def personality_function=(personality_function)
879
+ C.set_personality_fn(self, personality_function)
880
+ end
881
+
863
882
  # Returns an Enumerable of the BasicBlocks in this function.
864
883
  def basic_blocks
865
884
  @basic_block_collection ||= BasicBlockCollection.new(self)
@@ -921,7 +940,6 @@ module LLVM
921
940
  end
922
941
 
923
942
  class AttributeCollection
924
-
925
943
  def initialize(fun, index)
926
944
  @fun = fun
927
945
  @index = index
@@ -1001,7 +1019,6 @@ module LLVM
1001
1019
  LLVM::Attribute.memory(inaccessiblemem: :readwrite)
1002
1020
  end
1003
1021
  end
1004
-
1005
1022
  end
1006
1023
 
1007
1024
  # @private
@@ -1117,23 +1134,42 @@ module LLVM
1117
1134
  end
1118
1135
 
1119
1136
  def initializer=(val)
1137
+ raise ArgumentError unless val.is_a? Constant
1138
+
1120
1139
  C.set_initializer(self, val)
1121
1140
  end
1122
1141
 
1123
1142
  def thread_local?
1124
- case C.is_thread_local(self)
1125
- when 0 then false
1126
- else true
1127
- end
1143
+ C.is_thread_local(self)
1128
1144
  end
1129
1145
 
1130
1146
  def thread_local=(local)
1131
1147
  C.set_thread_local(self, local ? 1 : 0)
1132
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
1133
1170
  end
1134
1171
 
1135
1172
  class Instruction < User
1136
-
1137
1173
  def self.from_ptr(ptr)
1138
1174
  kind = C.get_value_kind(ptr)
1139
1175
  kind == :instruction ? super : LLVM::Value.from_ptr_kind(ptr)
@@ -1164,17 +1200,45 @@ module LLVM
1164
1200
  def inspect
1165
1201
  { self.class.name => { opcode: opcode, ptr: @ptr } }.to_s
1166
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
1167
1233
  end
1168
1234
 
1169
1235
  class Poison < Value
1170
-
1171
1236
  end
1172
1237
 
1173
1238
  class CallInst < Instruction
1174
1239
  # Sets the call convention to conv.
1175
1240
  def call_conv=(conv)
1176
1241
  C.set_instruction_call_conv(self, conv)
1177
- conv
1178
1242
  end
1179
1243
 
1180
1244
  # Returns the call insatnce's call convention.
@@ -1183,6 +1247,9 @@ module LLVM
1183
1247
  end
1184
1248
  end
1185
1249
 
1250
+ class InvokeInst < CallInst
1251
+ end
1252
+
1186
1253
  # @private
1187
1254
  class Phi < Instruction
1188
1255
  # Add incoming branches to a phi node by passing an alternating list of
@@ -1214,7 +1281,6 @@ module LLVM
1214
1281
  end
1215
1282
  end
1216
1283
 
1217
-
1218
1284
  # @private
1219
1285
  class IndirectBr < Instruction
1220
1286
  # Adds a basic block reference as a destination for this indirect branch.
@@ -1222,6 +1288,6 @@ module LLVM
1222
1288
  C.add_destination(self, dest)
1223
1289
  end
1224
1290
 
1225
- alias :<< :add_dest
1291
+ alias_method :<<, :add_dest
1226
1292
  end
1227
1293
  end