Skip to content

Commit 2576d01

Browse files
Added iteration attributes to Module, Global, and Function (#31)
1 parent 450ae96 commit 2576d01

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

Sources/LLVM/Function.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@ public class Function: IRGlobal {
5050
}
5151
}
5252

53+
/// Retrieves the previous function in the module, if there is one.
54+
public func previous() -> Function? {
55+
guard let previous = LLVMGetPreviousFunction(llvm) else { return nil }
56+
return Function(llvm: previous)
57+
}
58+
59+
/// Retrieves the next function in the module, if there is one.
60+
public func next() -> Function? {
61+
guard let next = LLVMGetNextFunction(llvm) else { return nil }
62+
return Function(llvm: next)
63+
}
64+
5365
/// Retrieves a parameter at the given index, if it exists.
5466
///
5567
/// - parameter index: The index of the parameter to retrieve.

Sources/LLVM/Global.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,18 @@ public struct Global: IRGlobal {
3333
set { LLVMSetThreadLocal(asLLVM(), newValue.llvm) }
3434
}
3535

36+
/// Retrieves the previous global in the module, if there is one.
37+
public func previous() -> Global? {
38+
guard let previous = LLVMGetPreviousGlobal(llvm) else { return nil }
39+
return Global(llvm: previous)
40+
}
41+
42+
/// Retrieves the next global in the module, if there is one.
43+
public func next() -> Global? {
44+
guard let next = LLVMGetNextGlobal(llvm) else { return nil }
45+
return Global(llvm: next)
46+
}
47+
3648
/// Deletes the global variable from its containing module.
3749
/// - note: This does not remove references to this global from the
3850
/// module. Ensure you have removed all insructions that reference

Sources/LLVM/Module.swift

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public enum ModuleError: Error, CustomStringConvertible {
4141
/// A `Module` represents the top-level structure of an LLVM program. An LLVM
4242
/// module is effectively a translation unit or a collection of translation
4343
/// units merged together.
44-
public final class Module {
44+
public final class Module: CustomStringConvertible {
4545
internal let llvm: LLVMModuleRef
4646

4747
/// Creates a `Module` with the given name.
@@ -123,11 +123,64 @@ public final class Module {
123123
}
124124
}
125125

126+
/// Retrieves the sequence of functions that make up this module.
127+
public var functions: AnySequence<Function> {
128+
var current = firstFunction
129+
return AnySequence<Function> {
130+
return AnyIterator<Function> {
131+
defer { current = current?.next() }
132+
return current
133+
}
134+
}
135+
}
136+
137+
/// Retrieves the first function in this module, if there are any functions.
138+
public var firstFunction: Function? {
139+
guard let fn = LLVMGetFirstFunction(llvm) else { return nil }
140+
return Function(llvm: fn)
141+
}
142+
143+
/// Retrieves the last function in this module, if there are any functions.
144+
public var lastFunction: Function? {
145+
guard let fn = LLVMGetLastFunction(llvm) else { return nil }
146+
return Function(llvm: fn)
147+
}
148+
149+
/// Retrieves the first global in this module, if there are any globals.
150+
public var firstGlobal: Global? {
151+
guard let fn = LLVMGetFirstGlobal(llvm) else { return nil }
152+
return Global(llvm: fn)
153+
}
154+
155+
/// Retrieves the last global in this module, if there are any globals.
156+
public var lastGlobal: Global? {
157+
guard let fn = LLVMGetLastGlobal(llvm) else { return nil }
158+
return Global(llvm: fn)
159+
}
160+
161+
/// Retrieves the sequence of functions that make up this module.
162+
public var globals: AnySequence<Global> {
163+
var current = firstGlobal
164+
return AnySequence<Global> {
165+
return AnyIterator<Global> {
166+
defer { current = current?.next() }
167+
return current
168+
}
169+
}
170+
}
171+
126172
/// Dump a representation of this module to stderr.
127173
public func dump() {
128174
LLVMDumpModule(llvm)
129175
}
130176

177+
/// The full text IR of this module
178+
public var description: String {
179+
let cStr = LLVMPrintModuleToString(llvm)!
180+
defer { LLVMDisposeMessage(cStr) }
181+
return String(cString: cStr)
182+
}
183+
131184
deinit {
132185
LLVMDisposeModule(llvm)
133186
}

0 commit comments

Comments
 (0)