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.LLVMInitializeIPA.argtypes = [PassRegistry]
469    library.LLVMInitializeIPA.restype = None
470
471    library.LLVMInitializeCodeGen.argtypes = [PassRegistry]
472    library.LLVMInitializeCodeGen.restype = None
473
474    library.LLVMInitializeTarget.argtypes = [PassRegistry]
475    library.LLVMInitializeTarget.restype = None
476
477    library.LLVMShutdown.argtypes = []
478    library.LLVMShutdown.restype = None
479
480    # Pass Registry declarations.
481    library.LLVMGetGlobalPassRegistry.argtypes = []
482    library.LLVMGetGlobalPassRegistry.restype = c_object_p
483
484    # Context declarations.
485    library.LLVMContextCreate.argtypes = []
486    library.LLVMContextCreate.restype = c_object_p
487
488    library.LLVMContextDispose.argtypes = [Context]
489    library.LLVMContextDispose.restype = None
490
491    library.LLVMGetGlobalContext.argtypes = []
492    library.LLVMGetGlobalContext.restype = c_object_p
493
494    # Memory buffer declarations
495    library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
496            POINTER(c_object_p), POINTER(c_char_p)]
497    library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
498
499    library.LLVMGetBufferSize.argtypes = [MemoryBuffer]
500
501    library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
502
503    # Module declarations
504    library.LLVMModuleCreateWithName.argtypes = [c_char_p]
505    library.LLVMModuleCreateWithName.restype = c_object_p
506
507    library.LLVMDisposeModule.argtypes = [Module]
508    library.LLVMDisposeModule.restype = None
509
510    library.LLVMGetDataLayout.argtypes = [Module]
511    library.LLVMGetDataLayout.restype = c_char_p
512
513    library.LLVMSetDataLayout.argtypes = [Module, c_char_p]
514    library.LLVMSetDataLayout.restype = None
515
516    library.LLVMGetTarget.argtypes = [Module]
517    library.LLVMGetTarget.restype = c_char_p
518
519    library.LLVMSetTarget.argtypes = [Module, c_char_p]
520    library.LLVMSetTarget.restype = None
521
522    library.LLVMDumpModule.argtypes = [Module]
523    library.LLVMDumpModule.restype = None
524
525    library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p,
526                                              POINTER(c_char_p)]
527    library.LLVMPrintModuleToFile.restype = bool
528
529    library.LLVMGetFirstFunction.argtypes = [Module]
530    library.LLVMGetFirstFunction.restype = c_object_p
531
532    library.LLVMGetLastFunction.argtypes = [Module]
533    library.LLVMGetLastFunction.restype = c_object_p
534
535    library.LLVMGetNextFunction.argtypes = [Function]
536    library.LLVMGetNextFunction.restype = c_object_p
537
538    library.LLVMGetPreviousFunction.argtypes = [Function]
539    library.LLVMGetPreviousFunction.restype = c_object_p
540
541    # Value declarations.
542    library.LLVMGetValueName.argtypes = [Value]
543    library.LLVMGetValueName.restype = c_char_p
544
545    library.LLVMDumpValue.argtypes = [Value]
546    library.LLVMDumpValue.restype = None
547
548    library.LLVMGetOperand.argtypes = [Value, c_uint]
549    library.LLVMGetOperand.restype = c_object_p
550
551    library.LLVMSetOperand.argtypes = [Value, Value, c_uint]
552    library.LLVMSetOperand.restype = None
553
554    library.LLVMGetNumOperands.argtypes = [Value]
555    library.LLVMGetNumOperands.restype = c_uint
556
557    # Basic Block Declarations.
558    library.LLVMGetFirstBasicBlock.argtypes = [Function]
559    library.LLVMGetFirstBasicBlock.restype = c_object_p
560
561    library.LLVMGetLastBasicBlock.argtypes = [Function]
562    library.LLVMGetLastBasicBlock.restype = c_object_p
563
564    library.LLVMGetNextBasicBlock.argtypes = [BasicBlock]
565    library.LLVMGetNextBasicBlock.restype = c_object_p
566
567    library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock]
568    library.LLVMGetPreviousBasicBlock.restype = c_object_p
569
570    library.LLVMGetFirstInstruction.argtypes = [BasicBlock]
571    library.LLVMGetFirstInstruction.restype = c_object_p
572
573    library.LLVMGetLastInstruction.argtypes = [BasicBlock]
574    library.LLVMGetLastInstruction.restype = c_object_p
575
576    library.LLVMBasicBlockAsValue.argtypes = [BasicBlock]
577    library.LLVMBasicBlockAsValue.restype = c_object_p
578
579    library.LLVMCountBasicBlocks.argtypes = [Function]
580    library.LLVMCountBasicBlocks.restype = c_uint
581
582    # Instruction Declarations.
583    library.LLVMGetNextInstruction.argtypes = [Instruction]
584    library.LLVMGetNextInstruction.restype = c_object_p
585
586    library.LLVMGetPreviousInstruction.argtypes = [Instruction]
587    library.LLVMGetPreviousInstruction.restype = c_object_p
588
589    library.LLVMGetInstructionOpcode.argtypes = [Instruction]
590    library.LLVMGetInstructionOpcode.restype = c_uint
591
592def register_enumerations():
593    if Enums:
594        return None
595    enums = [
596        (Attribute, enumerations.Attributes),
597        (OpCode, enumerations.OpCodes),
598        (TypeKind, enumerations.TypeKinds),
599        (Linkage, enumerations.Linkages),
600        (Visibility, enumerations.Visibility),
601        (CallConv, enumerations.CallConv),
602        (IntPredicate, enumerations.IntPredicate),
603        (RealPredicate, enumerations.RealPredicate),
604        (LandingPadClauseTy, enumerations.LandingPadClauseTy),
605    ]
606    for enum_class, enum_spec in enums:
607        for name, value in enum_spec:
608            print name, value
609            enum_class.register(name, value)
610    return enums
611
612def initialize_llvm():
613    Context.GetGlobalContext()
614    p = PassRegistry()
615    lib.LLVMInitializeCore(p)
616    lib.LLVMInitializeTransformUtils(p)
617    lib.LLVMInitializeScalarOpts(p)
618    lib.LLVMInitializeObjCARCOpts(p)
619    lib.LLVMInitializeVectorization(p)
620    lib.LLVMInitializeInstCombine(p)
621    lib.LLVMInitializeIPO(p)
622    lib.LLVMInitializeInstrumentation(p)
623    lib.LLVMInitializeAnalysis(p)
624    lib.LLVMInitializeIPA(p)
625    lib.LLVMInitializeCodeGen(p)
626    lib.LLVMInitializeTarget(p)
627
628register_library(lib)
629Enums = register_enumerations()
630initialize_llvm()
631