ruby-llvm-next 10.0.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 +7 -0
- data/LICENSE +30 -0
- data/README.md +67 -0
- data/ext/ruby-llvm-support/Rakefile +110 -0
- data/ext/ruby-llvm-support/support.cpp +32 -0
- data/lib/llvm.rb +29 -0
- data/lib/llvm/analysis.rb +49 -0
- data/lib/llvm/analysis_ffi.rb +77 -0
- data/lib/llvm/config.rb +10 -0
- data/lib/llvm/core.rb +97 -0
- data/lib/llvm/core/bitcode.rb +84 -0
- data/lib/llvm/core/bitcode_ffi.rb +132 -0
- data/lib/llvm/core/builder.rb +944 -0
- data/lib/llvm/core/context.rb +24 -0
- data/lib/llvm/core/module.rb +240 -0
- data/lib/llvm/core/pass_manager.rb +80 -0
- data/lib/llvm/core/type.rb +210 -0
- data/lib/llvm/core/value.rb +1005 -0
- data/lib/llvm/core_ffi.rb +6021 -0
- data/lib/llvm/execution_engine.rb +323 -0
- data/lib/llvm/execution_engine_ffi.rb +421 -0
- data/lib/llvm/linker.rb +16 -0
- data/lib/llvm/linker_ffi.rb +44 -0
- data/lib/llvm/support.rb +38 -0
- data/lib/llvm/target.rb +318 -0
- data/lib/llvm/target_ffi.rb +628 -0
- data/lib/llvm/transforms/builder.rb +107 -0
- data/lib/llvm/transforms/builder_ffi.rb +117 -0
- data/lib/llvm/transforms/ipo.rb +78 -0
- data/lib/llvm/transforms/ipo_ffi.rb +127 -0
- data/lib/llvm/transforms/scalar.rb +152 -0
- data/lib/llvm/transforms/scalar_ffi.rb +344 -0
- data/lib/llvm/transforms/vectorize.rb +22 -0
- data/lib/llvm/transforms/vectorize_ffi.rb +38 -0
- data/lib/llvm/version.rb +5 -0
- data/test/array_test.rb +38 -0
- data/test/basic_block_test.rb +87 -0
- data/test/binary_operations_test.rb +58 -0
- data/test/bitcode_test.rb +24 -0
- data/test/branch_test.rb +57 -0
- data/test/call_test.rb +82 -0
- data/test/comparisons_test.rb +66 -0
- data/test/conversions_test.rb +92 -0
- data/test/double_test.rb +34 -0
- data/test/equality_test.rb +89 -0
- data/test/function_test.rb +100 -0
- data/test/generic_value_test.rb +22 -0
- data/test/instruction_test.rb +30 -0
- data/test/ipo_test.rb +53 -0
- data/test/linker_test.rb +37 -0
- data/test/mcjit_test.rb +94 -0
- data/test/memory_access_test.rb +38 -0
- data/test/module_test.rb +93 -0
- data/test/parameter_collection_test.rb +28 -0
- data/test/pass_manager_builder_test.rb +53 -0
- data/test/phi_test.rb +33 -0
- data/test/select_test.rb +22 -0
- data/test/struct_test.rb +98 -0
- data/test/target_test.rb +113 -0
- data/test/test_helper.rb +62 -0
- data/test/type_test.rb +15 -0
- data/test/vector_test.rb +64 -0
- metadata +240 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Context
|
3
|
+
def initialize(ptr = nil)
|
4
|
+
@ptr = ptr || C.context_create()
|
5
|
+
end
|
6
|
+
|
7
|
+
# @private
|
8
|
+
def to_ptr
|
9
|
+
@ptr
|
10
|
+
end
|
11
|
+
|
12
|
+
# Obtains a reference to the global Context.
|
13
|
+
def self.global
|
14
|
+
new(C.get_global_context())
|
15
|
+
end
|
16
|
+
|
17
|
+
# Diposes the Context.
|
18
|
+
def dispose
|
19
|
+
return if @ptr.nil?
|
20
|
+
C.context_dispose(@ptr)
|
21
|
+
@ptr = nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,240 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Module
|
3
|
+
include PointerIdentity
|
4
|
+
|
5
|
+
# @private
|
6
|
+
def self.from_ptr(ptr)
|
7
|
+
return if ptr.null?
|
8
|
+
mod = allocate
|
9
|
+
mod.instance_variable_set(:@ptr, ptr)
|
10
|
+
mod
|
11
|
+
end
|
12
|
+
|
13
|
+
# Important: Call #dispose to free backend memory after use, but not when using JITCompiler with this module.
|
14
|
+
def initialize(name)
|
15
|
+
@ptr = C.module_create_with_name(name)
|
16
|
+
end
|
17
|
+
|
18
|
+
def dispose
|
19
|
+
return if @ptr.nil?
|
20
|
+
|
21
|
+
C.dispose_module(@ptr)
|
22
|
+
@ptr = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get module triple.
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
def triple
|
29
|
+
C.get_target(self)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Set module triple.
|
33
|
+
#
|
34
|
+
# @param [String] triple
|
35
|
+
def triple=(triple)
|
36
|
+
C.set_target(self, triple.to_s)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get module data layout.
|
40
|
+
#
|
41
|
+
# @return [String]
|
42
|
+
def data_layout
|
43
|
+
C.get_data_layout(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Set module data layout.
|
47
|
+
#
|
48
|
+
# @param [String, TargetDataLayout] data_layout
|
49
|
+
def data_layout=(data_layout)
|
50
|
+
C.set_data_layout(self, data_layout.to_s)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns a TypeCollection of all the Types in the module.
|
54
|
+
def types
|
55
|
+
@types ||= TypeCollection.new(self)
|
56
|
+
end
|
57
|
+
|
58
|
+
class TypeCollection
|
59
|
+
def initialize(mod)
|
60
|
+
@module = mod
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the Type with the given name (symbol or string).
|
64
|
+
def named(name)
|
65
|
+
Type.from_ptr(C.get_type_by_name(@module, name.to_s), nil)
|
66
|
+
end
|
67
|
+
|
68
|
+
alias [] named
|
69
|
+
end
|
70
|
+
|
71
|
+
# Returns an Enumerable of all the GlobalVariables in the module.
|
72
|
+
def globals
|
73
|
+
@globals ||= GlobalCollection.new(self)
|
74
|
+
end
|
75
|
+
|
76
|
+
class GlobalCollection
|
77
|
+
include Enumerable
|
78
|
+
|
79
|
+
def initialize(mod)
|
80
|
+
@module = mod
|
81
|
+
end
|
82
|
+
|
83
|
+
# Adds a GlobalVariable with the given type and name to the collection (symbol or string).
|
84
|
+
def add(ty, name)
|
85
|
+
GlobalVariable.from_ptr(C.add_global(@module, LLVM::Type(ty), name.to_s)).tap do |gvar|
|
86
|
+
yield gvar if block_given?
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Returns the GlobalVariable with the given name (symbol or string).
|
91
|
+
def named(name)
|
92
|
+
GlobalValue.from_ptr(C.get_named_global(@module, name.to_s))
|
93
|
+
end
|
94
|
+
|
95
|
+
# Returns the first GlobalVariable in the collection.
|
96
|
+
def first
|
97
|
+
GlobalValue.from_ptr(C.get_first_global(@module))
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns the last GlobalVariable in the collection.
|
101
|
+
def last
|
102
|
+
GlobalValue.from_ptr(C.get_last_global(@module))
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns the next GlobalVariable in the collection after global.
|
106
|
+
def next(global)
|
107
|
+
GlobalValue.from_ptr(C.get_next_global(global))
|
108
|
+
end
|
109
|
+
|
110
|
+
# Returns the previous GlobalVariable in the collection before global.
|
111
|
+
def previous(global)
|
112
|
+
GlobalValue.from_ptr(C.get_previous_global(global))
|
113
|
+
end
|
114
|
+
|
115
|
+
# Deletes the GlobalVariable from the collection.
|
116
|
+
def delete(global)
|
117
|
+
C.delete_global(global)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Returns the GlobalVariable with a name equal to key (symbol or string) or at key (integer).
|
121
|
+
def [](key)
|
122
|
+
case key
|
123
|
+
when String, Symbol then named(key)
|
124
|
+
when Integer then
|
125
|
+
i = 0
|
126
|
+
g = first
|
127
|
+
until i >= key || g.nil?
|
128
|
+
g = self.next(g)
|
129
|
+
i += 1
|
130
|
+
end
|
131
|
+
g
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# Iterates through each GlobalVariable in the collection.
|
136
|
+
def each
|
137
|
+
g = first
|
138
|
+
until g.nil?
|
139
|
+
yield g
|
140
|
+
g = self.next(g)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns a FunctionCollection of all the Functions in the module.
|
146
|
+
def functions
|
147
|
+
@functions ||= FunctionCollection.new(self)
|
148
|
+
end
|
149
|
+
|
150
|
+
class FunctionCollection
|
151
|
+
include Enumerable
|
152
|
+
|
153
|
+
def initialize(mod)
|
154
|
+
@module = mod
|
155
|
+
end
|
156
|
+
|
157
|
+
# Adds a Function with the given name (symbol or string) and args (Types).
|
158
|
+
def add(name, *args)
|
159
|
+
if args.first.kind_of? FunctionType
|
160
|
+
type = args.first
|
161
|
+
else
|
162
|
+
type = Type.function(*args)
|
163
|
+
end
|
164
|
+
function = Function.from_ptr(C.add_function(@module, name.to_s, type))
|
165
|
+
|
166
|
+
if block_given?
|
167
|
+
params = (0...function.params.size).map { |i| function.params[i] }
|
168
|
+
yield function, *params
|
169
|
+
end
|
170
|
+
|
171
|
+
function
|
172
|
+
end
|
173
|
+
|
174
|
+
# Returns the Function with the given name (symbol or string).
|
175
|
+
def named(name)
|
176
|
+
Function.from_ptr(C.get_named_function(@module, name.to_s))
|
177
|
+
end
|
178
|
+
|
179
|
+
# Returns the first Function in the collection.
|
180
|
+
def first
|
181
|
+
Function.from_ptr(C.get_first_function(@module))
|
182
|
+
end
|
183
|
+
|
184
|
+
# Returns the last Function in the collection.
|
185
|
+
def last
|
186
|
+
Function.from_ptr(C.get_last_function(@module))
|
187
|
+
end
|
188
|
+
|
189
|
+
# Returns the next Function in the collection after function.
|
190
|
+
def next(function)
|
191
|
+
Function.from_ptr(C.get_next_function(function))
|
192
|
+
end
|
193
|
+
|
194
|
+
# Returns the previous Function in the collection before function.
|
195
|
+
def previous(function)
|
196
|
+
Function.from_ptr(C.get_previous_function(function))
|
197
|
+
end
|
198
|
+
|
199
|
+
# Deletes the Function from the collection.
|
200
|
+
def delete(function)
|
201
|
+
C.delete_function(function)
|
202
|
+
end
|
203
|
+
|
204
|
+
# Returns the Function with a name equal to key (symbol or string) or at key (integer).
|
205
|
+
def [](key)
|
206
|
+
case key
|
207
|
+
when String, Symbol then named(key)
|
208
|
+
when Integer
|
209
|
+
i = 0
|
210
|
+
f = first
|
211
|
+
until i >= key || f.nil?
|
212
|
+
f = self.next(f)
|
213
|
+
i += 1
|
214
|
+
end
|
215
|
+
f
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# Iterates through each Function in the collection.
|
220
|
+
def each
|
221
|
+
f = first
|
222
|
+
until f.nil?
|
223
|
+
yield f
|
224
|
+
f = self.next(f)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Returns the LLVM IR of the module as a string.
|
230
|
+
def to_s
|
231
|
+
C.print_module_to_string(self)
|
232
|
+
end
|
233
|
+
|
234
|
+
# Print the module's IR to the standard error.
|
235
|
+
def dump
|
236
|
+
C.dump_module(self)
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module LLVM
|
2
|
+
# The PassManager runs a queue of passes on a module. See
|
3
|
+
# http://llvm.org/docs/Passes.html for the list of available passes.
|
4
|
+
class PassManager
|
5
|
+
# Creates a new pass manager.
|
6
|
+
#
|
7
|
+
# @param [LLVM::ExecutionEngine, LLVM::TargetMachine] machine
|
8
|
+
def initialize(machine = nil)
|
9
|
+
if machine
|
10
|
+
warn("[DEPRECATION] PassManager.new should be called without parameters")
|
11
|
+
end
|
12
|
+
@ptr = C.create_pass_manager()
|
13
|
+
end
|
14
|
+
|
15
|
+
# @private
|
16
|
+
def to_ptr
|
17
|
+
@ptr
|
18
|
+
end
|
19
|
+
|
20
|
+
# Append a pass to the pass queue.
|
21
|
+
#
|
22
|
+
# @param [Symbol] name
|
23
|
+
# @return [LLVM::PassManager]
|
24
|
+
def <<(name)
|
25
|
+
send(:"#{name}!")
|
26
|
+
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Run the pass queue on the given module.
|
31
|
+
#
|
32
|
+
# @param [LLVM::Module] mod
|
33
|
+
# @return [true, false] Indicates whether the module was modified.
|
34
|
+
def run(mod)
|
35
|
+
C.run_pass_manager(self, mod) != 0
|
36
|
+
end
|
37
|
+
|
38
|
+
# Disposes the pass manager.
|
39
|
+
def dispose
|
40
|
+
return if @ptr.nil?
|
41
|
+
|
42
|
+
finalize
|
43
|
+
|
44
|
+
C.dispose_pass_manager(@ptr)
|
45
|
+
@ptr = nil
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def finalize
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class FunctionPassManager < PassManager
|
55
|
+
# Creates a new function pass manager.
|
56
|
+
#
|
57
|
+
# @param [LLVM::ExecutionEngine, LLVM::TargetMachine] machine
|
58
|
+
# @param [LLVM::Module] mod
|
59
|
+
def initialize(machine, mod)
|
60
|
+
@ptr = C.create_function_pass_manager_for_module(mod)
|
61
|
+
C.add_target_data(machine.data_layout, @ptr)
|
62
|
+
|
63
|
+
C.initialize_function_pass_manager(self) != 0
|
64
|
+
end
|
65
|
+
|
66
|
+
# Run the pass queue on the given function.
|
67
|
+
#
|
68
|
+
# @param [LLVM::Function] fn
|
69
|
+
# @return [true, false] indicates whether the function was modified.
|
70
|
+
def run(fn)
|
71
|
+
C.run_function_pass_manager(self, fn) != 0
|
72
|
+
end
|
73
|
+
|
74
|
+
protected
|
75
|
+
|
76
|
+
def finalize
|
77
|
+
C.finalize_function_pass_manager(self) != 0
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
module LLVM
|
2
|
+
class Type
|
3
|
+
include PointerIdentity
|
4
|
+
|
5
|
+
# @private
|
6
|
+
def self.from_ptr(ptr, kind)
|
7
|
+
return if ptr.null?
|
8
|
+
kind ||= C.get_type_kind(ptr)
|
9
|
+
ty = case kind
|
10
|
+
when :integer then IntType.allocate
|
11
|
+
when :function then FunctionType.allocate
|
12
|
+
when :struct then StructType.allocate
|
13
|
+
else allocate
|
14
|
+
end
|
15
|
+
ty.instance_variable_set(:@ptr, ptr)
|
16
|
+
ty.instance_variable_set(:@kind, kind)
|
17
|
+
ty
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns a symbol representation of the types kind (ex. :pointer, :vector, :array.)
|
21
|
+
def kind
|
22
|
+
@kind
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the size of the type.
|
26
|
+
def size
|
27
|
+
LLVM::Int64.from_ptr(C.size_of(self))
|
28
|
+
end
|
29
|
+
|
30
|
+
def align
|
31
|
+
LLVM::Int64.from_ptr(C.align_of(self))
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the type of this types elements (works only for Pointer, Vector, and Array types.)
|
35
|
+
def element_type
|
36
|
+
case kind
|
37
|
+
when :pointer, :vector, :array
|
38
|
+
Type.from_ptr(C.get_element_type(self), nil)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a null pointer ConstantExpr of this type.
|
43
|
+
def null_pointer
|
44
|
+
ConstantExpr.from_ptr(C.const_pointer_null(self))
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a null ConstantExpr of this type.
|
48
|
+
def null
|
49
|
+
ConstantExpr.from_ptr(C.const_null(self))
|
50
|
+
end
|
51
|
+
|
52
|
+
# Creates a pointer type with this type and the given address space.
|
53
|
+
def pointer(address_space = 0)
|
54
|
+
Type.pointer(self, address_space)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Print the type's representation to stdout.
|
58
|
+
def dump
|
59
|
+
C.dump_type(self)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Creates an array type of Type with the given size.
|
63
|
+
def self.array(ty, sz = 0)
|
64
|
+
from_ptr(C.array_type(LLVM::Type(ty), sz), :array)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Creates the pointer type of Type with the given address space.
|
68
|
+
def self.pointer(ty, address_space = 0)
|
69
|
+
from_ptr(C.pointer_type(LLVM::Type(ty), address_space), :pointer)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Creates a vector type of Type with the given element count.
|
73
|
+
def self.vector(ty, element_count)
|
74
|
+
from_ptr(C.vector_type(LLVM::Type(ty), element_count), :vector)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Creates a function type. Takes an array of argument Types and the result Type. The only option is <tt>:varargs</tt>,
|
78
|
+
# which when set to true makes the function type take a variable number of args.
|
79
|
+
def self.function(arg_types, result_type, options = {})
|
80
|
+
arg_types.map! { |ty| LLVM::Type(ty) }
|
81
|
+
arg_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_types.size)
|
82
|
+
arg_types_ptr.write_array_of_pointer(arg_types)
|
83
|
+
from_ptr(C.function_type(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0), :function)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Creates a struct type with the given array of element types.
|
87
|
+
def self.struct(elt_types, is_packed, name = nil)
|
88
|
+
elt_types.map! { |ty| LLVM::Type(ty) }
|
89
|
+
elt_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * elt_types.size)
|
90
|
+
elt_types_ptr.write_array_of_pointer(elt_types)
|
91
|
+
if name
|
92
|
+
struct = from_ptr(C.struct_create_named(Context.global, name), :struct)
|
93
|
+
C.struct_set_body(struct, elt_types_ptr, elt_types.size, is_packed ? 1 : 0) unless elt_types.empty?
|
94
|
+
struct
|
95
|
+
else
|
96
|
+
from_ptr(C.struct_type(elt_types_ptr, elt_types.size, is_packed ? 1 : 0), :struct)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Creates a void type.
|
101
|
+
def self.void
|
102
|
+
from_ptr(C.void_type, :void)
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.rec
|
106
|
+
h = opaque
|
107
|
+
ty = yield h
|
108
|
+
h.refine(ty)
|
109
|
+
ty
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class IntType < Type
|
114
|
+
def width
|
115
|
+
C.get_int_type_width(self)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
class FunctionType < Type
|
120
|
+
def return_type
|
121
|
+
Type.from_ptr(C.get_return_type(self), nil)
|
122
|
+
end
|
123
|
+
|
124
|
+
def argument_types
|
125
|
+
size = C.count_param_types(self)
|
126
|
+
result = nil
|
127
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |types_ptr|
|
128
|
+
C.get_param_types(self, types_ptr)
|
129
|
+
result = types_ptr.read_array_of_pointer(size)
|
130
|
+
end
|
131
|
+
result.map { |p| Type.from_ptr(p, nil) }
|
132
|
+
end
|
133
|
+
|
134
|
+
def vararg?
|
135
|
+
C.is_function_var_arg(self) != 0
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
class StructType < Type
|
140
|
+
# Returns the name of the struct.
|
141
|
+
def name
|
142
|
+
C.get_struct_name(self)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Returns the element types of the struct.
|
146
|
+
def element_types
|
147
|
+
count = C.count_struct_element_types(self)
|
148
|
+
elt_types = nil
|
149
|
+
FFI::MemoryPointer.new(FFI.type_size(:pointer) * count) do |types_ptr|
|
150
|
+
C.get_struct_element_types(self, types_ptr)
|
151
|
+
elt_types = types_ptr.read_array_of_pointer(count).map { |type_ptr| Type.from_ptr(type_ptr, nil) }
|
152
|
+
end
|
153
|
+
elt_types
|
154
|
+
end
|
155
|
+
|
156
|
+
# Sets the struct body.
|
157
|
+
def element_types=(elt_types)
|
158
|
+
elt_types.map! { |ty| LLVM::Type(ty) }
|
159
|
+
elt_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * elt_types.size)
|
160
|
+
elt_types_ptr.write_array_of_pointer(elt_types)
|
161
|
+
C.struct_set_body(self, elt_types_ptr, elt_types.size, 0)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
module_function
|
166
|
+
|
167
|
+
# Creates a Type from the given object.
|
168
|
+
def Type(ty)
|
169
|
+
case ty
|
170
|
+
when LLVM::Type then ty
|
171
|
+
else ty.type
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# Shortcut to Type.array.
|
176
|
+
def Array(ty, sz = 0)
|
177
|
+
LLVM::Type.array(ty, sz)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Shortcut to Type.pointer.
|
181
|
+
def Pointer(ty)
|
182
|
+
LLVM::Type.pointer(ty)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Shortcut to Type.vector.
|
186
|
+
def Vector(ty, sz)
|
187
|
+
LLVM::Type.vector(ty, sz)
|
188
|
+
end
|
189
|
+
|
190
|
+
# Shortcut to Type.function.
|
191
|
+
def Function(argtypes, rettype, options = {})
|
192
|
+
LLVM::Type.function(argtypes, rettype, options)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Shortcut to Type.struct.
|
196
|
+
def Struct(*elt_types)
|
197
|
+
name = if elt_types.last.is_a? String
|
198
|
+
elt_types.pop
|
199
|
+
else
|
200
|
+
nil
|
201
|
+
end
|
202
|
+
LLVM::Type.struct(elt_types, false, name)
|
203
|
+
end
|
204
|
+
|
205
|
+
# Shortcut to Type.void.
|
206
|
+
def Void
|
207
|
+
LLVM::Type.void
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|