layout: page |
title: Types |
Types are what you think they are. A instance of llvm.core.Type, or one of its derived classes, represent a type. llvmpy does not use as many classes to represent types as does LLVM itself. Some types are represented using llvm.core.Type itself and the rest are represented using derived classes of llvm.core.Type. As usual, an instance is created via one of the static methods of Type. These methods return an instance of either llvm.core.Type itself or one of its derived classes.
The following table lists all the available types along with the static method which has to be used to construct it and the name of the class whose object is actually returned by the static method.
Name | Constructor Method | Class | —–|:——————:|:—–:| integer of bitwidth n | Type.int(n) | IntegerType | 32-bit float | Type.float() | Type | 64-bit double | Type.double() | Type | 80-bit float | Type.x86_fp80() | Type | 128-bit float (112-bit mantissa) | Type.fp128() | Type | 128-bit float (two 64-bits) | Type.ppc_fp128() | Type | function | Type.function(r, p, v) | FunctionType | unpacked struct | Type.struct(eltys, name) | StructType | packed struct | Type.packed_struct(eltys, name) | StructType | opaque struct | Type.opaque(name) | StructType | array | Type.array(elty, count) | ArrayType | pointer to value of type pty | Type.pointer(pty, addrspc) | PointerType | vector | Type.vector(elty, count) | VectorType | void | Type.void() | Type | label | Type.label() | Type |
The class hierarchy is:
Type
IntegerType
FunctionType
StructType
ArrayType
PointerType
VectorType
Here is an example that demonstrates the creation of types:
#!/usr/bin/env python
# integers
int_ty = Type.int() bool_ty = Type.int(1) int_64bit = Type.int(64)
# floats
sprec_real = Type.float() dprec_real = Type.double()
# arrays and vectors
intar_ty = Type.array( int_ty, 10 ) # "typedef int intar_ty[10];"
twodim = Type.array( intar_ty , 10 ) # "typedef int twodim[10][10];"
vec = Type.array( int_ty, 10 )
# structures
s1_ty = Type.struct( [ int_ty, sprec_real ] ) # "struct s1_ty { int
v1; float v2; };"
# pointers
intptr_ty = Type.pointer(int_ty) # "typedef int \*intptr_ty;"
# functions
f1 = Type.function( int_ty, [ int_ty ] ) # functions that take 1
int_ty and return 1 int_ty
f2 = Type.function( Type.void(), [ int_ty, int_ty ] ) # functions that
take 2 int_tys and return nothing
f3 = Type.function( Type.void(), ( int_ty, int_ty ) ) # same as f2;
any iterable can be used
fnargs = [ Type.pointer( Type.int(8) ) ] printf = Type.function(
Type.int(), fnargs, True ) # variadic function
The type system was rewritten in LLVM 3.0. The old opaque type was removed. Instead, identified StructType can now be defined without a body. Doing so creates a opaque structure. One can then set the body after the construction of a structure.
(See LLVM Blog for detail about the new type system.)
The following code defines a opaque structure, named “mystruct”. The body is defined after the construction using StructType.set_body. The second subtype is a pointer to a “mystruct” type.
ts = Type.opaque('mystruct')
ts.set_body([Type.int(), Type.pointer(ts)])