Skip to content

Commit abd6279

Browse files
committed
TSCUtility: support additional spellings for ARM
ARM uses `armv[4-9]-?[arm]` as the arch field to encode the ISA version and the core type for ARMv7. Use the custom parsing logic similar to the other fields to accommodate the spelling.
1 parent 71dcf5a commit abd6279

File tree

2 files changed

+118
-3
lines changed

2 files changed

+118
-3
lines changed

Sources/TSCUtility/Triple.swift

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,21 @@ public struct Triple: Encodable, Equatable {
3636
case unknownOS(os: String)
3737
}
3838

39-
public enum Arch: String, Encodable {
39+
public enum ARMCore: String, Encodable, CaseIterable {
40+
case a = "a"
41+
case r = "r"
42+
case m = "m"
43+
}
44+
45+
public enum Arch: Encodable {
4046
case x86_64
4147
case x86_64h
4248
case i686
4349
case powerpc64le
4450
case s390x
4551
case aarch64
4652
case amd64
47-
case armv7
53+
case armv7(core: ARMCore?)
4854
case armv6
4955
case armv5
5056
case arm
@@ -111,7 +117,7 @@ public struct Triple: Encodable, Equatable {
111117
throw Error.badFormat(triple: string)
112118
}
113119

114-
guard let arch = Arch(rawValue: components[0]) else {
120+
guard let arch = Triple.parseArch(components[0]) else {
115121
throw Error.unknownArch(arch: components[0])
116122
}
117123

@@ -135,6 +141,39 @@ public struct Triple: Encodable, Equatable {
135141
self.abiVersion = abiVersion
136142
}
137143

144+
fileprivate static func parseArch(_ string: String) -> Arch? {
145+
let candidates: [String:Arch] = [
146+
"x86_64h": .x86_64h,
147+
"x86_64": .x86_64,
148+
"i686": .i686,
149+
"powerpc64le": .powerpc64le,
150+
"s390x": .s390x,
151+
"aarch64": .aarch64,
152+
"amd64": .amd64,
153+
"armv7": .armv7(core: nil),
154+
"armv6": .armv6,
155+
"armv5": .armv5,
156+
"arm": .arm,
157+
"arm64": .arm64,
158+
"arm64e": .arm64e,
159+
"wasm32": .wasm32,
160+
]
161+
if let match = candidates.first(where: { string.hasPrefix($0.key) })?.value {
162+
if case let .armv7(core: _) = match {
163+
if string.hasPrefix("armv7-a") || string.hasPrefix("armv7a") {
164+
return .armv7(core: .a)
165+
} else if string.hasPrefix("armv7-r") || string.hasPrefix("armv7r") {
166+
return .armv7(core: .r)
167+
} else if string.hasPrefix("armv7-m") || string.hasPrefix("armv7m") {
168+
return .armv7(core: .m)
169+
}
170+
return .armv7(core: nil)
171+
}
172+
return match
173+
}
174+
return nil
175+
}
176+
138177
fileprivate static func parseOS(_ string: String) -> OS? {
139178
var candidates = OS.allCases.map{ (name: $0.rawValue, value: $0) }
140179
// LLVM target triples support this alternate spelling as well.
@@ -201,6 +240,7 @@ public struct Triple: Encodable, Equatable {
201240
fatalError("Failed to get target info (\(error))")
202241
#endif
203242
}
243+
204244
// Parse the compiler's JSON output.
205245
let parsedTargetInfo: JSON
206246
do {
@@ -283,6 +323,78 @@ extension Triple {
283323
}
284324
}
285325

326+
extension Triple.Arch: CustomStringConvertible {
327+
public var description: String {
328+
switch self {
329+
case .x86_64:
330+
return "x86_64"
331+
case .x86_64h:
332+
return "x86_64h"
333+
case .i686:
334+
return "i686"
335+
case .powerpc64le:
336+
return "powerpc64le"
337+
case .s390x:
338+
return "s390x"
339+
case .aarch64:
340+
return "aarch64"
341+
case .amd64:
342+
return "amd64"
343+
case .armv7(.none):
344+
return "armv7"
345+
case let .armv7(core: .some(core)):
346+
return "armv7\(core)"
347+
case .armv6:
348+
return "armv6"
349+
case .armv5:
350+
return "armv5"
351+
case .arm:
352+
return "arm"
353+
case .arm64:
354+
return "arm64"
355+
case .arm64e:
356+
return "arm64e"
357+
case .wasm32:
358+
return "wasm32"
359+
}
360+
}
361+
}
362+
363+
extension Triple.Arch: Equatable {
364+
public static func == (_ lhs: Triple.Arch, _ rhs: Triple.Arch) -> Bool {
365+
switch (lhs, rhs) {
366+
case (.x86_64, .x86_64):
367+
return true
368+
case (.x86_64h, .x86_64h):
369+
return true
370+
case (.i686, .i686):
371+
return true
372+
case (.powerpc64le, .powerpc64le):
373+
return true
374+
case (.s390x, .s390x):
375+
return true
376+
case (.armv7(.none), .armv7(.none)):
377+
return true
378+
case let (.armv7(.some(lhs)), .armv7(.some(rhs))) where lhs == rhs:
379+
return true
380+
case (.armv6, .armv6):
381+
return true
382+
case (.armv5, .armv5):
383+
return true
384+
case (.arm, .arm):
385+
return true
386+
case (.arm64, .arm64):
387+
return true
388+
case (.arm64e, .arm64e):
389+
return true
390+
case (.wasm32, .wasm32):
391+
return true
392+
default:
393+
return false
394+
}
395+
}
396+
}
397+
286398
extension Triple.Error: CustomNSError {
287399
public var errorUserInfo: [String : Any] {
288400
return [NSLocalizedDescriptionKey: "\(self)"]

Tests/TSCUtilityTests/TripleTests.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ class TripleTests : XCTestCase {
4040
let linuxWithABIVersion = try? Triple("x86_64-unknown-linux-gnu42")
4141
XCTAssertEqual(linuxWithABIVersion!.abi, .other(name: "gnu"))
4242
XCTAssertEqual(linuxWithABIVersion!.abiVersion, "42")
43+
44+
let androidArm = try? Triple("armv7a-unknown-linux-androideabi")
45+
XCTAssertEqual(androidArm!.arch, .armv7(core: .a))
4346
}
4447

4548
func testEquality() throws {

0 commit comments

Comments
 (0)