Frontend: add a frontend flag to generate empty ABI descriptors to workaround deserialization issues

ABI descriptors should always be emitted as sidecars for library-evolution-enabled modules.
However, generating these files requires traversing the entire module (like indexing), which may
hit additional deserialization issues. To unblock builds, this patch introduces a flag to skip
the traversing logic so that we emit an empty ABI descriptor file. The empty file serves as
a placeholder so that build system doesn't need to know the details.
This commit is contained in:
Xi Ge
2022-02-23 21:51:03 -08:00
parent a9a512de37
commit e1aaee4fec
9 changed files with 32 additions and 9 deletions

View File

@@ -816,7 +816,7 @@ int dumpSDKContent(const CompilerInvocation &InitInvok,
const llvm::StringSet<> &ModuleNames,
StringRef OutputFile, CheckerOptions Opts);
void dumpModuleContent(ModuleDecl *MD, StringRef OutputFile, bool ABI);
void dumpModuleContent(ModuleDecl *MD, StringRef OutputFile, bool ABI, bool Empty);
/// Mostly for testing purposes, this function de-serializes the SDK dump in
/// dumpPath and re-serialize them to OutputPath. If the tool performs correctly,

View File

@@ -447,6 +447,11 @@ public:
/// to encode the actual paths into the .swiftmodule file.
PathObfuscator serializedPathObfuscator;
/// Avoid printing actual module content into the ABI descriptor file.
/// This should only be used as a workaround when emitting ABI descriptor files
/// crashes the compiler.
bool emptyABIDescriptor = false;
private:
static bool canActionEmitDependencies(ActionType);
static bool canActionEmitReferenceDependencies(ActionType);

View File

@@ -169,6 +169,9 @@ def serialize_debugging_options : Flag<["-"], "serialize-debugging-options">,
def serialized_path_obfuscate : Separate<["-"], "serialized-path-obfuscate">,
HelpText<"Remap source paths in debug info">, MetaVarName<"<prefix=replacement>">;
def empty_abi_descriptor : Flag<["-"], "empty-abi-descriptor">,
HelpText<"Avoid printing actual module content into ABI descriptor file">;
def no_serialize_debugging_options :
Flag<["-"], "no-serialize-debugging-options">,
HelpText<"Never serialize options for debugging (default: only for apps)">;

View File

@@ -33,6 +33,7 @@ namespace swift {
const char *DocOutputPath = nullptr;
const char *SourceInfoOutputPath = nullptr;
std::string ABIDescriptorPath;
bool emptyABIDescriptor = false;
llvm::VersionTuple UserModuleVersion;
std::string SDKName;

View File

@@ -2498,7 +2498,7 @@ int swift::ide::api::deserializeSDKDump(StringRef dumpPath, StringRef OutputPath
}
void swift::ide::api::dumpModuleContent(ModuleDecl *MD, StringRef OutputFile,
bool ABI) {
bool ABI, bool Empty) {
CheckerOptions opts;
opts.ABI = ABI;
opts.SwiftOnly = true;
@@ -2509,12 +2509,17 @@ void swift::ide::api::dumpModuleContent(ModuleDecl *MD, StringRef OutputFile,
opts.Verbose = false;
SDKContext ctx(opts);
SwiftDeclCollector collector(ctx);
collector.lookupVisibleDecls({MD});
ConstExtractor extractor(ctx, MD->getASTContext());
extractor.extract(MD);
PayLoad payload;
payload.allContsValues = &extractor.getAllConstValues();
dumpSDKRoot(collector.getSDKRoot(), payload, OutputFile);
SWIFT_DEFER {
payload.allContsValues = &extractor.getAllConstValues();
dumpSDKRoot(collector.getSDKRoot(), payload, OutputFile);
};
if (Empty) {
return;
}
collector.lookupVisibleDecls({MD});
extractor.extract(MD);
}
int swift::ide::api::findDeclUsr(StringRef dumpPath, CheckerOptions Opts) {

View File

@@ -297,6 +297,7 @@ bool ArgsToFrontendOptionsConverter::convert(
auto SplitMap = StringRef(A).split('=');
Opts.serializedPathObfuscator.addMapping(SplitMap.first, SplitMap.second);
}
Opts.emptyABIDescriptor = Args.hasArg(OPT_empty_abi_descriptor);
return false;
}

View File

@@ -158,7 +158,8 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
getIRGenOptions().PublicLinkLibraries;
serializationOpts.SDKName = getLangOptions().SDKName;
serializationOpts.ABIDescriptorPath = outs.ABIDescriptorOutputPath.c_str();
serializationOpts.emptyABIDescriptor = opts.emptyABIDescriptor;
if (!getIRGenOptions().ForceLoadSymbolName.empty())
serializationOpts.AutolinkForceLoad = true;

View File

@@ -5802,10 +5802,11 @@ bool Serializer::allowCompilerErrors() const {
static void emitABIDescriptor(ModuleOrSourceFile DC,
const SerializationOptions &options) {
using namespace swift::ide::api;
if (!options.ABIDescriptorPath.empty()) {
if (DC.is<ModuleDecl*>()) {
swift::ide::api::dumpModuleContent(DC.get<ModuleDecl*>(),
options.ABIDescriptorPath, true);
dumpModuleContent(DC.get<ModuleDecl*>(), options.ABIDescriptorPath, true,
options.emptyABIDescriptor);
}
}
}

View File

@@ -0,0 +1,6 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -o %t/Foo.swiftmodule -emit-abi-descriptor-path %t/abi.json %S/Inputs/ConstExtraction/SimpleReferences.swift -empty-abi-descriptor
// RUN: %api-digester -deserialize-sdk -input-paths %t/abi.json -o %t/abi.result.json
// RUN: %api-digester -generate-empty-baseline -o %t/abi-tool.json -avoid-tool-args -abi
// RUN: diff -u %t/abi-tool.json %t/abi.result.json