[python-bindings] Added support for getting/setting operands of values and getting...
[oota-llvm.git] / bindings / python / llvm / core.py
1 #===- core.py - Python LLVM Bindings -------------------------*- python -*--===#
2 #
3 #                     The LLVM Compiler Infrastructure
4 #
5 # This file is distributed under the University of Illinois Open Source
6 # License. See LICENSE.TXT for details.
7 #
8 #===------------------------------------------------------------------------===#
9
10 from .common import LLVMObject
11 from .common import c_object_p
12 from .common import get_library
13
14 from . import enumerations
15
16 from ctypes import POINTER
17 from ctypes import byref
18 from ctypes import c_char_p
19 from ctypes import c_uint
20
21 __all__ = [
22     "lib",
23     "OpCode",
24     "MemoryBuffer",
25     "Module",
26     "Value",
27     "Function",
28     "BasicBlock",
29     "Instruction",
30     "Context",
31     "PassRegistry"
32 ]
33
34 lib = get_library()
35
36 class OpCode(object):
37     """Represents an individual OpCode enumeration."""
38
39     _value_map = {}
40
41     def __init__(self, name, value):
42         self.name = name
43         self.value = value
44
45     def __repr__(self):
46         return 'OpCode.%s' % self.name
47
48     @staticmethod
49     def from_value(value):
50         """Obtain an OpCode instance from a numeric value."""
51         result = OpCode._value_map.get(value, None)
52
53         if result is None:
54             raise ValueError('Unknown OpCode: %d' % value)
55
56         return result
57
58     @staticmethod
59     def register(name, value):
60         """Registers a new OpCode enumeration.
61
62         This is called by this module for each enumeration defined in
63         enumerations. You should not need to call this outside this module.
64         """
65         if value in OpCode._value_map:
66             raise ValueError('OpCode value already registered: %d' % value)
67
68         opcode = OpCode(name, value)
69         OpCode._value_map[value] = opcode
70         setattr(OpCode, name, opcode)
71
72 class MemoryBuffer(LLVMObject):
73     """Represents an opaque memory buffer."""
74
75     def __init__(self, filename=None):
76         """Create a new memory buffer.
77
78         Currently, we support creating from the contents of a file at the
79         specified filename.
80         """
81         if filename is None:
82             raise Exception("filename argument must be defined")
83
84         memory = c_object_p()
85         out = c_char_p(None)
86
87         result = lib.LLVMCreateMemoryBufferWithContentsOfFile(filename,
88                 byref(memory), byref(out))
89
90         if result:
91             raise Exception("Could not create memory buffer: %s" % out.value)
92
93         LLVMObject.__init__(self, memory, disposer=lib.LLVMDisposeMemoryBuffer)
94
95     def __len__(self):
96         return lib.LLVMGetBufferSize(self)
97
98 class Value(LLVMObject):
99     
100     def __init__(self, value):
101         LLVMObject.__init__(self, value)
102
103     @property
104     def name(self):
105         return lib.LLVMGetValueName(self)
106
107     def dump(self):
108         lib.LLVMDumpValue(self)
109     
110     def get_operand(self, i):
111         return Value(lib.LLVMGetOperand(self, i))
112     
113     def set_operand(self, i, v):
114         return lib.LLVMSetOperand(self, i, v)
115     
116     def __len__(self):
117         return lib.LLVMGetNumOperands(self)
118
119 class Module(LLVMObject):
120     """Represents the top-level structure of an llvm program in an opaque object."""
121
122     def __init__(self, module, name=None, context=None):
123         LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule)
124
125     @classmethod
126     def CreateWithName(cls, module_id):
127         m = Module(lib.LLVMModuleCreateWithName(module_id))
128         c = Context.GetGlobalContext().take_ownership(m)
129         return m
130
131     @property
132     def datalayout(self):
133         return lib.LLVMGetDataLayout(self)
134
135     @datalayout.setter
136     def datalayout(self, new_data_layout):
137         """new_data_layout is a string."""
138         lib.LLVMSetDataLayout(self, new_data_layout)
139
140     @property
141     def target(self):
142         return lib.LLVMGetTarget(self)
143
144     @target.setter
145     def target(self, new_target):
146         """new_target is a string."""
147         lib.LLVMSetTarget(self, new_target)
148
149     def dump(self):
150         lib.LLVMDumpModule(self)
151
152     class __function_iterator(object):
153         def __init__(self, module, reverse=False):
154             self.module = module
155             self.reverse = reverse
156             if self.reverse:
157                 self.function = self.module.last
158             else:
159                 self.function = self.module.first
160         
161         def __iter__(self):
162             return self
163         
164         def next(self):
165             if not isinstance(self.function, Function):
166                 raise StopIteration("")
167             result = self.function
168             if self.reverse:
169                 self.function = self.function.prev
170             else:
171                 self.function = self.function.next
172             return result
173     
174     def __iter__(self):
175         return Module.__function_iterator(self)
176
177     def __reversed__(self):
178         return Module.__function_iterator(self, reverse=True)
179
180     @property
181     def first(self):
182         return Function(lib.LLVMGetFirstFunction(self))
183
184     @property
185     def last(self):
186         return Function(lib.LLVMGetLastFunction(self))
187
188     def print_module_to_file(self, filename):
189         out = c_char_p(None)
190         # Result is inverted so 0 means everything was ok.
191         result = lib.LLVMPrintModuleToFile(self, filename, byref(out))        
192         if result:
193             raise RuntimeError("LLVM Error: %s" % out.value)
194
195 class Function(Value):
196
197     def __init__(self, value):
198         Value.__init__(self, value)
199     
200     @property
201     def next(self):
202         f = lib.LLVMGetNextFunction(self)
203         return f and Function(f)
204     
205     @property
206     def prev(self):
207         f = lib.LLVMGetPreviousFunction(self)
208         return f and Function(f)
209     
210     @property
211     def first(self):
212         b = lib.LLVMGetFirstBasicBlock(self)
213         return b and BasicBlock(b)
214
215     @property
216     def last(self):
217         b = lib.LLVMGetLastBasicBlock(self)
218         return b and BasicBlock(b)
219
220     class __bb_iterator(object):
221         def __init__(self, function, reverse=False):
222             self.function = function
223             self.reverse = reverse
224             if self.reverse:
225                 self.bb = function.last
226             else:
227                 self.bb = function.first
228         
229         def __iter__(self):
230             return self
231         
232         def next(self):
233             if not isinstance(self.bb, BasicBlock):
234                 raise StopIteration("")
235             result = self.bb
236             if self.reverse:
237                 self.bb = self.bb.prev
238             else:
239                 self.bb = self.bb.next
240             return result
241     
242     def __iter__(self):
243         return Function.__bb_iterator(self)
244
245     def __reversed__(self):
246         return Function.__bb_iterator(self, reverse=True)
247     
248     def __len__(self):
249         return lib.LLVMCountBasicBlocks(self)
250
251 class BasicBlock(LLVMObject):
252     
253     def __init__(self, value):
254         LLVMObject.__init__(self, value)
255
256     @property
257     def next(self):
258         b = lib.LLVMGetNextBasicBlock(self)
259         return b and BasicBlock(b)
260
261     @property
262     def prev(self):
263         b = lib.LLVMGetPreviousBasicBlock(self)
264         return b and BasicBlock(b)
265     
266     @property
267     def first(self):
268         i = lib.LLVMGetFirstInstruction(self)
269         return i and Instruction(i)
270
271     @property
272     def last(self):
273         i = lib.LLVMGetLastInstruction(self)
274         return i and Instruction(i)
275
276     def __as_value(self):
277         return Value(lib.LLVMBasicBlockAsValue(self))
278     
279     @property
280     def name(self):
281         return lib.LLVMGetValueName(self.__as_value())
282
283     def dump(self):
284         lib.LLVMDumpValue(self.__as_value())
285
286     def get_operand(self, i):
287         return Value(lib.LLVMGetOperand(self.__as_value(),
288                                         i))
289     
290     def set_operand(self, i, v):
291         return lib.LLVMSetOperand(self.__as_value(),
292                                   i, v)
293     
294     def __len__(self):
295         return lib.LLVMGetNumOperands(self.__as_value())
296
297     class __inst_iterator(object):
298         def __init__(self, bb, reverse=False):            
299             self.bb = bb
300             self.reverse = reverse
301             if self.reverse:
302                 self.inst = self.bb.last
303             else:
304                 self.inst = self.bb.first
305         
306         def __iter__(self):
307             return self
308         
309         def next(self):
310             if not isinstance(self.inst, Instruction):
311                 raise StopIteration("")
312             result = self.inst
313             if self.reverse:
314                 self.inst = self.inst.prev
315             else:
316                 self.inst = self.inst.next
317             return result
318     
319     def __iter__(self):
320         return BasicBlock.__inst_iterator(self)
321
322     def __reversed__(self):
323         return BasicBlock.__inst_iterator(self, reverse=True)
324
325
326 class Instruction(Value):
327
328     def __init__(self, value):
329         Value.__init__(self, value)
330
331     @property
332     def next(self):
333         i = lib.LLVMGetNextInstruction(self)
334         return i and Instruction(i)
335
336     @property
337     def prev(self):
338         i = lib.LLVMGetPreviousInstruction(self)
339         return i and Instruction(i)
340
341     @property
342     def opcode(self):
343         return OpCode.from_value(lib.LLVMGetInstructionOpcode(self))
344
345 class Context(LLVMObject):
346
347     def __init__(self, context=None):
348         if context is None:
349             context = lib.LLVMContextCreate()
350             LLVMObject.__init__(self, context, disposer=lib.LLVMContextDispose)
351         else:
352             LLVMObject.__init__(self, context)
353
354     @classmethod
355     def GetGlobalContext(cls):
356         return Context(lib.LLVMGetGlobalContext())
357
358 class PassRegistry(LLVMObject):
359     """Represents an opaque pass registry object."""
360
361     def __init__(self):
362         LLVMObject.__init__(self,
363                             lib.LLVMGetGlobalPassRegistry())
364
365 def register_library(library):
366     # Initialization/Shutdown declarations.
367     library.LLVMInitializeCore.argtypes = [PassRegistry]
368     library.LLVMInitializeCore.restype = None
369
370     library.LLVMInitializeTransformUtils.argtypes = [PassRegistry]
371     library.LLVMInitializeTransformUtils.restype = None
372
373     library.LLVMInitializeScalarOpts.argtypes = [PassRegistry]
374     library.LLVMInitializeScalarOpts.restype = None
375
376     library.LLVMInitializeObjCARCOpts.argtypes = [PassRegistry]
377     library.LLVMInitializeObjCARCOpts.restype = None
378
379     library.LLVMInitializeVectorization.argtypes = [PassRegistry]
380     library.LLVMInitializeVectorization.restype = None
381
382     library.LLVMInitializeInstCombine.argtypes = [PassRegistry]
383     library.LLVMInitializeInstCombine.restype = None
384
385     library.LLVMInitializeIPO.argtypes = [PassRegistry]
386     library.LLVMInitializeIPO.restype = None
387
388     library.LLVMInitializeInstrumentation.argtypes = [PassRegistry]
389     library.LLVMInitializeInstrumentation.restype = None
390
391     library.LLVMInitializeAnalysis.argtypes = [PassRegistry]
392     library.LLVMInitializeAnalysis.restype = None
393
394     library.LLVMInitializeIPA.argtypes = [PassRegistry]
395     library.LLVMInitializeIPA.restype = None
396
397     library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
398     library.LLVMInitializeCodeGen.restype = None
399
400     library.LLVMInitializeTarget.argtypes = [PassRegistry]
401     library.LLVMInitializeTarget.restype = None
402
403     library.LLVMShutdown.argtypes = []
404     library.LLVMShutdown.restype = None
405
406     # Pass Registry declarations.
407     library.LLVMGetGlobalPassRegistry.argtypes = []
408     library.LLVMGetGlobalPassRegistry.restype = c_object_p
409
410     # Context declarations.
411     library.LLVMContextCreate.argtypes = []
412     library.LLVMContextCreate.restype = c_object_p
413
414     library.LLVMContextDispose.argtypes = [Context]
415     library.LLVMContextDispose.restype = None
416
417     library.LLVMGetGlobalContext.argtypes = []
418     library.LLVMGetGlobalContext.restype = c_object_p
419
420     # Memory buffer declarations
421     library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
422             POINTER(c_object_p), POINTER(c_char_p)]
423     library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
424
425     library.LLVMGetBufferSize.argtypes = [MemoryBuffer]
426
427     library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
428
429     # Module declarations
430     library.LLVMModuleCreateWithName.argtypes = [c_char_p]
431     library.LLVMModuleCreateWithName.restype = c_object_p
432
433     library.LLVMDisposeModule.argtypes = [Module]
434     library.LLVMDisposeModule.restype = None
435
436     library.LLVMGetDataLayout.argtypes = [Module]
437     library.LLVMGetDataLayout.restype = c_char_p
438
439     library.LLVMSetDataLayout.argtypes = [Module, c_char_p]
440     library.LLVMSetDataLayout.restype = None
441
442     library.LLVMGetTarget.argtypes = [Module]
443     library.LLVMGetTarget.restype = c_char_p
444
445     library.LLVMSetTarget.argtypes = [Module, c_char_p]
446     library.LLVMSetTarget.restype = None
447
448     library.LLVMDumpModule.argtypes = [Module]
449     library.LLVMDumpModule.restype = None
450
451     library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p,
452                                               POINTER(c_char_p)]
453     library.LLVMPrintModuleToFile.restype = bool
454
455     library.LLVMGetFirstFunction.argtypes = [Module]
456     library.LLVMGetFirstFunction.restype = c_object_p
457
458     library.LLVMGetLastFunction.argtypes = [Module]
459     library.LLVMGetLastFunction.restype = c_object_p
460
461     library.LLVMGetNextFunction.argtypes = [Function]
462     library.LLVMGetNextFunction.restype = c_object_p
463
464     library.LLVMGetPreviousFunction.argtypes = [Function]
465     library.LLVMGetPreviousFunction.restype = c_object_p
466
467     # Value declarations.
468     library.LLVMGetValueName.argtypes = [Value]
469     library.LLVMGetValueName.restype = c_char_p
470
471     library.LLVMDumpValue.argtypes = [Value]
472     library.LLVMDumpValue.restype = None
473
474     library.LLVMGetOperand.argtypes = [Value, c_uint]
475     library.LLVMGetOperand.restype = c_object_p
476
477     library.LLVMSetOperand.argtypes = [Value, Value, c_uint]
478     library.LLVMSetOperand.restype = None
479
480     library.LLVMGetNumOperands.argtypes = [Value]
481     library.LLVMGetNumOperands.restype = c_uint
482
483     # Basic Block Declarations.
484     library.LLVMGetFirstBasicBlock.argtypes = [Function]
485     library.LLVMGetFirstBasicBlock.restype = c_object_p
486
487     library.LLVMGetLastBasicBlock.argtypes = [Function]
488     library.LLVMGetLastBasicBlock.restype = c_object_p
489
490     library.LLVMGetNextBasicBlock.argtypes = [BasicBlock]
491     library.LLVMGetNextBasicBlock.restype = c_object_p
492
493     library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock]
494     library.LLVMGetPreviousBasicBlock.restype = c_object_p
495
496     library.LLVMGetFirstInstruction.argtypes = [BasicBlock]
497     library.LLVMGetFirstInstruction.restype = c_object_p
498
499     library.LLVMGetLastInstruction.argtypes = [BasicBlock]
500     library.LLVMGetLastInstruction.restype = c_object_p
501
502     library.LLVMBasicBlockAsValue.argtypes = [BasicBlock]
503     library.LLVMBasicBlockAsValue.restype = c_object_p
504
505     library.LLVMCountBasicBlocks.argtypes = [Function]
506     library.LLVMCountBasicBlocks.restype = c_uint
507
508     # Instruction Declarations.
509     library.LLVMGetNextInstruction.argtypes = [Instruction]
510     library.LLVMGetNextInstruction.restype = c_object_p
511
512     library.LLVMGetPreviousInstruction.argtypes = [Instruction]
513     library.LLVMGetPreviousInstruction.restype = c_object_p
514
515     library.LLVMGetInstructionOpcode.argtypes = [Instruction]
516     library.LLVMGetInstructionOpcode.restype = c_uint
517
518 def register_enumerations():
519     for name, value in enumerations.OpCodes:
520         OpCode.register(name, value)
521
522 def initialize_llvm():
523     c = Context.GetGlobalContext()
524     p = PassRegistry()
525     lib.LLVMInitializeCore(p)
526     lib.LLVMInitializeTransformUtils(p)
527     lib.LLVMInitializeScalarOpts(p)
528     lib.LLVMInitializeObjCARCOpts(p)
529     lib.LLVMInitializeVectorization(p)
530     lib.LLVMInitializeInstCombine(p)
531     lib.LLVMInitializeIPO(p)
532     lib.LLVMInitializeInstrumentation(p)
533     lib.LLVMInitializeAnalysis(p)
534     lib.LLVMInitializeIPA(p)
535     lib.LLVMInitializeCodeGen(p)
536     lib.LLVMInitializeTarget(p)
537
538 register_library(lib)
539 register_enumerations()
540 initialize_llvm()