[python-bindings] Added support for iterating over a function's basic blocks, dumping...
[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     "Context",
30     "PassRegistry"
31 ]
32
33 lib = get_library()
34
35 class OpCode(object):
36     """Represents an individual OpCode enumeration."""
37
38     _value_map = {}
39
40     def __init__(self, name, value):
41         self.name = name
42         self.value = value
43
44     def __repr__(self):
45         return 'OpCode.%s' % self.name
46
47     @staticmethod
48     def from_value(value):
49         """Obtain an OpCode instance from a numeric value."""
50         result = OpCode._value_map.get(value, None)
51
52         if result is None:
53             raise ValueError('Unknown OpCode: %d' % value)
54
55         return result
56
57     @staticmethod
58     def register(name, value):
59         """Registers a new OpCode enumeration.
60
61         This is called by this module for each enumeration defined in
62         enumerations. You should not need to call this outside this module.
63         """
64         if value in OpCode._value_map:
65             raise ValueError('OpCode value already registered: %d' % value)
66
67         opcode = OpCode(name, value)
68         OpCode._value_map[value] = opcode
69         setattr(OpCode, name, opcode)
70
71 class MemoryBuffer(LLVMObject):
72     """Represents an opaque memory buffer."""
73
74     def __init__(self, filename=None):
75         """Create a new memory buffer.
76
77         Currently, we support creating from the contents of a file at the
78         specified filename.
79         """
80         if filename is None:
81             raise Exception("filename argument must be defined")
82
83         memory = c_object_p()
84         out = c_char_p(None)
85
86         result = lib.LLVMCreateMemoryBufferWithContentsOfFile(filename,
87                 byref(memory), byref(out))
88
89         if result:
90             raise Exception("Could not create memory buffer: %s" % out.value)
91
92         LLVMObject.__init__(self, memory, disposer=lib.LLVMDisposeMemoryBuffer)
93
94     def __len__(self):
95         return lib.LLVMGetBufferSize(self)
96
97 class Value(LLVMObject):
98     
99     def __init__(self, value):
100         LLVMObject.__init__(self, value)
101
102     @property
103     def name(self):
104         return lib.LLVMGetValueName(self)
105
106     def dump(self):
107         lib.LLVMDumpValue(self)
108
109 class Module(LLVMObject):
110     """Represents the top-level structure of an llvm program in an opaque object."""
111
112     def __init__(self, module, name=None, context=None):
113         LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule)
114
115     @classmethod
116     def CreateWithName(cls, module_id):
117         m = Module(lib.LLVMModuleCreateWithName(module_id))
118         c = Context.GetGlobalContext().take_ownership(m)
119         return m
120
121     @property
122     def datalayout(self):
123         return lib.LLVMGetDataLayout(self)
124
125     @datalayout.setter
126     def datalayout(self, new_data_layout):
127         """new_data_layout is a string."""
128         lib.LLVMSetDataLayout(self, new_data_layout)
129
130     @property
131     def target(self):
132         return lib.LLVMGetTarget(self)
133
134     @target.setter
135     def target(self, new_target):
136         """new_target is a string."""
137         lib.LLVMSetTarget(self, new_target)
138
139     def dump(self):
140         lib.LLVMDumpModule(self)
141
142     class __function_iterator(object):
143         def __init__(self, module, reverse=False):
144             self.module = module
145             self.reverse = reverse
146             if self.reverse:
147                 self.function = self.module.last
148             else:
149                 self.function = self.module.first
150         
151         def __iter__(self):
152             return self
153         
154         def next(self):
155             if not isinstance(self.function, Function):
156                 raise StopIteration("")
157             result = self.function
158             if self.reverse:
159                 self.function = self.function.prev
160             else:
161                 self.function = self.function.next
162             return result
163     
164     def __iter__(self):
165         return Module.__function_iterator(self)
166
167     def __reversed__(self):
168         return Module.__function_iterator(self, reverse=True)
169
170     @property
171     def first(self):
172         return Function(lib.LLVMGetFirstFunction(self))
173
174     @property
175     def last(self):
176         return Function(lib.LLVMGetLastFunction(self))
177
178     def print_module_to_file(self, filename):
179         out = c_char_p(None)
180         # Result is inverted so 0 means everything was ok.
181         result = lib.LLVMPrintModuleToFile(self, filename, byref(out))        
182         if result:
183             raise RuntimeError("LLVM Error: %s" % out.value)
184
185 class Function(Value):
186
187     def __init__(self, value):
188         Value.__init__(self, value)
189     
190     @property
191     def next(self):
192         f = lib.LLVMGetNextFunction(self)
193         return f and Function(f)
194     
195     @property
196     def prev(self):
197         f = lib.LLVMGetPreviousFunction(self)
198         return f and Function(f)
199     
200     @property
201     def first(self):
202         b = lib.LLVMGetFirstBasicBlock(self)
203         return b and BasicBlock(b)
204
205     @property
206     def last(self):
207         b = lib.LLVMGetLastBasicBlock(self)
208         return b and BasicBlock(b)
209
210     class __bb_iterator(object):
211         def __init__(self, function, reverse=False):
212             self.function = function
213             self.reverse = reverse
214             if self.reverse:
215                 self.bb = function.last
216             else:
217                 self.bb = function.first
218         
219         def __iter__(self):
220             return self
221         
222         def next(self):
223             if not isinstance(self.bb, BasicBlock):
224                 raise StopIteration("")
225             result = self.bb
226             if self.reverse:
227                 self.bb = self.bb.prev
228             else:
229                 self.bb = self.bb.next
230             return result
231     
232     def __iter__(self):
233         return Function.__bb_iterator(self)
234
235     def __reversed__(self):
236         return Function.__bb_iterator(self, reverse=True)
237     
238     def __len__(self):
239         return lib.LLVMCountBasicBlocks(self)
240
241 class BasicBlock(LLVMObject):
242     
243     def __init__(self, value):
244         LLVMObject.__init__(self, value)
245
246     @property
247     def next(self):
248         b = lib.LLVMGetNextBasicBlock(self)
249         return b and BasicBlock(b)
250
251     @property
252     def prev(self):
253         b = lib.LLVMGetPreviousBasicBlock(self)
254         return b and BasicBlock(b)
255     
256     @property
257     def name(self):
258         return lib.LLVMGetValueName(Value(lib.LLVMBasicBlockAsValue(self)))
259
260     def dump(self):
261         lib.LLVMDumpValue(Value(lib.LLVMBasicBlockAsValue(self)))
262
263 class Context(LLVMObject):
264
265     def __init__(self, context=None):
266         if context is None:
267             context = lib.LLVMContextCreate()
268             LLVMObject.__init__(self, context, disposer=lib.LLVMContextDispose)
269         else:
270             LLVMObject.__init__(self, context)
271
272     @classmethod
273     def GetGlobalContext(cls):
274         return Context(lib.LLVMGetGlobalContext())
275
276 class PassRegistry(LLVMObject):
277     """Represents an opaque pass registry object."""
278
279     def __init__(self):
280         LLVMObject.__init__(self,
281                             lib.LLVMGetGlobalPassRegistry())
282
283 def register_library(library):
284     # Initialization/Shutdown declarations.
285     library.LLVMInitializeCore.argtypes = [PassRegistry]
286     library.LLVMInitializeCore.restype = None
287
288     library.LLVMInitializeTransformUtils.argtypes = [PassRegistry]
289     library.LLVMInitializeTransformUtils.restype = None
290
291     library.LLVMInitializeScalarOpts.argtypes = [PassRegistry]
292     library.LLVMInitializeScalarOpts.restype = None
293
294     library.LLVMInitializeObjCARCOpts.argtypes = [PassRegistry]
295     library.LLVMInitializeObjCARCOpts.restype = None
296
297     library.LLVMInitializeVectorization.argtypes = [PassRegistry]
298     library.LLVMInitializeVectorization.restype = None
299
300     library.LLVMInitializeInstCombine.argtypes = [PassRegistry]
301     library.LLVMInitializeInstCombine.restype = None
302
303     library.LLVMInitializeIPO.argtypes = [PassRegistry]
304     library.LLVMInitializeIPO.restype = None
305
306     library.LLVMInitializeInstrumentation.argtypes = [PassRegistry]
307     library.LLVMInitializeInstrumentation.restype = None
308
309     library.LLVMInitializeAnalysis.argtypes = [PassRegistry]
310     library.LLVMInitializeAnalysis.restype = None
311
312     library.LLVMInitializeIPA.argtypes = [PassRegistry]
313     library.LLVMInitializeIPA.restype = None
314
315     library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
316     library.LLVMInitializeCodeGen.restype = None
317
318     library.LLVMInitializeTarget.argtypes = [PassRegistry]
319     library.LLVMInitializeTarget.restype = None
320
321     library.LLVMShutdown.argtypes = []
322     library.LLVMShutdown.restype = None
323
324     # Pass Registry declarations.
325     library.LLVMGetGlobalPassRegistry.argtypes = []
326     library.LLVMGetGlobalPassRegistry.restype = c_object_p
327
328     # Context declarations.
329     library.LLVMContextCreate.argtypes = []
330     library.LLVMContextCreate.restype = c_object_p
331
332     library.LLVMContextDispose.argtypes = [Context]
333     library.LLVMContextDispose.restype = None
334
335     library.LLVMGetGlobalContext.argtypes = []
336     library.LLVMGetGlobalContext.restype = c_object_p
337
338     # Memory buffer declarations
339     library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
340             POINTER(c_object_p), POINTER(c_char_p)]
341     library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
342
343     library.LLVMGetBufferSize.argtypes = [MemoryBuffer]
344
345     library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
346
347     # Module declarations
348     library.LLVMModuleCreateWithName.argtypes = [c_char_p]
349     library.LLVMModuleCreateWithName.restype = c_object_p
350
351     library.LLVMDisposeModule.argtypes = [Module]
352     library.LLVMDisposeModule.restype = None
353
354     library.LLVMGetDataLayout.argtypes = [Module]
355     library.LLVMGetDataLayout.restype = c_char_p
356
357     library.LLVMSetDataLayout.argtypes = [Module, c_char_p]
358     library.LLVMSetDataLayout.restype = None
359
360     library.LLVMGetTarget.argtypes = [Module]
361     library.LLVMGetTarget.restype = c_char_p
362
363     library.LLVMSetTarget.argtypes = [Module, c_char_p]
364     library.LLVMSetTarget.restype = None
365
366     library.LLVMDumpModule.argtypes = [Module]
367     library.LLVMDumpModule.restype = None
368
369     library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p,
370                                               POINTER(c_char_p)]
371     library.LLVMPrintModuleToFile.restype = bool
372
373     library.LLVMGetFirstFunction.argtypes = [Module]
374     library.LLVMGetFirstFunction.restype = c_object_p
375
376     library.LLVMGetLastFunction.argtypes = [Module]
377     library.LLVMGetLastFunction.restype = c_object_p
378
379     library.LLVMGetNextFunction.argtypes = [Function]
380     library.LLVMGetNextFunction.restype = c_object_p
381
382     library.LLVMGetPreviousFunction.argtypes = [Function]
383     library.LLVMGetPreviousFunction.restype = c_object_p
384
385     # Value declarations.
386     library.LLVMGetValueName.argtypes = [Value]
387     library.LLVMGetValueName.restype = c_char_p
388
389     library.LLVMDumpValue.argtypes = [Value]
390     library.LLVMDumpValue.restype = None
391
392     # Basic Block Declarations.
393     library.LLVMGetFirstBasicBlock.argtypes = [Function]
394     library.LLVMGetFirstBasicBlock.restype = c_object_p
395
396     library.LLVMGetLastBasicBlock.argtypes = [Function]
397     library.LLVMGetLastBasicBlock.restype = c_object_p
398
399     library.LLVMGetNextBasicBlock.argtypes = [BasicBlock]
400     library.LLVMGetNextBasicBlock.restype = c_object_p
401
402     library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock]
403     library.LLVMGetPreviousBasicBlock.restype = c_object_p
404
405     library.LLVMBasicBlockAsValue.argtypes = [BasicBlock]
406     library.LLVMBasicBlockAsValue.restype = c_object_p
407
408     library.LLVMCountBasicBlocks.argtypes = [Function]
409     library.LLVMCountBasicBlocks.restype = c_uint
410
411 def register_enumerations():
412     for name, value in enumerations.OpCodes:
413         OpCode.register(name, value)
414
415 def initialize_llvm():
416     c = Context.GetGlobalContext()
417     p = PassRegistry()
418     lib.LLVMInitializeCore(p)
419     lib.LLVMInitializeTransformUtils(p)
420     lib.LLVMInitializeScalarOpts(p)
421     lib.LLVMInitializeObjCARCOpts(p)
422     lib.LLVMInitializeVectorization(p)
423     lib.LLVMInitializeInstCombine(p)
424     lib.LLVMInitializeIPO(p)
425     lib.LLVMInitializeInstrumentation(p)
426     lib.LLVMInitializeAnalysis(p)
427     lib.LLVMInitializeIPA(p)
428     lib.LLVMInitializeCodeGen(p)
429     lib.LLVMInitializeTarget(p)
430
431 register_library(lib)
432 register_enumerations()
433 initialize_llvm()