ruby-llvm-next 10.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +30 -0
  3. data/README.md +67 -0
  4. data/ext/ruby-llvm-support/Rakefile +110 -0
  5. data/ext/ruby-llvm-support/support.cpp +32 -0
  6. data/lib/llvm.rb +29 -0
  7. data/lib/llvm/analysis.rb +49 -0
  8. data/lib/llvm/analysis_ffi.rb +77 -0
  9. data/lib/llvm/config.rb +10 -0
  10. data/lib/llvm/core.rb +97 -0
  11. data/lib/llvm/core/bitcode.rb +84 -0
  12. data/lib/llvm/core/bitcode_ffi.rb +132 -0
  13. data/lib/llvm/core/builder.rb +944 -0
  14. data/lib/llvm/core/context.rb +24 -0
  15. data/lib/llvm/core/module.rb +240 -0
  16. data/lib/llvm/core/pass_manager.rb +80 -0
  17. data/lib/llvm/core/type.rb +210 -0
  18. data/lib/llvm/core/value.rb +1005 -0
  19. data/lib/llvm/core_ffi.rb +6021 -0
  20. data/lib/llvm/execution_engine.rb +323 -0
  21. data/lib/llvm/execution_engine_ffi.rb +421 -0
  22. data/lib/llvm/linker.rb +16 -0
  23. data/lib/llvm/linker_ffi.rb +44 -0
  24. data/lib/llvm/support.rb +38 -0
  25. data/lib/llvm/target.rb +318 -0
  26. data/lib/llvm/target_ffi.rb +628 -0
  27. data/lib/llvm/transforms/builder.rb +107 -0
  28. data/lib/llvm/transforms/builder_ffi.rb +117 -0
  29. data/lib/llvm/transforms/ipo.rb +78 -0
  30. data/lib/llvm/transforms/ipo_ffi.rb +127 -0
  31. data/lib/llvm/transforms/scalar.rb +152 -0
  32. data/lib/llvm/transforms/scalar_ffi.rb +344 -0
  33. data/lib/llvm/transforms/vectorize.rb +22 -0
  34. data/lib/llvm/transforms/vectorize_ffi.rb +38 -0
  35. data/lib/llvm/version.rb +5 -0
  36. data/test/array_test.rb +38 -0
  37. data/test/basic_block_test.rb +87 -0
  38. data/test/binary_operations_test.rb +58 -0
  39. data/test/bitcode_test.rb +24 -0
  40. data/test/branch_test.rb +57 -0
  41. data/test/call_test.rb +82 -0
  42. data/test/comparisons_test.rb +66 -0
  43. data/test/conversions_test.rb +92 -0
  44. data/test/double_test.rb +34 -0
  45. data/test/equality_test.rb +89 -0
  46. data/test/function_test.rb +100 -0
  47. data/test/generic_value_test.rb +22 -0
  48. data/test/instruction_test.rb +30 -0
  49. data/test/ipo_test.rb +53 -0
  50. data/test/linker_test.rb +37 -0
  51. data/test/mcjit_test.rb +94 -0
  52. data/test/memory_access_test.rb +38 -0
  53. data/test/module_test.rb +93 -0
  54. data/test/parameter_collection_test.rb +28 -0
  55. data/test/pass_manager_builder_test.rb +53 -0
  56. data/test/phi_test.rb +33 -0
  57. data/test/select_test.rb +22 -0
  58. data/test/struct_test.rb +98 -0
  59. data/test/target_test.rb +113 -0
  60. data/test/test_helper.rb +62 -0
  61. data/test/type_test.rb +15 -0
  62. data/test/vector_test.rb +64 -0
  63. metadata +240 -0
@@ -0,0 +1,1005 @@
1
+ module LLVM
2
+ class Value
3
+ include PointerIdentity
4
+
5
+ # @private
6
+ def self.from_ptr(ptr)
7
+ return if ptr.null?
8
+ val = allocate
9
+ val.instance_variable_set(:@ptr, ptr)
10
+ val
11
+ end
12
+
13
+ # Returns the Value type. This is abstract and is overidden by its subclasses.
14
+ def self.type
15
+ raise NotImplementedError, "#{name}.type() is abstract."
16
+ end
17
+
18
+ def self.to_ptr
19
+ type.to_ptr
20
+ end
21
+
22
+ # Returns the value's type.
23
+ def type
24
+ Type.from_ptr(C.type_of(self), nil)
25
+ end
26
+
27
+ # Returns the value's name.
28
+ def name
29
+ C.get_value_name(self)
30
+ end
31
+
32
+ # Sets the value's name to str.
33
+ def name=(str)
34
+ C.set_value_name(self, str)
35
+ str
36
+ end
37
+
38
+ # Print the value's IR to stdout.
39
+ def dump
40
+ C.dump_value(self)
41
+ end
42
+
43
+ # Returns whether the value is constant.
44
+ def constant?
45
+ case C.is_constant(self)
46
+ when 0 then false
47
+ when 1 then true
48
+ end
49
+ end
50
+
51
+ # Returns whether the value is null.
52
+ def null?
53
+ case C.is_null(self)
54
+ when 0 then false
55
+ when 1 then true
56
+ end
57
+ end
58
+
59
+ # Returns whether the value is undefined.
60
+ def undefined?
61
+ case C.is_undef(self)
62
+ when 0 then false
63
+ when 1 then true
64
+ end
65
+ end
66
+
67
+ # Adds attr to this value's attributes.
68
+ def add_attribute(attr)
69
+ fun = param_parent
70
+ return unless fun
71
+
72
+ index = param_index(fun)
73
+ return unless index
74
+
75
+ fun.add_attribute(attr, index)
76
+ end
77
+
78
+ # Removes the given attribute from the function.
79
+ def remove_attribute(attr)
80
+ fun = param_parent
81
+ return unless fun
82
+
83
+ index = param_index(fun)
84
+ return unless index
85
+
86
+ fun.remove_attribute(attr, index)
87
+ end
88
+
89
+ private
90
+
91
+ # get function this param belongs to
92
+ # return if it is not a param
93
+ def param_parent
94
+ valueref = C.get_param_parent(self)
95
+ return if valueref.null?
96
+ fun = LLVM::Function.from_ptr(valueref)
97
+ return if fun.null?
98
+ fun
99
+ end
100
+
101
+ # get index of this param by llvm count (+1 from parametercollection)
102
+ def param_index(fun)
103
+ index = fun.params.find_index(self)
104
+ return if index.nil?
105
+ index + 1
106
+ end
107
+
108
+ end
109
+
110
+ class Argument < Value
111
+ end
112
+
113
+ class BasicBlock < Value
114
+ # Creates a basic block for the given function with the given name.
115
+ def self.create(fun = nil, name = "")
116
+ from_ptr(C.append_basic_block(fun, name))
117
+ end
118
+
119
+ # Build the basic block with the given builder. Creates a new one if nil. Yields the builder.
120
+ def build(builder = nil)
121
+ if builder.nil?
122
+ builder = Builder.new
123
+ builder.position_at_end(self)
124
+ yield builder
125
+ builder.dispose
126
+ else
127
+ builder.position_at_end(self)
128
+ yield builder
129
+ end
130
+ end
131
+
132
+ # Returns the parent of this basic block (a Function).
133
+ def parent
134
+ fp = C.get_basic_block_parent(self)
135
+ LLVM::Function.from_ptr(fp) unless fp.null?
136
+ end
137
+
138
+ # Returns the next basic block in the sequence.
139
+ def next
140
+ ptr = C.get_next_basic_block(self)
141
+ BasicBlock.from_ptr(ptr) unless ptr.null?
142
+ end
143
+
144
+ # Returns the previous basic block in the sequence.
145
+ def previous
146
+ ptr = C.get_previous_basic_block(self)
147
+ BasicBlock.from_ptr(ptr) unless ptr.null?
148
+ end
149
+
150
+ # deprecated
151
+ def first_instruction
152
+ instructions.first
153
+ end
154
+
155
+ # deprecated
156
+ def last_instruction
157
+ instructions.last
158
+ end
159
+
160
+ # Returns an Enumerable of the Instructions in the current block.
161
+ def instructions
162
+ @instructions ||= InstructionCollection.new(self)
163
+ end
164
+
165
+ # @private
166
+ class InstructionCollection
167
+ include Enumerable
168
+
169
+ def initialize(block)
170
+ @block = block
171
+ end
172
+
173
+ # Iterates through each Instruction in the collection.
174
+ def each
175
+ return to_enum :each unless block_given?
176
+ inst, last = first, last
177
+
178
+ while inst
179
+ yield inst
180
+ break if inst == last
181
+ inst = inst.next
182
+ end
183
+
184
+ self
185
+ end
186
+
187
+ # Returns the first Instruction in the collection.
188
+ def first
189
+ ptr = C.get_first_instruction(@block)
190
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
191
+ end
192
+
193
+ # Returns the last Instruction in the collection.
194
+ def last
195
+ ptr = C.get_last_instruction(@block)
196
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
197
+ end
198
+ end
199
+ end
200
+
201
+ class User < Value
202
+ # Returns an Enumerable of the operands in this user.
203
+ def operands
204
+ @operand_collection ||= OperandCollection.new(self)
205
+ end
206
+
207
+ # @private
208
+ class OperandCollection
209
+ include Enumerable
210
+
211
+ def initialize(user)
212
+ @user = user
213
+ end
214
+
215
+ # Get a reference to an operand by index.
216
+ def [](i)
217
+ ptr = C.get_operand(@user, i)
218
+ Value.from_ptr(ptr) unless ptr.null?
219
+ end
220
+
221
+ # Set or replace an operand by index.
222
+ def []=(i, v)
223
+ C.set_operand(@user, i, v)
224
+ end
225
+
226
+ # Returns the number of operands in the collection.
227
+ def size
228
+ C.get_num_operands(@user)
229
+ end
230
+
231
+ # Iterates through each operand in the collection.
232
+ def each
233
+ return to_enum :each unless block_given?
234
+ 0.upto(size - 1) { |i| yield self[i] }
235
+ self
236
+ end
237
+ end
238
+ end
239
+
240
+ class Constant < User
241
+ # Creates a null constant of Type.
242
+ def self.null(type)
243
+ from_ptr(C.const_null(type))
244
+ end
245
+
246
+ # Creates a undefined constant of Type.
247
+ def self.undef(type)
248
+ from_ptr(C.get_undef(type))
249
+ end
250
+
251
+ # Creates a null pointer constant of Type.
252
+ def self.null_ptr(type)
253
+ from_ptr(C.const_pointer_null(type))
254
+ end
255
+
256
+ # Bitcast this constant to Type.
257
+ def bitcast_to(type)
258
+ ConstantExpr.from_ptr(C.const_bit_cast(self, type))
259
+ end
260
+
261
+ # @deprecated
262
+ alias bit_cast bitcast_to
263
+
264
+ # Returns the element pointer at the given indices of the constant.
265
+ # For more information on gep go to: http://llvm.org/docs/GetElementPtr.html
266
+ def gep(*indices)
267
+ indices = Array(indices)
268
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * indices.size) do |indices_ptr|
269
+ indices_ptr.write_array_of_pointer(indices)
270
+ return ConstantExpr.from_ptr(
271
+ C.const_gep(self, indices_ptr, indices.size))
272
+ end
273
+ end
274
+
275
+ # Conversion to integer.
276
+ def ptr_to_int(type)
277
+ ConstantInt.from_ptr(C.const_ptr_to_int(self, type))
278
+ end
279
+ end
280
+
281
+ module Support
282
+ def allocate_pointers(size_or_values, &block)
283
+ if size_or_values.is_a?(Integer)
284
+ raise ArgumentError, 'block not given' unless block_given?
285
+ size = size_or_values
286
+ values = (0...size).map { |i| yield i }
287
+ else
288
+ values = size_or_values
289
+ size = values.size
290
+ end
291
+ FFI::MemoryPointer.new(:pointer, size).write_array_of_pointer(values)
292
+ end
293
+
294
+ module_function :allocate_pointers
295
+ end
296
+
297
+ class ConstantArray < Constant
298
+ def self.string(str, null_terminate = true)
299
+ from_ptr(C.const_string(str, str.length, null_terminate ? 0 : 1))
300
+ end
301
+
302
+ # ConstantArray.const(type, 3) {|i| ... } or
303
+ # ConstantArray.const(type, [...])
304
+ def self.const(type, size_or_values, &block)
305
+ vals = LLVM::Support.allocate_pointers(size_or_values, &block)
306
+ from_ptr C.const_array(type, vals, vals.size / vals.type_size)
307
+ end
308
+
309
+ def size
310
+ C.get_array_length(type)
311
+ end
312
+ end
313
+
314
+ class ConstantExpr < Constant
315
+ end
316
+
317
+ class ConstantInt < Constant
318
+ def self.all_ones
319
+ from_ptr(C.const_all_ones(type))
320
+ end
321
+
322
+ # Creates a ConstantInt from an integer.
323
+ def self.from_i(n, signed = true)
324
+ from_ptr(C.const_int(type, n, signed ? 1 : 0))
325
+ end
326
+
327
+ def self.parse(str, radix = 10)
328
+ from_ptr(C.const_int_of_string(type, str, radix))
329
+ end
330
+
331
+ # Negation.
332
+ def -@
333
+ self.class.from_ptr(C.const_neg(self))
334
+ end
335
+
336
+ alias neg -@
337
+
338
+ # "No signed wrap" negation.
339
+ def nsw_neg
340
+ self.class.from_ptr(C.const_nsw_neg(self))
341
+ end
342
+
343
+ # "No unsigned wrap" negation.
344
+ def nuw_neg
345
+ self.class.from_ptr(C.const_nuw_neg(self))
346
+ end
347
+
348
+ # Addition.
349
+ def +(rhs)
350
+ self.class.from_ptr(C.const_add(self, rhs))
351
+ end
352
+
353
+ alias add +
354
+
355
+ # "No signed wrap" addition.
356
+ def nsw_add(rhs)
357
+ self.class.from_ptr(C.const_nsw_add(self, rhs))
358
+ end
359
+
360
+ # "No unsigned wrap" addition.
361
+ def nuw_add(rhs)
362
+ self.class.from_ptr(C.const_nuw_add(self, rhs))
363
+ end
364
+
365
+ # Subtraction.
366
+ def -(rhs)
367
+ self.class.from_ptr(C.const_sub(self, rhs))
368
+ end
369
+
370
+ alias sub -
371
+
372
+ # "No signed wrap" subtraction.
373
+ def nsw_sub(rhs)
374
+ self.class.from_ptr(C.const_nsw_sub(self, rhs))
375
+ end
376
+
377
+ # "No unsigned wrap" subtraction.
378
+ def nuw_sub(rhs)
379
+ self.class.from_ptr(C.const_nuw_sub(self, rhs))
380
+ end
381
+
382
+ # Multiplication.
383
+ def *(rhs)
384
+ self.class.from_ptr(C.const_mul(self, rhs))
385
+ end
386
+
387
+ alias mul *
388
+
389
+ # "No signed wrap" multiplication.
390
+ def nsw_mul(rhs)
391
+ self.class.from_ptr(C.const_nsw_mul(self, rhs))
392
+ end
393
+
394
+ # "No unsigned wrap" multiplication.
395
+ def nuw_mul(rhs)
396
+ self.class.from_ptr(C.const_nuw_mul(self, rhs))
397
+ end
398
+
399
+ # Unsigned division.
400
+ def udiv(rhs)
401
+ self.class.from_ptr(C.const_u_div(self, rhs))
402
+ end
403
+
404
+ # Signed division.
405
+ def /(rhs)
406
+ self.class.from_ptr(C.const_s_div(self, rhs))
407
+ end
408
+
409
+ # Unsigned remainder.
410
+ def urem(rhs)
411
+ self.class.from_ptr(C.const_u_rem(self, rhs))
412
+ end
413
+
414
+ # Signed remainder.
415
+ def rem(rhs)
416
+ self.class.from_ptr(C.const_s_rem(self, rhs))
417
+ end
418
+
419
+ # Boolean negation.
420
+ def ~@
421
+ self.class.from_ptr(C.const_not(self))
422
+ end
423
+
424
+ alias not ~
425
+
426
+ # Integer AND.
427
+ def &(rhs)
428
+ self.class.from_ptr(C.const_and(self, rhs))
429
+ end
430
+
431
+ alias and &
432
+
433
+ # Integer OR.
434
+ def |(rhs)
435
+ self.class.from_ptr(C.const_or(self, rhs))
436
+ end
437
+
438
+ alias or |
439
+
440
+ # Integer XOR.
441
+ def ^(rhs)
442
+ self.class.from_ptr(C.const_xor(self, rhs))
443
+ end
444
+
445
+ alias xor ^
446
+
447
+ # Shift left.
448
+ def <<(bits)
449
+ self.class.from_ptr(C.const_shl(self, bits))
450
+ end
451
+
452
+ alias shl <<
453
+
454
+ # Shift right.
455
+ def >>(bits)
456
+ self.class.from_ptr(C.const_l_shr(self, bits))
457
+ end
458
+
459
+ alias shr >>
460
+
461
+ # Arithmatic shift right.
462
+ def ashr(bits)
463
+ self.class.from_ptr(C.const_a_shr(self, bits))
464
+ end
465
+
466
+ # Integer comparison using the predicate specified via the first parameter.
467
+ # Predicate can be any of:
468
+ # :eq - equal to
469
+ # :ne - not equal to
470
+ # :ugt - unsigned greater than
471
+ # :uge - unsigned greater than or equal to
472
+ # :ult - unsigned less than
473
+ # :ule - unsigned less than or equal to
474
+ # :sgt - signed greater than
475
+ # :sge - signed greater than or equal to
476
+ # :slt - signed less than
477
+ # :sle - signed less than or equal to
478
+ def icmp(pred, rhs)
479
+ self.class.from_ptr(C.const_i_cmp(pred, self, rhs))
480
+ end
481
+
482
+ # Conversion to pointer.
483
+ def int_to_ptr(type)
484
+ ConstantExpr.from_ptr(C.const_int_to_ptr(self, type))
485
+ end
486
+ end
487
+
488
+ def self.const_missing(const)
489
+ case const.to_s
490
+ when /Int(\d+)/
491
+ width = Regexp.last_match(1).to_i
492
+ name = "Int#{width}"
493
+ eval <<-KLASS
494
+ class #{name} < ConstantInt
495
+ def self.type
496
+ Type.from_ptr(C.int_type(#{width}), :integer)
497
+ end
498
+ end
499
+ KLASS
500
+ const_get(name)
501
+ else
502
+ super
503
+ end
504
+ end
505
+
506
+ # Native integer type
507
+ bits = FFI.type_size(:int) * 8
508
+ ::LLVM::Int = const_get("Int#{bits}")
509
+
510
+ # Creates a LLVM Int (subclass of ConstantInt) at the NATIVE_INT_SIZE from a integer (val).
511
+ def self.Int(val)
512
+ case val
513
+ when LLVM::ConstantInt then val
514
+ when Integer then Int.from_i(val)
515
+ when Value
516
+ return val if val.type.kind == :integer
517
+ raise "value not of integer type: #{val.type.kind}"
518
+ else raise "can't make an LLVM::ConstantInt from #{val.class.name}"
519
+ end
520
+ end
521
+
522
+ # Boolean values
523
+ ::LLVM::TRUE = ::LLVM::Int1.from_i(-1)
524
+ ::LLVM::FALSE = ::LLVM::Int1.from_i(0)
525
+
526
+ class ConstantReal < Constant
527
+ # Creates a ConstantReal from a float of Type.
528
+ def self.from_f(n)
529
+ from_ptr(C.const_real(type, n))
530
+ end
531
+
532
+ def self.parse(type, str)
533
+ from_ptr(C.const_real_of_string(type, str))
534
+ end
535
+
536
+ # Negation.
537
+ def -@
538
+ self.class.from_ptr(C.const_f_neg(self))
539
+ end
540
+
541
+ # Returns the result of adding this ConstantReal to rhs.
542
+ def +(rhs)
543
+ self.class.from_ptr(C.const_f_add(self, rhs))
544
+ end
545
+
546
+ # Returns the result of multiplying this ConstantReal by rhs.
547
+ def *(rhs)
548
+ self.class.from_ptr(C.const_f_mul(self, rhs))
549
+ end
550
+
551
+ # Returns the result of dividing this ConstantReal by rhs.
552
+ def /(rhs)
553
+ self.class.from_ptr(C.const_f_div(self, rhs))
554
+ end
555
+
556
+ # Remainder.
557
+ def rem(rhs)
558
+ self.class.from_ptr(C.const_f_rem(self, rhs))
559
+ end
560
+
561
+ # Floating point comparison using the predicate specified via the first
562
+ # parameter. Predicate can be any of:
563
+ # :ord - ordered
564
+ # :uno - unordered: isnan(X) | isnan(Y)
565
+ # :oeq - ordered and equal to
566
+ # :oeq - unordered and equal to
567
+ # :one - ordered and not equal to
568
+ # :one - unordered and not equal to
569
+ # :ogt - ordered and greater than
570
+ # :uge - unordered and greater than or equal to
571
+ # :olt - ordered and less than
572
+ # :ule - unordered and less than or equal to
573
+ # :oge - ordered and greater than or equal to
574
+ # :sge - unordered and greater than or equal to
575
+ # :ole - ordered and less than or equal to
576
+ # :sle - unordered and less than or equal to
577
+ # :true - always true
578
+ # :false- always false
579
+ def fcmp(pred, rhs)
580
+ self.class.from_ptr(C.llmv_const_f_cmp(pred, self, rhs))
581
+ end
582
+ end
583
+
584
+ class Float < ConstantReal
585
+ # Return a Type representation of the float.
586
+ def self.type
587
+ Type.from_ptr(C.float_type, :float)
588
+ end
589
+ end
590
+
591
+ # Create a LLVM::Float from a Ruby Float (val).
592
+ def self.Float(val)
593
+ Float.from_f(val)
594
+ end
595
+
596
+ class Double < ConstantReal
597
+ def self.type
598
+ Type.from_ptr(C.double_type, :double)
599
+ end
600
+ end
601
+
602
+ def self.Double(val)
603
+ Double.from_f(val)
604
+ end
605
+
606
+ class ConstantStruct < Constant
607
+ # ConstantStruct.const(size) {|i| ... } or
608
+ # ConstantStruct.const([...])
609
+ def self.const(size_or_values, packed = false, &block)
610
+ vals = LLVM::Support.allocate_pointers(size_or_values, &block)
611
+ from_ptr C.const_struct(vals, vals.size / vals.type_size, packed ? 1 : 0)
612
+ end
613
+
614
+ def self.named_const(type, size_or_values, &block)
615
+ vals = LLVM::Support.allocate_pointers(size_or_values, &block)
616
+ from_ptr C.const_named_struct(type, vals, vals.size / vals.type_size)
617
+ end
618
+ end
619
+
620
+ class ConstantVector < Constant
621
+ def self.all_ones
622
+ from_ptr(C.const_all_ones(type))
623
+ end
624
+
625
+ def self.const(size_or_values, &block)
626
+ vals = LLVM::Support.allocate_pointers(size_or_values, &block)
627
+ from_ptr(C.const_vector(vals, vals.size / vals.type_size))
628
+ end
629
+
630
+ def size
631
+ C.get_vector_size(type)
632
+ end
633
+ end
634
+
635
+ class GlobalValue < Constant
636
+ def declaration?
637
+ C.is_declaration(self)
638
+ end
639
+
640
+ def linkage
641
+ C.get_linkage(self)
642
+ end
643
+
644
+ def linkage=(linkage)
645
+ C.set_linkage(self, linkage)
646
+ end
647
+
648
+ def section
649
+ C.get_section(self)
650
+ end
651
+
652
+ def section=(section)
653
+ C.set_section(self, section)
654
+ end
655
+
656
+ def visibility
657
+ C.get_visibility(self)
658
+ end
659
+
660
+ def visibility=(viz)
661
+ C.set_visibility(self, viz)
662
+ end
663
+
664
+ def alignment
665
+ C.get_alignment(self)
666
+ end
667
+
668
+ def alignment=(bytes)
669
+ C.set_alignment(self, bytes)
670
+ end
671
+
672
+ def initializer
673
+ Value.from_ptr(C.get_initializer(self))
674
+ end
675
+
676
+ def initializer=(val)
677
+ C.set_initializer(self, val)
678
+ end
679
+
680
+ def global_constant?
681
+ C.is_global_constant(self) != 0
682
+ end
683
+
684
+ def global_constant=(flag)
685
+ if flag.kind_of?(Integer)
686
+ warn 'Warning: Passing Integer value to LLVM::GlobalValue#global_constant=(Boolean) is deprecated.'
687
+ flag = !flag.zero?
688
+ end
689
+
690
+ C.set_global_constant(self, flag ? 1 : 0)
691
+ end
692
+
693
+ def unnamed_addr?
694
+ C.has_unnamed_addr(self) != 0
695
+ end
696
+
697
+ def unnamed_addr=(flag)
698
+ C.set_unnamed_addr(self, flag ? 1 : 0)
699
+ end
700
+
701
+ def dll_storage_class
702
+ C.get_dll_storage_class(self)
703
+ end
704
+
705
+ def dll_storage_class=(klass)
706
+ C.set_dll_storage_class(self, klass)
707
+ end
708
+ end
709
+
710
+ class Function < GlobalValue
711
+ # Sets the function's calling convention and returns it.
712
+ def call_conv=(conv)
713
+ C.set_function_call_conv(self, conv)
714
+ conv
715
+ end
716
+
717
+ # Returns an Enumerable of the BasicBlocks in this function.
718
+ def basic_blocks
719
+ @basic_block_collection ||= BasicBlockCollection.new(self)
720
+ end
721
+
722
+ def type
723
+ Type.from_ptr(C.type_of(self), :pointer)
724
+ end
725
+
726
+ def function_type
727
+ type.element_type
728
+ end
729
+
730
+ # Adds attr to this value's attributes.
731
+ def add_attribute(attr, index = -1)
732
+ AttributeCollection.new(self, index).add(attr)
733
+ end
734
+
735
+ # Removes the given attribute from the function.
736
+ def remove_attribute(attr, index = -1)
737
+ AttributeCollection.new(self, index).remove(attr)
738
+ end
739
+
740
+ def attribute_count
741
+ function_attributes.count
742
+ end
743
+
744
+ def attributes
745
+ function_attributes.to_a
746
+ end
747
+
748
+ def function_attributes
749
+ AttributeCollection.new(self, -1)
750
+ end
751
+
752
+ def return_attributes
753
+ AttributeCollection.new(self, 0)
754
+ end
755
+
756
+ def param_attributes(index)
757
+ AttributeCollection.new(self, index)
758
+ end
759
+
760
+ class AttributeCollection
761
+
762
+ def initialize(fun, index)
763
+ @fun = fun
764
+ @index = index
765
+ end
766
+
767
+ def add(attr)
768
+ attr_kind_id = attribute_id(attr)
769
+ ctx = Context.global
770
+ attr_ref = C.create_enum_attribute(ctx, attr_kind_id, 0)
771
+ C.add_attribute_at_index(@fun, @index, attr_ref)
772
+ end
773
+
774
+ def remove(attr)
775
+ attr_kind_id = attribute_id(attr)
776
+ C.remove_enum_attribute_at_index(@fun, @index, attr_kind_id)
777
+ end
778
+
779
+ def count
780
+ C.get_attribute_count_at_index(@fun, @index)
781
+ end
782
+
783
+ def to_a
784
+ attr_refs = nil
785
+ n = count
786
+ FFI::MemoryPointer.new(:pointer, n) do |p|
787
+ C.get_attributes_at_index(@fun, @index, p)
788
+ attr_refs = p.read_array_of_type(:pointer, :read_pointer, n)
789
+ end
790
+
791
+ attr_refs.map { |e| C.get_enum_attribute_kind(e) }
792
+ end
793
+
794
+ private
795
+
796
+ def attribute_name(attr_name)
797
+ attr_name = attr_name.to_s
798
+ if attr_name =~ /_attribute$/
799
+ attr_name.chomp('_attribute').tr('_', '')
800
+ else
801
+ attr_name
802
+ end
803
+ end
804
+
805
+ def attribute_id(attr_name)
806
+ attr_mem = FFI::MemoryPointer.from_string(attribute_name(attr_name))
807
+ attr_kind_id = C.get_enum_attribute_kind_for_name(attr_mem, attr_mem.size - 1)
808
+
809
+ raise "No attribute named: #{attr_name}" if attr_kind_id.zero?
810
+ attr_kind_id
811
+ end
812
+ end
813
+
814
+ # @private
815
+ class BasicBlockCollection
816
+ include Enumerable
817
+
818
+ def initialize(fun)
819
+ @fun = fun
820
+ end
821
+
822
+ # Returns the number of BasicBlocks in the collection.
823
+ def size
824
+ C.count_basic_blocks(@fun)
825
+ end
826
+
827
+ # Iterates through each BasicBlock in the collection.
828
+ def each
829
+ return to_enum :each unless block_given?
830
+
831
+ ptr = C.get_first_basic_block(@fun)
832
+ 0.upto(size - 1) do |i|
833
+ yield BasicBlock.from_ptr(ptr)
834
+ ptr = C.get_next_basic_block(ptr)
835
+ end
836
+
837
+ self
838
+ end
839
+
840
+ # Adds a BasicBlock with the given name to the end of the collection.
841
+ def append(name = "")
842
+ BasicBlock.create(@fun, name)
843
+ end
844
+
845
+ # Returns the entry BasicBlock in the collection. This is the block the
846
+ # function starts on.
847
+ def entry
848
+ BasicBlock.from_ptr(C.get_entry_basic_block(@fun))
849
+ end
850
+
851
+ # Returns the first BasicBlock in the collection.
852
+ def first
853
+ ptr = C.get_first_basic_block(@fun)
854
+ BasicBlock.from_ptr(ptr) unless ptr.null?
855
+ end
856
+
857
+ # Returns the last BasicBlock in the collection.
858
+ def last
859
+ ptr = C.get_last_basic_block(@fun)
860
+ BasicBlock.from_ptr(ptr) unless ptr.null?
861
+ end
862
+ end
863
+
864
+ # Returns an Enumerable of the parameters in the function.
865
+ def params
866
+ @parameter_collection ||= ParameterCollection.new(self)
867
+ end
868
+
869
+ # @private
870
+ class ParameterCollection
871
+ def initialize(fun)
872
+ @fun = fun
873
+ end
874
+
875
+ # Returns a Value representation of the parameter at the given index.
876
+ def [](i)
877
+ sz = size
878
+ i = sz + i if i < 0
879
+ return unless 0 <= i && i < sz
880
+ Value.from_ptr(C.get_param(@fun, i))
881
+ end
882
+
883
+ # Returns the number of paramters in the collection.
884
+ def size
885
+ C.count_params(@fun)
886
+ end
887
+
888
+ include Enumerable
889
+
890
+ # Iteraters through each parameter in the collection.
891
+ def each
892
+ return to_enum :each unless block_given?
893
+ 0.upto(size - 1) { |i| yield self[i] }
894
+ self
895
+ end
896
+ end
897
+
898
+ def gc=(name)
899
+ C.set_gc(self, name)
900
+ end
901
+
902
+ def gc
903
+ C.get_gc(self)
904
+ end
905
+ end
906
+
907
+ class GlobalAlias < GlobalValue
908
+ end
909
+
910
+ class GlobalVariable < GlobalValue
911
+ def initializer
912
+ Value.from_ptr(C.get_initializer(self))
913
+ end
914
+
915
+ def initializer=(val)
916
+ C.set_initializer(self, val)
917
+ end
918
+
919
+ def thread_local?
920
+ case C.is_thread_local(self)
921
+ when 0 then false
922
+ else true
923
+ end
924
+ end
925
+
926
+ def thread_local=(local)
927
+ C.set_thread_local(self, local ? 1 : 0)
928
+ end
929
+ end
930
+
931
+ class Instruction < User
932
+ # Returns the parent of the instruction (a BasicBlock).
933
+ def parent
934
+ ptr = C.get_instruction_parent(self)
935
+ LLVM::BasicBlock.from_ptr(ptr) unless ptr.null?
936
+ end
937
+
938
+ # Returns the next instruction after this one.
939
+ def next
940
+ ptr = C.get_next_instruction(self)
941
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
942
+ end
943
+
944
+ # Returns the previous instruction before this one.
945
+ def previous
946
+ ptr = C.get_previous_instruction(self)
947
+ LLVM::Instruction.from_ptr(ptr) unless ptr.null?
948
+ end
949
+ end
950
+
951
+ class CallInst < Instruction
952
+ # Sets the call convention to conv.
953
+ def call_conv=(conv)
954
+ C.set_instruction_call_conv(self, conv)
955
+ conv
956
+ end
957
+
958
+ # Returns the call insatnce's call convention.
959
+ def call_conv
960
+ C.get_instruction_call_conv(self)
961
+ end
962
+ end
963
+
964
+ # @private
965
+ class Phi < Instruction
966
+ # Add incoming branches to a phi node by passing an alternating list of
967
+ # resulting values and BasicBlocks. e.g.
968
+ # phi.add_incoming(val1, block1, val2, block2, ...)
969
+ def add_incoming(incoming)
970
+ blks = incoming.keys
971
+ vals = incoming.values_at(*blks)
972
+ size = incoming.size
973
+
974
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |vals_ptr|
975
+ vals_ptr.write_array_of_pointer(vals)
976
+ FFI::MemoryPointer.new(FFI.type_size(:pointer) * size) do |blks_ptr|
977
+ blks_ptr.write_array_of_pointer(blks)
978
+ C.add_incoming(self, vals_ptr, blks_ptr, vals.size)
979
+ end
980
+ end
981
+
982
+ nil
983
+ end
984
+ end
985
+
986
+ # @private
987
+ class SwitchInst < Instruction
988
+ # Adds a case to a switch instruction. First the value to match on, then
989
+ # the basic block.
990
+ def add_case(val, block)
991
+ C.add_case(self, val, block)
992
+ end
993
+ end
994
+
995
+
996
+ # @private
997
+ class IndirectBr < Instruction
998
+ # Adds a basic block reference as a destination for this indirect branch.
999
+ def add_dest(dest)
1000
+ C.add_destination(self, dest)
1001
+ end
1002
+
1003
+ alias :<< :add_dest
1004
+ end
1005
+ end