Skip to content

Commit 7c12785

Browse files
committed
Extend Modules
1 parent 28627f8 commit 7c12785

File tree

5 files changed

+405
-295
lines changed

5 files changed

+405
-295
lines changed

.github/workflows/swift.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
swift --version
3030
3131
- name: Build
32-
run: swift build -v
32+
run: swift build -Xswiftc -DCLI_BUILD
3333
# - name: Run tests
3434
# run: swift test -v
3535

Package.swift

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
// swift-tools-version: 5.9
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

4-
import PackageDescription
54
import Foundation
5+
import PackageDescription
66

77
// Get LLVM flags and version
8-
let (cFlags, linkFlags, _version) = try! getLLVMConfig()
8+
#if CLI_BUILD
9+
let (cFlags, linkFlags, _version) = try! getLLVMConfig()
10+
#else
11+
let (cFlags, linkFlags, _version) = ([String](), [String](), [Int]())
12+
#endif
913

1014
let package = Package(
1115
name: "llvm-api",
@@ -15,17 +19,18 @@ let package = Package(
1519
targets: [
1620
.systemLibrary(
1721
name: "CLLVM",
18-
path: "llvm-api/CLLVM"
22+
path: "llvm-api/CLLVM",
23+
pkgConfig: "cllvm"
1924
),
2025
.target(
2126
name: "LLVM",
2227
dependencies: ["CLLVM"],
2328
path: "llvm-api/LLVM",
2429
cSettings: [
25-
.unsafeFlags(cFlags)
30+
.unsafeFlags(cFlags),
2631
],
2732
linkerSettings: [
28-
.unsafeFlags(linkFlags)
33+
.unsafeFlags(linkFlags),
2934
]
3035
),
3136
]

llvm-api/LLVM/Core/Context.swift

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import CLLVM
1212
/// context, it is recommended that each thread of execution be assigned a unique
1313
/// context. LLVM's core infrastructure and API provides no locking guarantees
1414
/// and no atomicity guarantees.
15-
public class Context: ContextRef {
15+
public final class Context: ContextRef {
1616
private let llvm: LLVMContextRef
1717

1818
/// Retrieves the underlying LLVM type object.
@@ -185,20 +185,17 @@ public class Context: ContextRef {
185185
}
186186

187187
/// Get the string attribute's kind.
188-
public static func getStringAttributeKind(attributeRef: AttributeRef, length: UInt32) -> String? {
189-
var mutLength = length
190-
guard let cString = withUnsafeMutablePointer(to: &mutLength, { lengthPtr in
191-
LLVMGetStringAttributeKind(attributeRef.attributeRef, lengthPtr)
192-
}) else { return nil }
188+
public static func getStringAttributeKind(attributeRef: AttributeRef) -> String? {
189+
var length: UInt32 = 0
190+
guard let cString = LLVMGetStringAttributeKind(attributeRef.attributeRef, &length) else { return nil }
193191
return String(cString: cString)
194192
}
195193

196194
/// Get the string attribute's value.
197-
public static func getStringAttributeValue(attributeRef: AttributeRef, length: UInt32) -> String? {
198-
var mutLength = length
199-
guard let cString = withUnsafeMutablePointer(to: &mutLength, { lengthPtr in
200-
LLVMGetStringAttributeValue(attributeRef.attributeRef, lengthPtr)
201-
}) else { return nil }
195+
public static func getStringAttributeValue(attributeRef: AttributeRef) -> String? {
196+
var length: UInt32 = 0
197+
guard let cString =
198+
LLVMGetStringAttributeValue(attributeRef.attributeRef, &length) else { return nil }
202199
return String(cString: cString)
203200
}
204201

llvm-api/LLVM/Core/Modules.swift

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import CLLVM
2+
3+
/// Modules represent the top-level structure in an LLVM program. An LLVM
4+
/// module is effectively a translation unit or a collection of
5+
/// translation units merged together.
6+
public final class Module: ModuleRef {
7+
private let llvm: LLVMModuleRef
8+
9+
/// Retrieves the underlying LLVM value object.
10+
public var moduleRef: LLVMModuleRef { llvm }
11+
12+
/// Init function by LLVM Value
13+
public init(llvm: LLVMModuleRef) {
14+
self.llvm = llvm
15+
}
16+
17+
/// Create a new, empty module in the global context.
18+
///
19+
/// This is equivalent to calling LLVMModuleCreateWithNameInContext with
20+
/// LLVMGetGlobalContext() as the context parameter.
21+
///
22+
/// Every invocation should be paired with LLVMDisposeModule() or memory will be leaked.
23+
public init(name: String) {
24+
llvm = name.withCString { cString in
25+
LLVMModuleCreateWithName(cString)
26+
}
27+
}
28+
29+
/// Create a new, empty module in a specific context.
30+
///
31+
/// Every invocation should be paired with LLVMDisposeModule() or memory will be leaked.
32+
public init(name: String, context: ContextRef) {
33+
llvm = name.withCString { cString in
34+
LLVMModuleCreateWithNameInContext(cString, context.contextRef)
35+
}
36+
}
37+
38+
/// Return an exact copy of the specified module.
39+
public func clone_nodule() -> ModuleRef {
40+
let new_module = LLVMCloneModule(llvm)!
41+
return Self(llvm: new_module)
42+
}
43+
44+
/// Obtain the identifier of a module.
45+
public var getLLVMModuleIdentifier: String {
46+
var length: UInt = 0
47+
guard let cString = LLVMGetModuleIdentifier(llvm, &length) else { return "" }
48+
return String(cString: cString)
49+
}
50+
51+
public func setLLVMModuleIdentifier(module: LLVMModuleRef, identifier: String) {
52+
identifier.withCString { cString in
53+
LLVMSetModuleIdentifier(module, cString, identifier.count)
54+
}
55+
}
56+
57+
public var getModuleIdentifier: String? {
58+
var length: UInt = 0
59+
guard let cString = LLVMGetModuleIdentifier(llvm, &length) else {
60+
return nil
61+
}
62+
return String(cString: cString)
63+
}
64+
65+
/// Set the identifier of a module to a string Ident with length Len.
66+
public func setSourceFileName(fileName: String) {
67+
fileName.withCString { cString in
68+
LLVMSetSourceFileName(llvm, cString, fileName.utf8.count)
69+
}
70+
}
71+
72+
/// Obtain the module's original source file name.
73+
public var getSourceFileName: String? {
74+
var length: size_t = 0
75+
guard let cString = LLVMGetSourceFileName(llvm, &length) else {
76+
return nil
77+
}
78+
return String(cString: cString)
79+
}
80+
81+
/// Set the data layout for a module.
82+
public func setDataLayout(module: LLVMModuleRef, dataLayout: String) {
83+
dataLayout.withCString { cString in
84+
LLVMSetDataLayout(module, cString)
85+
}
86+
}
87+
88+
/// Obtain the data layout for a module.
89+
public var getDataLayout: String? {
90+
guard let cString = LLVMGetDataLayoutStr(llvm) else {
91+
return nil
92+
}
93+
return String(cString: cString)
94+
}
95+
96+
/// Set the target triple for a module.
97+
public func setTarget(triple: String) {
98+
triple.withCString { cString in
99+
LLVMSetTarget(llvm, cString)
100+
}
101+
}
102+
103+
/// Destroy a module instance.
104+
///
105+
/// This must be called for every created module or memory will be leaked.
106+
deinit {
107+
LLVMDisposeModule(llvm)
108+
}
109+
}

0 commit comments

Comments
 (0)