1
1
import cllvm
2
2
3
+ /// A `Context` represents execution states for the core LLVM IR system.
3
4
public class Context {
4
5
internal let llvm : LLVMContextRef
6
+
7
+ /// Retrieves the global context instance.
5
8
public static let global = Context ( llvm: LLVMGetGlobalContext ( ) !)
9
+
10
+ /// Creates a `Context` object from an `LLVMContextRef` object.
6
11
public init ( llvm: LLVMContextRef ) {
7
12
self . llvm = llvm
8
13
}
9
14
}
10
15
16
+ /// Represents the possible errors that can be thrown while interacting with a
17
+ /// `Module` object.
11
18
public enum ModuleError : Error , CustomStringConvertible {
19
+ /// Thrown when a module does not pass the module verification process.
20
+ /// Includes the reason the module did not pass verification.
12
21
case didNotPassVerification( String )
22
+ /// Thrown when a module cannot be printed at a given path. Provides the
23
+ /// erroneous path and a deeper reason why printing to that path failed.
13
24
case couldNotPrint( path: String , error: String )
25
+ /// Thrown when a module cannot emit bitcode because it contains erroneous
26
+ /// declarations.
14
27
case couldNotEmitBitCode( path: String )
15
-
28
+
16
29
public var description : String {
17
30
switch self {
18
31
case . didNotPassVerification( let message) :
@@ -25,8 +38,17 @@ public enum ModuleError: Error, CustomStringConvertible {
25
38
}
26
39
}
27
40
41
+ /// A `Module` represents the top-level structure of an LLVM program. An LLVM
42
+ /// module is effectively a translation unit or a collection of translation
43
+ /// units merged together.
28
44
public final class Module {
29
45
internal let llvm : LLVMModuleRef
46
+
47
+ /// Creates a `Module` with the given name.
48
+ ///
49
+ /// - parameter name: The name of the module.
50
+ /// - parameter context: The context to associate this module with. If no
51
+ /// context is provided, one will be inferred.
30
52
public init ( name: String , context: Context ? = nil ) {
31
53
if let context = context {
32
54
llvm = LLVMModuleCreateWithNameInContext ( name, context. llvm)
@@ -36,13 +58,21 @@ public final class Module {
36
58
self . context = Context ( llvm: LLVMGetModuleContext ( llvm) !)
37
59
}
38
60
}
39
-
61
+
62
+ /// Returns the context associated with this module.
40
63
public let context : Context
41
-
64
+
65
+ /// Obtain the data layout for this module.
42
66
public var dataLayout : TargetData {
43
67
return TargetData ( llvm: LLVMGetModuleDataLayout ( llvm) )
44
68
}
45
-
69
+
70
+ /// Print a representation of a module to a file at the given path.
71
+ ///
72
+ /// If the provided path is not suitable for writing, this function will throw
73
+ /// `ModuleError.couldNotPrint`.
74
+ ///
75
+ /// - parameter path: The path to write the module's representation to.
46
76
public func print( to path: String ) throws {
47
77
var err : UnsafeMutablePointer < Int8 > ?
48
78
path. withCString { cString in
@@ -55,7 +85,13 @@ public final class Module {
55
85
throw ModuleError . couldNotPrint ( path: path, error: String ( cString: err) )
56
86
}
57
87
}
58
-
88
+
89
+ /// Writes the bitcode of elements in this module to a file at the given path.
90
+ ///
91
+ /// If the provided path is not suitable for writing, this function will throw
92
+ /// `ModuleError.couldNotEmitBitCode`.
93
+ ///
94
+ /// - parameter path: The path to write the module's representation to.
59
95
public func emitBitCode( to path: String ) throws {
60
96
let status = path. withCString { cString -> Int32 in
61
97
let mutable = strdup ( cString)
@@ -67,17 +103,35 @@ public final class Module {
67
103
throw ModuleError . couldNotEmitBitCode ( path: path)
68
104
}
69
105
}
70
-
106
+
107
+ /// Searches for and retrieves a type with the given name in this module if
108
+ /// that name references an existing type.
109
+ ///
110
+ /// - parameter name: The name of the type to create.
111
+ ///
112
+ /// - returns: A representation of the newly created type with the given name
113
+ /// or nil if such a representation could not be created.
71
114
public func type( named name: String ) -> IRType ? {
72
115
guard let type = LLVMGetTypeByName ( llvm, name) else { return nil }
73
116
return convertType ( type)
74
117
}
75
-
118
+
119
+ /// Searches for and retrieves a function with the given name in this module
120
+ /// if that name references an existing function.
121
+ ///
122
+ /// - parameter name: The name of the function to create.
123
+ ///
124
+ /// - returns: A representation of the newly created function with the given
125
+ /// name or nil if such a representation could not be created.
76
126
public func function( named name: String ) -> Function ? {
77
127
guard let fn = LLVMGetNamedFunction ( llvm, name) else { return nil }
78
128
return Function ( llvm: fn)
79
129
}
80
-
130
+
131
+ /// Verifies that this module is valid, taking the specified action if not.
132
+ /// If this module did not pass verification, a description of any invalid
133
+ /// constructs is provided with the thrown
134
+ /// `ModuleError.didNotPassVerification` error.
81
135
public func verify( ) throws {
82
136
var message : UnsafeMutablePointer < Int8 > ?
83
137
let status = Int ( LLVMVerifyModule ( llvm, LLVMReturnStatusAction, & message) )
@@ -86,7 +140,8 @@ public final class Module {
86
140
throw ModuleError . didNotPassVerification ( String ( cString: message) )
87
141
}
88
142
}
89
-
143
+
144
+ /// Dump a representation of this module to stderr.
90
145
public func dump( ) {
91
146
LLVMDumpModule ( llvm)
92
147
}
0 commit comments