Skip to content

Commit 21f4aef

Browse files
committed
Added CompositeConstant
1 parent 7ce4e17 commit 21f4aef

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import CLLVM
2+
3+
/// Functions in this group operate on composite constants.
4+
public enum CompositeConstant {
5+
/// Create a ConstantDataSequential and initialize it with a string.
6+
public static func constStringInContext(context: ContextRef, str: String, dontNullTerminate: Bool) -> Value {
7+
let valueRef = str.withCString { cStr in
8+
let length = UInt32(str.utf8.count)
9+
return LLVMConstStringInContext(context.contextRef, cStr, length, dontNullTerminate.llvm)!
10+
}
11+
return Value(llvm: valueRef)
12+
}
13+
14+
/// Create a ConstantDataSequential with string content in the global context.
15+
/// This is the same as `constStringInContext` except it operates on the global context.
16+
public static func constString(str: String, dontNullTerminate: Bool) -> Value {
17+
let valueRef = str.withCString { cStr in
18+
let length = UInt32(str.utf8.count)
19+
return LLVMConstString(cStr, length, dontNullTerminate.llvm)!
20+
}
21+
return Value(llvm: valueRef)
22+
}
23+
24+
/// Returns true if the specified constant is an array of i8.
25+
public static func isConstantString(value: ValueRef) -> Bool {
26+
LLVMIsConstantString(value.valueRef) != 0
27+
}
28+
29+
/// Get the given constant data sequential as a string.
30+
public static func getString(value: ValueRef) -> (String, UInt) {
31+
var length: UInt = 0
32+
let lengthPtr = UnsafeMutablePointer<UInt>.allocate(capacity: 1)
33+
defer {
34+
lengthPtr.deallocate()
35+
}
36+
37+
if let cStr = LLVMGetAsString(value.valueRef, lengthPtr) {
38+
length = lengthPtr.pointee
39+
let swiftStr = String(cString: cStr)
40+
return (swiftStr, length)
41+
} else {
42+
return ("", 0)
43+
}
44+
}
45+
46+
/// Create an anonymous `ConstantStruct` with the specified values.
47+
public static func constStructInContext(context: ContextRef, constantVals: [ValueRef], packed: Bool) -> Value? {
48+
let count = UInt32(constantVals.count)
49+
let vals = UnsafeMutablePointer<LLVMValueRef?>.allocate(capacity: Int(count))
50+
defer {
51+
vals.deallocate()
52+
}
53+
54+
for (index, val) in constantVals.enumerated() {
55+
vals[index] = val.valueRef
56+
}
57+
guard let valueRef = LLVMConstStructInContext(context.contextRef, vals, count, packed.llvm) else { return nil }
58+
return Value(llvm: valueRef)
59+
}
60+
61+
/// Create a `ConstantStruct` in the global Context.
62+
/// This is the same as `constStructInContext` except it operates on the global `Context`.
63+
public static func createLLVMConstStruct(constantVals: [ValueRef], packed: Bool) -> Value? {
64+
let count = UInt32(constantVals.count)
65+
let vals = UnsafeMutablePointer<LLVMValueRef?>.allocate(capacity: Int(count))
66+
defer {
67+
vals.deallocate()
68+
}
69+
70+
for (index, val) in constantVals.enumerated() {
71+
vals[index] = val.valueRef
72+
}
73+
guard let valueRef = LLVMConstStruct(vals, count, packed.llvm) else { return nil }
74+
return Value(llvm: valueRef)
75+
}
76+
77+
/// Create a `ConstantArray` from values.
78+
@available(*, deprecated, message: "ConstArray is deprecated in favor of the API accurate constArray2")
79+
public static func createLLVMConstArray(elementType: TypeRef, constantValues: [ValueRef]) -> Value? {
80+
let length = UInt32(constantValues.count)
81+
let values = UnsafeMutablePointer<LLVMValueRef?>.allocate(capacity: Int(length))
82+
defer {
83+
values.deallocate()
84+
}
85+
86+
for (index, value) in constantValues.enumerated() {
87+
values[index] = value.valueRef
88+
}
89+
guard let valueRef = LLVMConstArray(elementType.typeRef, values, length) else { return nil }
90+
return Value(llvm: valueRef)
91+
}
92+
93+
/// Create a ConstantArray from values.
94+
public static func constArray2(elementType: TypeRef, constantValues: [ValueRef]) -> Value? {
95+
let length = UInt64(constantValues.count)
96+
let values = UnsafeMutablePointer<LLVMValueRef?>.allocate(capacity: Int(length))
97+
defer {
98+
values.deallocate()
99+
}
100+
101+
for (index, value) in constantValues.enumerated() {
102+
values[index] = value.valueRef
103+
}
104+
guard let valueRef = LLVMConstArray2(elementType.typeRef, values, length) else { return nil }
105+
return Value(llvm: valueRef)
106+
}
107+
108+
/**
109+
* Create a non-anonymous ConstantStruct from values.
110+
*/
111+
// LLVMValueRef LLVMConstNamedStruct(LLVMTypeRef StructTy, LLVMValueRef *ConstantVals, unsigned Count);
112+
113+
/**
114+
* Get element of a constant aggregate (struct, array or vector) at the
115+
* specified index. Returns null if the index is out of range, or it's not
116+
* possible to determine the element (e.g., because the constant is a
117+
* constant expression.)
118+
*/
119+
// LLVMValueRef LLVMGetAggregateElement(LLVMValueRef C, unsigned Idx);
120+
121+
/**
122+
* Get an element at specified index as a constant.
123+
*/
124+
// LLVM_ATTRIBUTE_C_DEPRECATED( LLVMValueRef LLVMGetElementAsConstant(LLVMValueRef C, unsigned idx), "Use LLVMGetAggregateElement instead");
125+
126+
/**
127+
* Create a ConstantVector from values.
128+
*/
129+
// LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size);
130+
}

0 commit comments

Comments
 (0)