ruby-llvm 20.1.2 → 21.1.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 +4 -4
- data/lib/llvm/analysis.rb +9 -0
- data/lib/llvm/analysis_ffi.rb +2 -1
- data/lib/llvm/config.rb +1 -1
- data/lib/llvm/core/attribute.rb +41 -2
- data/lib/llvm/core/bitcode.rb +24 -6
- data/lib/llvm/core/bitcode_ffi.rb +2 -1
- data/lib/llvm/core/builder.rb +136 -17
- data/lib/llvm/core/context.rb +6 -1
- data/lib/llvm/core/module.rb +23 -4
- data/lib/llvm/core/pass_manager.rb +1 -0
- data/lib/llvm/core/type.rb +110 -49
- data/lib/llvm/core/value.rb +125 -32
- data/lib/llvm/core.rb +7 -4
- data/lib/llvm/core_ffi.rb +2 -28
- data/lib/llvm/execution_engine.rb +37 -11
- data/lib/llvm/execution_engine_ffi.rb +2 -1
- data/lib/llvm/linker.rb +2 -0
- data/lib/llvm/linker_ffi.rb +2 -1
- data/lib/llvm/lljit.rb +3 -1
- data/lib/llvm/pass_builder.rb +12 -1
- data/lib/llvm/support.rb +1 -0
- data/lib/llvm/target.rb +15 -6
- data/lib/llvm/target_ffi.rb +2 -1
- data/lib/llvm/transforms/ipo.rb +1 -0
- data/lib/llvm/transforms/pass_manager_builder.rb +1 -0
- data/lib/llvm/transforms/scalar.rb +1 -0
- data/lib/llvm/transforms/utils.rb +1 -0
- data/lib/llvm/transforms/vectorize.rb +1 -0
- data/lib/llvm/version.rb +4 -3
- data/lib/llvm.rb +10 -3
- metadata +33 -22
data/lib/llvm/core/value.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# typed: true
|
2
3
|
|
3
4
|
module LLVM
|
4
5
|
class Value
|
@@ -31,6 +32,8 @@ module LLVM
|
|
31
32
|
ConstantExpr.from_ptr(ptr)
|
32
33
|
when :const_null
|
33
34
|
ConstantNull.from_ptr(ptr)
|
35
|
+
when :const_struct, :const_aggregregate_zero
|
36
|
+
ConstantStruct.from_ptr(ptr)
|
34
37
|
else
|
35
38
|
raise "from_ptr_kind cannot handle: #{kind}"
|
36
39
|
end
|
@@ -46,8 +49,9 @@ module LLVM
|
|
46
49
|
end
|
47
50
|
|
48
51
|
# Returns the value's type.
|
52
|
+
#: -> Type
|
49
53
|
def type
|
50
|
-
Type.from_ptr(C.type_of(self)
|
54
|
+
Type.from_ptr(C.type_of(self))
|
51
55
|
end
|
52
56
|
|
53
57
|
# Returns the value's kind.
|
@@ -55,6 +59,7 @@ module LLVM
|
|
55
59
|
C.get_value_kind(self)
|
56
60
|
end
|
57
61
|
|
62
|
+
#: -> bool
|
58
63
|
def allocated_type?
|
59
64
|
case self
|
60
65
|
when Instruction
|
@@ -72,9 +77,10 @@ module LLVM
|
|
72
77
|
alloc_type = C.get_allocated_type(self)
|
73
78
|
return nil if alloc_type.nil?
|
74
79
|
|
75
|
-
Type.from_ptr(alloc_type
|
80
|
+
Type.from_ptr(alloc_type)
|
76
81
|
end
|
77
82
|
|
83
|
+
#: -> bool
|
78
84
|
def gep_source_element_type?
|
79
85
|
is_a?(Instruction)
|
80
86
|
end
|
@@ -108,21 +114,25 @@ module LLVM
|
|
108
114
|
end
|
109
115
|
|
110
116
|
# Returns whether the value is constant.
|
117
|
+
#: -> bool
|
111
118
|
def constant?
|
112
119
|
C.is_constant(self)
|
113
120
|
end
|
114
121
|
|
115
122
|
# Returns whether the value is null.
|
123
|
+
#: -> bool
|
116
124
|
def null?
|
117
125
|
C.is_null(self)
|
118
126
|
end
|
119
127
|
|
120
128
|
# Returns whether the value is undefined.
|
129
|
+
#: -> bool
|
121
130
|
def undef?
|
122
131
|
C.is_undef(self)
|
123
132
|
end
|
124
133
|
alias_method :undefined?, :undef?
|
125
134
|
|
135
|
+
#: -> bool
|
126
136
|
def poison?
|
127
137
|
C.is_poison(self)
|
128
138
|
end
|
@@ -238,7 +248,7 @@ module LLVM
|
|
238
248
|
end
|
239
249
|
|
240
250
|
# Iterates through each Instruction in the collection.
|
241
|
-
def each
|
251
|
+
def each(&)
|
242
252
|
return to_enum :each unless block_given?
|
243
253
|
inst = first
|
244
254
|
final = last
|
@@ -297,7 +307,7 @@ module LLVM
|
|
297
307
|
end
|
298
308
|
|
299
309
|
# Iterates through each operand in the collection.
|
300
|
-
def each
|
310
|
+
def each(&)
|
301
311
|
return to_enum :each unless block_given?
|
302
312
|
0.upto(size - 1) { |i| yield self[i] }
|
303
313
|
self
|
@@ -330,6 +340,11 @@ module LLVM
|
|
330
340
|
ConstantExpr.from_ptr(C.const_bit_cast(self, type))
|
331
341
|
end
|
332
342
|
|
343
|
+
# Conversion to pointer.
|
344
|
+
def int_to_ptr(type = LLVM.Pointer)
|
345
|
+
ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
|
346
|
+
end
|
347
|
+
|
333
348
|
# @deprecated
|
334
349
|
alias_method :bit_cast, :bitcast_to
|
335
350
|
|
@@ -377,8 +392,8 @@ module LLVM
|
|
377
392
|
|
378
393
|
# ConstantArray.const(type, 3) {|i| ... } or
|
379
394
|
# ConstantArray.const(type, [...])
|
380
|
-
def self.const(type, size_or_values, &
|
381
|
-
vals = LLVM::Support.allocate_pointers(size_or_values, &
|
395
|
+
def self.const(type, size_or_values, &)
|
396
|
+
vals = LLVM::Support.allocate_pointers(size_or_values, &)
|
382
397
|
from_ptr C.const_array(type, vals, vals.size / vals.type_size)
|
383
398
|
end
|
384
399
|
|
@@ -428,6 +443,7 @@ module LLVM
|
|
428
443
|
# end
|
429
444
|
|
430
445
|
# Negation.
|
446
|
+
#: -> ConstantInt
|
431
447
|
def -@
|
432
448
|
self.class.from_ptr(C.const_neg(self))
|
433
449
|
end
|
@@ -435,12 +451,14 @@ module LLVM
|
|
435
451
|
alias_method :neg, :-@
|
436
452
|
|
437
453
|
# "No signed wrap" negation.
|
454
|
+
#: -> ConstantInt
|
438
455
|
def nsw_neg
|
439
456
|
self.class.from_ptr(C.const_nsw_neg(self))
|
440
457
|
end
|
441
458
|
|
442
459
|
# "No unsigned wrap" negation.
|
443
460
|
# @deprecated
|
461
|
+
#: -> ConstantInt
|
444
462
|
def nuw_neg
|
445
463
|
# :nocov:
|
446
464
|
self.class.from_ptr(C.const_nuw_neg(self))
|
@@ -449,6 +467,7 @@ module LLVM
|
|
449
467
|
deprecate :nuw_neg, "neg", 2025, 3
|
450
468
|
|
451
469
|
# Addition.
|
470
|
+
#: (ConstantInt) -> ConstantInt
|
452
471
|
def +(rhs)
|
453
472
|
self.class.from_ptr(C.const_add(self, rhs))
|
454
473
|
end
|
@@ -456,16 +475,19 @@ module LLVM
|
|
456
475
|
alias_method :add, :+
|
457
476
|
|
458
477
|
# "No signed wrap" addition.
|
478
|
+
#: (ConstantInt) -> ConstantInt
|
459
479
|
def nsw_add(rhs)
|
460
480
|
self.class.from_ptr(C.const_nsw_add(self, rhs))
|
461
481
|
end
|
462
482
|
|
463
483
|
# "No unsigned wrap" addition.
|
484
|
+
#: (ConstantInt) -> ConstantInt
|
464
485
|
def nuw_add(rhs)
|
465
486
|
self.class.from_ptr(C.const_nuw_add(self, rhs))
|
466
487
|
end
|
467
488
|
|
468
489
|
# Subtraction.
|
490
|
+
#: (ConstantInt) -> ConstantInt
|
469
491
|
def -(rhs)
|
470
492
|
self.class.from_ptr(C.const_sub(self, rhs))
|
471
493
|
end
|
@@ -473,58 +495,71 @@ module LLVM
|
|
473
495
|
alias_method :sub, :-
|
474
496
|
|
475
497
|
# "No signed wrap" subtraction.
|
498
|
+
#: (ConstantInt) -> ConstantInt
|
476
499
|
def nsw_sub(rhs)
|
477
500
|
self.class.from_ptr(C.const_nsw_sub(self, rhs))
|
478
501
|
end
|
479
502
|
|
480
503
|
# "No unsigned wrap" subtraction.
|
504
|
+
#: (ConstantInt) -> ConstantInt
|
481
505
|
def nuw_sub(rhs)
|
482
506
|
self.class.from_ptr(C.const_nuw_sub(self, rhs))
|
483
507
|
end
|
484
508
|
|
485
509
|
# Multiplication.
|
510
|
+
#: (ConstantInt) -> ConstantInt
|
486
511
|
def *(rhs)
|
487
|
-
|
512
|
+
width = [type.width, rhs.type.width].max
|
513
|
+
product = to_i * rhs.to_i
|
514
|
+
modulo = product % (2**width)
|
515
|
+
LLVM::Type.integer(width).from_i(modulo, false)
|
488
516
|
end
|
489
517
|
|
490
518
|
alias_method :mul, :*
|
491
519
|
|
492
520
|
# "No signed wrap" multiplication.
|
521
|
+
#: (ConstantInt) -> ConstantInt
|
493
522
|
def nsw_mul(rhs)
|
494
|
-
|
523
|
+
mul(rhs)
|
495
524
|
end
|
496
525
|
|
497
526
|
# "No unsigned wrap" multiplication.
|
527
|
+
#: (ConstantInt) -> ConstantInt
|
498
528
|
def nuw_mul(rhs)
|
499
|
-
|
529
|
+
mul(rhs)
|
500
530
|
end
|
501
531
|
|
502
532
|
# Unsigned division.
|
533
|
+
#: (ConstantInt) -> ConstantInt
|
503
534
|
def udiv(rhs)
|
504
535
|
width = [type.width, rhs.type.width].max
|
505
536
|
LLVM::Type.integer(width).from_i(to_ui / rhs.to_ui, false)
|
506
537
|
end
|
507
538
|
|
508
539
|
# Signed division.
|
540
|
+
#: (ConstantInt) -> ConstantInt
|
509
541
|
def /(rhs)
|
510
542
|
width = [type.width, rhs.type.width].max
|
511
543
|
LLVM::Type.integer(width).from_i(to_si / rhs.to_si, true)
|
512
544
|
end
|
513
545
|
|
514
546
|
# Unsigned remainder.
|
547
|
+
#: (ConstantInt) -> ConstantInt
|
515
548
|
def urem(rhs)
|
516
549
|
width = [type.width, rhs.type.width].max
|
517
550
|
LLVM::Type.integer(width).from_i(to_ui % rhs.to_ui, false)
|
518
551
|
end
|
519
552
|
|
520
553
|
# Signed remainder.
|
554
|
+
#: (ConstantInt) -> ConstantInt
|
521
555
|
def rem(rhs)
|
522
556
|
width = [type.width, rhs.type.width].max
|
523
557
|
LLVM::Type.integer(width).from_i(to_si % rhs.to_si, true)
|
524
558
|
end
|
525
559
|
|
526
560
|
# Boolean negation.
|
527
|
-
|
561
|
+
#: -> ConstantInt
|
562
|
+
def ~
|
528
563
|
self.class.from_ptr(C.const_not(self))
|
529
564
|
end
|
530
565
|
|
@@ -593,11 +628,6 @@ module LLVM
|
|
593
628
|
raise DeprecationError
|
594
629
|
end
|
595
630
|
|
596
|
-
# Conversion to pointer.
|
597
|
-
def int_to_ptr(type = LLVM.Pointer)
|
598
|
-
ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
|
599
|
-
end
|
600
|
-
|
601
631
|
def to_ui
|
602
632
|
to_i(false)
|
603
633
|
end
|
@@ -664,6 +694,12 @@ module LLVM
|
|
664
694
|
end
|
665
695
|
end
|
666
696
|
|
697
|
+
::LLVM::Int1 = const_get(:Int1) #: LLVM::IntType
|
698
|
+
::LLVM::Int8 = const_get(:Int8) #: LLVM::IntType
|
699
|
+
::LLVM::Int16 = const_get(:Int16) #: LLVM::IntType
|
700
|
+
::LLVM::Int32 = const_get(:Int32) #: LLVM::IntType
|
701
|
+
::LLVM::Int64 = const_get(:Int64) #: LLVM::IntType
|
702
|
+
|
667
703
|
# Native integer type
|
668
704
|
bits = FFI.type_size(:int) * 8
|
669
705
|
::LLVM::Int = const_get(:"Int#{bits}")
|
@@ -687,34 +723,40 @@ module LLVM
|
|
687
723
|
class ConstantReal < Constant
|
688
724
|
# Negation.
|
689
725
|
# fneg
|
726
|
+
#: -> ConstantReal
|
690
727
|
def -@
|
691
728
|
type.from_f(-to_f)
|
692
729
|
end
|
693
730
|
|
694
731
|
# Returns the result of adding this ConstantReal to rhs.
|
732
|
+
#: (ConstantReal) -> ConstantReal
|
695
733
|
def +(rhs)
|
696
734
|
type = LLVM::RealType.fits([self.type, rhs.type])
|
697
735
|
type.from_f(to_f + rhs.to_f)
|
698
736
|
end
|
699
737
|
|
738
|
+
#: (ConstantReal) -> ConstantReal
|
700
739
|
def -(rhs)
|
701
740
|
type = LLVM::RealType.fits([self.type, rhs.type])
|
702
741
|
type.from_f(to_f - rhs.to_f)
|
703
742
|
end
|
704
743
|
|
705
744
|
# Returns the result of multiplying this ConstantReal by rhs.
|
745
|
+
#: (ConstantReal) -> ConstantReal
|
706
746
|
def *(rhs)
|
707
747
|
type = LLVM::RealType.fits([self.type, rhs.type])
|
708
748
|
type.from_f(to_f * rhs.to_f)
|
709
749
|
end
|
710
750
|
|
711
751
|
# Returns the result of dividing this ConstantReal by rhs.
|
752
|
+
#: (ConstantReal) -> ConstantReal
|
712
753
|
def /(rhs)
|
713
754
|
type = LLVM::RealType.fits([self.type, rhs.type])
|
714
755
|
type.from_f(to_f / rhs.to_f)
|
715
756
|
end
|
716
757
|
|
717
758
|
# Remainder.
|
759
|
+
#: (ConstantReal) -> ConstantReal
|
718
760
|
def rem(rhs)
|
719
761
|
type = LLVM::RealType.fits([self.type, rhs.type])
|
720
762
|
type.from_f(to_f.divmod(rhs.to_f).last)
|
@@ -763,10 +805,11 @@ module LLVM
|
|
763
805
|
end
|
764
806
|
|
765
807
|
# get double from value
|
808
|
+
#: -> ::Float
|
766
809
|
def to_f
|
767
|
-
double =
|
810
|
+
double = 0.0 #: ::Float
|
768
811
|
FFI::MemoryPointer.new(:bool, 1) do |loses_info|
|
769
|
-
double = C.const_real_get_double(self, loses_info)
|
812
|
+
double = C.const_real_get_double(self, loses_info) #: ::Float
|
770
813
|
end
|
771
814
|
double
|
772
815
|
end
|
@@ -775,18 +818,18 @@ module LLVM
|
|
775
818
|
class ConstantStruct < Constant
|
776
819
|
# ConstantStruct.const(size) {|i| ... } or
|
777
820
|
# ConstantStruct.const([...])
|
778
|
-
def self.const(size_or_values, packed = false, &
|
779
|
-
vals = LLVM::Support.allocate_pointers(size_or_values, &
|
821
|
+
def self.const(size_or_values, packed = false, &)
|
822
|
+
vals = LLVM::Support.allocate_pointers(size_or_values, &)
|
780
823
|
from_ptr C.const_struct(vals, vals.size / vals.type_size, packed ? 1 : 0)
|
781
824
|
end
|
782
825
|
|
783
|
-
def self.named_const(type, size_or_values, &
|
784
|
-
vals = LLVM::Support.allocate_pointers(size_or_values, &
|
826
|
+
def self.named_const(type, size_or_values, &)
|
827
|
+
vals = LLVM::Support.allocate_pointers(size_or_values, &)
|
785
828
|
from_ptr C.const_named_struct(type, vals, vals.size / vals.type_size)
|
786
829
|
end
|
787
830
|
|
788
831
|
def [](idx)
|
789
|
-
|
832
|
+
Value.from_ptr_kind(C.get_aggregate_element(self, idx))
|
790
833
|
end
|
791
834
|
end
|
792
835
|
|
@@ -795,8 +838,8 @@ module LLVM
|
|
795
838
|
from_ptr(C.const_all_ones(type))
|
796
839
|
end
|
797
840
|
|
798
|
-
def self.const(size_or_values, &
|
799
|
-
vals = LLVM::Support.allocate_pointers(size_or_values, &
|
841
|
+
def self.const(size_or_values, &)
|
842
|
+
vals = LLVM::Support.allocate_pointers(size_or_values, &)
|
800
843
|
|
801
844
|
# size 0, or empty values
|
802
845
|
# this will segfault in const_vector
|
@@ -818,6 +861,7 @@ module LLVM
|
|
818
861
|
end
|
819
862
|
|
820
863
|
class GlobalValue < Constant
|
864
|
+
#: -> bool
|
821
865
|
def declaration?
|
822
866
|
C.is_declaration(self)
|
823
867
|
end
|
@@ -854,6 +898,7 @@ module LLVM
|
|
854
898
|
C.set_alignment(self, bytes)
|
855
899
|
end
|
856
900
|
|
901
|
+
#: -> bool
|
857
902
|
def unnamed_addr?
|
858
903
|
C.has_unnamed_addr(self) != 0
|
859
904
|
end
|
@@ -893,20 +938,24 @@ module LLVM
|
|
893
938
|
# Set personality function of function
|
894
939
|
# @note Experimental and unsupported
|
895
940
|
# @return self
|
941
|
+
#: (Value) -> void
|
896
942
|
def personality_function=(personality_function)
|
897
943
|
C.set_personality_fn(self, personality_function)
|
898
944
|
end
|
899
945
|
|
900
946
|
# Returns an Enumerable of the BasicBlocks in this function.
|
947
|
+
#: -> BasicBlockCollection
|
901
948
|
def basic_blocks
|
902
949
|
@basic_block_collection ||= BasicBlockCollection.new(self)
|
903
950
|
end
|
904
951
|
|
952
|
+
#: -> Type?
|
905
953
|
def function_type
|
906
|
-
Type.from_ptr(C.get_element_type(self), :function)
|
954
|
+
Type.from_ptr(C.get_element_type(self), kind: :function)
|
907
955
|
end
|
908
956
|
|
909
957
|
# In LLVM 15, not overriding this yields a pointer type instead of a function type
|
958
|
+
#: -> Type?
|
910
959
|
def type
|
911
960
|
function_type
|
912
961
|
end
|
@@ -929,30 +978,37 @@ module LLVM
|
|
929
978
|
function_attributes.count
|
930
979
|
end
|
931
980
|
|
981
|
+
# -> [Attribute]
|
932
982
|
def attributes
|
933
983
|
function_attributes.to_a
|
934
984
|
end
|
935
985
|
|
986
|
+
#: -> bool
|
936
987
|
def readnone?
|
937
988
|
attributes.detect(&:readnone?)
|
938
989
|
end
|
939
990
|
|
991
|
+
#: -> bool
|
940
992
|
def readonly?
|
941
993
|
attributes.detect(&:readonly?)
|
942
994
|
end
|
943
995
|
|
996
|
+
#: -> bool
|
944
997
|
def writeonly?
|
945
998
|
attributes.detect(&:writeonly?)
|
946
999
|
end
|
947
1000
|
|
1001
|
+
# -> AttributeCollection
|
948
1002
|
def function_attributes
|
949
1003
|
AttributeCollection.new(self, -1)
|
950
1004
|
end
|
951
1005
|
|
1006
|
+
# -> AttributeCollection
|
952
1007
|
def return_attributes
|
953
1008
|
AttributeCollection.new(self, 0)
|
954
1009
|
end
|
955
1010
|
|
1011
|
+
# -> AttributeCollection
|
956
1012
|
def param_attributes(index)
|
957
1013
|
AttributeCollection.new(self, index)
|
958
1014
|
end
|
@@ -975,6 +1031,8 @@ module LLVM
|
|
975
1031
|
else
|
976
1032
|
attr_kind_id
|
977
1033
|
end
|
1034
|
+
when Integer
|
1035
|
+
C.create_enum_attribute(ctx, attr, 0)
|
978
1036
|
else
|
979
1037
|
raise "Adding unknown attribute type: #{attr.inspect}"
|
980
1038
|
end
|
@@ -990,8 +1048,9 @@ module LLVM
|
|
990
1048
|
C.get_attribute_count_at_index(@fun, @index)
|
991
1049
|
end
|
992
1050
|
|
1051
|
+
# -> Array[Attribute]
|
993
1052
|
def to_a
|
994
|
-
attr_refs =
|
1053
|
+
attr_refs = [] #: Array[Attribute]
|
995
1054
|
n = count
|
996
1055
|
FFI::MemoryPointer.new(:pointer, n) do |p|
|
997
1056
|
C.get_attributes_at_index(@fun, @index, p)
|
@@ -1003,6 +1062,7 @@ module LLVM
|
|
1003
1062
|
|
1004
1063
|
private
|
1005
1064
|
|
1065
|
+
# (Symbol | String) -> String
|
1006
1066
|
def attribute_name(attr_name)
|
1007
1067
|
attr_name = attr_name.to_s
|
1008
1068
|
if /_attribute$/.match?(attr_name)
|
@@ -1012,6 +1072,7 @@ module LLVM
|
|
1012
1072
|
end
|
1013
1073
|
end
|
1014
1074
|
|
1075
|
+
# (Symbol | String) -> Integer
|
1015
1076
|
def attribute_id(attr_name)
|
1016
1077
|
upgrade = upgrade_attr(attr_name)
|
1017
1078
|
return upgrade if upgrade
|
@@ -1025,6 +1086,7 @@ module LLVM
|
|
1025
1086
|
|
1026
1087
|
# Upgrade attributes from before LLVM 16
|
1027
1088
|
# readnone, readonly, writeonly
|
1089
|
+
#: (Symbol | String) -> LLVM::Attribute?
|
1028
1090
|
def upgrade_attr(attr)
|
1029
1091
|
case attr.to_sym
|
1030
1092
|
when :readnone
|
@@ -1035,6 +1097,8 @@ module LLVM
|
|
1035
1097
|
LLVM::Attribute.memory(memory: :write)
|
1036
1098
|
when :inaccessiblememonly
|
1037
1099
|
LLVM::Attribute.memory(inaccessiblemem: :readwrite)
|
1100
|
+
when :no_capture_attribute
|
1101
|
+
LLVM::Attribute.captures_none
|
1038
1102
|
end
|
1039
1103
|
end
|
1040
1104
|
end
|
@@ -1048,12 +1112,13 @@ module LLVM
|
|
1048
1112
|
end
|
1049
1113
|
|
1050
1114
|
# Returns the number of BasicBlocks in the collection.
|
1115
|
+
#: -> Integer
|
1051
1116
|
def size
|
1052
1117
|
C.count_basic_blocks(@fun)
|
1053
1118
|
end
|
1054
1119
|
|
1055
1120
|
# Iterates through each BasicBlock in the collection.
|
1056
|
-
def each
|
1121
|
+
def each(&)
|
1057
1122
|
return to_enum :each unless block_given?
|
1058
1123
|
|
1059
1124
|
ptr = C.get_first_basic_block(@fun)
|
@@ -1066,23 +1131,27 @@ module LLVM
|
|
1066
1131
|
end
|
1067
1132
|
|
1068
1133
|
# Adds a BasicBlock with the given name to the end of the collection.
|
1134
|
+
#: (?String) -> BasicBlock
|
1069
1135
|
def append(name = "")
|
1070
1136
|
BasicBlock.create(@fun, name)
|
1071
1137
|
end
|
1072
1138
|
|
1073
1139
|
# Returns the entry BasicBlock in the collection. This is the block the
|
1074
1140
|
# function starts on.
|
1141
|
+
#: -> BasicBlock
|
1075
1142
|
def entry
|
1076
1143
|
BasicBlock.from_ptr(C.get_entry_basic_block(@fun))
|
1077
1144
|
end
|
1078
1145
|
|
1079
1146
|
# Returns the first BasicBlock in the collection.
|
1147
|
+
#: -> BasicBlock?
|
1080
1148
|
def first
|
1081
1149
|
ptr = C.get_first_basic_block(@fun)
|
1082
1150
|
BasicBlock.from_ptr(ptr) unless ptr.null?
|
1083
1151
|
end
|
1084
1152
|
|
1085
1153
|
# Returns the last BasicBlock in the collection.
|
1154
|
+
#: -> BasicBlock?
|
1086
1155
|
def last
|
1087
1156
|
ptr = C.get_last_basic_block(@fun)
|
1088
1157
|
BasicBlock.from_ptr(ptr) unless ptr.null?
|
@@ -1090,6 +1159,7 @@ module LLVM
|
|
1090
1159
|
end
|
1091
1160
|
|
1092
1161
|
# Returns an Enumerable of the parameters in the function.
|
1162
|
+
#: -> ParameterCollection
|
1093
1163
|
def params
|
1094
1164
|
@parameter_collection ||= ParameterCollection.new(self)
|
1095
1165
|
end
|
@@ -1101,14 +1171,16 @@ module LLVM
|
|
1101
1171
|
end
|
1102
1172
|
|
1103
1173
|
# Returns a Value representation of the parameter at the given index.
|
1174
|
+
# (Integer) -> Value?
|
1104
1175
|
def [](i)
|
1105
1176
|
sz = size
|
1106
|
-
i = sz + i if i
|
1177
|
+
i = sz + i if i.negative?
|
1107
1178
|
return unless 0 <= i && i < sz
|
1108
1179
|
Value.from_ptr(C.get_param(@fun, i))
|
1109
1180
|
end
|
1110
1181
|
|
1111
1182
|
# Returns the number of paramters in the collection.
|
1183
|
+
#: -> Integer
|
1112
1184
|
def size
|
1113
1185
|
C.count_params(@fun)
|
1114
1186
|
end
|
@@ -1116,7 +1188,7 @@ module LLVM
|
|
1116
1188
|
include Enumerable
|
1117
1189
|
|
1118
1190
|
# Iteraters through each parameter in the collection.
|
1119
|
-
def each
|
1191
|
+
def each(&)
|
1120
1192
|
return to_enum :each unless block_given?
|
1121
1193
|
0.upto(size - 1) { |i| yield self[i] }
|
1122
1194
|
self
|
@@ -1131,9 +1203,10 @@ module LLVM
|
|
1131
1203
|
C.get_gc(self)
|
1132
1204
|
end
|
1133
1205
|
|
1206
|
+
#: -> String
|
1134
1207
|
def inspect
|
1135
1208
|
{
|
1136
|
-
signature: to_s.lines[attribute_count
|
1209
|
+
signature: to_s.lines[attribute_count.zero? ? 0 : 1],
|
1137
1210
|
type: type.to_s,
|
1138
1211
|
attributes: attribute_count,
|
1139
1212
|
valid: valid?,
|
@@ -1157,6 +1230,7 @@ module LLVM
|
|
1157
1230
|
C.set_initializer(self, val)
|
1158
1231
|
end
|
1159
1232
|
|
1233
|
+
#: -> bool
|
1160
1234
|
def thread_local?
|
1161
1235
|
C.is_thread_local(self)
|
1162
1236
|
end
|
@@ -1165,6 +1239,7 @@ module LLVM
|
|
1165
1239
|
C.set_thread_local(self, local ? 1 : 0)
|
1166
1240
|
end
|
1167
1241
|
|
1242
|
+
#: -> bool
|
1168
1243
|
def global_constant?
|
1169
1244
|
C.is_global_constant(self)
|
1170
1245
|
end
|
@@ -1178,6 +1253,7 @@ module LLVM
|
|
1178
1253
|
C.set_global_constant(self, flag ? 1 : 0)
|
1179
1254
|
end
|
1180
1255
|
|
1256
|
+
#: -> bool
|
1181
1257
|
def externally_initialized?
|
1182
1258
|
C.is_externally_initialized(self)
|
1183
1259
|
end
|
@@ -1190,57 +1266,68 @@ module LLVM
|
|
1190
1266
|
class Instruction < User
|
1191
1267
|
# Create Instruction from pointer to value
|
1192
1268
|
# many places where this is called, the instruction may be a constant, so create those instead
|
1269
|
+
#: (FFI::Pointer) -> (Value | Instruction)
|
1193
1270
|
def self.from_ptr(ptr)
|
1194
1271
|
kind = C.get_value_kind(ptr)
|
1195
1272
|
kind == :instruction ? super : LLVM::Value.from_ptr_kind(ptr)
|
1196
1273
|
end
|
1197
1274
|
|
1198
1275
|
# Returns the parent of the instruction (a BasicBlock).
|
1276
|
+
#: -> LLVM::BasicBlock?
|
1199
1277
|
def parent
|
1200
1278
|
ptr = C.get_instruction_parent(self)
|
1201
1279
|
LLVM::BasicBlock.from_ptr(ptr) unless ptr.null?
|
1202
1280
|
end
|
1203
1281
|
|
1204
1282
|
# Returns the next instruction after this one.
|
1283
|
+
#: -> LLVM::Instruction?
|
1205
1284
|
def next
|
1206
1285
|
ptr = C.get_next_instruction(self)
|
1207
|
-
LLVM::Instruction.from_ptr(ptr) unless ptr.null?
|
1286
|
+
LLVM::Instruction.from_ptr(ptr) unless ptr.null? #: as LLVM::Instruction?
|
1208
1287
|
end
|
1209
1288
|
|
1210
1289
|
# Returns the previous instruction before this one.
|
1290
|
+
#: -> LLVM::Instruction?
|
1211
1291
|
def previous
|
1212
1292
|
ptr = C.get_previous_instruction(self)
|
1213
|
-
LLVM::Instruction.from_ptr(ptr) unless ptr.null?
|
1293
|
+
LLVM::Instruction.from_ptr(ptr) unless ptr.null? #: as LLVM::Instruction?
|
1214
1294
|
end
|
1215
1295
|
|
1296
|
+
#: -> Integer
|
1216
1297
|
def opcode
|
1217
1298
|
C.get_instruction_opcode(self)
|
1218
1299
|
end
|
1219
1300
|
|
1301
|
+
#: -> String
|
1220
1302
|
def inspect
|
1221
1303
|
{ self.class.name => { opcode: opcode, ptr: @ptr } }.to_s
|
1222
1304
|
end
|
1223
1305
|
|
1306
|
+
#: -> self
|
1224
1307
|
def nsw!
|
1225
1308
|
C.set_nsw(self, true)
|
1226
1309
|
self
|
1227
1310
|
end
|
1228
1311
|
|
1312
|
+
#: -> self
|
1229
1313
|
def clear_nsw!
|
1230
1314
|
C.set_nsw(self, false)
|
1231
1315
|
self
|
1232
1316
|
end
|
1233
1317
|
|
1318
|
+
#: -> self
|
1234
1319
|
def nuw!
|
1235
1320
|
C.set_nuw(self, true)
|
1236
1321
|
self
|
1237
1322
|
end
|
1238
1323
|
|
1324
|
+
#: -> self
|
1239
1325
|
def clear_nuw!
|
1240
1326
|
C.set_nuw(self, false)
|
1241
1327
|
self
|
1242
1328
|
end
|
1243
1329
|
|
1330
|
+
#: -> self
|
1244
1331
|
def exact!
|
1245
1332
|
C.set_exact(self, true)
|
1246
1333
|
self
|
@@ -1257,6 +1344,7 @@ module LLVM
|
|
1257
1344
|
|
1258
1345
|
class CallInst < Instruction
|
1259
1346
|
# Sets the call convention to conv.
|
1347
|
+
#: (Symbol) -> void
|
1260
1348
|
def call_conv=(conv)
|
1261
1349
|
C.set_instruction_call_conv(self, conv)
|
1262
1350
|
end
|
@@ -1270,6 +1358,9 @@ module LLVM
|
|
1270
1358
|
class InvokeInst < CallInst
|
1271
1359
|
end
|
1272
1360
|
|
1361
|
+
class Alloca < Instruction
|
1362
|
+
end
|
1363
|
+
|
1273
1364
|
# @private
|
1274
1365
|
class Phi < Instruction
|
1275
1366
|
# Add incoming branches to a phi node by passing an alternating list of
|
@@ -1296,6 +1387,7 @@ module LLVM
|
|
1296
1387
|
class SwitchInst < Instruction
|
1297
1388
|
# Adds a case to a switch instruction. First the value to match on, then
|
1298
1389
|
# the basic block.
|
1390
|
+
#: (Value, BasicBlock) -> void
|
1299
1391
|
def add_case(val, block)
|
1300
1392
|
C.add_case(self, val, block)
|
1301
1393
|
end
|
@@ -1304,6 +1396,7 @@ module LLVM
|
|
1304
1396
|
# @private
|
1305
1397
|
class IndirectBr < Instruction
|
1306
1398
|
# Adds a basic block reference as a destination for this indirect branch.
|
1399
|
+
#: (BasicBlock) -> void
|
1307
1400
|
def add_dest(dest)
|
1308
1401
|
C.add_destination(self, dest)
|
1309
1402
|
end
|
data/lib/llvm/core.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
2
3
|
|
3
4
|
require 'llvm'
|
4
5
|
require 'llvm/core_ffi'
|
@@ -12,8 +13,9 @@ module LLVM
|
|
12
13
|
#
|
13
14
|
# @yield [FFI::MemoryPointer]
|
14
15
|
# @return [String, nil]
|
15
|
-
|
16
|
-
|
16
|
+
#: { (FFI::MemoryPointer) -> Integer } -> String?
|
17
|
+
def self.with_message_output(&)
|
18
|
+
message = nil #: String?
|
17
19
|
|
18
20
|
FFI::MemoryPointer.new(FFI.type_size(:pointer)) do |str|
|
19
21
|
result = yield str
|
@@ -36,8 +38,9 @@ module LLVM
|
|
36
38
|
#
|
37
39
|
# @yield [FFI::MemoryPointer]
|
38
40
|
# @return [nil]
|
39
|
-
|
40
|
-
|
41
|
+
#: { (FFI::MemoryPointer) -> Integer } -> String?
|
42
|
+
def self.with_error_output(&blk)
|
43
|
+
error = with_message_output(&blk)
|
41
44
|
|
42
45
|
raise error unless error.nil?
|
43
46
|
end
|