[python-bindings] Added support for iterating over a basic blocks instructions, getti...
[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 class Module(LLVMObject):
111     """Represents the top-level structure of an llvm program in an opaque object."""
112
113     def __init__(self, module, name=None, context=None):
114         LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule)
115
116     @classmethod
117     def CreateWithName(cls, module_id):
118         m = Module(lib.LLVMModuleCreateWithName(module_id))
119         c = Context.GetGlobalContext().take_ownership(m)
120         return m
121
122     @property
123     def datalayout(self):
124         return lib.LLVMGetDataLayout(self)
125
126     @datalayout.setter
127     def datalayout(self, new_data_layout):
128         """new_data_layout is a string."""
129         lib.LLVMSetDataLayout(self, new_data_layout)
130
131     @property
132     def target(self):
133         return lib.LLVMGetTarget(self)
134
135     @target.setter
136     def target(self, new_target):
137         """new_target is a string."""
138         lib.LLVMSetTarget(self, new_target)
139
140     def dump(self):
141         lib.LLVMDumpModule(self)
142
143     class __function_iterator(object):
144         def __init__(self, module, reverse=False):
145             self.module = module
146             self.reverse = reverse
147             if self.reverse:
148                 self.function = self.module.last
149             else:
150                 self.function = self.module.first
151         
152         def __iter__(self):
153             return self
154         
155         def next(self):
156             if not isinstance(self.function, Function):
157                 raise StopIteration("")
158             result = self.function
159             if self.reverse:
160                 self.function = self.function.prev
161             else:
162                 self.function = self.function.next
163             return result
164     
165     def __iter__(self):
166         return Module.__function_iterator(self)
167
168     def __reversed__(self):
169         return Module.__function_iterator(self, reverse=True)
170
171     @property
172     def first(self):
173         return Function(lib.LLVMGetFirstFunction(self))
174
175     @property
176     def last(self):
177         return Function(lib.LLVMGetLastFunction(self))
178
179     def print_module_to_file(self, filename):
180         out = c_char_p(None)
181         # Result is inverted so 0 means everything was ok.
182         result = lib.LLVMPrintModuleToFile(self, filename, byref(out))        
183         if result:
184             raise RuntimeError("LLVM Error: %s" % out.value)
185
186 class Function(Value):
187
188     def __init__(self, value):
189         Value.__init__(self, value)
190     
191     @property
192     def next(self):
193         f = lib.LLVMGetNextFunction(self)
194         return f and Function(f)
195     
196     @property
197     def prev(self):
198         f = lib.LLVMGetPreviousFunction(self)
199         return f and Function(f)
200     
201     @property
202     def first(self):
203         b = lib.LLVMGetFirstBasicBlock(self)
204         return b and BasicBlock(b)
205
206     @property
207     def last(self):
208         b = lib.LLVMGetLastBasicBlock(self)
209         return b and BasicBlock(b)
210
211     class __bb_iterator(object):
212         def __init__(self, function, reverse=False):
213             self.function = function
214             self.reverse = reverse
215             if self.reverse:
216                 self.bb = function.last
217             else:
218                 self.bb = function.first
219         
220         def __iter__(self):
221             return self
222         
223         def next(self):
224             if not isinstance(self.bb, BasicBlock):
225                 raise StopIteration("")
226             result = self.bb
227             if self.reverse:
228                 self.bb = self.bb.prev
229             else:
230                 self.bb = self.bb.next
231             return result
232     
233     def __iter__(self):
234         return Function.__bb_iterator(self)
235
236     def __reversed__(self):
237         return Function.__bb_iterator(self, reverse=True)
238     
239     def __len__(self):
240         return lib.LLVMCountBasicBlocks(self)
241
242 class BasicBlock(LLVMObject):
243     
244     def __init__(self, value):
245         LLVMObject.__init__(self, value)
246
247     @property
248     def next(self):
249         b = lib.LLVMGetNextBasicBlock(self)
250         return b and BasicBlock(b)
251
252     @property
253     def prev(self):
254         b = lib.LLVMGetPreviousBasicBlock(self)
255         return b and BasicBlock(b)
256     
257     @property
258     def first(self):
259         i = lib.LLVMGetFirstInstruction(self)
260         return i and Instruction(i)
261
262     @property
263     def last(self):
264         i = lib.LLVMGetLastInstruction(self)
265         return i and Instruction(i)
266
267     @property
268     def name(self):
269         return lib.LLVMGetValueName(Value(lib.LLVMBasicBlockAsValue(self)))
270
271     def dump(self):
272         lib.LLVMDumpValue(Value(lib.LLVMBasicBlockAsValue(self)))
273
274     class __inst_iterator(object):
275         def __init__(self, bb, reverse=False):            
276             self.bb = bb
277             self.reverse = reverse
278             if self.reverse:
279                 self.inst = self.bb.last
280             else:
281                 self.inst = self.bb.first
282         
283         def __iter__(self):
284             return self
285         
286         def next(self):
287             if not isinstance(self.inst, Instruction):
288                 raise StopIteration("")
289             result = self.inst
290             if self.reverse:
291                 self.inst = self.inst.prev
292             else:
293                 self.inst = self.inst.next
294             return result
295     
296     def __iter__(self):
297         return BasicBlock.__inst_iterator(self)
298
299     def __reversed__(self):
300         return BasicBlock.__inst_iterator(self, reverse=True)
301
302
303 class Instruction(Value):
304
305     def __init__(self, value):
306         Value.__init__(self, value)
307
308     @property
309     def next(self):
310         i = lib.LLVMGetNextInstruction(self)
311         return i and Instruction(i)
312
313     @property
314     def prev(self):
315         i = lib.LLVMGetPreviousInstruction(self)
316         return i and Instruction(i)
317
318     @property
319     def opcode(self):
320         return OpCode.from_value(lib.LLVMGetInstructionOpcode(self))
321
322 class Context(LLVMObject):
323
324     def __init__(self, context=None):
325         if context is None:
326             context = lib.LLVMContextCreate()
327             LLVMObject.__init__(self, context, disposer=lib.LLVMContextDispose)
328         else:
329             LLVMObject.__init__(self, context)
330
331     @classmethod
332     def GetGlobalContext(cls):
333         return Context(lib.LLVMGetGlobalContext())
334
335 class PassRegistry(LLVMObject):
336     """Represents an opaque pass registry object."""
337
338     def __init__(self):
339         LLVMObject.__init__(self,
340                             lib.LLVMGetGlobalPassRegistry())
341
342 def register_library(library):
343     # Initialization/Shutdown declarations.
344     library.LLVMInitializeCore.argtypes = [PassRegistry]
345     library.LLVMInitializeCore.restype = None
346
347     library.LLVMInitializeTransformUtils.argtypes = [PassRegistry]
348     library.LLVMInitializeTransformUtils.restype = None
349
350     library.LLVMInitializeScalarOpts.argtypes = [PassRegistry]
351     library.LLVMInitializeScalarOpts.restype = None
352
353     library.LLVMInitializeObjCARCOpts.argtypes = [PassRegistry]
354     library.LLVMInitializeObjCARCOpts.restype = None
355
356     library.LLVMInitializeVectorization.argtypes = [PassRegistry]
357     library.LLVMInitializeVectorization.restype = None
358
359     library.LLVMInitializeInstCombine.argtypes = [PassRegistry]
360     library.LLVMInitializeInstCombine.restype = None
361
362     library.LLVMInitializeIPO.argtypes = [PassRegistry]
363     library.LLVMInitializeIPO.restype = None
364
365     library.LLVMInitializeInstrumentation.argtypes = [PassRegistry]
366     library.LLVMInitializeInstrumentation.restype = None
367
368     library.LLVMInitializeAnalysis.argtypes = [PassRegistry]
369     library.LLVMInitializeAnalysis.restype = None
370
371     library.LLVMInitializeIPA.argtypes = [PassRegistry]
372     library.LLVMInitializeIPA.restype = None
373
374     library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
375     library.LLVMInitializeCodeGen.restype = None
376
377     library.LLVMInitializeTarget.argtypes = [PassRegistry]
378     library.LLVMInitializeTarget.restype = None
379
380     library.LLVMShutdown.argtypes = []
381     library.LLVMShutdown.restype = None
382
383     # Pass Registry declarations.
384     library.LLVMGetGlobalPassRegistry.argtypes = []
385     library.LLVMGetGlobalPassRegistry.restype = c_object_p
386
387     # Context declarations.
388     library.LLVMContextCreate.argtypes = []
389     library.LLVMContextCreate.restype = c_object_p
390
391     library.LLVMContextDispose.argtypes = [Context]
392     library.LLVMContextDispose.restype = None
393
394     library.LLVMGetGlobalContext.argtypes = []
395     library.LLVMGetGlobalContext.restype = c_object_p
396
397     # Memory buffer declarations
398     library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
399             POINTER(c_object_p), POINTER(c_char_p)]
400     library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
401
402     library.LLVMGetBufferSize.argtypes = [MemoryBuffer]
403
404     library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
405
406     # Module declarations
407     library.LLVMModuleCreateWithName.argtypes = [c_char_p]
408     library.LLVMModuleCreateWithName.restype = c_object_p
409
410     library.LLVMDisposeModule.argtypes = [Module]
411     library.LLVMDisposeModule.restype = None
412
413     library.LLVMGetDataLayout.argtypes = [Module]
414     library.LLVMGetDataLayout.restype = c_char_p
415
416     library.LLVMSetDataLayout.argtypes = [Module, c_char_p]
417     library.LLVMSetDataLayout.restype = None
418
419     library.LLVMGetTarget.argtypes = [Module]
420     library.LLVMGetTarget.restype = c_char_p
421
422     library.LLVMSetTarget.argtypes = [Module, c_char_p]
423     library.LLVMSetTarget.restype = None
424
425     library.LLVMDumpModule.argtypes = [Module]
426     library.LLVMDumpModule.restype = None
427
428     library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p,
429                                               POINTER(c_char_p)]
430     library.LLVMPrintModuleToFile.restype = bool
431
432     library.LLVMGetFirstFunction.argtypes = [Module]
433     library.LLVMGetFirstFunction.restype = c_object_p
434
435     library.LLVMGetLastFunction.argtypes = [Module]
436     library.LLVMGetLastFunction.restype = c_object_p
437
438     library.LLVMGetNextFunction.argtypes = [Function]
439     library.LLVMGetNextFunction.restype = c_object_p
440
441     library.LLVMGetPreviousFunction.argtypes = [Function]
442     library.LLVMGetPreviousFunction.restype = c_object_p
443
444     # Value declarations.
445     library.LLVMGetValueName.argtypes = [Value]
446     library.LLVMGetValueName.restype = c_char_p
447
448     library.LLVMDumpValue.argtypes = [Value]
449     library.LLVMDumpValue.restype = None
450
451     # Basic Block Declarations.
452     library.LLVMGetFirstBasicBlock.argtypes = [Function]
453     library.LLVMGetFirstBasicBlock.restype = c_object_p
454
455     library.LLVMGetLastBasicBlock.argtypes = [Function]
456     library.LLVMGetLastBasicBlock.restype = c_object_p
457
458     library.LLVMGetNextBasicBlock.argtypes = [BasicBlock]
459     library.LLVMGetNextBasicBlock.restype = c_object_p
460
461     library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock]
462     library.LLVMGetPreviousBasicBlock.restype = c_object_p
463
464     library.LLVMGetFirstInstruction.argtypes = [BasicBlock]
465     library.LLVMGetFirstInstruction.restype = c_object_p
466
467     library.LLVMGetLastInstruction.argtypes = [BasicBlock]
468     library.LLVMGetLastInstruction.restype = c_object_p
469
470     library.LLVMBasicBlockAsValue.argtypes = [BasicBlock]
471     library.LLVMBasicBlockAsValue.restype = c_object_p
472
473     library.LLVMCountBasicBlocks.argtypes = [Function]
474     library.LLVMCountBasicBlocks.restype = c_uint
475
476     # Instruction Declarations.
477     library.LLVMGetNextInstruction.argtypes = [Instruction]
478     library.LLVMGetNextInstruction.restype = c_object_p
479
480     library.LLVMGetPreviousInstruction.argtypes = [Instruction]
481     library.LLVMGetPreviousInstruction.restype = c_object_p
482
483     library.LLVMGetInstructionOpcode.argtypes = [Instruction]
484     library.LLVMGetInstructionOpcode.restype = c_uint
485
486 def register_enumerations():
487     for name, value in enumerations.OpCodes:
488         OpCode.register(name, value)
489
490 def initialize_llvm():
491     c = Context.GetGlobalContext()
492     p = PassRegistry()
493     lib.LLVMInitializeCore(p)
494     lib.LLVMInitializeTransformUtils(p)
495     lib.LLVMInitializeScalarOpts(p)
496     lib.LLVMInitializeObjCARCOpts(p)
497     lib.LLVMInitializeVectorization(p)
498     lib.LLVMInitializeInstCombine(p)
499     lib.LLVMInitializeIPO(p)
500     lib.LLVMInitializeInstrumentation(p)
501     lib.LLVMInitializeAnalysis(p)
502     lib.LLVMInitializeIPA(p)
503     lib.LLVMInitializeCodeGen(p)
504     lib.LLVMInitializeTarget(p)
505
506 register_library(lib)
507 register_enumerations()
508 initialize_llvm()