Skip to content

Commit 983422b

Browse files
authored
Merge pull request #80 from sjavora/triple-normalization-upgrade
Windows triple normalization
2 parents 7758e7f + 3d096a4 commit 983422b

File tree

2 files changed

+139
-58
lines changed

2 files changed

+139
-58
lines changed

Sources/SwiftDriver/Utilities/Triple.swift

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,53 @@ public struct Triple {
105105
parser.rematch(&parsedOS, at: 2)
106106
parser.rematch(&parsedEnv, at: 3)
107107

108-
// TODO: This normalization logic is a little less robust than LLVM's.
109-
// In particular, it doesn't correct Windows triples as well as
110-
// llvm::Triple::normalize() does.
108+
let isCygwin = parser.componentsIndicateCygwin
109+
let isMinGW32 = parser.componentsIndicateMinGW32
110+
111+
if
112+
let parsedEnv = parsedEnv,
113+
parsedEnv.value.environment == .android,
114+
parsedEnv.substring.hasPrefix("androideabi") {
115+
let androidVersion = parsedEnv.substring.dropFirst("androideabi".count)
116+
117+
parser.components[3] = "android\(androidVersion)"
118+
}
119+
120+
// SUSE uses "gnueabi" to mean "gnueabihf"
121+
if parsedVendor?.value == .suse && parsedEnv?.value.environment == .gnueabi {
122+
parser.components[3] = "gnueabihf"
123+
}
124+
125+
if parsedOS?.value == .win32 {
126+
parser.components.resize(toCount: 4, paddingWith: "")
127+
parser.components[2] = "windows"
128+
if parsedEnv?.value.environment == nil {
129+
if let objectFormat = parsedEnv?.value.objectFormat, objectFormat != .coff {
130+
parser.components[3] = Substring(objectFormat.name)
131+
} else {
132+
parser.components[3] = "msvc"
133+
}
134+
}
135+
} else if isMinGW32 {
136+
parser.components.resize(toCount: 4, paddingWith: "")
137+
parser.components[2] = "windows"
138+
parser.components[3] = "gnu"
139+
} else if isCygwin {
140+
parser.components.resize(toCount: 4, paddingWith: "")
141+
parser.components[2] = "windows"
142+
parser.components[3] = "cygnus"
143+
}
144+
145+
if isMinGW32 || isCygwin || (parsedOS?.value == .win32 && parsedEnv?.value.environment != nil) {
146+
if let objectFormat = parsedEnv?.value.objectFormat, objectFormat != .coff {
147+
parser.components.resize(toCount: 5, paddingWith: "")
148+
parser.components[4] = Substring(objectFormat.name)
149+
}
150+
}
111151

112152
// Now that we've parsed everything, we construct a normalized form of the
113153
// triple string.
114-
triple = parser.components.map { $0 == "" ? "unknown" : $0 }
115-
.joined(separator: "-")
154+
triple = parser.components.map({ $0.isEmpty ? "unknown" : $0 }).joined(separator: "-")
116155
}
117156
else {
118157
triple = string
@@ -141,6 +180,14 @@ public struct Triple {
141180

142181
fileprivate protocol TripleComponent {
143182
static func parse(_ component: Substring) -> Self?
183+
184+
static func valueIsValid(_ value: Substring) -> Bool
185+
}
186+
187+
extension TripleComponent {
188+
static func valueIsValid(_ value: Substring) -> Bool {
189+
parse(value) != nil
190+
}
144191
}
145192

146193
fileprivate struct ParsedComponent<Value: TripleComponent> {
@@ -178,6 +225,14 @@ fileprivate struct TripleParser {
178225
var components: [Substring]
179226
var isMatched: Set<Int> = []
180227

228+
var componentsIndicateCygwin: Bool {
229+
components.count > 2 ? components[2].hasPrefix("cygwin") : false
230+
}
231+
232+
var componentsIndicateMinGW32: Bool {
233+
components.count > 2 ? components[2].hasPrefix("mingw") : false
234+
}
235+
181236
init(_ string: String, allowMore: Bool) {
182237
components = string.split(
183238
separator: "-", maxSplits: allowMore ? Int.max : 3,
@@ -214,11 +269,11 @@ fileprivate struct TripleParser {
214269
"Lost the parsed component somehow?")
215270

216271
for i in unmatchedIndices {
217-
guard let parsed = ParsedComponent(components[i], as: Value.self) else {
272+
guard Value.valueIsValid(components[i]) else {
218273
continue
219274
}
220275

221-
value = parsed
276+
value = ParsedComponent(components[i], as: Value.self)
222277
shiftComponent(at: i, to: correctIndex)
223278
isMatched.insert(correctIndex)
224279

@@ -1120,6 +1175,10 @@ extension Triple {
11201175
return nil
11211176
}
11221177
}
1178+
1179+
fileprivate static func valueIsValid(_ value: Substring) -> Bool {
1180+
parse(value) != nil || value.hasPrefix("cygwin") || value.hasPrefix("mingw")
1181+
}
11231182
}
11241183
}
11251184

@@ -1361,6 +1420,16 @@ extension Triple {
13611420
return .wasm
13621421
}
13631422
}
1423+
1424+
var name: String {
1425+
switch self {
1426+
case .coff: return "coff"
1427+
case .elf: return "elf"
1428+
case .macho: return "macho"
1429+
case .wasm: return "wasm"
1430+
case .xcoff: return "xcoff"
1431+
}
1432+
}
13641433
}
13651434
}
13661435

@@ -1558,3 +1627,15 @@ extension Triple {
15581627
}
15591628
}
15601629
}
1630+
1631+
fileprivate extension Array {
1632+
1633+
mutating func resize(toCount desiredCount: Int, paddingWith element: Element) {
1634+
1635+
if desiredCount > count {
1636+
append(contentsOf: repeatElement(element, count: desiredCount - count))
1637+
} else if desiredCount < count {
1638+
removeLast(count - desiredCount)
1639+
}
1640+
}
1641+
}

Tests/SwiftDriverTests/TripleTests.swift

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -712,8 +712,8 @@ final class TripleTests: XCTestCase {
712712
func testNormalizeSpecialCases() {
713713
// Various real-world funky triples. The value returned by GCC's config.sub
714714
// is given in the comment.
715-
// assertNormalizesEqual("i386-mingw32",
716-
// "i386-unknown-windows-gnu") // i386-pc-mingw32
715+
assertNormalizesEqual("i386-mingw32",
716+
"i386-unknown-windows-gnu") // i386-pc-mingw32
717717
assertNormalizesEqual("x86_64-linux-gnu",
718718
"x86_64-unknown-linux-gnu") // x86_64-pc-linux-gnu
719719
assertNormalizesEqual("i486-linux-gnu",
@@ -731,37 +731,37 @@ final class TripleTests: XCTestCase {
731731
}
732732

733733
func testNormalizeWindows() {
734-
// assertNormalizesEqual("i686-pc-win32", "i686-pc-windows-msvc")
735-
// assertNormalizesEqual("i686-win32", "i686-unknown-windows-msvc")
736-
// assertNormalizesEqual("i686-pc-mingw32", "i686-pc-windows-gnu")
737-
// assertNormalizesEqual("i686-mingw32", "i686-unknown-windows-gnu")
738-
// assertNormalizesEqual("i686-pc-mingw32-w64", "i686-pc-windows-gnu")
739-
// assertNormalizesEqual("i686-mingw32-w64", "i686-unknown-windows-gnu")
740-
// assertNormalizesEqual("i686-pc-cygwin", "i686-pc-windows-cygnus")
741-
// assertNormalizesEqual("i686-cygwin", "i686-unknown-windows-cygnus")
742-
//
743-
// assertNormalizesEqual("x86_64-pc-win32", "x86_64-pc-windows-msvc")
744-
// assertNormalizesEqual("x86_64-win32", "x86_64-unknown-windows-msvc")
745-
// assertNormalizesEqual("x86_64-pc-mingw32", "x86_64-pc-windows-gnu")
746-
// assertNormalizesEqual("x86_64-mingw32", "x86_64-unknown-windows-gnu")
747-
// assertNormalizesEqual("x86_64-pc-mingw32-w64",
748-
// "x86_64-pc-windows-gnu")
749-
// assertNormalizesEqual("x86_64-mingw32-w64",
750-
// "x86_64-unknown-windows-gnu")
751-
//
752-
// assertNormalizesEqual("i686-pc-win32-elf", "i686-pc-windows-elf")
753-
// assertNormalizesEqual("i686-win32-elf", "i686-unknown-windows-elf")
754-
// assertNormalizesEqual("i686-pc-win32-macho", "i686-pc-windows-macho")
755-
// assertNormalizesEqual("i686-win32-macho",
756-
// "i686-unknown-windows-macho")
757-
//
758-
// assertNormalizesEqual("x86_64-pc-win32-elf", "x86_64-pc-windows-elf")
759-
// assertNormalizesEqual("x86_64-win32-elf",
760-
// "x86_64-unknown-windows-elf")
761-
// assertNormalizesEqual("x86_64-pc-win32-macho",
762-
// "x86_64-pc-windows-macho")
763-
// assertNormalizesEqual("x86_64-win32-macho",
764-
// "x86_64-unknown-windows-macho")
734+
assertNormalizesEqual("i686-pc-win32", "i686-pc-windows-msvc")
735+
assertNormalizesEqual("i686-win32", "i686-unknown-windows-msvc")
736+
assertNormalizesEqual("i686-pc-mingw32", "i686-pc-windows-gnu")
737+
assertNormalizesEqual("i686-mingw32", "i686-unknown-windows-gnu")
738+
assertNormalizesEqual("i686-pc-mingw32-w64", "i686-pc-windows-gnu")
739+
assertNormalizesEqual("i686-mingw32-w64", "i686-unknown-windows-gnu")
740+
assertNormalizesEqual("i686-pc-cygwin", "i686-pc-windows-cygnus")
741+
assertNormalizesEqual("i686-cygwin", "i686-unknown-windows-cygnus")
742+
743+
assertNormalizesEqual("x86_64-pc-win32", "x86_64-pc-windows-msvc")
744+
assertNormalizesEqual("x86_64-win32", "x86_64-unknown-windows-msvc")
745+
assertNormalizesEqual("x86_64-pc-mingw32", "x86_64-pc-windows-gnu")
746+
assertNormalizesEqual("x86_64-mingw32", "x86_64-unknown-windows-gnu")
747+
assertNormalizesEqual("x86_64-pc-mingw32-w64",
748+
"x86_64-pc-windows-gnu")
749+
assertNormalizesEqual("x86_64-mingw32-w64",
750+
"x86_64-unknown-windows-gnu")
751+
752+
assertNormalizesEqual("i686-pc-win32-elf", "i686-pc-windows-elf")
753+
assertNormalizesEqual("i686-win32-elf", "i686-unknown-windows-elf")
754+
assertNormalizesEqual("i686-pc-win32-macho", "i686-pc-windows-macho")
755+
assertNormalizesEqual("i686-win32-macho",
756+
"i686-unknown-windows-macho")
757+
758+
assertNormalizesEqual("x86_64-pc-win32-elf", "x86_64-pc-windows-elf")
759+
assertNormalizesEqual("x86_64-win32-elf",
760+
"x86_64-unknown-windows-elf")
761+
assertNormalizesEqual("x86_64-pc-win32-macho",
762+
"x86_64-pc-windows-macho")
763+
assertNormalizesEqual("x86_64-win32-macho",
764+
"x86_64-unknown-windows-macho")
765765

766766
assertNormalizesEqual("i686-pc-windows-cygnus",
767767
"i686-pc-windows-cygnus")
@@ -770,8 +770,8 @@ final class TripleTests: XCTestCase {
770770
"i686-pc-windows-itanium")
771771
assertNormalizesEqual("i686-pc-windows-msvc", "i686-pc-windows-msvc")
772772

773-
// assertNormalizesEqual("i686-pc-windows-elf-elf",
774-
// "i686-pc-windows-elf")
773+
assertNormalizesEqual("i686-pc-windows-elf-elf",
774+
"i686-pc-windows-elf")
775775
}
776776

777777
func testNormalizeARM() {
@@ -792,8 +792,8 @@ final class TripleTests: XCTestCase {
792792
assertNormalizesEqual("armv7eb-netbsd-eabihf",
793793
"armv7eb-unknown-netbsd-eabihf")
794794

795-
// assertNormalizesEqual("armv7-suse-linux-gnueabi",
796-
// "armv7-suse-linux-gnueabihf")
795+
assertNormalizesEqual("armv7-suse-linux-gnueabi",
796+
"armv7-suse-linux-gnueabihf")
797797

798798
var T: Triple
799799
T = Triple("armv6--netbsd-eabi")
@@ -815,9 +815,9 @@ final class TripleTests: XCTestCase {
815815
T = Triple("i386-apple-darwin9")
816816
XCTAssertTrue(T.os?.isMacOSX)
817817
XCTAssertFalse(T.os?.isiOS)
818-
// XCTAssertFalse(T.isArch16Bit())
819-
// XCTAssertTrue(T.isArch32Bit())
820-
// XCTAssertFalse(T.isArch64Bit())
818+
XCTAssertFalse(T.arch?.is16Bit)
819+
XCTAssertTrue(T.arch?.is32Bit)
820+
XCTAssertFalse(T.arch?.is64Bit)
821821
V = T._macOSVersion
822822
XCTAssertEqual(V?.major, 10)
823823
XCTAssertEqual(V?.minor, 5)
@@ -830,9 +830,9 @@ final class TripleTests: XCTestCase {
830830
T = Triple("x86_64-apple-darwin9")
831831
XCTAssertTrue(T.os?.isMacOSX)
832832
XCTAssertFalse(T.os?.isiOS)
833-
// XCTAssertFalse(T.isArch16Bit())
834-
// XCTAssertFalse(T.isArch32Bit())
835-
// XCTAssertTrue(T.isArch64Bit())
833+
XCTAssertFalse(T.arch?.is16Bit)
834+
XCTAssertFalse(T.arch?.is32Bit)
835+
XCTAssertTrue(T.arch?.is64Bit)
836836
V = T._macOSVersion
837837
XCTAssertEqual(V?.major, 10)
838838
XCTAssertEqual(V?.minor, 5)
@@ -845,9 +845,9 @@ final class TripleTests: XCTestCase {
845845
T = Triple("x86_64-apple-macosx")
846846
XCTAssertTrue(T.os?.isMacOSX)
847847
XCTAssertFalse(T.os?.isiOS)
848-
// XCTAssertFalse(T.isArch16Bit())
849-
// XCTAssertFalse(T.isArch32Bit())
850-
// XCTAssertTrue(T.isArch64Bit())
848+
XCTAssertFalse(T.arch?.is16Bit)
849+
XCTAssertFalse(T.arch?.is32Bit)
850+
XCTAssertTrue(T.arch?.is64Bit)
851851
V = T._macOSVersion
852852
XCTAssertEqual(V?.major, 10)
853853
XCTAssertEqual(V?.minor, 4)
@@ -860,9 +860,9 @@ final class TripleTests: XCTestCase {
860860
T = Triple("x86_64-apple-macosx10.7")
861861
XCTAssertTrue(T.os?.isMacOSX)
862862
XCTAssertFalse(T.os?.isiOS)
863-
// XCTAssertFalse(T.isArch16Bit())
864-
// XCTAssertFalse(T.isArch32Bit())
865-
// XCTAssertTrue(T.isArch64Bit())
863+
XCTAssertFalse(T.arch?.is16Bit)
864+
XCTAssertFalse(T.arch?.is32Bit)
865+
XCTAssertTrue(T.arch?.is64Bit)
866866
V = T._macOSVersion
867867
XCTAssertEqual(V?.major, 10)
868868
XCTAssertEqual(V?.minor, 7)
@@ -970,8 +970,8 @@ final class TripleTests: XCTestCase {
970970
// let GNUWindowsNormalized = Triple("i686-pc-windows-gnu-elf", normalizing: true)
971971
// XCTAssertEqual(.elf, GNUWindowsNormalized.objectFormat)
972972

973-
// let CygnusNormalised = Triple("i686-pc-windows-cygnus-elf", normalizing: true)
974-
// XCTAssertEqual(.elf, CygnusNormalised.objectFormat)
973+
// let CygnusNormalized = Triple("i686-pc-windows-cygnus-elf", normalizing: true)
974+
// XCTAssertEqual(.elf, CygnusNormalized.objectFormat)
975975

976976
let CygwinNormalized = Triple("i686-pc-cygwin-elf", normalizing: true)
977977
XCTAssertEqual(.elf, CygwinNormalized.objectFormat)

0 commit comments

Comments
 (0)