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