rltk3 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/AUTHORS +1 -0
  3. data/LICENSE +27 -0
  4. data/README.md +852 -0
  5. data/Rakefile +197 -0
  6. data/lib/rltk/ast.rb +573 -0
  7. data/lib/rltk/cfg.rb +683 -0
  8. data/lib/rltk/cg/basic_block.rb +157 -0
  9. data/lib/rltk/cg/bindings.rb +151 -0
  10. data/lib/rltk/cg/builder.rb +1127 -0
  11. data/lib/rltk/cg/context.rb +48 -0
  12. data/lib/rltk/cg/contractor.rb +51 -0
  13. data/lib/rltk/cg/execution_engine.rb +194 -0
  14. data/lib/rltk/cg/function.rb +237 -0
  15. data/lib/rltk/cg/generated_bindings.rb +8118 -0
  16. data/lib/rltk/cg/generic_value.rb +95 -0
  17. data/lib/rltk/cg/instruction.rb +519 -0
  18. data/lib/rltk/cg/llvm.rb +150 -0
  19. data/lib/rltk/cg/memory_buffer.rb +75 -0
  20. data/lib/rltk/cg/module.rb +451 -0
  21. data/lib/rltk/cg/pass_manager.rb +252 -0
  22. data/lib/rltk/cg/support.rb +29 -0
  23. data/lib/rltk/cg/target.rb +230 -0
  24. data/lib/rltk/cg/triple.rb +58 -0
  25. data/lib/rltk/cg/type.rb +554 -0
  26. data/lib/rltk/cg/value.rb +1272 -0
  27. data/lib/rltk/cg.rb +32 -0
  28. data/lib/rltk/lexer.rb +372 -0
  29. data/lib/rltk/lexers/calculator.rb +44 -0
  30. data/lib/rltk/lexers/ebnf.rb +38 -0
  31. data/lib/rltk/parser.rb +1702 -0
  32. data/lib/rltk/parsers/infix_calc.rb +43 -0
  33. data/lib/rltk/parsers/postfix_calc.rb +34 -0
  34. data/lib/rltk/parsers/prefix_calc.rb +34 -0
  35. data/lib/rltk/token.rb +90 -0
  36. data/lib/rltk/version.rb +11 -0
  37. data/lib/rltk.rb +16 -0
  38. data/test/cg/tc_basic_block.rb +83 -0
  39. data/test/cg/tc_control_flow.rb +191 -0
  40. data/test/cg/tc_function.rb +54 -0
  41. data/test/cg/tc_generic_value.rb +33 -0
  42. data/test/cg/tc_instruction.rb +256 -0
  43. data/test/cg/tc_llvm.rb +25 -0
  44. data/test/cg/tc_math.rb +88 -0
  45. data/test/cg/tc_module.rb +89 -0
  46. data/test/cg/tc_transforms.rb +68 -0
  47. data/test/cg/tc_type.rb +69 -0
  48. data/test/cg/tc_value.rb +151 -0
  49. data/test/cg/ts_cg.rb +23 -0
  50. data/test/tc_ast.rb +332 -0
  51. data/test/tc_cfg.rb +164 -0
  52. data/test/tc_lexer.rb +216 -0
  53. data/test/tc_parser.rb +711 -0
  54. data/test/tc_token.rb +34 -0
  55. data/test/ts_rltk.rb +47 -0
  56. metadata +317 -0
@@ -0,0 +1,95 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/04/18
4
+ # Description: This file defines the GenericValue class.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Ruby Language Toolkit
11
+ require 'rltk/cg/bindings'
12
+ require 'rltk/cg/type'
13
+
14
+ #######################
15
+ # Classes and Modules #
16
+ #######################
17
+
18
+ module RLTK::CG
19
+
20
+ # GenericValue objects are used to pass parameters into
21
+ # {ExecutionEngine ExecutionEngines} as well as retreive an evaluated
22
+ # function's result. They may contain values of several different types:
23
+ #
24
+ # * Integer
25
+ # * Float
26
+ # * Boolean
27
+ class GenericValue
28
+ include BindingClass
29
+
30
+ # The Proc object called by the garbage collector to free resources used by LLVM.
31
+ CLASS_FINALIZER = Proc.new { |id| Bindings.dispose_generic_value(ptr) if ptr = ObjectSpace._id2ref(id).ptr }
32
+
33
+ # @return [Type] LLVM type of this GenericValue.
34
+ attr_reader :type
35
+
36
+ # Creates a new GenericValue from a given Ruby value.
37
+ #
38
+ # @param [FFI::Pointer, Integer, ::Float, Boolean] ruby_val
39
+ # @param [Type] type Type of Integer or Float to create.
40
+ # @param [Boolean] signed Signed or unsigned Integer.
41
+ def initialize(ruby_val, type = nil, signed = true)
42
+ @ptr, @type =
43
+ case ruby_val
44
+ when FFI::Pointer
45
+ [ruby_val, nil]
46
+
47
+ when ::Integer
48
+ type = if type then check_cg_type(type, IntType) else NativeIntType.instance end
49
+
50
+ [Bindings.create_generic_value_of_int(type, ruby_val, signed.to_i), type]
51
+
52
+ when ::Float
53
+ type = if type then check_cg_type(type, RealType) else FloatType.instance end
54
+
55
+ [Bindings.create_generic_value_of_float(type, ruby_val), type]
56
+
57
+ when TrueClass
58
+ [Bindings.create_generic_value_of_int(Int1Type, 1, 0), Int1Type]
59
+
60
+ when FalseClass
61
+ [Bindings.create_generic_value_of_int(Int1Type, 0, 0), Int1Type]
62
+ end
63
+
64
+ # Define a finalizer to free the memory used by LLVM for this
65
+ # generic value.
66
+ ObjectSpace.define_finalizer(self, CLASS_FINALIZER)
67
+ end
68
+
69
+ # @param [Boolean] signed Treat the GenericValue as a signed integer.
70
+ #
71
+ # @return [Integer]
72
+ def to_i(signed = true)
73
+ val = Bindings.generic_value_to_int(@ptr, signed.to_i)
74
+
75
+ if signed and val >= 2**63 then val - 2**64 else val end
76
+ end
77
+
78
+ # @param [FloatType] type Type of the real value stored in this GenericValue.
79
+ #
80
+ # @return [Float]
81
+ def to_f(type = RLTK::CG::FloatType)
82
+ Bindings.generic_value_to_float(@type || check_cg_type(type, RLTK::CG::NumberType), @ptr)
83
+ end
84
+
85
+ # @return [Boolean]
86
+ def to_bool
87
+ self.to_i(false).to_bool
88
+ end
89
+
90
+ # @return [FFI::Pointer] GenericValue as a pointer.
91
+ def to_ptr_value
92
+ Bindings.generic_value_to_pointer(@ptr)
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,519 @@
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Ruby Language Toolkit
3
+ # Date: 2012/04/09
4
+ # Description: This file defines LLVM Instruction classes.
5
+
6
+ ############
7
+ # Requires #
8
+ ############
9
+
10
+ # Ruby Language Toolkit
11
+ require 'rltk/cg/bindings'
12
+ require 'rltk/cg/value'
13
+
14
+ #######################
15
+ # Classes and Modules #
16
+ #######################
17
+
18
+ module RLTK::CG
19
+
20
+ # This class represents LLVM IR instructions.
21
+ class Instruction < User
22
+
23
+ # Many of the C functions for interacting with instructions treat
24
+ # all instructions as Instruction objects. However, some Instruction
25
+ # sub-types can be tested for. This is a list of those sub-types and
26
+ # the names of their tests.
27
+ TESTABLE = [
28
+ :AddrSpaceCast,
29
+ :Alloca,
30
+ :BitCast,
31
+ :Call,
32
+ :ExtractElement,
33
+ :ExtractValue,
34
+ :FCmp,
35
+ [:FPExtend, :FPExt],
36
+ :FPToSI,
37
+ :FPToUI,
38
+ :FPTrunc,
39
+ :GetElementPtr,
40
+ [:IntCmp, :ICmp],
41
+ :InsertElement,
42
+ :InsertValue,
43
+ :IntToPtr,
44
+ :Invoke,
45
+ :Load,
46
+ :PtrToInt,
47
+ :Return,
48
+ [:SignExtend, :SExt],
49
+ :SIToFP,
50
+ :Select,
51
+ :ShuffleVector,
52
+ :Store,
53
+ :Switch,
54
+ [:Truncate, :Trunc],
55
+ :UIToFP,
56
+ :Unreachable
57
+ ]
58
+
59
+ # Instantiate an Instruction object from a given pointer. The type
60
+ # of the instruction is tested and the appropriate sub-type is picked
61
+ # if possible. If not, a generic Instruction object is returned.
62
+ #
63
+ # @param [FFI::Pointer] ptr Pointer to a C instruction object.
64
+ #
65
+ # @return [Instruction] An Instruction or one of its sub-types.
66
+ def self.from_ptr(ptr)
67
+ match = nil
68
+
69
+ TESTABLE.each do |el|
70
+ klass, test =
71
+ if el.is_a?(Symbol)
72
+ [RLTK::CG.const_get("#{el}Inst".to_sym), Bindings.get_bname("IsA#{el}Inst")]
73
+
74
+ else
75
+ [RLTK::CG.const_get("#{el.first}Inst".to_sym), Bindings.get_bname("IsA#{el.last}Inst")]
76
+ end
77
+
78
+ match = klass if Bindings.send(test, ptr)
79
+ end
80
+
81
+ if match then match else Intruction end.new(ptr)
82
+ end
83
+
84
+ # You should never instantiate Instruction object directly. Use the
85
+ # builder class to add new instructions.
86
+ #
87
+ # @param [FFI::Pointer] ptr Pointer to a C instruction object.
88
+ def initialize(ptr)
89
+ @ptr = check_type(ptr, FFI::Pointer, 'ptr')
90
+ end
91
+
92
+ # @return [Instruction, nil] Instruction that follows the current one in a {BasicBlock}.
93
+ def next
94
+ if (ptr = Bindings.get_next_instruction(@ptr)).null? then nil else Instruction.from_ptr(ptr) end
95
+ end
96
+
97
+ # @return [BasicBlock] BasicBlock that contains this Instruction.
98
+ def parent
99
+ if (ptr = Bindings.get_instruction_parent(@ptr)).null? then nil else BasicBlock.new(ptr) end
100
+ end
101
+
102
+ # @return [Instruction, nil] Instruction that precedes the current on in a {BasicBlock}.
103
+ def previous
104
+ if (ptr = Bindings.get_previous_instruction(@ptr)).null? then nil else Instruction.from_ptr(ptr) end
105
+ end
106
+
107
+ ##########################################
108
+ # Instruction Testing Method Definitions #
109
+ ##########################################
110
+
111
+ selector = Regexp.new(/LLVMIsA.*Inst/)
112
+ syms = Symbol.all_symbols.select { |sym| selector.match(sym.to_s) }
113
+
114
+ syms.each do |sym|
115
+ sym = (Bindings.get_bname(sym).to_s + '?').to_sym
116
+
117
+ define_method(sym) do
118
+ Bindings.send(sym, @ptr)
119
+ end
120
+ end
121
+ end
122
+
123
+ # An Instruction representing a function call.
124
+ #
125
+ # @LLVMInst call
126
+ class CallInst < Instruction
127
+ # Get the calling convention used for this call.
128
+ #
129
+ # @see Bindings._enum_call_conv_
130
+ #
131
+ # @return [Symbol]
132
+ def calling_convention
133
+ Bindings.enum_type(:call_conv)[Bindings.get_instruction_call_conv(@ptr)]
134
+ end
135
+
136
+ # Set the calling convention used for this call.
137
+ #
138
+ # @see Bindings._enum_call_conv_
139
+ #
140
+ # @param [Symbol] conv Calling convention to set.
141
+ def calling_convention=(conv)
142
+ Bindings.set_instruction_call_conv(@ptr, Bindings.enum_type(:call_conv)[conv])
143
+
144
+ conv
145
+ end
146
+
147
+ # @return [Boolean]
148
+ def tail_call?
149
+ Bindings.is_tail_call(@ptr).to_bool
150
+ end
151
+
152
+ # Sets the *tail call* property for this call instruction.
153
+ #
154
+ # @param [Boolean] bool If this is a tail call or not
155
+ #
156
+ # @return [void]
157
+ def tail_call=(bool)
158
+ Bindings.set_tail_call(@ptr, bool.to_i)
159
+ end
160
+ end
161
+
162
+ # An Instruction representing a Phi node.
163
+ #
164
+ # @see http://en.wikipedia.org/wiki/Static_single_assignment_form
165
+ # @LLVMInst phi
166
+ class PhiInst < Instruction
167
+ # @return [IncomingCollection] Proxy object for inspecting the incoming {BasicBlock}/{Value} pairs.
168
+ def incoming
169
+ @incoming_collection ||= IncomingCollection.new(self)
170
+ end
171
+
172
+ # This class is used to access a Phi node's incoming {BasicBlock}/{Value} pairs.
173
+ class IncomingCollection
174
+ include Enumerable
175
+
176
+ # @param [PhiInst] phi Phi instruction for which this is a proxy.
177
+ def initialize(phi)
178
+ @phi = phi
179
+ end
180
+
181
+ # Access the {BasicBlock}/{Value} pair at the given index.
182
+ #
183
+ # @param [Integer] index Index of the desired pair. May be negative.
184
+ #
185
+ # @return [Array(BasicBlock, Value)]
186
+ def [](index)
187
+ index += self.size if index < 0
188
+
189
+ if 0 <= index and index < self.size
190
+ [self.block(index), self.value(index)]
191
+ end
192
+ end
193
+
194
+ # Add incoming {BasicBlock}/{Value} pairs to a Phi node.
195
+ #
196
+ # @example Adding a single block/value pair:
197
+ # phi.incoming.add(bb, val)
198
+ #
199
+ # @example Adding several block/value pairs:
200
+ # phi.incoming.add({bb0 => val0, bb1 => val1})
201
+ #
202
+ # @param [BasicBlock, Hash{BasicBlock => Value}] overloaded
203
+ # @param [Value, nil] value
204
+ #
205
+ # @return [void]
206
+ def add(overloaded, value = nil)
207
+ blks, vals =
208
+ if overloaded.is_a?(BasicBlock) and check_type(value, Value, 'value')
209
+ [overloaded, value]
210
+ else
211
+ if RUBY_VERSION[0..2] == '1.9'
212
+ [overloaded.keys, overloaded.values]
213
+ else
214
+ [(keys = overloaded.keys), overloaded.values_at(*keys)]
215
+ end
216
+ end
217
+
218
+ vals_ptr = FFI::MemoryPointer.new(:pointer, vals.size)
219
+ vals_ptr.write_array_of_pointer(vals)
220
+
221
+ blks_ptr = FFI::MemoryPointer.new(:pointer, blks.size)
222
+ blks_ptr.write_array_of_pointer(blks)
223
+
224
+ nil.tap { Bindings.add_incoming(@phi, vals_ptr, blks_ptr, vals.length) }
225
+ end
226
+ alias :<< :add
227
+
228
+ # @param [Integer] index Index of desired incoming {BasicBlock}.
229
+ #
230
+ # @return [BasicBlock] Incoming {BasicBlock}.
231
+ def block(index)
232
+ index += self.size if index < 0
233
+
234
+ if 0 <= index and index < self.size
235
+ BasicBlock.new(Bindings.get_incoming_block(@phi, index))
236
+ end
237
+ end
238
+
239
+ # An iterator for each incoming {BasicBlock}/{Value} pair.
240
+ #
241
+ # @yieldparam pair [Array(BasicBlock, Value)]
242
+ #
243
+ # @return [Enumerator] Returns an Enumerator if no block is given.
244
+ def each
245
+ return to_enum(:each) unless block_given?
246
+
247
+ self.size.times { |index| yield self[index] }
248
+
249
+ self
250
+ end
251
+
252
+ # @return [Integer] Number of incoming {BasicBlock}/{Value} pairs.
253
+ def size
254
+ Bindings.count_incoming(@phi)
255
+ end
256
+
257
+ # @param [Integer] index Index of desired incoming {Value}.
258
+ #
259
+ # @return [BasicBlock] Incoming {Value}.
260
+ def value(index)
261
+ index += self.size if index < 0
262
+
263
+ if 0 <= index and index < self.size
264
+ Value.new(Bindings.get_incoming_value(@phi, index))
265
+ end
266
+ end
267
+ end
268
+ end
269
+
270
+ # An Instruction representing a conditional jump with multiple cases.
271
+ #
272
+ # @LLVMInst switch
273
+ class SwitchInst < Instruction
274
+ # Add a case to this conditional jump.
275
+ #
276
+ # @param [Value] val Value for this case.
277
+ # @param [BasicBlock] block BasicBlock to jump to if this case is matched.
278
+ #
279
+ # @return [void]
280
+ def add_case(val, block)
281
+ Bindings.add_case(@ptr, val, block)
282
+ end
283
+ end
284
+
285
+ #############################
286
+ # Empty Instruction Classes #
287
+ #############################
288
+
289
+ # @LLVMInst add
290
+ class AddInst < Instruction; end
291
+
292
+ # @LLVMInst addr_space_cast
293
+ class AddrSpaceCastInst < Instruction; end
294
+
295
+ # @LLVMInst alloca
296
+ class AllocaInst < Instruction; end
297
+
298
+ # @LLVMInst and
299
+ class AndInst < Instruction; end
300
+
301
+ # @LLVMInst ashr
302
+ class ARightShiftInst < Instruction; end
303
+
304
+ # @LLVMInst alloca
305
+ class ArrayAllocaInst < Instruction; end
306
+
307
+ class ArrayMallocInst < Instruction; end
308
+
309
+ # @LLVMInst atomicrmw
310
+ class AtomicRMWInst < Instruction; end
311
+
312
+ # @LLVMInst bitcast
313
+ class BitCastInst < Instruction; end
314
+
315
+ # @LLVMInst br
316
+ class BranchInst < Instruction; end
317
+
318
+ # @LLVMInst br
319
+ class CondBranchInst < Instruction; end
320
+
321
+ # @LLVMInst sdiv
322
+ class ExactSDivInst < Instruction; end
323
+
324
+ # @LLVMInst extractelement
325
+ class ExtractElementInst < Instruction; end
326
+
327
+ # @LLVMInst extractvalue
328
+ class ExtractValueInst < Instruction; end
329
+
330
+ # @LLVMInst fadd
331
+ class FAddInst < Instruction; end
332
+
333
+ # @LLVMInst fcmp
334
+ class FCmpInst < Instruction; end
335
+
336
+ # @LLVMInst fdiv
337
+ class FDivInst < Instruction; end
338
+
339
+ # @LLVMInst fmul
340
+ class FMulInst < Instruction; end
341
+
342
+ # @LLVMInst fsub
343
+ class FNegInst < Instruction; end
344
+
345
+ # @LLVMInst fptosi
346
+ class FPToSIInst < Instruction; end
347
+
348
+ # @LLVMInst fptoui
349
+ class FPToUIInst < Instruction; end
350
+
351
+ class FPCastInst < Instruction; end
352
+
353
+ # @LLVMInst fpext
354
+ class FPExtendInst < Instruction; end
355
+
356
+ # @LLVMInst fptrunc
357
+ class FPTruncInst < Instruction; end
358
+
359
+ class FreeInst < Instruction; end
360
+
361
+ # @LLVMInst frem
362
+ class FRemInst < Instruction; end
363
+
364
+ # @LLVMInst fsub
365
+ class FSubInst < Instruction; end
366
+
367
+ # @LLVMInst gep
368
+ # @see http://llvm.org/docs/GetElementPtr.html
369
+ class GetElementPtrInst < Instruction; end
370
+
371
+ class GlobalStringInst < Instruction; end
372
+ class GlobalStringPtrInst < Instruction; end
373
+
374
+ # @LLVMInst gep
375
+ # @see http://llvm.org/docs/GetElementPtr.html
376
+ class InBoundsGEPInst < Instruction; end
377
+
378
+ # @LLVMInst insertelement
379
+ class InsertElementInst < Instruction; end
380
+
381
+ # @LLVMInst insertvalue
382
+ class InsertValueInst < Instruction; end
383
+
384
+ # @LLVMInst inttoptr
385
+ class IntToPtrInst < Instruction; end
386
+
387
+ class IntCastInst < Instruction; end
388
+
389
+ # @LLVMInst icmp
390
+ class IntCmpInst < Instruction; end
391
+
392
+ # @LLVMInst invoke
393
+ class InvokeInst < Instruction; end
394
+
395
+ class IsNotNullInst < Instruction; end
396
+ class IsNullInstInst < Instruction; end
397
+
398
+ # @LLVMInst shl
399
+ class LeftShiftInst < Instruction; end
400
+
401
+ # @LLVMInst load
402
+ class LoadInst < Instruction; end
403
+
404
+ # @LLVMInst lshr
405
+ class LRightShiftInst < Instruction; end
406
+
407
+ class MallocInst < Instruction; end
408
+
409
+ # @LLVMInst mul
410
+ class MulInst < Instruction; end
411
+
412
+ # @LLVMInst sub
413
+ class NegInst < Instruction; end
414
+
415
+ class NotInst < Instruction; end
416
+
417
+ # @LLVMInst add
418
+ class NSWAddInst < Instruction; end
419
+
420
+ # @LLVMInst mul
421
+ class NSWMulInst < Instruction; end
422
+
423
+ # @LLVMInst sub
424
+ class NSWNegInst < Instruction; end
425
+
426
+ # @LLVMInst sub
427
+ class NSWSubInst < Instruction; end
428
+
429
+ # @LLVMInst add
430
+ class NUWAddInst < Instruction; end
431
+
432
+ # @LLVMInst mul
433
+ class NUWMulInst < Instruction; end
434
+
435
+ # @LLVMInst sub
436
+ class NUWNegInst < Instruction; end
437
+
438
+ # @LLVMInst sub
439
+ class NUWSubInst < Instruction; end
440
+
441
+ # @LLVMInst or
442
+ class OrInst < Instruction; end
443
+
444
+ # @LLVMInst ptrtoint
445
+ class PtrToIntInst < Instruction; end
446
+
447
+ class PtrCastInst < Instruction; end
448
+ class PtrDiffInst < Instruction; end
449
+
450
+ # @LLVMInst ret
451
+ class ReturnInst < Instruction; end
452
+
453
+ # @LLVMInst ret
454
+ class ReturnAggregateInst < Instruction; end
455
+
456
+ # @LLVMInst ret
457
+ class ReturnVoidInst < Instruction; end
458
+
459
+ # @LLVMInst sdiv
460
+ class SDivInst < Instruction; end
461
+
462
+ # @LLVMInst select
463
+ class SelectInst < Instruction; end
464
+
465
+ # @LLVMInst shufflevector
466
+ class ShuffleVectorInst < Instruction; end
467
+
468
+ # @LLVMInst sext
469
+ class SignExtendInst < Instruction; end
470
+
471
+ # @LLVMInst sext
472
+ # @LLVMInst bitcast
473
+ class SignExtendOrBitCastInst < Instruction; end
474
+
475
+ # @LLVMInst sitofp
476
+ class SIToFPInst < Instruction; end
477
+
478
+ # @LLVMInst srem
479
+ class SRemInst < Instruction; end
480
+
481
+ # @LLVMInst store
482
+ class StoreInst < Instruction; end
483
+
484
+ # @LLVMInst gep
485
+ # @see http://llvm.org/docs/GetElementPtr.html
486
+ class StructGEPInst < Instruction; end
487
+
488
+ # @LLVMInst sub
489
+ class SubInst < Instruction; end
490
+
491
+ # @LLVMInst trunc
492
+ class TruncateInst < Instruction; end
493
+
494
+ # @LLVMInst trunc
495
+ # @LLVMInst bitcast
496
+ class TruncateOrBitCastInst < Instruction; end
497
+
498
+ # @LLVMInst udiv
499
+ class UDivInst < Instruction; end
500
+
501
+ # @LLVMInst uitofp
502
+ class UIToFPInst < Instruction; end
503
+
504
+ # @LLVMInst unreachable
505
+ class UnreachableInst < Instruction; end
506
+
507
+ # @LLVMInst urem
508
+ class URemInst < Instruction; end
509
+
510
+ # @LLVMInst xor
511
+ class XOrInst < Instruction; end
512
+
513
+ # @LLVMInst zext
514
+ class ZeroExtendInst < Instruction; end
515
+
516
+ # @LLVMInst zext
517
+ # @LLVMInst bitcast
518
+ class ZeroExtendOrBitCastInst < Instruction; end
519
+ end