11
11
//===----------------------------------------------------------------------===//
12
12
13
13
import Dispatch
14
+ import SKLogging
14
15
import SwiftExtensions
15
16
import TSCExtensions
16
17
@@ -68,10 +69,14 @@ package final actor ToolchainRegistry {
68
69
private let toolchainsByIdentifier : [ String : [ Toolchain ] ]
69
70
70
71
/// The toolchains indexed by their path.
71
- ///
72
- /// Note: Not all toolchains have a path.
73
72
private let toolchainsByPath : [ URL : Toolchain ]
74
73
74
+ /// Map from compiler paths (`clang`, `swift`, `swiftc`) mapping to the toolchain that contained them.
75
+ ///
76
+ /// This allows us to find the toolchain that should be used for semantic functionality based on which compiler it is
77
+ /// built with in the `compile_commands.json`.
78
+ private let toolchainsByCompiler : [ URL : Toolchain ]
79
+
75
80
/// The currently selected toolchain identifier on Darwin.
76
81
package let darwinToolchainOverride : String ?
77
82
@@ -98,29 +103,40 @@ package final actor ToolchainRegistry {
98
103
var toolchainsAndReasons : [ ( toolchain: Toolchain , reason: ToolchainRegisterReason ) ] = [ ]
99
104
var toolchainsByIdentifier : [ String : [ Toolchain ] ] = [ : ]
100
105
var toolchainsByPath : [ URL : Toolchain ] = [ : ]
106
+ var toolchainsByCompiler : [ URL : Toolchain ] = [ : ]
101
107
for (toolchain, reason) in toolchainsAndReasonsParam {
102
108
// Non-XcodeDefault toolchain: disallow all duplicates.
103
- if toolchain. identifier != ToolchainRegistry . darwinDefaultToolchainIdentifier {
104
- guard toolchainsByIdentifier [ toolchain. identifier] == nil else {
105
- continue
106
- }
109
+ if toolchainsByIdentifier [ toolchain. identifier] != nil ,
110
+ toolchain. identifier != ToolchainRegistry . darwinDefaultToolchainIdentifier
111
+ {
112
+ logger. error ( " Found two toolchains with the same identifier: \( toolchain. identifier) " )
113
+ continue
114
+ }
115
+
116
+ // Toolchain should always be unique by path.
117
+ if toolchainsByPath [ toolchain. path] != nil {
118
+ logger. fault ( " Found two toolchains with the same path: \( toolchain. path) " )
119
+ continue
107
120
}
108
121
109
- // Toolchain should always be unique by path if it is present.
110
- if let path = toolchain. path {
111
- guard toolchainsByPath [ path] == nil else {
122
+ toolchainsByPath [ toolchain. path] = toolchain
123
+ toolchainsByIdentifier [ toolchain. identifier, default: [ ] ] . append ( toolchain)
124
+
125
+ for case . some( let compiler) in [ toolchain. clang, toolchain. swift, toolchain. swiftc] {
126
+ guard toolchainsByCompiler [ compiler] == nil else {
127
+ logger. fault ( " Found two toolchains with the same compiler: \( compiler) " )
112
128
continue
113
129
}
114
- toolchainsByPath [ path ] = toolchain
130
+ toolchainsByCompiler [ compiler ] = toolchain
115
131
}
116
132
117
- toolchainsByIdentifier [ toolchain. identifier, default: [ ] ] . append ( toolchain)
118
133
toolchainsAndReasons. append ( ( toolchain, reason) )
119
134
}
120
135
121
136
self . toolchainsAndReasons = toolchainsAndReasons
122
137
self . toolchainsByIdentifier = toolchainsByIdentifier
123
138
self . toolchainsByPath = toolchainsByPath
139
+ self . toolchainsByCompiler = toolchainsByCompiler
124
140
125
141
if let darwinToolchainOverride, !darwinToolchainOverride. isEmpty, darwinToolchainOverride != " default " {
126
142
self . darwinToolchainOverride = darwinToolchainOverride
@@ -267,12 +283,7 @@ package final actor ToolchainRegistry {
267
283
/// If we have a toolchain in the toolchain registry that contains the compiler with the given URL, return it.
268
284
/// Otherwise, return `nil`.
269
285
package func toolchain( withCompiler compiler: URL ) -> Toolchain ? {
270
- for toolchain in toolchains {
271
- if [ toolchain. clang, toolchain. swift, toolchain. swiftc] . contains ( compiler) {
272
- return toolchain
273
- }
274
- }
275
- return nil
286
+ return toolchainsByCompiler [ compiler]
276
287
}
277
288
}
278
289
0 commit comments