Skip to content

Commit 00124ea

Browse files
authored
Merge pull request #38979 from nkcsgexi/compile-interface-gen-abi-baseline
2 parents 46b45b6 + 1a660c0 commit 00124ea

15 files changed

+103
-10
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ ERROR(error_mode_cannot_emit_module_summary,none,
129129
"this mode does not support emitting module summary files", ())
130130
ERROR(error_mode_cannot_emit_symbol_graph,none,
131131
"this mode does not support emitting symbol graph files", ())
132+
ERROR(error_mode_cannot_emit_abi_descriptor,none,
133+
"this mode does not support emitting ABI descriptor", ())
132134
ERROR(cannot_emit_ir_skipping_function_bodies,none,
133135
"the -experimental-skip-*-function-bodies* flags do not support "
134136
"emitting IR", ())

include/swift/Basic/SupplementaryOutputPaths.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ struct SupplementaryOutputPaths {
143143
/// The path to which we should emit module summary file.
144144
std::string ModuleSummaryOutputPath;
145145

146+
/// The output path to generate ABI baseline.
147+
std::string ABIDescriptorOutputPath;
148+
146149
SupplementaryOutputPaths() = default;
147150
SupplementaryOutputPaths(const SupplementaryOutputPaths &) = default;
148151

@@ -174,6 +177,8 @@ struct SupplementaryOutputPaths {
174177
fn(PrivateModuleInterfaceOutputPath);
175178
if (!ModuleSummaryOutputPath.empty())
176179
fn(ModuleSummaryOutputPath);
180+
if (!ABIDescriptorOutputPath.empty())
181+
fn(ABIDescriptorOutputPath);
177182
}
178183

179184
bool empty() const {
@@ -182,7 +187,7 @@ struct SupplementaryOutputPaths {
182187
ReferenceDependenciesFilePath.empty() &&
183188
SerializedDiagnosticsPath.empty() && LoadedModuleTracePath.empty() &&
184189
TBDPath.empty() && ModuleInterfaceOutputPath.empty() &&
185-
ModuleSourceInfoOutputPath.empty();
190+
ModuleSourceInfoOutputPath.empty() && ABIDescriptorOutputPath.empty();
186191
}
187192
};
188193
} // namespace swift

include/swift/Frontend/FrontendInputsAndOutputs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ class FrontendInputsAndOutputs {
256256
bool hasModuleSourceInfoOutputPath() const;
257257
bool hasModuleInterfaceOutputPath() const;
258258
bool hasPrivateModuleInterfaceOutputPath() const;
259+
bool hasABIDescriptorOutputPath() const;
259260
bool hasModuleSummaryOutputPath() const;
260261
bool hasTBDPath() const;
261262

include/swift/Frontend/FrontendOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ class FrontendOptions {
427427
static bool canActionEmitModuleDoc(ActionType);
428428
static bool canActionEmitModuleSummary(ActionType);
429429
static bool canActionEmitInterface(ActionType);
430+
static bool canActionEmitABIDescriptor(ActionType);
430431

431432
public:
432433
static bool doesActionGenerateSIL(ActionType);

include/swift/Frontend/ModuleInterfaceLoader.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,8 @@ class ModuleInterfaceLoader : public SerializedModuleLoaderBase {
430430
const ClangImporterOptions &ClangOpts, StringRef CacheDir,
431431
StringRef PrebuiltCacheDir, StringRef BackupInterfaceDir,
432432
StringRef ModuleName, StringRef InPath,
433-
StringRef OutPath, bool SerializeDependencyHashes,
433+
StringRef OutPath, StringRef ABIOutputPath,
434+
bool SerializeDependencyHashes,
434435
bool TrackSystemDependencies, ModuleInterfaceLoaderOptions Opts,
435436
RequireOSSAModules_t RequireOSSAModules);
436437
};

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def emit_fixits_path
6464
: Separate<["-"], "emit-fixits-path">, MetaVarName<"<path>">,
6565
HelpText<"Output compiler fixits as source edits to <path>">;
6666

67+
def emit_abi_descriptor_path
68+
: Separate<["-"], "emit-abi-descriptor-path">, MetaVarName<"<path>">,
69+
HelpText<"Output the ABI descriptor of current module to <path>">;
70+
6771
def serialize_module_interface_dependency_hashes
6872
: Flag<["-"], "serialize-module-interface-dependency-hashes">,
6973
Flags<[HelpHidden]>;

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,11 @@ bool ArgsToFrontendOptionsConverter::checkUnusedSupplementaryOutputPaths()
610610
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_doc);
611611
return true;
612612
}
613+
if (!FrontendOptions::canActionEmitABIDescriptor(Opts.RequestedAction) &&
614+
Opts.InputsAndOutputs.hasABIDescriptorOutputPath()) {
615+
Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_abi_descriptor);
616+
return true;
617+
}
613618
// If we cannot emit module doc, we cannot emit source information file either.
614619
if (!FrontendOptions::canActionEmitModuleDoc(Opts.RequestedAction) &&
615620
Opts.InputsAndOutputs.hasModuleSourceInfoOutputPath()) {

lib/Frontend/ArgsToFrontendOutputsConverter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,11 +339,13 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
339339
options::OPT_emit_module_source_info_path);
340340
auto moduleSummaryOutput = getSupplementaryFilenamesFromArguments(
341341
options::OPT_emit_module_summary_path);
342+
auto abiDescriptorOutput = getSupplementaryFilenamesFromArguments(
343+
options::OPT_emit_abi_descriptor_path);
342344
if (!objCHeaderOutput || !moduleOutput || !moduleDocOutput ||
343345
!dependenciesFile || !referenceDependenciesFile ||
344346
!serializedDiagnostics || !fixItsOutput || !loadedModuleTrace || !TBD ||
345347
!moduleInterfaceOutput || !privateModuleInterfaceOutput ||
346-
!moduleSourceInfoOutput || !moduleSummaryOutput) {
348+
!moduleSourceInfoOutput || !moduleSummaryOutput || !abiDescriptorOutput) {
347349
return None;
348350
}
349351
std::vector<SupplementaryOutputPaths> result;
@@ -365,6 +367,7 @@ SupplementaryOutputPathsComputer::getSupplementaryOutputPathsFromArguments()
365367
sop.PrivateModuleInterfaceOutputPath = (*privateModuleInterfaceOutput)[i];
366368
sop.ModuleSourceInfoOutputPath = (*moduleSourceInfoOutput)[i];
367369
sop.ModuleSummaryOutputPath = (*moduleSummaryOutput)[i];
370+
sop.ABIDescriptorOutputPath = (*abiDescriptorOutput)[i];
368371
result.push_back(sop);
369372
}
370373
return result;
@@ -463,6 +466,8 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
463466
auto PrivateModuleInterfaceOutputPath =
464467
pathsFromArguments.PrivateModuleInterfaceOutputPath;
465468

469+
// There is no non-path form of -emit-abi-descriptor-path
470+
auto ABIDescriptorOutputPath = pathsFromArguments.ABIDescriptorOutputPath;
466471
ID emitModuleOption;
467472
std::string moduleExtension;
468473
std::string mainOutputIfUsableForModule;
@@ -488,6 +493,7 @@ SupplementaryOutputPathsComputer::computeOutputPathsForOneInput(
488493
sop.PrivateModuleInterfaceOutputPath = PrivateModuleInterfaceOutputPath;
489494
sop.ModuleSourceInfoOutputPath = moduleSourceInfoOutputPath;
490495
sop.ModuleSummaryOutputPath = moduleSummaryOutputPath;
496+
sop.ABIDescriptorOutputPath = ABIDescriptorOutputPath;
491497
return sop;
492498
}
493499

lib/Frontend/FrontendInputsAndOutputs.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,12 @@ bool FrontendInputsAndOutputs::hasPrivateModuleInterfaceOutputPath() const {
503503
return outs.PrivateModuleInterfaceOutputPath;
504504
});
505505
}
506+
bool FrontendInputsAndOutputs::hasABIDescriptorOutputPath() const {
507+
return hasSupplementaryOutputPath(
508+
[](const SupplementaryOutputPaths &outs) -> const std::string & {
509+
return outs.ABIDescriptorOutputPath;
510+
});
511+
}
506512
bool FrontendInputsAndOutputs::hasModuleSummaryOutputPath() const {
507513
return hasSupplementaryOutputPath(
508514
[](const SupplementaryOutputPaths &outs) -> const std::string & {

lib/Frontend/FrontendOptions.cpp

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

lib/Frontend/ModuleInterfaceBuilder.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
284284
if (SubInstance.getDiags().hadAnyError()) {
285285
return std::make_error_code(std::errc::not_supported);
286286
}
287+
if (!ABIDescriptorPath.empty()) {
288+
swift::ide::api::dumpModuleContent(Mod, ABIDescriptorPath, true);
289+
}
287290
return std::error_code();
288291
});
289292
}, ThreadStackSize);

lib/Frontend/ModuleInterfaceBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ModuleInterfaceBuilder {
4242
const StringRef moduleCachePath;
4343
const StringRef prebuiltCachePath;
4444
const StringRef backupInterfaceDir;
45+
const StringRef ABIDescriptorPath;
4546
const bool disableInterfaceFileLock;
4647
const SourceLoc diagnosticLoc;
4748
DependencyTracker *const dependencyTracker;
@@ -96,6 +97,7 @@ class ModuleInterfaceBuilder {
9697
StringRef moduleCachePath,
9798
StringRef backupInterfaceDir,
9899
StringRef prebuiltCachePath,
100+
StringRef ABIDescriptorPath,
99101
bool disableInterfaceFileLock = false,
100102
SourceLoc diagnosticLoc = SourceLoc(),
101103
DependencyTracker *tracker = nullptr)
@@ -104,6 +106,7 @@ class ModuleInterfaceBuilder {
104106
interfacePath(interfacePath), moduleName(moduleName),
105107
moduleCachePath(moduleCachePath), prebuiltCachePath(prebuiltCachePath),
106108
backupInterfaceDir(backupInterfaceDir),
109+
ABIDescriptorPath(ABIDescriptorPath),
107110
disableInterfaceFileLock(disableInterfaceFileLock),
108111
diagnosticLoc(diagnosticLoc), dependencyTracker(tracker) {}
109112

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ class ModuleInterfaceLoaderImpl {
10071007
ModuleInterfaceBuilder builder(
10081008
ctx.SourceMgr, diagsToUse,
10091009
astDelegate, interfacePath, moduleName, cacheDir,
1010-
prebuiltCacheDir, backupInterfaceDir,
1010+
prebuiltCacheDir, backupInterfaceDir, StringRef(),
10111011
Opts.disableInterfaceLock, diagnosticLoc,
10121012
dependencyTracker);
10131013
// If we found an out-of-date .swiftmodule, we still want to add it as
@@ -1039,7 +1039,7 @@ class ModuleInterfaceLoaderImpl {
10391039
// the genericSubInvocation we'll need to use to compute the cache paths.
10401040
ModuleInterfaceBuilder fallbackBuilder(
10411041
ctx.SourceMgr, &ctx.Diags, astDelegate, backupPath, moduleName, cacheDir,
1042-
prebuiltCacheDir, backupInterfaceDir,
1042+
prebuiltCacheDir, backupInterfaceDir, StringRef(),
10431043
Opts.disableInterfaceLock, diagnosticLoc,
10441044
dependencyTracker);
10451045
if (rebuildInfo.sawOutOfDateModule(modulePath))
@@ -1208,7 +1208,8 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
12081208
const ClangImporterOptions &ClangOpts, StringRef CacheDir,
12091209
StringRef PrebuiltCacheDir, StringRef BackupInterfaceDir,
12101210
StringRef ModuleName, StringRef InPath,
1211-
StringRef OutPath, bool SerializeDependencyHashes,
1211+
StringRef OutPath, StringRef ABIOutputPath,
1212+
bool SerializeDependencyHashes,
12121213
bool TrackSystemDependencies, ModuleInterfaceLoaderOptions LoaderOpts,
12131214
RequireOSSAModules_t RequireOSSAModules) {
12141215
InterfaceSubContextDelegateImpl astDelegate(
@@ -1218,7 +1219,7 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
12181219
SerializeDependencyHashes, TrackSystemDependencies, RequireOSSAModules);
12191220
ModuleInterfaceBuilder builder(SourceMgr, &Diags, astDelegate, InPath,
12201221
ModuleName, CacheDir, PrebuiltCacheDir,
1221-
BackupInterfaceDir,
1222+
BackupInterfaceDir, ABIOutputPath,
12221223
LoaderOpts.disableInterfaceLock);
12231224
// FIXME: We really only want to serialize 'important' dependencies here, if
12241225
// we want to ship the built swiftmodules to another machine.
@@ -1236,7 +1237,7 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
12361237
assert(!backInPath.empty());
12371238
ModuleInterfaceBuilder backupBuilder(SourceMgr, &Diags, astDelegate, backInPath,
12381239
ModuleName, CacheDir, PrebuiltCacheDir,
1239-
BackupInterfaceDir,
1240+
BackupInterfaceDir, ABIOutputPath,
12401241
LoaderOpts.disableInterfaceLock);
12411242
// Ensure we can rebuild module after user changed the original interface file.
12421243
backupBuilder.addExtraDependency(InPath);

lib/FrontendTool/FrontendTool.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,13 +412,15 @@ static bool buildModuleFromInterface(CompilerInstance &Instance) {
412412
StringRef InputPath = FEOpts.InputsAndOutputs.getFilenameOfFirstInput();
413413
StringRef PrebuiltCachePath = FEOpts.PrebuiltModuleCachePath;
414414
ModuleInterfaceLoaderOptions LoaderOpts(FEOpts);
415+
StringRef ABIPath = Instance.getPrimarySpecificPathsForAtMostOnePrimary()
416+
.SupplementaryOutputs.ABIDescriptorOutputPath;
415417
return ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
416418
Instance.getSourceMgr(), Instance.getDiags(),
417419
Invocation.getSearchPathOptions(), Invocation.getLangOptions(),
418420
Invocation.getClangImporterOptions(),
419421
Invocation.getClangModuleCachePath(), PrebuiltCachePath,
420422
FEOpts.BackupModuleInterfaceDir,
421-
Invocation.getModuleName(), InputPath, Invocation.getOutputFilename(),
423+
Invocation.getModuleName(), InputPath, Invocation.getOutputFilename(), ABIPath,
422424
FEOpts.SerializeModuleInterfaceDependencyHashes,
423425
FEOpts.shouldTrackSystemDependencies(), LoaderOpts,
424426
RequireOSSAModules_t(Invocation.getSILOptions()));
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/Foo.swiftmodule)
3+
// RUN: %empty-directory(%t/ResourceDir/%target-sdk-name/prebuilt-modules/Foo.swiftmodule)
4+
// RUN: echo "public func foo() {}" > %t/Foo.swift
5+
6+
// RUN: %target-swift-frontend -emit-module %t/Foo.swift -module-name Foo -emit-module-interface-path %t/Foo.swiftinterface
7+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Foo.swiftinterface -o %t/Foo.swiftmodule -module-name Foo -emit-abi-descriptor-path %t/Foo.json
8+
9+
// RUN: %FileCheck %s < %t/Foo.json
10+
11+
// CHECK: "kind": "Root"
12+
// CHECK-NEXT: "name": "TopLevel"
13+
// CHECK-NEXT: "printedName": "TopLevel"

0 commit comments

Comments
 (0)