Skip to content

Commit 504e8b0

Browse files
committed
Added struct to Constant.swift
1 parent 3ae7553 commit 504e8b0

File tree

3 files changed

+81
-4
lines changed

3 files changed

+81
-4
lines changed

Sources/LLVM/Constant.swift

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ public enum Unsigned: IntegralConstantRepresentation {}
1313
public enum Signed: IntegralConstantRepresentation {}
1414
/// Represents floating types and operations.
1515
public enum Floating: ConstantRepresentation {}
16+
/// Represents struct types and operations.
17+
public enum Struct: ConstantRepresentation {}
1618

1719
/// A `Constant` represents a value initialized to a constant. Constant values
1820
/// may be manipulated with standard Swift arithmetic operations and used with
@@ -28,6 +30,7 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
2830
case unsigned
2931
case signed
3032
case floating
33+
case `struct`
3134
}
3235
fileprivate let repr: Representation
3336

@@ -43,6 +46,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
4346
self.repr = .signed
4447
} else if reprID == ObjectIdentifier(Floating.self) {
4548
self.repr = .floating
49+
} else if reprID == ObjectIdentifier(Struct.self) {
50+
self.repr = .struct
4651
} else {
4752
fatalError("Invalid representation \(type(of: Repr.self))")
4853
}
@@ -71,6 +76,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
7176
return Constant<T>(llvm: LLVMConstIntCast(val, type.asLLVM(), /*signed:*/ false.llvm))
7277
case .floating:
7378
return Constant<T>(llvm: LLVMConstFPToUI(val, type.asLLVM()))
79+
case .struct:
80+
fatalError("Cannot cast struct type to integer type")
7481
}
7582
} else if destID == ObjectIdentifier(Signed.self) {
7683
switch self.repr {
@@ -79,6 +86,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
7986
return Constant<T>(llvm: LLVMConstIntCast(val, type.asLLVM(), /*signed:*/ true.llvm))
8087
case .floating:
8188
return Constant<T>(llvm: LLVMConstFPToSI(val, type.asLLVM()))
89+
case .struct:
90+
fatalError("Cannot cast struct type to integer type")
8291
}
8392
} else {
8493
fatalError("Invalid representation \(type(of: T.self))")
@@ -100,6 +109,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
100109
return Constant<Floating>(llvm: LLVMConstSIToFP(val, type.asLLVM()))
101110
case .floating:
102111
return Constant<Floating>(llvm: LLVMConstFPCast(val, type.asLLVM()))
112+
case .struct:
113+
fatalError("Cannot cast struct type to float type")
103114
}
104115
}
105116

@@ -152,6 +163,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
152163
}
153164
case .floating:
154165
return Constant(llvm: LLVMConstFAdd(lhsVal, rhsVal))
166+
case .struct:
167+
fatalError("Operation undefined on struct type")
155168
}
156169
}
157170

@@ -170,6 +183,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
170183
return Constant(llvm: LLVMConstAdd(lhs.llvm, rhs.llvm))
171184
case .floating:
172185
return Constant(llvm: LLVMConstFAdd(lhs.llvm, rhs.llvm))
186+
case .struct:
187+
fatalError("Operation undefined on struct type")
173188
}
174189
}
175190

@@ -199,6 +214,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
199214
}
200215
case .floating:
201216
return lhs - rhs
217+
case .struct:
218+
fatalError("Operation undefined on struct type")
202219
}
203220
}
204221

@@ -217,6 +234,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
217234
return Constant(llvm: LLVMConstSub(lhs.llvm, rhs.llvm))
218235
case .floating:
219236
return Constant(llvm: LLVMConstFSub(lhs.llvm, rhs.llvm))
237+
case .struct:
238+
fatalError("Operation undefined on struct type")
220239
}
221240
}
222241

@@ -246,6 +265,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
246265
}
247266
case .floating:
248267
return lhs * rhs
268+
case .struct:
269+
fatalError("Operation undefined on struct type")
249270
}
250271
}
251272

@@ -264,6 +285,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
264285
return Constant(llvm: LLVMConstMul(lhs.llvm, rhs.llvm))
265286
case .floating:
266287
return Constant(llvm: LLVMConstFMul(lhs.llvm, rhs.llvm))
288+
case .struct:
289+
fatalError("Operation undefined on struct type")
267290
}
268291
}
269292

@@ -285,6 +308,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
285308
return Constant(llvm: LLVMConstUDiv(lhs.llvm, rhs.llvm))
286309
case .floating:
287310
return Constant(llvm: LLVMConstFDiv(lhs.llvm, rhs.llvm))
311+
case .struct:
312+
fatalError("Operation undefined on struct type")
288313
}
289314
}
290315

@@ -306,6 +331,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
306331
return Constant(llvm: LLVMConstURem(lhs.llvm, rhs.llvm))
307332
case .floating:
308333
return Constant(llvm: LLVMConstFRem(lhs.llvm, rhs.llvm))
334+
case .struct:
335+
fatalError("Operation undefined on struct type")
309336
}
310337
}
311338

@@ -328,6 +355,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
328355
return Constant<Signed>(llvm: LLVMConstICmp(IntPredicate.equal.llvm, lhs.llvm, rhs.llvm))
329356
case .floating:
330357
return Constant<Signed>(llvm: LLVMConstFCmp(RealPredicate.orderedEqual.llvm, lhs.llvm, rhs.llvm))
358+
case .struct:
359+
fatalError("Operation undefined on struct type")
331360
}
332361
}
333362

@@ -348,6 +377,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
348377
return Constant<Signed>(llvm: LLVMConstICmp(IntPredicate.unsignedLessThan.llvm, lhs.llvm, rhs.llvm))
349378
case .floating:
350379
return Constant<Signed>(llvm: LLVMConstFCmp(RealPredicate.orderedLessThan.llvm, lhs.llvm, rhs.llvm))
380+
case .struct:
381+
fatalError("Operation undefined on struct type")
351382
}
352383
}
353384

@@ -368,6 +399,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
368399
return Constant<Signed>(llvm: LLVMConstICmp(IntPredicate.unsignedGreaterThan.llvm, lhs.llvm, rhs.llvm))
369400
case .floating:
370401
return Constant<Signed>(llvm: LLVMConstFCmp(RealPredicate.orderedGreaterThan.llvm, lhs.llvm, rhs.llvm))
402+
case .struct:
403+
fatalError("Operation undefined on struct type")
371404
}
372405
}
373406

@@ -388,6 +421,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
388421
return Constant<Signed>(llvm: LLVMConstICmp(IntPredicate.unsignedLessThanOrEqual.llvm, lhs.llvm, rhs.llvm))
389422
case .floating:
390423
return Constant<Signed>(llvm: LLVMConstFCmp(RealPredicate.orderedLessThanOrEqual.llvm, lhs.llvm, rhs.llvm))
424+
case .struct:
425+
fatalError("Operation undefined on struct type")
391426
}
392427
}
393428

@@ -408,6 +443,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
408443
return Constant<Signed>(llvm: LLVMConstICmp(IntPredicate.unsignedGreaterThanOrEqual.llvm, lhs.llvm, rhs.llvm))
409444
case .floating:
410445
return Constant<Signed>(llvm: LLVMConstFCmp(RealPredicate.orderedGreaterThanOrEqual.llvm, lhs.llvm, rhs.llvm))
446+
case .struct:
447+
fatalError("Operation undefined on struct type")
411448
}
412449
}
413450
}
@@ -521,3 +558,16 @@ extension Constant where Repr: IntegralConstantRepresentation {
521558
return Constant<T>(llvm: LLVMConstSelect(cond.llvm, then.llvm, `else`.llvm))
522559
}
523560
}
561+
562+
// MARK: Struct Operations
563+
564+
extension Constant where Repr == Struct {
565+
566+
public func getElement(indices: [Int]) -> IRValue {
567+
assert(repr == .struct)
568+
var indices = indices.map({ UInt32($0) })
569+
return indices.withUnsafeMutableBufferPointer { buf in
570+
return LLVMConstExtractValue(asLLVM(), buf.baseAddress, UInt32(buf.count))
571+
}
572+
}
573+
}

Sources/LLVM/StructType.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ public struct StructType: IRType {
6060
/// - parameter values: A list of values of members of this structure.
6161
///
6262
/// - returns: A value representing a constant value of this structure type.
63-
public func constant(values: [IRValue]) -> IRValue {
63+
public func constant(values: [IRValue]) -> Constant<Struct> {
6464
var vals = values.map { $0.asLLVM() as Optional }
6565
return vals.withUnsafeMutableBufferPointer { buf in
66-
return LLVMConstNamedStruct(asLLVM(), buf.baseAddress, UInt32(buf.count))
66+
return Constant(llvm: LLVMConstNamedStruct(asLLVM(),
67+
buf.baseAddress,
68+
UInt32(buf.count)))
6769
}
6870
}
6971

@@ -74,10 +76,12 @@ public struct StructType: IRType {
7476
/// no packing between fields. Defaults to `false`.
7577
///
7678
/// - returns: A value representing a complex constant value with given the values.
77-
public static func constant(values: [IRValue], isPacked: Bool = false) -> IRValue {
79+
public static func constant(values: [IRValue], isPacked: Bool = false) -> Constant<Struct> {
7880
var vals = values.map { $0.asLLVM() as Optional }
7981
return vals.withUnsafeMutableBufferPointer { buf in
80-
return LLVMConstStruct(buf.baseAddress, UInt32(buf.count), isPacked.llvm)
82+
return Constant(llvm: LLVMConstStruct(buf.baseAddress,
83+
UInt32(buf.count),
84+
isPacked.llvm))
8185
}
8286
}
8387

Tests/LLVMTests/ConstantSpec.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,29 @@ class ConstantSpec : XCTestCase {
8989
// FLOATINGCONST-NEXT: }
9090
module.dump()
9191
})
92+
93+
XCTAssert(fileCheckOutput(of: .stderr, withPrefixes: ["STRUCTCONST"]) {
94+
// STRUCTCONST: ; ModuleID = '[[ModuleName:ConstantTest]]'
95+
// STRUCTCONST-NEXT: source_filename = "[[ModuleName]]"
96+
let module = Module(name: "ConstantTest")
97+
let builder = IRBuilder(module: module)
98+
// STRUCTCONST: define void @main() {
99+
let main = builder.addFunction("main",
100+
type: FunctionType(argTypes: [],
101+
returnType: VoidType()))
102+
103+
let constant = StructType(elementTypes: [IntType.int64])
104+
.constant(values: [Int64(42).asLLVM()])
105+
106+
// STRUCTCONST-NEXT: entry:
107+
let entry = main.appendBasicBlock(named: "entry")
108+
builder.positionAtEnd(of: entry)
109+
110+
// STRUCTCONST-NEXT: ret { i64 } { i64 42 }
111+
builder.buildRet(constant)
112+
// STRUCTCONST-NEXT: }
113+
module.dump()
114+
})
92115
}
93116

94117
#if !os(macOS)

0 commit comments

Comments
 (0)