Skip to content

Commit 52862d4

Browse files
vdkaCodaFi
authored andcommitted
Type contexts (#101)
* Added context to all types * Make static FloatType members public * Added context to LabelType * Maintain context after translating LLVMTypeRef into IRType * All types have a context therefore context should be non optional * Added accessor for a context on an IRType * Fix doc comments remove optionality on StructType initializer * Added empty init for contexts and flag for ownership * Fix indentation
1 parent 9ed47d0 commit 52862d4

12 files changed

+136
-43
lines changed

Sources/LLVM/ArrayType.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public struct ArrayType: IRType {
1212
public let count: Int
1313

1414
/// Creates an array type from an underlying element type and count.
15+
/// - note: The context of this type is taken from it's `elementType`
1516
public init(elementType: IRType, count: Int) {
1617
self.elementType = elementType
1718
self.count = count

Sources/LLVM/FloatType.swift

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,51 @@ import cllvm
44

55
/// `FloatType` enumerates representations of a floating value of a particular
66
/// bit width and semantics.
7-
public enum FloatType: IRType {
8-
/// 16-bit floating point value
9-
case half
10-
/// 32-bit floating point value
11-
case float
12-
/// 64-bit floating point value
13-
case double
14-
/// 80-bit floating point value (X87)
15-
case x86FP80
16-
/// 128-bit floating point value (112-bit mantissa)
17-
case fp128
18-
/// 128-bit floating point value (two 64-bits)
19-
case ppcFP128
7+
public struct FloatType: IRType {
8+
9+
/// The kind of floating point type this is
10+
public var kind: Kind
11+
12+
/// Returns the context associated with this type.
13+
public let context: Context
14+
15+
/// Creates a float type of a particular kind
16+
///
17+
/// - parameter kind: The kind of floating point type to create
18+
/// - parameter context: The context to create this type in
19+
/// - SeeAlso: http://llvm.org/docs/ProgrammersManual.html#achieving-isolation-with-llvmcontext
20+
public init(kind: Kind, in context: Context = Context.global) {
21+
self.kind = kind
22+
self.context = context
23+
}
24+
25+
public enum Kind {
26+
/// 16-bit floating point value
27+
case half
28+
/// 32-bit floating point value
29+
case float
30+
/// 64-bit floating point value
31+
case double
32+
/// 80-bit floating point value (X87)
33+
case x86FP80
34+
/// 128-bit floating point value (112-bit mantissa)
35+
case fp128
36+
/// 128-bit floating point value (two 64-bits)
37+
case ppcFP128
38+
}
39+
40+
/// 16-bit floating point value in the global context
41+
public static let half = FloatType(kind: .half)
42+
/// 32-bit floating point value in the global context
43+
public static let float = FloatType(kind: .float)
44+
/// 64-bit floating point value in the global context
45+
public static let double = FloatType(kind: .double)
46+
/// 80-bit floating point value (X87) in the global context
47+
public static let x86FP80 = FloatType(kind: .x86FP80)
48+
/// 128-bit floating point value (112-bit mantissa) in the global context
49+
public static let fp128 = FloatType(kind: .fp128)
50+
/// 128-bit floating point value (two 64-bits) in the global context
51+
public static let ppcFP128 = FloatType(kind: .ppcFP128)
2052

2153
/// Creates a constant floating value of this type from a Swift `Double` value.
2254
public func constant(_ value: Double) -> Constant<Floating> {
@@ -25,13 +57,13 @@ public enum FloatType: IRType {
2557

2658
/// Retrieves the underlying LLVM type object.
2759
public func asLLVM() -> LLVMTypeRef {
28-
switch self {
29-
case .half: return LLVMHalfType()
30-
case .float: return LLVMFloatType()
31-
case .double: return LLVMDoubleType()
32-
case .x86FP80: return LLVMX86FP80Type()
33-
case .fp128: return LLVMFP128Type()
34-
case .ppcFP128: return LLVMPPCFP128Type()
60+
switch kind {
61+
case .half: return LLVMHalfTypeInContext(context.llvm)
62+
case .float: return LLVMFloatTypeInContext(context.llvm)
63+
case .double: return LLVMDoubleTypeInContext(context.llvm)
64+
case .x86FP80: return LLVMX86FP80TypeInContext(context.llvm)
65+
case .fp128: return LLVMFP128TypeInContext(context.llvm)
66+
case .ppcFP128: return LLVMPPCFP128TypeInContext(context.llvm)
3567
}
3668
}
3769
}

Sources/LLVM/FunctionType.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public struct FunctionType: IRType {
2020
/// - parameter returnType: The return type of the function type.
2121
/// - parameter isVarArg: Indicates whether this function type is variadic.
2222
/// Defaults to `false`.
23+
/// - note: The context of this type is taken from it's `returnType`
2324
public init(argTypes: [IRType], returnType: IRType, isVarArg: Bool = false) {
2425
self.argTypes = argTypes
2526
self.returnType = returnType

Sources/LLVM/IRType.swift

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,27 @@ public extension IRType {
2929
public func constPointerNull() -> IRValue {
3030
return LLVMConstPointerNull(asLLVM())
3131
}
32+
33+
/// Returns the context associated with this type
34+
public var context: Context {
35+
return Context(llvm: LLVMGetTypeContext(asLLVM()))
36+
}
3237
}
3338

3439
internal func convertType(_ type: LLVMTypeRef) -> IRType {
40+
let context = Context(llvm: LLVMGetTypeContext(type))
3541
switch LLVMGetTypeKind(type) {
36-
case LLVMVoidTypeKind:
37-
return VoidType()
38-
case LLVMHalfTypeKind:
39-
return FloatType.half
40-
case LLVMFloatTypeKind: return FloatType.float
41-
case LLVMDoubleTypeKind: return FloatType.double
42-
case LLVMX86_FP80TypeKind: return FloatType.x86FP80
43-
case LLVMFP128TypeKind: return FloatType.fp128
44-
case LLVMPPC_FP128TypeKind: return FloatType.fp128
45-
case LLVMLabelTypeKind: return LabelType()
42+
case LLVMVoidTypeKind: return VoidType(in: context)
43+
case LLVMFloatTypeKind: return FloatType(kind: .float, in: context)
44+
case LLVMHalfTypeKind: return FloatType(kind: .half, in: context)
45+
case LLVMDoubleTypeKind: return FloatType(kind: .double, in: context)
46+
case LLVMX86_FP80TypeKind: return FloatType(kind: .x86FP80, in: context)
47+
case LLVMFP128TypeKind: return FloatType(kind: .fp128, in: context)
48+
case LLVMPPC_FP128TypeKind: return FloatType(kind: .fp128, in: context)
49+
case LLVMLabelTypeKind: return LabelType(in: context)
4650
case LLVMIntegerTypeKind:
4751
let width = LLVMGetIntTypeWidth(type)
48-
return IntType(width: Int(width))
52+
return IntType(width: Int(width), in: context)
4953
case LLVMFunctionTypeKind:
5054
var params = [IRType]()
5155
let count = Int(LLVMCountParamTypes(type))
@@ -76,7 +80,7 @@ internal func convertType(_ type: LLVMTypeRef) -> IRType {
7680
case LLVMMetadataTypeKind:
7781
return MetadataType(llvm: type)
7882
case LLVMX86_MMXTypeKind:
79-
return X86MMXType()
83+
return X86MMXType(in: context)
8084
case LLVMTokenTypeKind:
8185
return TokenType(llvm: type)
8286
default: fatalError("unknown type kind for type \(type)")

Sources/LLVM/IntType.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@ public struct IntType: IRType {
1111
/// Retrieves the bit width of this integer type.
1212
public let width: Int
1313

14+
/// Returns the context associated with this type.
15+
public let context: Context
16+
1417
/// Creates an integer type with the specified bit width.
15-
public init(width: Int) { self.width = width }
18+
///
19+
/// - parameter width: The width in bits of the integer type
20+
/// - parameter context: The context to create this type in
21+
/// - SeeAlso: http://llvm.org/docs/ProgrammersManual.html#achieving-isolation-with-llvmcontext
22+
public init(width: Int, in context: Context = Context.global) {
23+
self.width = width
24+
self.context = context
25+
}
1626

1727
/// Retrieves the `i1` type.
1828
public static let int1 = IntType(width: 1)
@@ -68,6 +78,6 @@ public struct IntType: IRType {
6878

6979
/// Retrieves the underlying LLVM type object.
7080
public func asLLVM() -> LLVMTypeRef {
71-
return LLVMIntType(UInt32(width))
81+
return LLVMIntTypeInContext(context.llvm, UInt32(width))
7282
}
7383
}

Sources/LLVM/LabelType.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,20 @@ import cllvm
44

55
/// `LabelType` represents code labels.
66
public struct LabelType: IRType {
7+
8+
/// Returns the context associated with this type.
9+
public let context: Context
10+
711
/// Creates a code label.
8-
public init() {}
12+
///
13+
/// - parameter context: The context to create this type in
14+
/// - SeeAlso: http://llvm.org/docs/ProgrammersManual.html#achieving-isolation-with-llvmcontext
15+
public init(in context: Context = Context.global) {
16+
self.context = context
17+
}
918

1019
/// Retrieves the underlying LLVM type object.
1120
public func asLLVM() -> LLVMTypeRef {
12-
return LLVMLabelType()
21+
return LLVMLabelTypeInContext(context.llvm)
1322
}
1423
}

Sources/LLVM/Module.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,27 @@ import cllvm
55
/// A `Context` represents execution states for the core LLVM IR system.
66
public class Context {
77
internal let llvm: LLVMContextRef
8+
internal let ownsContext: Bool
89

910
/// Retrieves the global context instance.
1011
public static let global = Context(llvm: LLVMGetGlobalContext()!)
1112

13+
/// Creates a `Context` object using `LLVMContextCreate`
14+
public init() {
15+
llvm = LLVMContextCreate()
16+
ownsContext = true
17+
}
18+
1219
/// Creates a `Context` object from an `LLVMContextRef` object.
13-
public init(llvm: LLVMContextRef) {
20+
public init(llvm: LLVMContextRef, ownsContext: Bool = false) {
1421
self.llvm = llvm
22+
self.ownsContext = ownsContext
23+
}
24+
25+
deinit {
26+
if ownsContext {
27+
LLVMContextDispose(llvm)
28+
}
1529
}
1630
}
1731

Sources/LLVM/PointerType.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public struct PointerType: IRType {
2323
/// - parameter pointee: The type of the pointed-to object.
2424
/// - parameter addressSpace: The optional address space where the pointed-to
2525
/// object resides.
26+
/// - note: The context of this type is taken from it's pointee
2627
public init(pointee: IRType, addressSpace: Int = 0) {
2728
// FIXME: This class of invalid reference is not caught by Module.verify(),
2829
// only `lli`.

Sources/LLVM/StructType.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ public struct StructType: IRType {
3535
/// - parameter elementTypes: A list of types of members of this structure.
3636
/// - parameter isPacked: Whether or not this structure is 1-byte aligned with
3737
/// no packing between fields. Defaults to `false`.
38-
public init(elementTypes: [IRType], isPacked: Bool = false) {
38+
/// - parameter context: The context to create this type in
39+
/// - SeeAlso: http://llvm.org/docs/ProgrammersManual.html#achieving-isolation-with-llvmcontext
40+
public init(elementTypes: [IRType], isPacked: Bool = false, in context: Context = Context.global) {
3941
var irTypes = elementTypes.map { $0.asLLVM() as Optional }
4042
self.llvm = irTypes.withUnsafeMutableBufferPointer { buf in
41-
LLVMStructType(buf.baseAddress, UInt32(buf.count), isPacked.llvm)
43+
return LLVMStructTypeInContext(context.llvm, buf.baseAddress, UInt32(buf.count), isPacked.llvm)
4244
}
4345
}
4446

Sources/LLVM/VectorType.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public struct VectorType: IRType {
1616
///
1717
/// - parameter elementType: The type of elements of this vector.
1818
/// - parameter count: The number of elements in this vector.
19+
/// - note: The context of this type is taken from it's `elementType`
1920
public init(elementType: IRType, count: Int) {
2021
self.elementType = elementType
2122
self.count = count

Sources/LLVM/VoidType.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,20 @@ import cllvm
44

55
/// The `Void` type represents any value and has no size.
66
public struct VoidType: IRType {
7+
8+
/// Returns the context associated with this type.
9+
public let context: Context
10+
711
/// Creates an instance of the `Void` type.
8-
public init() {}
12+
///
13+
/// - parameter context: The context to create this type in
14+
/// - SeeAlso: http://llvm.org/docs/ProgrammersManual.html#achieving-isolation-with-llvmcontext
15+
public init(in context: Context = Context.global) {
16+
self.context = context
17+
}
918

1019
/// Retrieves the underlying LLVM type object.
1120
public func asLLVM() -> LLVMTypeRef {
12-
return LLVMVoidType()
21+
return LLVMVoidTypeInContext(context.llvm)
1322
}
1423
}

Sources/LLVM/X86MMXType.swift

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,20 @@ import cllvm
99
/// represented as intrinsic or asm calls with arguments and/or results of this
1010
/// type. There are no arrays, vectors or constants of this type.
1111
public struct X86MMXType: IRType {
12+
13+
/// Returns the context associated with this type.
14+
public let context: Context
15+
1216
/// Creates an `X86MMXType`.
13-
public init() {}
17+
///
18+
/// - parameter context: The context to create this type in
19+
/// - SeeAlso: http://llvm.org/docs/ProgrammersManual.html#achieving-isolation-with-llvmcontext
20+
public init(in context: Context = Context.global) {
21+
self.context = context
22+
}
1423

1524
/// Retrieves the underlying LLVM type object.
1625
public func asLLVM() -> LLVMTypeRef {
17-
return LLVMX86MMXType()
26+
return LLVMX86MMXTypeInContext(context.llvm)
1827
}
1928
}

0 commit comments

Comments
 (0)