Skip to content

Commit 37708ed

Browse files
committed
Add frontend mode -build-module-from-parseable-interface
Makes it easier to test the caching behavior, and may also be useful for "prebuilding" swiftinterfaces in the future, or having the Driver kick off a bunch of separate builds as proper tasks.
1 parent 13c8a75 commit 37708ed

File tree

9 files changed

+80
-6
lines changed

9 files changed

+80
-6
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ class FrontendOptions {
126126
EmitModuleOnly, ///< Emit module only
127127
MergeModules, ///< Merge modules only
128128

129+
/// Build from a swiftinterface, as close to `import` as possible
130+
BuildModuleFromParseableInterface,
131+
129132
EmitSIBGen, ///< Emit serialized AST + raw SIL
130133
EmitSIB, ///< Emit serialized AST + canonical SIL
131134

include/swift/Frontend/ParseableInterfaceSupport.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,17 @@ class ParseableInterfaceModuleLoader : public SerializedModuleLoaderBase {
9292
return std::unique_ptr<ParseableInterfaceModuleLoader>(
9393
new ParseableInterfaceModuleLoader(ctx, cacheDir, tracker, loadMode));
9494
}
95+
96+
/// Unconditionally build \p InPath (a swiftinterface file) to \p OutPath (as
97+
/// a swiftmodule file).
98+
///
99+
/// A simplified version of the core logic in #openModuleFiles, mostly for
100+
/// testing purposes.
101+
static bool buildSwiftModuleFromSwiftInterface(ASTContext &Ctx,
102+
StringRef CacheDir,
103+
StringRef ModuleName,
104+
StringRef InPath,
105+
StringRef OutPath);
95106
};
96107

97108

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,11 @@ def dump_interface_hash : Flag<["-"], "dump-interface-hash">,
513513
HelpText<"Parse input file(s) and dump interface token hash(es)">,
514514
ModeOpt;
515515

516+
def build_module_from_parseable_interface :
517+
Flag<["-"], "build-module-from-parseable-interface">,
518+
HelpText<"Treat the (single) input as a swiftinterface and produce a module">,
519+
ModeOpt;
520+
516521
def enable_resilience_bypass : Flag<["-"], "enable-resilience-bypass">,
517522
HelpText<"Completely bypass resilience when accessing types in resilient frameworks">;
518523

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,8 @@ ArgsToFrontendOptionsConverter::determineRequestedAction(const ArgList &args) {
370370
return FrontendOptions::ActionType::REPL;
371371
if (Opt.matches(OPT_interpret))
372372
return FrontendOptions::ActionType::Immediate;
373+
if (Opt.matches(OPT_build_module_from_parseable_interface))
374+
return FrontendOptions::ActionType::BuildModuleFromParseableInterface;
373375

374376
llvm_unreachable("Unhandled mode option");
375377
}

lib/Frontend/FrontendOptions.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ bool FrontendOptions::needsProperModuleName(ActionType action) {
4848
case ActionType::EmitSIB:
4949
case ActionType::EmitModuleOnly:
5050
case ActionType::MergeModules:
51+
case ActionType::BuildModuleFromParseableInterface:
5152
return true;
5253
case ActionType::Immediate:
5354
case ActionType::REPL:
@@ -83,6 +84,7 @@ bool FrontendOptions::isActionImmediate(ActionType action) {
8384
case ActionType::EmitSIB:
8485
case ActionType::EmitModuleOnly:
8586
case ActionType::MergeModules:
87+
case ActionType::BuildModuleFromParseableInterface:
8688
return false;
8789
case ActionType::Immediate:
8890
case ActionType::REPL:
@@ -170,6 +172,7 @@ FrontendOptions::formatForPrincipalOutputFileForAction(ActionType action) {
170172

171173
case ActionType::MergeModules:
172174
case ActionType::EmitModuleOnly:
175+
case ActionType::BuildModuleFromParseableInterface:
173176
return TY_SwiftModuleFile;
174177

175178
case ActionType::Immediate:
@@ -207,6 +210,7 @@ bool FrontendOptions::canActionEmitDependencies(ActionType action) {
207210
case ActionType::DumpScopeMaps:
208211
case ActionType::DumpTypeRefinementContexts:
209212
case ActionType::DumpTypeInfo:
213+
case ActionType::BuildModuleFromParseableInterface:
210214
case ActionType::Immediate:
211215
case ActionType::REPL:
212216
return false;
@@ -242,6 +246,7 @@ bool FrontendOptions::canActionEmitReferenceDependencies(ActionType action) {
242246
case ActionType::DumpScopeMaps:
243247
case ActionType::DumpTypeRefinementContexts:
244248
case ActionType::DumpTypeInfo:
249+
case ActionType::BuildModuleFromParseableInterface:
245250
case ActionType::Immediate:
246251
case ActionType::REPL:
247252
return false;
@@ -277,6 +282,7 @@ bool FrontendOptions::canActionEmitObjCHeader(ActionType action) {
277282
case ActionType::DumpScopeMaps:
278283
case ActionType::DumpTypeRefinementContexts:
279284
case ActionType::DumpTypeInfo:
285+
case ActionType::BuildModuleFromParseableInterface:
280286
case ActionType::Immediate:
281287
case ActionType::REPL:
282288
return false;
@@ -309,6 +315,7 @@ bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) {
309315
case ActionType::DumpScopeMaps:
310316
case ActionType::DumpTypeRefinementContexts:
311317
case ActionType::DumpTypeInfo:
318+
case ActionType::BuildModuleFromParseableInterface:
312319
case ActionType::Immediate:
313320
case ActionType::REPL:
314321
return false;
@@ -347,6 +354,7 @@ bool FrontendOptions::canActionEmitModule(ActionType action) {
347354
case ActionType::DumpTypeRefinementContexts:
348355
case ActionType::DumpTypeInfo:
349356
case ActionType::EmitSILGen:
357+
case ActionType::BuildModuleFromParseableInterface:
350358
case ActionType::Immediate:
351359
case ActionType::REPL:
352360
return false;
@@ -379,15 +387,16 @@ bool FrontendOptions::canActionEmitInterface(ActionType action) {
379387
case ActionType::DumpAST:
380388
case ActionType::EmitSyntax:
381389
case ActionType::PrintAST:
390+
case ActionType::EmitImportedModules:
382391
case ActionType::EmitPCH:
383392
case ActionType::DumpScopeMaps:
384393
case ActionType::DumpTypeRefinementContexts:
385394
case ActionType::DumpTypeInfo:
386395
case ActionType::EmitSILGen:
387396
case ActionType::EmitSIBGen:
397+
case ActionType::BuildModuleFromParseableInterface:
388398
case ActionType::Immediate:
389399
case ActionType::REPL:
390-
case ActionType::EmitImportedModules:
391400
return false;
392401
case ActionType::Typecheck:
393402
case ActionType::MergeModules:
@@ -427,6 +436,7 @@ bool FrontendOptions::doesActionProduceOutput(ActionType action) {
427436
case ActionType::EmitObject:
428437
case ActionType::EmitImportedModules:
429438
case ActionType::MergeModules:
439+
case ActionType::BuildModuleFromParseableInterface:
430440
case ActionType::DumpTypeInfo:
431441
return true;
432442

@@ -446,6 +456,7 @@ bool FrontendOptions::doesActionProduceTextualOutput(ActionType action) {
446456
case ActionType::EmitSIB:
447457
case ActionType::MergeModules:
448458
case ActionType::EmitModuleOnly:
459+
case ActionType::BuildModuleFromParseableInterface:
449460
case ActionType::EmitBC:
450461
case ActionType::EmitObject:
451462
case ActionType::Immediate:
@@ -488,6 +499,7 @@ bool FrontendOptions::doesActionGenerateSIL(ActionType action) {
488499
case ActionType::DumpTypeRefinementContexts:
489500
case ActionType::EmitImportedModules:
490501
case ActionType::EmitPCH:
502+
case ActionType::BuildModuleFromParseableInterface:
491503
return false;
492504
case ActionType::EmitSILGen:
493505
case ActionType::EmitSIBGen:

lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static std::string getCacheHash(ASTContext &Ctx,
129129
}
130130

131131
static CompilerInvocation
132-
createInvocationForBuildingFromInterface(ASTContext &Ctx, Identifier ModuleName,
132+
createInvocationForBuildingFromInterface(ASTContext &Ctx, StringRef ModuleName,
133133
StringRef CacheDir) {
134134
auto &SearchPathOpts = Ctx.SearchPathOpts;
135135
auto &LangOpts = Ctx.LangOpts;
@@ -145,7 +145,7 @@ createInvocationForBuildingFromInterface(ASTContext &Ctx, Identifier ModuleName,
145145
SubInvocation.setRuntimeResourcePath(SearchPathOpts.RuntimeResourcePath);
146146
SubInvocation.setTargetTriple(LangOpts.Target);
147147
SubInvocation.setClangModuleCachePath(CacheDir);
148-
SubInvocation.setModuleName(ModuleName.str());
148+
SubInvocation.setModuleName(ModuleName);
149149

150150
// Inhibit warnings from the SubInvocation since we are assuming the user
151151
// is not in a position to fix them.
@@ -479,7 +479,7 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
479479
// Set up a _potential_ sub-invocation to consume the .swiftinterface and emit
480480
// the .swiftmodule.
481481
CompilerInvocation SubInvocation =
482-
createInvocationForBuildingFromInterface(Ctx, ModuleID.first, CacheDir);
482+
createInvocationForBuildingFromInterface(Ctx, ModuleID.first.str(), CacheDir);
483483
computeCachedOutputPath(Ctx, SubInvocation, InPath, OutPath);
484484
configureSubInvocationInputsAndOutputs(SubInvocation, InPath, OutPath);
485485

@@ -507,6 +507,21 @@ std::error_code ParseableInterfaceModuleLoader::openModuleFiles(
507507
return ErrorCode;
508508
}
509509

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+
510525
/// Diagnose any scoped imports in \p imports, i.e. those with a non-empty
511526
/// access path. These are not yet supported by parseable interfaces, since the
512527
/// information about the declaration kind is not preserved through the binary

lib/FrontendTool/FrontendTool.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,17 @@ static bool precompileBridgingHeader(CompilerInvocation &Invocation,
559559
.InputsAndOutputs.getSingleOutputFilename());
560560
}
561561

562+
static bool buildModuleFromParseableInterface(CompilerInvocation &Invocation,
563+
CompilerInstance &Instance) {
564+
const auto &InputsAndOutputs =
565+
Invocation.getFrontendOptions().InputsAndOutputs;
566+
assert(InputsAndOutputs.hasSingleInput());
567+
StringRef InputPath = InputsAndOutputs.getFilenameOfFirstInput();
568+
return ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface(
569+
Instance.getASTContext(), Invocation.getClangModuleCachePath(),
570+
Invocation.getModuleName(), InputPath, Invocation.getOutputFilename());
571+
}
572+
562573
static bool compileLLVMIR(CompilerInvocation &Invocation,
563574
CompilerInstance &Instance,
564575
UnifiedStatsReporter *Stats) {
@@ -923,6 +934,9 @@ static bool performCompile(CompilerInstance &Instance,
923934
if (Action == FrontendOptions::ActionType::EmitPCH)
924935
return precompileBridgingHeader(Invocation, Instance);
925936

937+
if (Action == FrontendOptions::ActionType::BuildModuleFromParseableInterface)
938+
return buildModuleFromParseableInterface(Invocation, Instance);
939+
926940
if (Invocation.getInputKind() == InputFileKind::LLVM)
927941
return compileLLVMIR(Invocation, Instance, Stats);
928942

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -parse-stdlib
3+
4+
// Note that the "-parse-stdlib" is picked up from the module flags. It should
5+
// not be written in any of the invocations below.
6+
7+
// RUN: %empty-directory(%t)
8+
// RUN: %target-swift-frontend -build-module-from-parseable-interface -o %t/ParseStdlib.swiftmodule %s
9+
// RUN: %target-swift-ide-test -print-module -module-to-print ParseStdlib -I %t -source-filename x -print-interface | %FileCheck %s
10+
11+
// CHECK: func test(_: Int42)
12+
public func test(_: Builtin.Int42) {}

test/ParseableInterface/SmokeTest.swiftinterface

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
// swift-tools-version: 4.0
1+
// swift-interface-format-version: 1.0
22
// swift-module-flags:
33

44
// Make sure parse-only works...
55
// RUN: %target-swift-frontend -parse %s
66

77
// ...and then make sure parse-and-typecheck-and-serialize works.
88
// RUN: %empty-directory(%t)
9-
// RUN: %target-swift-frontend -emit-module -o %t/SmokeTest.swiftmodule %s
9+
// RUN: %target-swift-frontend -build-module-from-parseable-interface -o %t/SmokeTest.swiftmodule %s
1010
// RUN: %target-swift-ide-test -print-module -module-to-print SmokeTest -I %t -source-filename x -print-interface > %t/SmokeTest.txt
1111
// RUN: %FileCheck %s < %t/SmokeTest.txt
1212
// RUN: %FileCheck -check-prefix NEGATIVE %s < %t/SmokeTest.txt

0 commit comments

Comments
 (0)