ruby-llvm 20.1.7 → 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/core/attribute.rb +41 -2
- data/lib/llvm/core/bitcode.rb +23 -5
- data/lib/llvm/core/bitcode_ffi.rb +2 -1
- data/lib/llvm/core/builder.rb +134 -16
- 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 +123 -30
- data/lib/llvm/core.rb +7 -4
- data/lib/llvm/core_ffi.rb +2 -28
- data/lib/llvm/execution_engine.rb +37 -10
- 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/context.rb
CHANGED
@@ -1,22 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
2
3
|
|
3
4
|
module LLVM
|
4
5
|
class Context
|
6
|
+
#: (?FFI::Pointer?) -> void
|
5
7
|
def initialize(ptr = nil)
|
6
|
-
@ptr = ptr || C.context_create()
|
8
|
+
@ptr = ptr || C.context_create() #: FFI::Pointer?
|
7
9
|
end
|
8
10
|
|
9
11
|
# @private
|
12
|
+
#: -> FFI::Pointer?
|
10
13
|
def to_ptr
|
11
14
|
@ptr
|
12
15
|
end
|
13
16
|
|
14
17
|
# Obtains a reference to the global Context.
|
18
|
+
#: -> Context
|
15
19
|
def self.global
|
16
20
|
new(C.get_global_context())
|
17
21
|
end
|
18
22
|
|
19
23
|
# Diposes the Context.
|
24
|
+
#: -> void
|
20
25
|
def dispose
|
21
26
|
return if @ptr.nil?
|
22
27
|
C.context_dispose(@ptr)
|
data/lib/llvm/core/module.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# typed: true
|
2
3
|
|
3
4
|
module LLVM
|
4
5
|
class Module
|
@@ -24,10 +25,12 @@ module LLVM
|
|
24
25
|
@ptr = nil
|
25
26
|
end
|
26
27
|
|
28
|
+
#: -> LLVM::Module
|
27
29
|
def clone_module
|
28
30
|
Module.from_ptr(C.clone_module(self))
|
29
31
|
end
|
30
32
|
|
33
|
+
#: -> String
|
31
34
|
def inspect
|
32
35
|
{
|
33
36
|
triple: triple,
|
@@ -41,6 +44,7 @@ module LLVM
|
|
41
44
|
# Get module triple.
|
42
45
|
#
|
43
46
|
# @return [String]
|
47
|
+
#: -> String
|
44
48
|
def triple
|
45
49
|
C.get_target(self)
|
46
50
|
end
|
@@ -48,6 +52,7 @@ module LLVM
|
|
48
52
|
# Set module triple.
|
49
53
|
#
|
50
54
|
# @param [String] triple
|
55
|
+
#: (String) -> void
|
51
56
|
def triple=(triple)
|
52
57
|
C.set_target(self, triple.to_s)
|
53
58
|
end
|
@@ -55,6 +60,7 @@ module LLVM
|
|
55
60
|
# Get module data layout.
|
56
61
|
#
|
57
62
|
# @return [String]
|
63
|
+
#: -> String
|
58
64
|
def data_layout
|
59
65
|
C.get_data_layout(self)
|
60
66
|
end
|
@@ -62,11 +68,13 @@ module LLVM
|
|
62
68
|
# Set module data layout.
|
63
69
|
#
|
64
70
|
# @param [String, TargetDataLayout] data_layout
|
71
|
+
#: (String) -> void
|
65
72
|
def data_layout=(data_layout)
|
66
73
|
C.set_data_layout(self, data_layout.to_s)
|
67
74
|
end
|
68
75
|
|
69
76
|
# Returns a TypeCollection of all the Types in the module.
|
77
|
+
#: -> TypeCollection
|
70
78
|
def types
|
71
79
|
@types ||= TypeCollection.new(self)
|
72
80
|
end
|
@@ -77,14 +85,16 @@ module LLVM
|
|
77
85
|
end
|
78
86
|
|
79
87
|
# Returns the Type with the given name (symbol or string).
|
88
|
+
#: (untyped) -> Type
|
80
89
|
def named(name)
|
81
|
-
Type.from_ptr(C.get_type_by_name(@module, name.to_s)
|
90
|
+
Type.from_ptr(C.get_type_by_name(@module, name.to_s))
|
82
91
|
end
|
83
92
|
|
84
93
|
alias_method :[], :named
|
85
94
|
end
|
86
95
|
|
87
96
|
# Returns an Enumerable of all the GlobalVariables in the module.
|
97
|
+
#: -> GlobalCollection
|
88
98
|
def globals
|
89
99
|
@globals ||= GlobalCollection.new(self)
|
90
100
|
end
|
@@ -104,31 +114,37 @@ module LLVM
|
|
104
114
|
end
|
105
115
|
|
106
116
|
# Returns the GlobalVariable with the given name (symbol or string).
|
117
|
+
#: (untyped) -> GlobalVariable
|
107
118
|
def named(name)
|
108
119
|
GlobalVariable.from_ptr(C.get_named_global(@module, name.to_s))
|
109
120
|
end
|
110
121
|
|
111
122
|
# Returns the first GlobalVariable in the collection.
|
123
|
+
#: -> GlobalVariable
|
112
124
|
def first
|
113
125
|
GlobalVariable.from_ptr(C.get_first_global(@module))
|
114
126
|
end
|
115
127
|
|
116
128
|
# Returns the last GlobalVariable in the collection.
|
129
|
+
#: -> GlobalVariable
|
117
130
|
def last
|
118
131
|
GlobalVariable.from_ptr(C.get_last_global(@module))
|
119
132
|
end
|
120
133
|
|
121
134
|
# Returns the next GlobalVariable in the collection after global.
|
135
|
+
#: (GlobalVariable) -> GlobalVariable
|
122
136
|
def next(global)
|
123
137
|
GlobalVariable.from_ptr(C.get_next_global(global))
|
124
138
|
end
|
125
139
|
|
126
140
|
# Returns the previous GlobalVariable in the collection before global.
|
141
|
+
#: (GlobalVariable) -> GlobalVariable
|
127
142
|
def previous(global)
|
128
143
|
GlobalVariable.from_ptr(C.get_previous_global(global))
|
129
144
|
end
|
130
145
|
|
131
146
|
# Deletes the GlobalVariable from the collection.
|
147
|
+
#: (GlobalVariable) -> void
|
132
148
|
def delete(global)
|
133
149
|
C.delete_global(global)
|
134
150
|
end
|
@@ -149,7 +165,7 @@ module LLVM
|
|
149
165
|
end
|
150
166
|
|
151
167
|
# Iterates through each GlobalVariable in the collection.
|
152
|
-
def each
|
168
|
+
def each(&)
|
153
169
|
g = first
|
154
170
|
until g.nil?
|
155
171
|
yield g
|
@@ -159,6 +175,7 @@ module LLVM
|
|
159
175
|
end
|
160
176
|
|
161
177
|
# Returns a FunctionCollection of all the Functions in the module.
|
178
|
+
#: -> FunctionCollection
|
162
179
|
def functions
|
163
180
|
@functions ||= FunctionCollection.new(self)
|
164
181
|
end
|
@@ -175,7 +192,9 @@ module LLVM
|
|
175
192
|
if args.first.kind_of? FunctionType
|
176
193
|
type = args.first
|
177
194
|
else
|
178
|
-
type = Type.function(
|
195
|
+
type = Type.function(
|
196
|
+
*args #: as untyped
|
197
|
+
)
|
179
198
|
end
|
180
199
|
function = Function.from_ptr(C.add_function(@module, name.to_s, type))
|
181
200
|
|
@@ -233,7 +252,7 @@ module LLVM
|
|
233
252
|
end
|
234
253
|
|
235
254
|
# Iterates through each Function in the collection.
|
236
|
-
def each
|
255
|
+
def each(&)
|
237
256
|
f = first
|
238
257
|
until f.nil?
|
239
258
|
yield f
|
data/lib/llvm/core/type.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# typed: strict
|
2
3
|
|
3
4
|
module LLVM
|
4
5
|
class Type
|
5
6
|
include PointerIdentity
|
6
7
|
|
7
8
|
# @private
|
8
|
-
|
9
|
-
|
9
|
+
#: (untyped, ?kind: Symbol?) -> Type
|
10
|
+
def self.from_ptr(ptr, kind: nil)
|
11
|
+
raise ArgumentError if ptr.null?
|
10
12
|
kind ||= C.get_type_kind(ptr)
|
11
13
|
ty = case kind
|
12
14
|
when :integer
|
@@ -26,18 +28,21 @@ module LLVM
|
|
26
28
|
end
|
27
29
|
|
28
30
|
# Returns a symbol representation of the types kind (ex. :pointer, :vector, :array.)
|
29
|
-
attr_reader :kind
|
31
|
+
attr_reader :kind #: Symbol?
|
30
32
|
|
31
33
|
# Returns the size of the type.
|
34
|
+
#: -> ConstantInt
|
32
35
|
def size
|
33
36
|
LLVM::Int64.from_ptr(C.size_of(self))
|
34
37
|
end
|
35
38
|
|
39
|
+
#: -> ConstantInt
|
36
40
|
def align
|
37
41
|
LLVM::Int64.from_ptr(C.align_of(self))
|
38
42
|
end
|
39
43
|
|
40
44
|
# Returns the type of this types elements (works only for Pointer, Vector, and Array types.)
|
45
|
+
#: -> Type
|
41
46
|
def element_type
|
42
47
|
case kind
|
43
48
|
when :vector, :array
|
@@ -51,32 +56,38 @@ module LLVM
|
|
51
56
|
end
|
52
57
|
|
53
58
|
# Returns a null pointer ConstantExpr of this type.
|
59
|
+
#: -> ConstantExpr
|
54
60
|
def null_pointer
|
55
61
|
ConstantExpr.from_ptr(C.const_pointer_null(self))
|
56
62
|
end
|
57
63
|
|
58
64
|
# Returns a null ConstantExpr of this type.
|
65
|
+
#: -> Constant
|
59
66
|
def null
|
60
67
|
# ConstantExpr.from_ptr(C.const_null(self))
|
61
68
|
Constant.null(self)
|
62
69
|
end
|
63
70
|
|
71
|
+
#: -> Constant
|
64
72
|
def poison
|
65
73
|
# ConstantExpr.from_ptr(C.get_poison(self))
|
66
74
|
Constant.poison(self)
|
67
75
|
end
|
68
76
|
|
77
|
+
#: -> Constant
|
69
78
|
def undef
|
70
79
|
# ConstantExpr.from_ptr(C.get_undef(self))
|
71
80
|
Constant.undef(self)
|
72
81
|
end
|
73
82
|
|
74
83
|
# Creates a pointer type with this type and the given address space.
|
75
|
-
|
76
|
-
|
84
|
+
#: (?address_space: Integer) -> Type
|
85
|
+
def pointer(address_space: 0)
|
86
|
+
Type.pointer(self, address_space: address_space)
|
77
87
|
end
|
78
88
|
|
79
89
|
# Print the type's representation to stdout.
|
90
|
+
#: -> void
|
80
91
|
def dump
|
81
92
|
# :nocov:
|
82
93
|
C.dump_type(self)
|
@@ -84,26 +95,32 @@ module LLVM
|
|
84
95
|
end
|
85
96
|
|
86
97
|
# Build string of LLVM type representation.
|
98
|
+
#: -> String
|
87
99
|
def to_s
|
88
100
|
C.print_type_to_string(self)
|
89
101
|
end
|
90
102
|
|
103
|
+
#: -> bool
|
91
104
|
def aggregate?
|
92
105
|
[:struct, :array].include?(kind)
|
93
106
|
end
|
94
107
|
|
108
|
+
#: -> bool
|
95
109
|
def opaque_struct?
|
96
110
|
C.is_opaque_struct(self)
|
97
111
|
end
|
98
112
|
|
113
|
+
#: -> bool
|
99
114
|
def packed_struct?
|
100
115
|
C.is_packed_struct(self)
|
101
116
|
end
|
102
117
|
|
118
|
+
#: -> bool
|
103
119
|
def literal_struct?
|
104
120
|
C.is_literal_struct(self)
|
105
121
|
end
|
106
122
|
|
123
|
+
#: (untyped) -> bool
|
107
124
|
def ===(other)
|
108
125
|
if other.is_a?(LLVM::Value)
|
109
126
|
return self == other.type
|
@@ -114,82 +131,95 @@ module LLVM
|
|
114
131
|
|
115
132
|
# Creates an array type of Type with the given size.
|
116
133
|
# arrays can be size >= 0, https://llvm.org/docs/LangRef.html#array-type
|
134
|
+
#: (Type, ?Integer) -> Type
|
117
135
|
def self.array(ty, sz = 0)
|
118
136
|
sz = sz.to_i
|
119
137
|
raise ArgumentError, "LLVM Array size must be >= 0" if sz.negative?
|
120
138
|
|
121
|
-
from_ptr(C.array_type(LLVM::Type(ty), sz), :array)
|
139
|
+
from_ptr(C.array_type(LLVM::Type(ty), sz), kind: :array)
|
122
140
|
end
|
123
141
|
|
124
142
|
# Creates the pointer type of Type with the given address space.
|
125
|
-
|
143
|
+
#: (?Type?, ?address_space: Integer) -> Type
|
144
|
+
def self.pointer(ty = nil, address_space: 0)
|
126
145
|
if ty
|
127
|
-
from_ptr(C.pointer_type(LLVM::Type(ty), address_space), :pointer)
|
146
|
+
from_ptr(C.pointer_type(LLVM::Type(ty), address_space), kind: :pointer)
|
128
147
|
else
|
129
|
-
ptr(address_space)
|
148
|
+
ptr(address_space: address_space)
|
130
149
|
end
|
131
150
|
end
|
132
151
|
|
133
152
|
# opaque pointer
|
134
|
-
|
135
|
-
|
153
|
+
#: (?address_space: Integer) -> Type
|
154
|
+
def self.ptr(address_space: 0)
|
155
|
+
from_ptr(C.pointer_type(void, address_space), kind: :pointer)
|
136
156
|
end
|
137
157
|
|
138
158
|
# Creates a vector type of Type with the given element count.
|
139
159
|
# vectors can be size > 0, https://llvm.org/docs/LangRef.html#vector-type
|
160
|
+
#: (Type, Integer) -> Type
|
140
161
|
def self.vector(ty, element_count)
|
141
162
|
element_count = element_count.to_i
|
142
163
|
raise ArgumentError, "LLVM Vector size must be > 0" unless element_count.positive?
|
143
164
|
|
144
|
-
from_ptr(C.vector_type(LLVM::Type(ty), element_count), :vector)
|
165
|
+
from_ptr(C.vector_type(LLVM::Type(ty), element_count), kind: :vector)
|
145
166
|
end
|
146
167
|
|
147
168
|
# Creates a function type. Takes an array of argument Types and the result Type. The only option is <tt>:varargs</tt>,
|
148
169
|
# which when set to true makes the function type take a variable number of args.
|
170
|
+
#: ([Type] | [], Type, ?Hash[untyped, untyped]) -> FunctionType
|
149
171
|
def self.function(arg_types, result_type, options = {})
|
150
172
|
arg_types.map! { |ty| LLVM::Type(ty) }
|
151
173
|
arg_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_types.size)
|
152
174
|
arg_types_ptr.write_array_of_pointer(arg_types)
|
153
|
-
|
175
|
+
function_type_ptr = C.function_type(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0)
|
176
|
+
from_ptr(function_type_ptr, kind: :function) #: as FunctionType
|
154
177
|
end
|
155
178
|
|
156
179
|
# Creates a struct type with the given array of element types.
|
180
|
+
#: ([Type] | [], bool, ?String?) -> Type
|
157
181
|
def self.struct(elt_types, is_packed, name = nil)
|
158
182
|
elt_types.map! { |ty| LLVM::Type(ty) }
|
159
183
|
elt_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * elt_types.size)
|
160
184
|
elt_types_ptr.write_array_of_pointer(elt_types)
|
161
185
|
if name
|
162
|
-
struct = from_ptr(C.struct_create_named(Context.global, name), :struct)
|
186
|
+
struct = from_ptr(C.struct_create_named(Context.global, name), kind: :struct)
|
163
187
|
C.struct_set_body(struct, elt_types_ptr, elt_types.size, is_packed ? 1 : 0) unless elt_types.empty?
|
164
188
|
struct
|
165
189
|
else
|
166
|
-
from_ptr(C.struct_type(elt_types_ptr, elt_types.size, is_packed ? 1 : 0), :struct)
|
190
|
+
from_ptr(C.struct_type(elt_types_ptr, elt_types.size, is_packed ? 1 : 0), kind: :struct)
|
167
191
|
end
|
168
192
|
end
|
169
193
|
|
194
|
+
#: (untyped) -> Type
|
170
195
|
def self.opaque_struct(name)
|
171
|
-
from_ptr(C.struct_create_named(Context.global, name.to_s), :struct)
|
196
|
+
from_ptr(C.struct_create_named(Context.global, name.to_s), kind: :struct)
|
172
197
|
end
|
173
198
|
|
199
|
+
#: (untyped) -> Type?
|
174
200
|
def self.named(name)
|
175
|
-
from_ptr(C.get_type_by_name2(Context.global, name.to_s)
|
201
|
+
from_ptr(C.get_type_by_name2(Context.global, name.to_s))
|
176
202
|
end
|
177
203
|
|
178
204
|
# Creates a void type.
|
205
|
+
#: -> Type
|
179
206
|
def self.void
|
180
|
-
from_ptr(C.void_type, :void)
|
207
|
+
from_ptr(C.void_type, kind: :void)
|
181
208
|
end
|
182
209
|
|
210
|
+
#: -> Type
|
183
211
|
def self.label
|
184
|
-
from_ptr(C.label_type, :label)
|
212
|
+
from_ptr(C.label_type, kind: :label)
|
185
213
|
end
|
186
214
|
|
215
|
+
#: -> Type
|
187
216
|
def self.x86_mmx
|
188
217
|
raise DeprecationError
|
189
218
|
end
|
190
219
|
|
220
|
+
#: -> Type
|
191
221
|
def self.x86_amx
|
192
|
-
from_ptr(C.x86amx_type, :x86amx)
|
222
|
+
from_ptr(C.x86amx_type, kind: :x86amx)
|
193
223
|
end
|
194
224
|
# def self.opaque_pointer
|
195
225
|
# from_ptr(C.opaque_type, :pointer)
|
@@ -202,32 +232,38 @@ module LLVM
|
|
202
232
|
# ty
|
203
233
|
# end
|
204
234
|
|
235
|
+
#: (Integer) -> Type
|
205
236
|
def self.integer(width)
|
206
|
-
IntType.from_ptr(C.int_type(width), :integer)
|
237
|
+
IntType.from_ptr(C.int_type(width), kind: :integer)
|
207
238
|
end
|
208
239
|
|
209
240
|
class << self
|
210
241
|
alias_method :i, :integer
|
211
242
|
end
|
212
243
|
|
244
|
+
#: -> RealType
|
213
245
|
def self.float
|
214
|
-
RealType.from_ptr(C.float_type, kind: :float)
|
246
|
+
RealType.from_ptr(C.float_type, kind: :float) #: as RealType
|
215
247
|
end
|
216
248
|
|
249
|
+
#: -> RealType
|
217
250
|
def self.double
|
218
|
-
RealType.from_ptr(C.double_type, kind: :double)
|
251
|
+
RealType.from_ptr(C.double_type, kind: :double) #: as RealType
|
219
252
|
end
|
220
253
|
end
|
221
254
|
|
222
255
|
class IntType < Type
|
256
|
+
#: -> ConstantInt
|
223
257
|
def all_ones
|
224
258
|
from_ptr(C.const_all_ones(self))
|
225
259
|
end
|
226
260
|
|
261
|
+
#: -> Integer
|
227
262
|
def width
|
228
263
|
C.get_int_type_width(self)
|
229
264
|
end
|
230
265
|
|
266
|
+
#: (Hash[Symbol, untyped] | bool) -> bool
|
231
267
|
private def get_sign_option(options)
|
232
268
|
case options
|
233
269
|
when true, false
|
@@ -239,6 +275,7 @@ module LLVM
|
|
239
275
|
end
|
240
276
|
end
|
241
277
|
|
278
|
+
#: ((Numeric | String), ?Hash[untyped, untyped] | bool) -> Value
|
242
279
|
def from_i(int, options = {})
|
243
280
|
signed = get_sign_option(options)
|
244
281
|
|
@@ -249,23 +286,14 @@ module LLVM
|
|
249
286
|
unpoisoned ? val : poison
|
250
287
|
end
|
251
288
|
|
252
|
-
|
253
|
-
private def fits_width?(int, width, signed)
|
254
|
-
# :nocov:
|
255
|
-
if signed
|
256
|
-
int.bit_length < width || int == 1
|
257
|
-
else
|
258
|
-
int >= 0 && int.bit_length <= width
|
259
|
-
end
|
260
|
-
# :nocov:
|
261
|
-
end
|
262
|
-
|
289
|
+
#: (FFI::Pointer) -> ConstantInt
|
263
290
|
def from_ptr(ptr)
|
264
291
|
ConstantInt.from_ptr(ptr)
|
265
292
|
end
|
266
293
|
|
267
294
|
# parse string using const_int_of_string_and_size
|
268
295
|
# normalize the string to base 10 (used in llvm ir), and handle prefixes like 0x
|
296
|
+
#: (String, Integer) -> Value
|
269
297
|
private def const_int_of_string_and_size(str, radix)
|
270
298
|
normalized_string = radix == 10 ? str : str.to_i(radix).to_s
|
271
299
|
val = from_ptr(C.const_int_of_string_and_size(self, normalized_string, normalized_string.size, 10))
|
@@ -277,54 +305,64 @@ module LLVM
|
|
277
305
|
# parse string using const_int_of_string_and_size
|
278
306
|
# alternative implementation parsing with ruby:
|
279
307
|
# from_i(str.to_i(radix))
|
308
|
+
#: (untyped, ?Integer) -> Value
|
280
309
|
def parse(str, radix = 10)
|
281
|
-
const_int_of_string_and_size(str, radix)
|
310
|
+
const_int_of_string_and_size(str.to_s, radix)
|
282
311
|
end
|
283
312
|
|
313
|
+
#: -> self
|
284
314
|
def type
|
285
315
|
self
|
286
316
|
end
|
287
317
|
end
|
288
318
|
|
289
319
|
class RealType < Type
|
290
|
-
# given an array of values, return the type that will fit all of them
|
320
|
+
# given an array of values or types, return the type that will fit all of them
|
291
321
|
# currently only works for floats and doubles
|
322
|
+
#: ([Value | Type]) -> RealType
|
292
323
|
def self.fits(values)
|
293
324
|
values.detect { |v| v.type.to_s == 'double' } ? double : float
|
294
325
|
end
|
295
326
|
|
327
|
+
#: (Integer | ::Float | Rational | BigDecimal) -> ConstantReal
|
296
328
|
def from_f(value)
|
297
|
-
ConstantReal.from_ptr(C.const_real(self, value))
|
329
|
+
ConstantReal.from_ptr(C.const_real(self, value.to_f))
|
298
330
|
end
|
299
331
|
|
332
|
+
#: (untyped) -> ConstantReal
|
300
333
|
def parse(str)
|
301
|
-
ConstantReal.from_ptr(C.const_real_of_string(self, str))
|
334
|
+
ConstantReal.from_ptr(C.const_real_of_string(self, str.to_s))
|
302
335
|
end
|
303
336
|
|
337
|
+
#: -> self
|
304
338
|
def type
|
305
339
|
self
|
306
340
|
end
|
307
341
|
end
|
308
342
|
|
309
343
|
class FunctionType < Type
|
344
|
+
#: -> Type
|
310
345
|
def return_type
|
311
346
|
Type.from_ptr(C.get_return_type(self))
|
312
347
|
end
|
313
348
|
|
349
|
+
#: -> self
|
314
350
|
def element_type
|
315
351
|
self
|
316
352
|
end
|
317
353
|
|
354
|
+
#: -> Array[Type?]
|
318
355
|
def argument_types
|
319
356
|
size = C.count_param_types(self)
|
320
|
-
result =
|
357
|
+
result = [] #: Array[Type]
|
321
358
|
FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |types_ptr|
|
322
359
|
C.get_param_types(self, types_ptr)
|
323
360
|
result = types_ptr.read_array_of_pointer(size)
|
324
361
|
end
|
325
|
-
result.map { |p| Type.from_ptr(p
|
362
|
+
result.map { |p| Type.from_ptr(p) }
|
326
363
|
end
|
327
364
|
|
365
|
+
#: -> bool
|
328
366
|
def vararg?
|
329
367
|
C.is_function_var_arg(self) != 0
|
330
368
|
end
|
@@ -332,22 +370,25 @@ module LLVM
|
|
332
370
|
|
333
371
|
class StructType < Type
|
334
372
|
# Returns the name of the struct.
|
373
|
+
#: -> String
|
335
374
|
def name
|
336
375
|
C.get_struct_name(self)
|
337
376
|
end
|
338
377
|
|
339
378
|
# Returns the element types of the struct.
|
379
|
+
#: -> Array[Type]
|
340
380
|
def element_types
|
341
381
|
count = C.count_struct_element_types(self)
|
342
|
-
elt_types =
|
382
|
+
elt_types = [] #: Array[Type]
|
343
383
|
FFI::MemoryPointer.new(FFI.type_size(:pointer) * count) do |types_ptr|
|
344
384
|
C.get_struct_element_types(self, types_ptr)
|
345
|
-
elt_types = types_ptr.read_array_of_pointer(count).map { |type_ptr| Type.from_ptr(type_ptr
|
385
|
+
elt_types = types_ptr.read_array_of_pointer(count).map { |type_ptr| Type.from_ptr(type_ptr) }
|
346
386
|
end
|
347
387
|
elt_types
|
348
388
|
end
|
349
389
|
|
350
390
|
# Sets the struct body.
|
391
|
+
#: ([untyped]) -> void
|
351
392
|
def element_types=(elt_types)
|
352
393
|
elt_types.map! { |ty| LLVM::Type(ty) }
|
353
394
|
elt_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * elt_types.size)
|
@@ -359,6 +400,7 @@ module LLVM
|
|
359
400
|
module_function
|
360
401
|
|
361
402
|
# Creates a Type from the given object.
|
403
|
+
#: (LLVM::Type | LLVM::Value) -> LLVM::Type
|
362
404
|
def Type(ty)
|
363
405
|
case ty
|
364
406
|
when LLVM::Type
|
@@ -369,76 +411,95 @@ module LLVM
|
|
369
411
|
end
|
370
412
|
|
371
413
|
# Shortcut to Type.array.
|
414
|
+
#: (LLVM::Type, ?Integer) -> LLVM::Type
|
372
415
|
def Array(ty, sz = 0)
|
373
416
|
LLVM::Type.array(ty, sz)
|
374
417
|
end
|
375
418
|
|
376
419
|
# Shortcut to Type.pointer.
|
420
|
+
#: (?Type?) -> Type`
|
377
421
|
def Pointer(ty = nil)
|
378
422
|
LLVM::Type.pointer(ty)
|
379
423
|
end
|
380
424
|
|
381
425
|
# Shortcut to Type.vector.
|
426
|
+
#: (LLVM::Type, Integer) -> LLVM::Type
|
382
427
|
def Vector(ty, sz)
|
383
428
|
LLVM::Type.vector(ty, sz)
|
384
429
|
end
|
385
430
|
|
386
431
|
# Shortcut to Type.function.
|
432
|
+
#: ([Type] | [], Type, ?Hash[untyped, untyped]) -> FunctionType
|
387
433
|
def Function(argtypes, rettype, options = {})
|
388
434
|
LLVM::Type.function(argtypes, rettype, options)
|
389
435
|
end
|
390
436
|
|
391
437
|
# Shortcut to Type.struct.
|
438
|
+
#: (*untyped) -> LLVM::Type
|
392
439
|
def Struct(*elt_types)
|
393
440
|
name = if elt_types.last.is_a? String
|
394
441
|
elt_types.pop
|
395
442
|
else
|
396
443
|
nil
|
397
444
|
end
|
398
|
-
LLVM::Type.struct(
|
445
|
+
LLVM::Type.struct(
|
446
|
+
elt_types, #: as [LLVM::Type]
|
447
|
+
false,
|
448
|
+
name
|
449
|
+
)
|
399
450
|
end
|
400
451
|
|
401
452
|
# Shortcut to Type.void.
|
453
|
+
#: -> Type
|
402
454
|
def Void
|
403
455
|
LLVM::Type.void
|
404
456
|
end
|
405
457
|
|
458
|
+
#: -> Type
|
406
459
|
def void
|
407
460
|
LLVM::Type.void
|
408
461
|
end
|
409
462
|
|
463
|
+
#: (Integer, ?(Numeric | String)?) -> (ConstantInt | IntType)
|
410
464
|
def i(width, value = nil)
|
411
465
|
type = LLVM::Type.i(width)
|
412
466
|
value ? type.from_i(value) : type
|
413
467
|
end
|
414
468
|
|
469
|
+
#: (?Numeric?) -> (ConstantReal | RealType)
|
415
470
|
def double(value = nil)
|
416
471
|
type = LLVM::Type.double
|
417
|
-
value ? type.from_f(value) : type
|
472
|
+
value ? type.from_f(value.to_f) : type
|
418
473
|
end
|
419
474
|
|
475
|
+
#: (?Numeric?) -> (ConstantReal | RealType)
|
420
476
|
def float(value = nil)
|
421
477
|
type = LLVM::Type.float
|
422
|
-
value ? type.from_f(value) : type
|
478
|
+
value ? type.from_f(value.to_f) : type
|
423
479
|
end
|
424
480
|
|
481
|
+
#: -> Type
|
425
482
|
def ptr
|
426
483
|
LLVM::Type.pointer
|
427
484
|
end
|
428
485
|
|
429
486
|
# for compatibility
|
430
487
|
# Create a float LLVM::ContantReal from a Ruby Float (value).
|
488
|
+
# This will always return ConstantReal because value will always be Numeric
|
489
|
+
#: (Numeric) -> ConstantReal
|
431
490
|
def Float(value)
|
432
|
-
float(value)
|
491
|
+
float(value) #: as ConstantReal
|
433
492
|
end
|
434
493
|
|
435
494
|
# for compatibility
|
436
495
|
# Create a double LLVM::ContantReal from a Ruby Float (value).
|
496
|
+
# This will always return ConstantReal because value will always be Numeric
|
497
|
+
#: (Numeric) -> ConstantReal
|
437
498
|
def Double(value)
|
438
|
-
double(value)
|
499
|
+
double(value) #: as ConstantReal
|
439
500
|
end
|
440
501
|
|
441
502
|
# for compatibility
|
442
|
-
Float = float.freeze
|
443
|
-
Double = double.freeze
|
503
|
+
Float = LLVM::Type.float.freeze #: LLVM::RealType
|
504
|
+
Double = LLVM::Type.double.freeze #: LLVM::RealType
|
444
505
|
end
|