@@ -35,6 +35,29 @@ class Identifier;
35
35
// / Which kind of module dependencies we are looking for.
36
36
enum class ModuleDependenciesKind : int8_t {
37
37
Swift,
38
+ // Placeholder dependencies are a kind of dependencies used only by the
39
+ // dependency scanner. They are swift modules that the scanner will not be
40
+ // able to locate in its search paths and which are the responsibility of the
41
+ // scanner's client to ensure are provided.
42
+ //
43
+ // Placeholder dependencies will be specified in the scanner's output
44
+ // dependency graph where it is the responsibility of the scanner's client to
45
+ // ensure required post-processing takes place to "resolve" them. In order to
46
+ // do so, the client (swift driver, or any other client build system) is
47
+ // expected to have access to a full dependency graph of all placeholder
48
+ // dependencies and be able to replace placeholder nodes in the dependency
49
+ // graph with their full dependency trees, `uniquing` common dependency module
50
+ // nodes in the process.
51
+ //
52
+ // One example where placeholder dependencies are employed is when using
53
+ // SwiftPM in Explicit Module Build mode. SwiftPM constructs a build plan for
54
+ // all targets ahead-of-time. When planning a build for a target that depends
55
+ // on other targets, the dependency scanning action is not able to locate
56
+ // dependency target modules, because they have not yet been built. Instead,
57
+ // the build system treats them as placeholder dependencies and resolves them
58
+ // with `actual` dependencies in a post-processing step once dependency graphs
59
+ // of all targets, individually, have been computed.
60
+ SwiftPlaceholder,
38
61
Clang,
39
62
};
40
63
@@ -43,11 +66,11 @@ enum class ModuleDependenciesKind : int8_t {
43
66
// / This class is mostly an implementation detail for \c ModuleDependencies.
44
67
class ModuleDependenciesStorageBase {
45
68
public:
46
- const bool isSwiftModule ;
69
+ const ModuleDependenciesKind dependencyKind ;
47
70
48
- ModuleDependenciesStorageBase (bool isSwiftModule ,
71
+ ModuleDependenciesStorageBase (ModuleDependenciesKind dependencyKind ,
49
72
const std::string &compiledModulePath)
50
- : isSwiftModule(isSwiftModule ),
73
+ : dependencyKind(dependencyKind ),
51
74
compiledModulePath (compiledModulePath) { }
52
75
53
76
virtual ModuleDependenciesStorageBase *clone () const = 0;
@@ -103,7 +126,8 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
103
126
ArrayRef<StringRef> buildCommandLine,
104
127
ArrayRef<StringRef> extraPCMArgs,
105
128
StringRef contextHash
106
- ) : ModuleDependenciesStorageBase(/* isSwiftModule=*/ true , compiledModulePath),
129
+ ) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Swift,
130
+ compiledModulePath),
107
131
swiftInterfaceFile (swiftInterfaceFile),
108
132
compiledModuleCandidates(compiledModuleCandidates.begin(),
109
133
compiledModuleCandidates.end()),
@@ -116,7 +140,7 @@ class SwiftModuleDependenciesStorage : public ModuleDependenciesStorageBase {
116
140
}
117
141
118
142
static bool classof (const ModuleDependenciesStorageBase *base) {
119
- return base->isSwiftModule ;
143
+ return base->dependencyKind == ModuleDependenciesKind::Swift ;
120
144
}
121
145
};
122
146
@@ -143,7 +167,7 @@ class ClangModuleDependenciesStorage : public ModuleDependenciesStorageBase {
143
167
const std::string &contextHash,
144
168
const std::vector<std::string> &nonPathCommandLine,
145
169
const std::vector<std::string> &fileDependencies
146
- ) : ModuleDependenciesStorageBase(/* isSwiftModule= */ false ,
170
+ ) : ModuleDependenciesStorageBase(ModuleDependenciesKind::Clang ,
147
171
compiledModulePath),
148
172
moduleMapFile (moduleMapFile),
149
173
contextHash(contextHash),
@@ -155,7 +179,35 @@ class ClangModuleDependenciesStorage : public ModuleDependenciesStorageBase {
155
179
}
156
180
157
181
static bool classof (const ModuleDependenciesStorageBase *base) {
158
- return !base->isSwiftModule ;
182
+ return base->dependencyKind == ModuleDependenciesKind::Clang;
183
+ }
184
+ };
185
+
186
+ // / Describes an placeholder Swift module dependency module stub.
187
+ // /
188
+ // / This class is mostly an implementation detail for \c ModuleDependencies.
189
+ class PlaceholderSwiftModuleDependencyStorage : public ModuleDependenciesStorageBase {
190
+ public:
191
+ PlaceholderSwiftModuleDependencyStorage (const std::string &compiledModulePath,
192
+ const std::string &moduleDocPath,
193
+ const std::string &sourceInfoPath)
194
+ : ModuleDependenciesStorageBase(ModuleDependenciesKind::SwiftPlaceholder,
195
+ compiledModulePath),
196
+ moduleDocPath (moduleDocPath),
197
+ sourceInfoPath(sourceInfoPath) {}
198
+
199
+ ModuleDependenciesStorageBase *clone () const override {
200
+ return new PlaceholderSwiftModuleDependencyStorage (*this );
201
+ }
202
+
203
+ // / The path to the .swiftModuleDoc file.
204
+ const std::string moduleDocPath;
205
+
206
+ // / The path to the .swiftSourceInfo file.
207
+ const std::string sourceInfoPath;
208
+
209
+ static bool classof (const ModuleDependenciesStorageBase *base) {
210
+ return base->dependencyKind == ModuleDependenciesKind::SwiftPlaceholder;
159
211
}
160
212
};
161
213
@@ -230,6 +282,16 @@ class ModuleDependencies {
230
282
fileDependencies));
231
283
}
232
284
285
+ // / Describe a placeholder dependency swift module.
286
+ static ModuleDependencies forPlaceholderSwiftModuleStub (
287
+ const std::string &compiledModulePath,
288
+ const std::string &moduleDocPath,
289
+ const std::string &sourceInfoPath) {
290
+ return ModuleDependencies (
291
+ std::make_unique<PlaceholderSwiftModuleDependencyStorage>(
292
+ compiledModulePath, moduleDocPath, sourceInfoPath));
293
+ }
294
+
233
295
// / Retrieve the path to the compiled module.
234
296
const std::string getCompiledModulePath () const {
235
297
return storage->compiledModulePath ;
@@ -243,16 +305,22 @@ class ModuleDependencies {
243
305
// / Whether the dependencies are for a Swift module.
244
306
bool isSwiftModule () const ;
245
307
308
+ // / Whether this represents a placeholder module stub
309
+ bool isPlaceholderSwiftModule () const ;
310
+
246
311
ModuleDependenciesKind getKind () const {
247
- return isSwiftModule () ? ModuleDependenciesKind::Swift
248
- : ModuleDependenciesKind::Clang;
312
+ return storage->dependencyKind ;
249
313
}
250
314
// / Retrieve the dependencies for a Swift module.
251
315
const SwiftModuleDependenciesStorage *getAsSwiftModule () const ;
252
316
253
317
// / Retrieve the dependencies for a Clang module.
254
318
const ClangModuleDependenciesStorage *getAsClangModule () const ;
255
319
320
+ // / Retrieve the dependencies for a placeholder dependency module stub.
321
+ const PlaceholderSwiftModuleDependencyStorage *
322
+ getAsPlaceholderDependencyModule () const ;
323
+
256
324
// / Add a dependency on the given module, if it was not already in the set.
257
325
void addModuleDependency (StringRef module ,
258
326
llvm::StringSet<> *alreadyAddedModules = nullptr );
@@ -293,6 +361,9 @@ class ModuleDependenciesCache {
293
361
// / Dependencies for Swift modules that have already been computed.
294
362
llvm::StringMap<ModuleDependencies> SwiftModuleDependencies;
295
363
364
+ // / Dependencies for Swift placeholder dependency modules.
365
+ llvm::StringMap<ModuleDependencies> PlaceholderSwiftModuleDependencies;
366
+
296
367
// / Dependencies for Clang modules that have already been computed.
297
368
llvm::StringMap<ModuleDependencies> ClangModuleDependencies;
298
369
0 commit comments