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