ruby-llvm 2.7.0 → 2.9.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.
@@ -1,9 +1,7 @@
1
1
  module LLVM
2
2
  class Context
3
- class << self
4
- private :new
5
- end
6
-
3
+ private_class_method :new
4
+
7
5
  def initialize(ptr) # :nodoc:
8
6
  @ptr = ptr
9
7
  end
@@ -1,8 +1,6 @@
1
1
  module LLVM
2
2
  class Module
3
- class << self
4
- private :new
5
- end
3
+ private_class_method :new
6
4
 
7
5
  def self.from_ptr(ptr)
8
6
  ptr.null? ? nil : new(ptr)
@@ -16,6 +14,19 @@ module LLVM
16
14
  @ptr
17
15
  end
18
16
 
17
+ def ==(other)
18
+ case other
19
+ when LLVM::Module
20
+ @ptr == other.to_ptr
21
+ else
22
+ false
23
+ end
24
+ end
25
+
26
+ def eql?(other)
27
+ other.instance_of?(self.class) && self == other
28
+ end
29
+
19
30
  def self.create(name)
20
31
  new(C.LLVMModuleCreateWithName(name))
21
32
  end
@@ -1,7 +1,6 @@
1
1
  module LLVM
2
2
  # The PassManager runs a queue of passes on a module. See
3
3
  # http://llvm.org/docs/Passes.html for the list of available passes.
4
- # Currently, only scalar transformation passes are supported.
5
4
  class PassManager
6
5
  def initialize(execution_engine)
7
6
  ptr = C.LLVMCreatePassManager()
@@ -18,7 +17,13 @@ module LLVM
18
17
  send(:"#{name}!")
19
18
  self
20
19
  end
21
-
20
+
21
+ def do_initialization
22
+ end
23
+
24
+ def do_finalization
25
+ end
26
+
22
27
  def run(mod)
23
28
  C.LLVMRunPassManager(self, mod)
24
29
  end
@@ -27,4 +32,25 @@ module LLVM
27
32
  C.LLVMDisposePassManager(self)
28
33
  end
29
34
  end
35
+
36
+ class FunctionPassManager < PassManager
37
+ def initialize(execution_engine, mod)
38
+ ptr = C.LLVMCreateFunctionPassManagerForModule(mod)
39
+ C.LLVMAddTargetData(
40
+ C.LLVMGetExecutionEngineTargetData(execution_engine), ptr)
41
+ @ptr = ptr
42
+ end
43
+
44
+ def do_initialization
45
+ C.LLVMInitializeFunctionPassManager(self) != 0
46
+ end
47
+
48
+ def do_finalization
49
+ C.LLVMFinalizeFunctionPassManager(self) != 0
50
+ end
51
+
52
+ def run(fn)
53
+ C.LLVMRunFunctionPassManager(self, fn)
54
+ end
55
+ end
30
56
  end
@@ -1,8 +1,6 @@
1
1
  module LLVM
2
2
  class Type
3
- class << self
4
- private :new
5
- end
3
+ private_class_method :new
6
4
 
7
5
  def initialize(ptr) # :nodoc:
8
6
  @ptr = ptr
@@ -22,6 +20,14 @@ module LLVM
22
20
  end
23
21
  end
24
22
 
23
+ def eql?(other)
24
+ other.instance_of?(self.class) && self == other
25
+ end
26
+
27
+ def kind
28
+ C.LLVMGetTypeKind(self)
29
+ end
30
+
25
31
  def size
26
32
  Int64.from_ptr(C.LLVMSizeOf(self))
27
33
  end
@@ -29,6 +35,25 @@ module LLVM
29
35
  def align
30
36
  Int64.from_ptr(C.LLVMAlignOf(self))
31
37
  end
38
+
39
+ def element_type
40
+ case self.kind
41
+ when :pointer, :vector, :array
42
+ Type.from_ptr(C.LLVMGetElementType(self))
43
+ end
44
+ end
45
+
46
+ def null_pointer
47
+ ConstantExpr.from_ptr(C.LLVMConstPointerNull(self))
48
+ end
49
+
50
+ def null
51
+ ConstantExpr.from_ptr(C.LLVMConstNull(self))
52
+ end
53
+
54
+ def pointer(address_space = 0)
55
+ Type.pointer(self, address_space)
56
+ end
32
57
 
33
58
  def self.from_ptr(ptr)
34
59
  ptr.null? ? nil : new(ptr)
@@ -46,11 +71,11 @@ module LLVM
46
71
  from_ptr(C.LLVMVectorType(LLVM::Type(ty), element_count))
47
72
  end
48
73
 
49
- def self.function(arg_types, result_type)
74
+ def self.function(arg_types, result_type, options = {})
50
75
  arg_types.map! { |ty| LLVM::Type(ty) }
51
76
  arg_types_ptr = FFI::MemoryPointer.new(FFI.type_size(:pointer) * arg_types.size)
52
77
  arg_types_ptr.write_array_of_pointer(arg_types)
53
- from_ptr(C.LLVMFunctionType(LLVM::Type(result_type), arg_types_ptr, arg_types.size, 0))
78
+ from_ptr(C.LLVMFunctionType(LLVM::Type(result_type), arg_types_ptr, arg_types.size, options[:varargs] ? 1 : 0))
54
79
  end
55
80
 
56
81
  def self.struct(elt_types, is_packed)
@@ -99,8 +124,8 @@ module LLVM
99
124
  LLVM::Type.vector(ty, sz)
100
125
  end
101
126
 
102
- def LLVM.Function(argtypes, rettype)
103
- LLVM::Type.function(argtypes, rettype)
127
+ def LLVM.Function(argtypes, rettype, options = {})
128
+ LLVM::Type.function(argtypes, rettype, options)
104
129
  end
105
130
 
106
131
  def LLVM.Struct(*elt_types)
@@ -3,74 +3,89 @@ module LLVM
3
3
  def self.from_ptr(ptr)
4
4
  new(ptr) unless ptr.null?
5
5
  end
6
-
7
- class << self
8
- private :new
9
- end
10
-
6
+
7
+ private_class_method :new
8
+
11
9
  def initialize(ptr)
12
10
  @ptr = ptr
13
11
  end
14
-
12
+
15
13
  def to_ptr # :nodoc:
16
14
  @ptr
17
15
  end
18
-
16
+
17
+ def ==(other)
18
+ case other
19
+ when LLVM::Value
20
+ @ptr == other.to_ptr
21
+ else
22
+ false
23
+ end
24
+ end
25
+
26
+ def eql?(other)
27
+ other.instance_of?(self.class) && self == other
28
+ end
29
+
19
30
  def self.type
20
- raise NotImplementedError, "Value.type is abstract"
31
+ raise NotImplementedError, "#{self.name}.type() is abstract."
21
32
  end
22
-
33
+
23
34
  def self.to_ptr
24
35
  type.to_ptr
25
36
  end
26
-
37
+
27
38
  def type
28
39
  Type.from_ptr(C.LLVMTypeOf(self))
29
40
  end
30
-
41
+
31
42
  def name
32
43
  C.LLVMGetValueName(self)
33
44
  end
34
-
45
+
35
46
  def name=(str)
36
47
  C.LLVMSetValueName(self, str)
37
48
  str
38
49
  end
39
-
50
+
40
51
  def dump
41
52
  C.LLVMDumpValue(self)
42
53
  end
43
-
54
+
44
55
  def constant?
45
56
  case C.LLVMIsConstant(self)
46
57
  when 0 then false
47
58
  when 1 then true
48
59
  end
49
60
  end
50
-
61
+
51
62
  def null?
52
63
  case C.LLVMIsNull(self)
53
64
  when 0 then false
54
65
  when 1 then true
55
66
  end
56
67
  end
57
-
68
+
58
69
  def undefined?
59
70
  case C.LLVMIsUndef(self)
60
71
  when 0 then false
61
72
  when 1 then true
62
73
  end
63
74
  end
64
-
75
+
65
76
  def add_attribute(attr)
66
77
  C.LLVMAddAttribute(self, attr)
67
78
  end
68
79
  end
69
-
80
+
70
81
  class Argument < Value
71
82
  end
72
-
83
+
73
84
  class BasicBlock < Value
85
+ def self.create(fun = nil, name = "")
86
+ self.from_ptr(C.LLVMAppendBasicBlock(fun, name))
87
+ end
88
+
74
89
  def build(builder = nil)
75
90
  if builder.nil?
76
91
  builder = Builder.create
@@ -81,120 +96,238 @@ module LLVM
81
96
  builder.position_at_end(self)
82
97
  yield builder
83
98
  ensure
84
- builder.dispose
99
+ builder.dispose if islocal
100
+ end
101
+
102
+ def parent
103
+ fp = C.LLVMGetBasicBlockParent(self)
104
+ LLVM::Function.from_ptr(fp) unless fp.null?
105
+ end
106
+
107
+ def next
108
+ ptr = C.LLVMGetNextBasicBlock(self)
109
+ BasicBlock.from_ptr(ptr) unless ptr.null?
110
+ end
111
+
112
+ def previous
113
+ ptr = C.LLVMGetPreviousBasicBlock(self)
114
+ BasicBlock.from_ptr(ptr) unless ptr.null?
115
+ end
116
+
117
+ def first_instruction # deprecated
118
+ instructions.first
119
+ end
120
+
121
+ def last_instruction # deprecated
122
+ instructions.last
123
+ end
124
+
125
+ def instructions
126
+ @instructions ||= InstructionCollection.new(self)
127
+ end
128
+
129
+ class InstructionCollection
130
+ include Enumerable
131
+
132
+ def initialize(block)
133
+ @block = block
134
+ end
135
+
136
+ def each
137
+ return to_enum :each unless block_given?
138
+ inst, last = first, last
139
+
140
+ while inst
141
+ yield inst
142
+ break if inst == last
143
+ inst = inst.next
144
+ end
145
+
146
+ self
147
+ end
148
+
149
+ def first
150
+ ptr = C.LLVMGetFirstInstruction(@block)
151
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
152
+ end
153
+
154
+ def last
155
+ ptr = C.LLVMGetLastInstruction(@block)
156
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
157
+ end
85
158
  end
86
159
  end
87
-
88
- class Constant < Value
89
- def self.type
90
- raise NotImplementedError, "Constant.type() is abstract."
160
+
161
+ class User < Value
162
+ def operands
163
+ @operand_collection ||= OperandCollection.new(self)
164
+ end
165
+
166
+ class OperandCollection
167
+ include Enumerable
168
+
169
+ def initialize(user)
170
+ @user = user
171
+ end
172
+
173
+ def [](i)
174
+ ptr = C.LLVMGetOperand(@user, i)
175
+ Value.from_ptr(ptr) unless ptr.null?
176
+ end
177
+
178
+ def []=(i, v)
179
+ C.LLVMSetOperand(@user, i, v)
180
+ end
181
+
182
+ def size
183
+ C.LLVMGetNumOperands(@user)
184
+ end
185
+
186
+ def each
187
+ return to_enum :each unless block_given?
188
+ 0.upto(size-1) { |i| yield self[i] }
189
+ self
190
+ end
91
191
  end
92
-
192
+ end
193
+
194
+ class Constant < User
93
195
  def self.null
94
196
  from_ptr(C.LLVMConstNull(type))
95
197
  end
96
-
198
+
97
199
  def self.undef
98
200
  from_ptr(C.LLVMGetUndef(type))
99
201
  end
100
-
202
+
101
203
  def self.null_ptr
102
204
  from_ptr(C.LLVMConstPointerNull(type))
103
205
  end
206
+
207
+ def bitcast_to(type)
208
+ ConstantExpr.from_ptr(C.LLVMConstBitCast(self, type))
209
+ end
210
+
211
+ def gep(*indices)
212
+ indices = Array(indices)
213
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * indices.size) do |indices_ptr|
214
+ indices_ptr.write_array_of_pointer(indices)
215
+ return ConstantExpr.from_ptr(
216
+ C.LLVMConstGEP(self, indices_ptr, indices.size))
217
+ end
218
+ end
104
219
  end
105
-
220
+
221
+ module Support
222
+ def allocate_pointers(size_or_values, &block)
223
+ if size_or_values.is_a?(Integer)
224
+ raise ArgumentError, 'block not given' unless block_given?
225
+ size = size_or_values
226
+ values = (0...size).map { |i| yield i }
227
+ else
228
+ values = size_or_values
229
+ size = values.size
230
+ end
231
+ FFI::MemoryPointer.new(:pointer, size).write_array_of_pointer(values)
232
+ end
233
+
234
+ module_function :allocate_pointers
235
+ end
236
+
106
237
  class ConstantArray < Constant
107
238
  def self.string(str, null_terminate = true)
108
- from_ptr(C.LLVMConstString(str, null_terminate ? 0 : 1))
239
+ from_ptr(C.LLVMConstString(str, str.length, null_terminate ? 0 : 1))
109
240
  end
110
-
111
- def self.const(type, size)
112
- vals = (0...size).map { |i| yield i }
113
- from_ptr C.LLVMConstArray(type, vals, size)
241
+
242
+ # ConstantArray.const(type, 3) {|i| ... } or
243
+ # ConstantArray.const(type, [...])
244
+ def self.const(type, size_or_values, &block)
245
+ vals = LLVM::Support.allocate_pointers(size_or_values, &block)
246
+ from_ptr C.LLVMConstArray(type, vals, vals.size / vals.type_size)
114
247
  end
115
248
  end
116
-
249
+
117
250
  class ConstantExpr < Constant
118
251
  end
119
-
252
+
120
253
  class ConstantInt < Constant
121
254
  def self.all_ones
122
255
  from_ptr(C.LLVMConstAllOnes(type))
123
256
  end
124
-
257
+
125
258
  def self.from_i(n, signed = true)
126
259
  from_ptr(C.LLVMConstInt(type, n, signed ? 1 : 0))
127
260
  end
128
-
261
+
129
262
  def self.parse(str, radix = 10)
130
263
  from_ptr(C.LLVMConstIntOfString(type, str, radix))
131
264
  end
132
-
265
+
133
266
  def -@
134
267
  self.class.from_ptr(C.LLVMConstNeg(self))
135
268
  end
136
-
269
+
137
270
  def not
138
271
  self.class.from_ptr(C.LLVMConstNot(self))
139
272
  end
140
-
273
+
141
274
  def +(rhs)
142
275
  self.class.from_ptr(C.LLVMConstAdd(self, rhs))
143
276
  end
144
-
277
+
145
278
  def nsw_add(rhs)
146
279
  self.class.from_ptr(C.LLVMConstNSWAdd(self, rhs))
147
280
  end
148
-
281
+
149
282
  def *(rhs)
150
283
  self.class.from_ptr(C.LLVMConstMul(self, rhs))
151
284
  end
152
-
285
+
153
286
  def udiv(rhs)
154
287
  self.class.from_ptr(C.LLVMConstUDiv(self, rhs))
155
288
  end
156
-
289
+
157
290
  def /(rhs)
158
291
  self.class.from_ptr(C.LLVMConstSDiv(self, rhs))
159
292
  end
160
-
293
+
161
294
  def urem(rhs)
162
295
  self.class.from_ptr(C.LLVMConstURem(self, rhs))
163
296
  end
164
-
297
+
165
298
  def rem(rhs)
166
299
  self.class.from_ptr(C.LLVMConstSRem(self, rhs))
167
300
  end
168
-
301
+
169
302
  def and(rhs) # Ruby's && cannot be overloaded
170
303
  self.class.from_ptr(C.LLVMConstAnd(self, rhs))
171
304
  end
172
-
305
+
173
306
  def or(rhs) # Nor is ||.
174
307
  self.class.from_ptr(C.LLVMConstOr(self, rhs))
175
308
  end
176
-
309
+
177
310
  def xor(rhs) # Nor is ||.
178
311
  self.class.from_ptr(C.LLVMConstXor(self, rhs))
179
312
  end
180
-
313
+
181
314
  def icmp(pred, rhs)
182
315
  self.class.from_ptr(C.LLVMConstICmp(pred, self, rhs))
183
316
  end
184
-
317
+
185
318
  def <<(bits)
186
319
  self.class.from_ptr(C.LLVMConstShl(self, rhs))
187
320
  end
188
-
321
+
189
322
  def >>(bits)
190
323
  self.class.from_ptr(C.LLVMConstLShr(self, rhs))
191
324
  end
192
-
325
+
193
326
  def ashr(bits)
194
327
  self.class.from_ptr(C.LLVMConstAShr(self, rhs))
195
328
  end
196
329
  end
197
-
330
+
198
331
  def LLVM.const_missing(const) # :nodoc:
199
332
  case const.to_s
200
333
  when /Int(\d+)/
@@ -212,226 +345,284 @@ module LLVM
212
345
  super
213
346
  end
214
347
  end
215
-
348
+
216
349
  # Native integer type
217
350
  ::LLVM::Int = const_get("Int#{NATIVE_INT_SIZE}")
218
-
351
+
219
352
  def LLVM.Int(val)
220
353
  case val
221
354
  when LLVM::ConstantInt then val
222
355
  when Integer then Int.from_i(val)
223
356
  end
224
357
  end
225
-
358
+
226
359
  class ConstantReal < Constant
227
360
  def self.from_f(n)
228
361
  from_ptr(C.LLVMConstReal(type, n))
229
362
  end
230
-
363
+
231
364
  def self.parse(str)
232
365
  from_ptr(C.LLVMConstRealOfString(type, str))
233
366
  end
234
-
367
+
235
368
  def -@
236
369
  self.class.from_ptr(C.LLVMConstFNeg(self))
237
370
  end
238
-
371
+
239
372
  def +(rhs)
240
373
  self.class.from_ptr(C.LLVMConstFAdd(self, rhs))
241
374
  end
242
-
375
+
243
376
  def *(rhs)
244
377
  self.class.from_ptr(C.LLVMConstFMul(self, rhs))
245
378
  end
246
-
379
+
247
380
  def /(rhs)
248
381
  self.class.from_ptr(C.LLVMConstFDiv(self, rhs))
249
382
  end
250
-
383
+
251
384
  def rem(rhs)
252
385
  self.class.from_ptr(C.LLVMConstFRem(self, rhs))
253
386
  end
254
-
387
+
255
388
  def fcmp(pred, rhs)
256
389
  self.class.from_ptr(C.LLMVConstFCmp(pred, self, rhs))
257
390
  end
258
391
  end
259
-
392
+
260
393
  class Float < ConstantReal
261
394
  def self.type
262
395
  Type.from_ptr(C.LLVMFloatType)
263
396
  end
264
397
  end
265
-
398
+
266
399
  def LLVM.Float(val)
267
400
  Float.from_f(val)
268
401
  end
269
-
402
+
270
403
  class Double < ConstantReal
271
404
  def self.type
272
405
  Type.from_ptr(C.LLVMDoubleType)
273
406
  end
274
407
  end
275
-
408
+
276
409
  def LLVM.Double(val)
277
410
  Double.from_f(val)
278
411
  end
279
-
412
+
280
413
  class ConstantStruct < Constant
281
- def self.const(size, packed = false)
282
- vals = (0..size).map { |i| yield i }
283
- from_ptr(C.LLVMConstStruct(vals, size, packed ? 1 : 0))
414
+ # ConstantStruct.const(size) {|i| ... } or
415
+ # ConstantStruct.const([...])
416
+ def self.const(size_or_values, packed = false, &block)
417
+ vals = LLVM::Support.allocate_pointers(size_or_values, &block)
418
+ from_ptr C.LLVMConstStruct(vals, vals.size / vals.type_size, packed ? 1 : 0)
284
419
  end
285
420
  end
286
-
421
+
287
422
  class ConstantVector < Constant
288
423
  def self.all_ones
289
424
  from_ptr(C.LLVMConstAllOnes(type))
290
425
  end
291
-
292
- def self.const(size)
293
- vals = (0..size).map { |i| yield i }
294
- from_ptr(C.LLVMConstVector(vals, size))
426
+
427
+ def self.const(size_or_values, &block)
428
+ vals = LLVM::Support.allocate_pointers(size_or_values, &block)
429
+ from_ptr(C.LLVMConstVector(vals, vals.size / vals.type_size))
295
430
  end
296
431
  end
297
-
432
+
298
433
  class GlobalValue < Constant
299
434
  def declaration?
300
435
  C.LLVMIsDeclaration(self)
301
436
  end
302
-
437
+
303
438
  def linkage
304
439
  C.LLVMGetLinkage(self)
305
440
  end
306
-
441
+
307
442
  def linkage=(linkage)
308
443
  C.LLVMSetLinkage(self, linkage)
309
444
  end
310
-
445
+
311
446
  def section
312
447
  C.LLVMGetSection(self)
313
448
  end
314
-
449
+
315
450
  def section=(section)
316
451
  C.LLVMSetSection(self, section)
317
452
  end
318
-
453
+
319
454
  def visibility
320
455
  C.LLVMGetVisibility(self)
321
456
  end
322
-
457
+
323
458
  def visibility=(viz)
324
459
  C.LLVMSetVisibility(self, viz)
325
460
  end
326
-
461
+
327
462
  def alignment
328
463
  C.LLVMGetAlignment(self)
329
464
  end
330
-
465
+
331
466
  def alignment=(bytes)
332
467
  C.LLVMSetAlignment(self, bytes)
333
468
  end
469
+
470
+ def initializer
471
+ Value.from_ptr(C.LLVMGetInitializer(self))
472
+ end
473
+
474
+ def initializer=(val)
475
+ C.LLVMSetInitializer(self, val)
476
+ end
477
+
478
+ def global_constant?
479
+ C.LLVMIsGlobalConstant(self)
480
+ end
481
+
482
+ def global_constant=(flag)
483
+ C.LLVMSetGlobalConstant(self, flag)
484
+ end
334
485
  end
335
-
486
+
336
487
  class Function < GlobalValue
337
488
  def call_conv=(conv)
338
489
  C.LLVMSetFunctionCallConv(self, conv)
339
490
  conv
340
491
  end
341
-
492
+
342
493
  def add_attribute(attr)
343
494
  C.LLVMAddFunctionAttr(self, attr)
344
495
  end
345
-
496
+
346
497
  def remove_attribute(attr)
347
498
  C.LLVMRemoveFunctionAttr(self, attr)
348
499
  end
349
-
500
+
350
501
  def basic_blocks
351
502
  @basic_block_collection ||= BasicBlockCollection.new(self)
352
503
  end
353
-
504
+
354
505
  class BasicBlockCollection
506
+ include Enumerable
507
+
355
508
  def initialize(fun)
356
509
  @fun = fun
357
510
  end
358
-
511
+
359
512
  def size
360
513
  C.LLVMCountBasicBlocks(@fun)
361
514
  end
362
-
515
+
516
+ def each
517
+ return to_enum :each unless block_given?
518
+
519
+ ptr = C.LLVMGetFirstBasicBlock(@fun)
520
+ 0.upto(size-1) do |i|
521
+ yield BasicBlock.from_ptr(ptr)
522
+ ptr = C.LLVMGetNextBasicBlock(ptr)
523
+ end
524
+
525
+ self
526
+ end
527
+
363
528
  def append(name = "")
364
- BasicBlock.from_ptr(C.LLVMAppendBasicBlock(@fun, name))
529
+ BasicBlock.create(@fun, name)
365
530
  end
366
-
531
+
367
532
  def entry
368
533
  BasicBlock.from_ptr(C.LLVMGetEntryBasicBlock(@fun))
369
534
  end
535
+
536
+ def first
537
+ ptr = C.LLVMGetFirstBasicBlock(@fun)
538
+ BasicBlock.from_ptr(ptr) unless ptr.null?
539
+ end
540
+
541
+ def last
542
+ ptr = C.LLVMGetLastBasicBlock(@fun)
543
+ BasicBlock.from_ptr(ptr) unless ptr.null?
544
+ end
370
545
  end
371
-
546
+
372
547
  def params
373
548
  @parameter_collection ||= ParameterCollection.new(self)
374
549
  end
375
-
550
+
376
551
  class ParameterCollection
377
552
  def initialize(fun)
378
553
  @fun = fun
379
554
  end
380
-
555
+
381
556
  def [](i)
382
557
  Value.from_ptr(C.LLVMGetParam(@fun, i))
383
558
  end
384
-
559
+
385
560
  def size
386
561
  C.LLVMCountParams(@fun)
387
562
  end
388
-
563
+
389
564
  include Enumerable
390
-
565
+
391
566
  def each
567
+ return to_enum :each unless block_given?
392
568
  0.upto(size-1) { |i| yield self[i] }
569
+ self
393
570
  end
394
571
  end
395
572
  end
396
-
573
+
397
574
  class GlobalAlias < GlobalValue
398
575
  end
399
-
576
+
400
577
  class GlobalVariable < GlobalValue
401
578
  def initializer
402
579
  Value.from_ptr(C.LLVMGetInitializer(self))
403
580
  end
404
-
581
+
405
582
  def initializer=(val)
406
583
  C.LLVMSetInitializer(self, val)
407
584
  end
408
-
585
+
409
586
  def thread_local?
410
587
  case C.LLVMIsThreadLocal(self)
411
588
  when 0 then false
412
589
  else true
413
590
  end
414
591
  end
415
-
592
+
416
593
  def thread_local=(local)
417
594
  C.LLVMSetThreadLocal(self, local ? 1 : 0)
418
595
  end
419
596
  end
420
-
421
- class Instruction < Value
597
+
598
+ class Instruction < User
599
+ def parent
600
+ ptr = C.LLVMGetInstructionParent(self)
601
+ LLVM::BasicBlock.from_ptr(ptr) unless ptr.null?
602
+ end
603
+
604
+ def next
605
+ ptr = C.LLVMGetNextInstruction(self)
606
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
607
+ end
608
+
609
+ def previous
610
+ ptr = C.LLVMGetPreviousInstruction(self)
611
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
612
+ end
422
613
  end
423
-
614
+
424
615
  class CallInst < Instruction
425
616
  def call_conv=(conv)
426
617
  C.LLVMSetInstructionCallConv(self, conv)
427
618
  conv
428
619
  end
429
-
620
+
430
621
  def call_conv
431
622
  C.LLVMGetInstructionCallConv(self)
432
623
  end
433
624
  end
434
-
625
+
435
626
  class Phi < Instruction
436
627
  # Add incoming branches to a phi node by passing an alternating list
437
628
  # of resulting values and basic blocks. e.g.
@@ -441,11 +632,11 @@ module LLVM
441
632
  incoming.each_with_index do |node, i|
442
633
  (i % 2 == 0 ? vals : blocks) << node
443
634
  end
444
-
635
+
445
636
  unless vals.size == blocks.size
446
637
  raise ArgumentError, "Expected vals.size and blocks.size to match"
447
638
  end
448
-
639
+
449
640
  size = vals.size
450
641
  FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |vals_ptr|
451
642
  vals_ptr.write_array_of_pointer(vals)
@@ -454,11 +645,11 @@ module LLVM
454
645
  C.LLVMAddIncoming(self, vals_ptr, blocks_ptr, vals.size)
455
646
  end
456
647
  end
457
-
648
+
458
649
  nil
459
650
  end
460
651
  end
461
-
652
+
462
653
  class SwitchInst < Instruction
463
654
  # Adds a case to a switch instruction. First the value to match on,
464
655
  # then the basic block.