@@ -107,7 +107,7 @@ getBufferOfDependency(clang::vfs::FileSystem &FS,
107
107
// / with dead entries -- when other factors change, such as the contents of
108
108
// / the .swiftinterface input or its dependencies.
109
109
static std::string getCacheHash (ASTContext &Ctx,
110
- CompilerInvocation &SubInvocation,
110
+ const CompilerInvocation &SubInvocation,
111
111
StringRef InPath) {
112
112
// Start with the compiler version (which will be either tag names or revs).
113
113
std::string vers = swift::version::getSwiftFullVersion (
@@ -128,16 +128,14 @@ static std::string getCacheHash(ASTContext &Ctx,
128
128
return llvm::APInt (64 , H).toString (36 , /* Signed=*/ false );
129
129
}
130
130
131
- void
132
- ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths (
133
- CompilerInvocation &SubInvocation,
134
- Identifier ModuleName,
135
- StringRef InPath,
136
- llvm::SmallString<128 > &OutPath) {
137
-
131
+ static CompilerInvocation
132
+ createInvocationForBuildingFromInterface (ASTContext &Ctx, StringRef ModuleName,
133
+ StringRef CacheDir) {
138
134
auto &SearchPathOpts = Ctx.SearchPathOpts ;
139
135
auto &LangOpts = Ctx.LangOpts ;
140
136
137
+ CompilerInvocation SubInvocation;
138
+
141
139
// Start with a SubInvocation that copies various state from our
142
140
// invoking ASTContext.
143
141
SubInvocation.setImportSearchPaths (SearchPathOpts.ImportSearchPaths );
@@ -147,7 +145,7 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
147
145
SubInvocation.setRuntimeResourcePath (SearchPathOpts.RuntimeResourcePath );
148
146
SubInvocation.setTargetTriple (LangOpts.Target );
149
147
SubInvocation.setClangModuleCachePath (CacheDir);
150
- SubInvocation.setModuleName (ModuleName. str () );
148
+ SubInvocation.setModuleName (ModuleName);
151
149
152
150
// Inhibit warnings from the SubInvocation since we are assuming the user
153
151
// is not in a position to fix them.
@@ -161,24 +159,35 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
161
159
// modules that don't import Foundation.
162
160
SubInvocation.getLangOptions ().EnableObjCAttrRequiresFoundation = false ;
163
161
164
- // Calculate an output filename that includes a hash of relevant key data, and
165
- // wire up the SubInvocation's InputsAndOutputs to contain both input and
166
- // output filenames.
167
- OutPath = CacheDir;
168
- llvm::sys::path::append (OutPath, ModuleName.str ());
162
+ return SubInvocation;
163
+ }
164
+
165
+ // / Calculate an output filename in \p SubInvocation's cache path that includes
166
+ // / a hash of relevant key data.
167
+ static void computeCachedOutputPath (ASTContext &Ctx,
168
+ const CompilerInvocation &SubInvocation,
169
+ StringRef InPath,
170
+ llvm::SmallString<128 > &OutPath) {
171
+ OutPath = SubInvocation.getClangModuleCachePath ();
172
+ llvm::sys::path::append (OutPath, SubInvocation.getModuleName ());
169
173
OutPath.append (" -" );
170
174
OutPath.append (getCacheHash (Ctx, SubInvocation, InPath));
171
175
OutPath.append (" ." );
172
176
auto OutExt = file_types::getExtension (file_types::TY_SwiftModuleFile);
173
177
OutPath.append (OutExt);
178
+ }
174
179
180
+ void ParseableInterfaceModuleLoader::configureSubInvocationInputsAndOutputs (
181
+ CompilerInvocation &SubInvocation, StringRef InPath, StringRef OutPath) {
175
182
auto &SubFEOpts = SubInvocation.getFrontendOptions ();
176
183
SubFEOpts.RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
177
184
SubFEOpts.EnableParseableModuleInterface = true ;
178
185
SubFEOpts.InputsAndOutputs .addPrimaryInputFile (InPath);
179
186
SupplementaryOutputPaths SOPs;
180
187
SOPs.ModuleOutputPath = OutPath.str ();
181
- StringRef MainOut = " /dev/null" ;
188
+
189
+ // Pick a primary output path that will cause problems to use.
190
+ StringRef MainOut = " /<unused>" ;
182
191
SubFEOpts.InputsAndOutputs .setMainAndSupplementaryOutputs ({MainOut}, {SOPs});
183
192
}
184
193
@@ -258,6 +267,9 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
258
267
uint64_t Hash = xxHash64 (DepBuf->getBuffer ());
259
268
Deps.push_back (FileDependency{Size, Hash, DepName});
260
269
270
+ if (ModuleCachePath.empty ())
271
+ continue ;
272
+
261
273
// If Dep is itself a .swiftmodule in the cache dir, pull out its deps
262
274
// and include them in our own, so we have a single-file view of
263
275
// transitive deps: removes redundancies, and avoids opening and reading
@@ -290,11 +302,21 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
290
302
291
303
static bool buildSwiftModuleFromSwiftInterface (
292
304
clang::vfs::FileSystem &FS, DiagnosticEngine &Diags, SourceLoc DiagLoc,
293
- CompilerInvocation &SubInvocation, StringRef InPath, StringRef OutPath ,
294
- StringRef ModuleCachePath, DependencyTracker *OuterTracker) {
305
+ CompilerInvocation &SubInvocation, StringRef ModuleCachePath ,
306
+ DependencyTracker *OuterTracker) {
295
307
bool SubError = false ;
296
308
bool RunSuccess = llvm::CrashRecoveryContext ().RunSafelyOnThread ([&] {
297
- (void )llvm::sys::fs::create_directory (ModuleCachePath);
309
+ // Note that we don't assume ModuleCachePath is the same as the Clang
310
+ // module cache path at this point.
311
+ if (!ModuleCachePath.empty ())
312
+ (void )llvm::sys::fs::create_directory (ModuleCachePath);
313
+
314
+ FrontendOptions &FEOpts = SubInvocation.getFrontendOptions ();
315
+ const auto &InputInfo = FEOpts.InputsAndOutputs .firstInput ();
316
+ StringRef InPath = InputInfo.file ();
317
+ const auto &OutputInfo =
318
+ InputInfo.getPrimarySpecificPaths ().SupplementaryOutputs ;
319
+ StringRef OutPath = OutputInfo.ModuleOutputPath ;
298
320
299
321
llvm::BumpPtrAllocator SubArgsAlloc;
300
322
llvm::StringSaver SubArgSaver (SubArgsAlloc);
@@ -343,6 +365,7 @@ static bool buildSwiftModuleFromSwiftInterface(
343
365
LLVM_DEBUG (llvm::dbgs () << " Setting up instance to compile "
344
366
<< InPath << " to " << OutPath << " \n " );
345
367
CompilerInstance SubInstance;
368
+ SubInstance.getSourceMgr ().setFileSystem (&FS);
346
369
347
370
ForwardingDiagnosticConsumer FDC (Diags);
348
371
SubInstance.addDiagnosticConsumer (&FDC);
@@ -372,7 +395,6 @@ static bool buildSwiftModuleFromSwiftInterface(
372
395
373
396
// Setup the callbacks for serialization, which can occur during the
374
397
// optimization pipeline.
375
- FrontendOptions &FEOpts = SubInvocation.getFrontendOptions ();
376
398
SerializationOptions SerializationOpts;
377
399
std::string OutPathStr = OutPath;
378
400
SerializationOpts.OutputPath = OutPathStr.c_str ();
@@ -456,15 +478,16 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
456
478
457
479
// Set up a _potential_ sub-invocation to consume the .swiftinterface and emit
458
480
// the .swiftmodule.
459
- CompilerInvocation SubInvocation;
460
- configureSubInvocationAndOutputPaths (SubInvocation, ModuleID.first , InPath,
461
- OutPath);
481
+ CompilerInvocation SubInvocation =
482
+ createInvocationForBuildingFromInterface (Ctx, ModuleID.first .str (), CacheDir);
483
+ computeCachedOutputPath (Ctx, SubInvocation, InPath, OutPath);
484
+ configureSubInvocationInputsAndOutputs (SubInvocation, InPath, OutPath);
462
485
463
486
// Evaluate if we need to run this sub-invocation, and if so run it.
464
487
if (!swiftModuleIsUpToDate (FS, ModuleID, OutPath, Diags, dependencyTracker)) {
465
- if (buildSwiftModuleFromSwiftInterface (FS, Diags, ModuleID.second ,
466
- SubInvocation, InPath, OutPath ,
467
- CacheDir, dependencyTracker))
488
+ if (:: buildSwiftModuleFromSwiftInterface (FS, Diags, ModuleID.second ,
489
+ SubInvocation, CacheDir ,
490
+ dependencyTracker))
468
491
return std::make_error_code (std::errc::invalid_argument);
469
492
}
470
493
@@ -484,6 +507,21 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
484
507
return ErrorCode;
485
508
}
486
509
510
+ bool
511
+ ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface (
512
+ ASTContext &Ctx, StringRef CacheDir, StringRef ModuleName,
513
+ StringRef InPath, StringRef OutPath) {
514
+ CompilerInvocation SubInvocation =
515
+ createInvocationForBuildingFromInterface (Ctx, ModuleName, CacheDir);
516
+ configureSubInvocationInputsAndOutputs (SubInvocation, InPath, OutPath);
517
+
518
+ auto &FS = *Ctx.SourceMgr .getFileSystem ();
519
+ auto &Diags = Ctx.Diags ;
520
+ return ::buildSwiftModuleFromSwiftInterface (FS, Diags, /* DiagLoc*/ SourceLoc (),
521
+ SubInvocation, /* CachePath*/ " " ,
522
+ /* OuterTracker*/ nullptr );
523
+ }
524
+
487
525
// / Diagnose any scoped imports in \p imports, i.e. those with a non-empty
488
526
// / access path. These are not yet supported by parseable interfaces, since the
489
527
// / information about the declaration kind is not preserved through the binary
0 commit comments