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.
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