Skip to content

Commit 2d43a92

Browse files
committed
Frontend: teach final module emitting jobs to dump a placeholder file for module semantic info
This additional supplement output should capture semantic info the compiler has captured while building a Swift module. Similar to the source info file, the content of the semantic info file should only be consumed by local tooling written in Swift.
1 parent c2fd49c commit 2d43a92

11 files changed

+100
-1
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ ERROR(error_mode_cannot_emit_symbol_graph,none,
131131
"this mode does not support emitting symbol graph files", ())
132132
ERROR(error_mode_cannot_emit_abi_descriptor,none,
133133
"this mode does not support emitting ABI descriptor", ())
134+
ERROR(error_mode_cannot_emit_module_semantic_info,none,
135+
"this mode does not support emitting module semantic info", ())
134136
ERROR(cannot_emit_ir_skipping_function_bodies,none,
135137
"the -experimental-skip-*-function-bodies* flags do not support "
136138
"emitting IR", ())

include/swift/Basic/SupplementaryOutputPaths.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ struct SupplementaryOutputPaths {
146146
/// The output path to generate ABI baseline.
147147
std::string ABIDescriptorOutputPath;
148148

149+
/// The output path of Swift semantic info for this module.
150+
std::string ModuleSemanticInfoOutputPath;
151+
149152
/// The output path for YAML optimization record file.
150153
std::string YAMLOptRecordPath;
151154

@@ -189,6 +192,8 @@ struct SupplementaryOutputPaths {
189192
fn(YAMLOptRecordPath);
190193
if (!BitstreamOptRecordPath.empty())
191194
fn(BitstreamOptRecordPath);
195+
if (!ModuleSemanticInfoOutputPath.empty())
196+
fn(ModuleSemanticInfoOutputPath);
192197
}
193198

194199
bool empty() const {
@@ -198,6 +203,7 @@ struct SupplementaryOutputPaths {
198203
SerializedDiagnosticsPath.empty() && LoadedModuleTracePath.empty() &&
199204
TBDPath.empty() && ModuleInterfaceOutputPath.empty() &&
200205
ModuleSourceInfoOutputPath.empty() && ABIDescriptorOutputPath.empty() &&
206+
ModuleSemanticInfoOutputPath.empty() &&
201207
YAMLOptRecordPath.empty() && BitstreamOptRecordPath.empty();
202208
}
203209
};

include/swift/Frontend/FrontendInputsAndOutputs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ class FrontendInputsAndOutputs {
257257
bool hasModuleInterfaceOutputPath() const;
258258
bool hasPrivateModuleInterfaceOutputPath() const;
259259
bool hasABIDescriptorOutputPath() const;
260+
bool hasModuleSemanticInfoOutputPath() const;
260261
bool hasModuleSummaryOutputPath() const;
261262
bool hasTBDPath() const;
262263
bool hasYAMLOptRecordPath() const;

include/swift/Frontend/FrontendOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ class FrontendOptions {
437437
static bool canActionEmitModuleSummary(ActionType);
438438
static bool canActionEmitInterface(ActionType);
439439
static bool canActionEmitABIDescriptor(ActionType);
440+
static bool canActionEmitModuleSemanticInfo(ActionType);
440441

441442
public:
442443
static bool doesActionGenerateSIL(ActionType);

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ def emit_abi_descriptor_path
6868
: Separate<["-"], "emit-abi-descriptor-path">, MetaVarName<"<path>">,
6969
HelpText<"Output the ABI descriptor of current module to <path>">;
7070

71+
def emit_module_semantic_info_path
72+
: Separate<["-"], "emit-module-semantic-info-path">, MetaVarName<"<path>">,
73+
HelpText<"Output semantic info of current module to <path>">;
74+
7175
def serialize_module_interface_dependency_hashes
7276
: Flag<["-"], "serialize-module-interface-dependency-hashes">,
7377
Flags<[HelpHidden]>;

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,11 @@ bool ArgsToFrontendOptionsConverter::checkUnusedSupplementaryOutputPaths()
680680
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_abi_descriptor);
681681
return true;
682682
}
683+
if (!FrontendOptions::canActionEmitModuleSemanticInfo(Opts.RequestedAction) &&
684+
Opts.InputsAndOutputs.hasModuleSemanticInfoOutputPath()) {
685+
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_semantic_info);
686+
return true;
687+
}
683688
// If we cannot emit module doc, we cannot emit source information file either.
684689
if (!FrontendOptions::canActionEmitModuleDoc(Opts.RequestedAction) &&
685690
Opts.InputsAndOutputs.hasModuleSourceInfoOutputPath()) {

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,16 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
341341
options::OPT_emit_module_summary_path);
342342
auto abiDescriptorOutput = getSupplementaryFilenamesFromArguments(
343343
options::OPT_emit_abi_descriptor_path);
344+
auto moduleSemanticInfoOutput = getSupplementaryFilenamesFromArguments(
345+
options::OPT_emit_module_semantic_info_path);
344346
auto optRecordOutput = getSupplementaryFilenamesFromArguments(
345347
options::OPT_save_optimization_record_path);
346348
if (!objCHeaderOutput || !moduleOutput || !moduleDocOutput ||
347349
!dependenciesFile || !referenceDependenciesFile ||
348350
!serializedDiagnostics || !fixItsOutput || !loadedModuleTrace || !TBD ||
349351
!moduleInterfaceOutput || !privateModuleInterfaceOutput ||
350352
!moduleSourceInfoOutput || !moduleSummaryOutput || !abiDescriptorOutput ||
351-
!optRecordOutput) {
353+
!moduleSemanticInfoOutput || !optRecordOutput) {
352354
return None;
353355
}
354356
std::vector<SupplementaryOutputPaths> result;
@@ -371,6 +373,7 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
371373
sop.ModuleSourceInfoOutputPath = (*moduleSourceInfoOutput)[i];
372374
sop.ModuleSummaryOutputPath = (*moduleSummaryOutput)[i];
373375
sop.ABIDescriptorOutputPath = (*abiDescriptorOutput)[i];
376+
sop.ModuleSemanticInfoOutputPath = (*moduleSemanticInfoOutput)[i];
374377
sop.YAMLOptRecordPath = (*optRecordOutput)[i];
375378
sop.BitstreamOptRecordPath = (*optRecordOutput)[i];
376379
result.push_back(sop);
@@ -473,6 +476,7 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
473476

474477
// There is no non-path form of -emit-abi-descriptor-path
475478
auto ABIDescriptorOutputPath = pathsFromArguments.ABIDescriptorOutputPath;
479+
auto ModuleSemanticInfoOutputPath = pathsFromArguments.ModuleSemanticInfoOutputPath;
476480
ID emitModuleOption;
477481
std::string moduleExtension;
478482
std::string mainOutputIfUsableForModule;
@@ -508,6 +512,7 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
508512
sop.ModuleSourceInfoOutputPath = moduleSourceInfoOutputPath;
509513
sop.ModuleSummaryOutputPath = moduleSummaryOutputPath;
510514
sop.ABIDescriptorOutputPath = ABIDescriptorOutputPath;
515+
sop.ModuleSemanticInfoOutputPath = ModuleSemanticInfoOutputPath;
511516
sop.YAMLOptRecordPath = YAMLOptRecordPath;
512517
sop.BitstreamOptRecordPath = bitstreamOptRecordPath;
513518
return sop;

lib/Frontend/FrontendInputsAndOutputs.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,12 @@ bool FrontendInputsAndOutputs::hasABIDescriptorOutputPath() const {
509509
return outs.ABIDescriptorOutputPath;
510510
});
511511
}
512+
bool FrontendInputsAndOutputs::hasModuleSemanticInfoOutputPath() const {
513+
return hasSupplementaryOutputPath(
514+
[](const SupplementaryOutputPaths &outs) -> const std::string & {
515+
return outs.ModuleSemanticInfoOutputPath;
516+
});
517+
}
512518
bool FrontendInputsAndOutputs::hasModuleSummaryOutputPath() const {
513519
return hasSupplementaryOutputPath(
514520
[](const SupplementaryOutputPaths &outs) -> const std::string & {

lib/Frontend/FrontendOptions.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,48 @@ bool FrontendOptions::canActionEmitLoadedModuleTrace(ActionType action) {
524524
}
525525
llvm_unreachable("unhandled action");
526526
}
527+
bool FrontendOptions::canActionEmitModuleSemanticInfo(ActionType action) {
528+
switch (action) {
529+
case ActionType::MergeModules:
530+
case ActionType::EmitModuleOnly:
531+
case ActionType::CompileModuleFromInterface:
532+
// For test
533+
case ActionType::Typecheck:
534+
return true;
535+
case ActionType::NoneAction:
536+
case ActionType::Parse:
537+
case ActionType::ResolveImports:
538+
case ActionType::DumpParse:
539+
case ActionType::DumpInterfaceHash:
540+
case ActionType::DumpAST:
541+
case ActionType::EmitSyntax:
542+
case ActionType::PrintAST:
543+
case ActionType::EmitPCH:
544+
case ActionType::DumpScopeMaps:
545+
case ActionType::DumpTypeRefinementContexts:
546+
case ActionType::DumpTypeInfo:
547+
case ActionType::EmitSILGen:
548+
case ActionType::TypecheckModuleFromInterface:
549+
case ActionType::Immediate:
550+
case ActionType::REPL:
551+
case ActionType::EmitPCM:
552+
case ActionType::DumpPCM:
553+
case ActionType::ScanDependencies:
554+
case ActionType::PrintVersion:
555+
case ActionType::PrintFeature:
556+
case ActionType::EmitSIL:
557+
case ActionType::EmitSIBGen:
558+
case ActionType::EmitSIB:
559+
case ActionType::EmitIRGen:
560+
case ActionType::EmitIR:
561+
case ActionType::EmitBC:
562+
case ActionType::EmitAssembly:
563+
case ActionType::EmitObject:
564+
case ActionType::EmitImportedModules:
565+
return false;
566+
}
567+
llvm_unreachable("unhandled action");
568+
}
527569
bool FrontendOptions::canActionEmitABIDescriptor(ActionType action) {
528570
switch (action) {
529571
case ActionType::MergeModules:

lib/FrontendTool/FrontendTool.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
#include "llvm/Support/ErrorHandling.h"
8181
#include "llvm/Support/Path.h"
8282
#include "llvm/Support/raw_ostream.h"
83+
#include "llvm/Support/FileSystem.h"
8384

8485
#if __has_include(<unistd.h>)
8586
#include <unistd.h>
@@ -660,6 +661,22 @@ static void emitSwiftdepsForAllPrimaryInputsIfNeeded(
660661
}
661662
}
662663

664+
static bool writeModuleSemanticInfoIfNeeded(CompilerInstance &Instance) {
665+
const auto &Invocation = Instance.getInvocation();
666+
const auto &frontendOpts = Invocation.getFrontendOptions();
667+
if (!frontendOpts.InputsAndOutputs.hasModuleSemanticInfoOutputPath())
668+
return false;
669+
std::error_code EC;
670+
assert(frontendOpts.InputsAndOutputs.isWholeModule() &&
671+
"TBDPath only makes sense when the whole module can be seen");
672+
auto ModuleSemanticPath = frontendOpts.InputsAndOutputs
673+
.getPrimarySpecificPathsForAtMostOnePrimary().SupplementaryOutputs
674+
.ModuleSemanticInfoOutputPath;
675+
llvm::raw_fd_ostream OS(ModuleSemanticPath, EC, llvm::sys::fs::OF_None);
676+
OS << "{}\n";
677+
return false;
678+
}
679+
663680
static bool writeTBDIfNeeded(CompilerInstance &Instance) {
664681
const auto &Invocation = Instance.getInvocation();
665682
const auto &frontendOpts = Invocation.getFrontendOptions();
@@ -842,6 +859,9 @@ static bool emitAnyWholeModulePostTypeCheckSupplementaryOutputs(
842859
hadAnyError |= writeTBDIfNeeded(Instance);
843860
}
844861

862+
{
863+
hadAnyError |= writeModuleSemanticInfoIfNeeded(Instance);
864+
}
845865
return hadAnyError;
846866
}
847867

test/IDE/emit-module-semantic.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// REQUIRES: VENDOR=apple
2+
// RUN: %empty-directory(%t)
3+
4+
// RUN: %target-swift-frontend -emit-module %s -emit-module-path %t/Foo.swiftmodule -module-name Foo -emit-module-semantic-info-path %t/Foo.swiftsemanticinfo
5+
6+
// RUN: ls %t/Foo.swiftmodule
7+
// RUN: ls %t/Foo.swiftsemanticinfo

0 commit comments

Comments
 (0)