@@ -107,7 +107,7 @@ getBufferOfDependency(clang::vfs::FileSystem &FS,
107107// / with dead entries -- when other factors change, such as the contents of
108108// / the .swiftinterface input or its dependencies.
109109static std::string getCacheHash (ASTContext &Ctx,
110- CompilerInvocation &SubInvocation,
110+ const CompilerInvocation &SubInvocation,
111111 StringRef InPath) {
112112 // Start with the compiler version (which will be either tag names or revs).
113113 std::string vers = swift::version::getSwiftFullVersion (
@@ -128,16 +128,14 @@ static std::string getCacheHash(ASTContext &Ctx,
128128 return llvm::APInt (64 , H).toString (36 , /* Signed=*/ false );
129129}
130130
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) {
138134 auto &SearchPathOpts = Ctx.SearchPathOpts ;
139135 auto &LangOpts = Ctx.LangOpts ;
140136
137+ CompilerInvocation SubInvocation;
138+
141139 // Start with a SubInvocation that copies various state from our
142140 // invoking ASTContext.
143141 SubInvocation.setImportSearchPaths (SearchPathOpts.ImportSearchPaths );
@@ -147,7 +145,7 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
147145 SubInvocation.setRuntimeResourcePath (SearchPathOpts.RuntimeResourcePath );
148146 SubInvocation.setTargetTriple (LangOpts.Target );
149147 SubInvocation.setClangModuleCachePath (CacheDir);
150- SubInvocation.setModuleName (ModuleName. str () );
148+ SubInvocation.setModuleName (ModuleName);
151149
152150 // Inhibit warnings from the SubInvocation since we are assuming the user
153151 // is not in a position to fix them.
@@ -161,24 +159,35 @@ ParseableInterfaceModuleLoader::configureSubInvocationAndOutputPaths(
161159 // modules that don't import Foundation.
162160 SubInvocation.getLangOptions ().EnableObjCAttrRequiresFoundation = false ;
163161
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 ());
169173 OutPath.append (" -" );
170174 OutPath.append (getCacheHash (Ctx, SubInvocation, InPath));
171175 OutPath.append (" ." );
172176 auto OutExt = file_types::getExtension (file_types::TY_SwiftModuleFile);
173177 OutPath.append (OutExt);
178+ }
174179
180+ void ParseableInterfaceModuleLoader::configureSubInvocationInputsAndOutputs (
181+ CompilerInvocation &SubInvocation, StringRef InPath, StringRef OutPath) {
175182 auto &SubFEOpts = SubInvocation.getFrontendOptions ();
176183 SubFEOpts.RequestedAction = FrontendOptions::ActionType::EmitModuleOnly;
177184 SubFEOpts.EnableParseableModuleInterface = true ;
178185 SubFEOpts.InputsAndOutputs .addPrimaryInputFile (InPath);
179186 SupplementaryOutputPaths SOPs;
180187 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>" ;
182191 SubFEOpts.InputsAndOutputs .setMainAndSupplementaryOutputs ({MainOut}, {SOPs});
183192}
184193
@@ -258,6 +267,9 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
258267 uint64_t Hash = xxHash64 (DepBuf->getBuffer ());
259268 Deps.push_back (FileDependency{Size, Hash, DepName});
260269
270+ if (ModuleCachePath.empty ())
271+ continue ;
272+
261273 // If Dep is itself a .swiftmodule in the cache dir, pull out its deps
262274 // and include them in our own, so we have a single-file view of
263275 // transitive deps: removes redundancies, and avoids opening and reading
@@ -290,11 +302,21 @@ collectDepsForSerialization(clang::vfs::FileSystem &FS,
290302
291303static bool buildSwiftModuleFromSwiftInterface (
292304 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) {
295307 bool SubError = false ;
296308 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 ;
298320
299321 llvm::BumpPtrAllocator SubArgsAlloc;
300322 llvm::StringSaver SubArgSaver (SubArgsAlloc);
@@ -343,6 +365,7 @@ static bool buildSwiftModuleFromSwiftInterface(
343365 LLVM_DEBUG (llvm::dbgs () << " Setting up instance to compile "
344366 << InPath << " to " << OutPath << " \n " );
345367 CompilerInstance SubInstance;
368+ SubInstance.getSourceMgr ().setFileSystem (&FS);
346369
347370 ForwardingDiagnosticConsumer FDC (Diags);
348371 SubInstance.addDiagnosticConsumer (&FDC);
@@ -372,7 +395,6 @@ static bool buildSwiftModuleFromSwiftInterface(
372395
373396 // Setup the callbacks for serialization, which can occur during the
374397 // optimization pipeline.
375- FrontendOptions &FEOpts = SubInvocation.getFrontendOptions ();
376398 SerializationOptions SerializationOpts;
377399 std::string OutPathStr = OutPath;
378400 SerializationOpts.OutputPath = OutPathStr.c_str ();
@@ -456,15 +478,16 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
456478
457479 // Set up a _potential_ sub-invocation to consume the .swiftinterface and emit
458480 // 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);
462485
463486 // Evaluate if we need to run this sub-invocation, and if so run it.
464487 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))
468491 return std::make_error_code (std::errc::invalid_argument);
469492 }
470493
@@ -484,6 +507,21 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
484507 return ErrorCode;
485508}
486509
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+
487525// / Diagnose any scoped imports in \p imports, i.e. those with a non-empty
488526// / access path. These are not yet supported by parseable interfaces, since the
489527// / information about the declaration kind is not preserved through the binary
0 commit comments