Add flag that allows ignoring compiler flags specified in an interface file when running a '-compile-module-from-interface' frontend action.

This commit is contained in:
Artem Chikin
2022-08-02 10:02:53 -07:00
parent 78f5e0b0fd
commit 7bdec998b1
12 changed files with 92 additions and 14 deletions

View File

@@ -99,6 +99,8 @@ WARNING(warning_cannot_find_locale_file,none,
"cannot find translations for '%0' at '%1': no such file", (StringRef, StringRef))
WARNING(warning_cannot_multithread_batch_mode,none,
"ignoring -num-threads argument; cannot multithread batch mode", ())
ERROR(error_cannot_ignore_interface_options_in_mode,none,
"'-ignore-interface-provided-options' only supported when building a module from interface ('-compile-module-from-interface')'", ())
ERROR(error_unsupported_option_argument,none,
"unsupported argument '%1' to option '%0'", (StringRef, StringRef))
ERROR(error_immediate_mode_missing_stdlib,none,

View File

@@ -165,6 +165,7 @@ struct InterfaceSubContextDelegate {
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
bool ignoreInterfaceProvidedOptions,
llvm::function_ref<std::error_code(ASTContext&, ModuleDecl*,
ArrayRef<StringRef>,
ArrayRef<StringRef>, StringRef)> action) = 0;
@@ -172,6 +173,7 @@ struct InterfaceSubContextDelegate {
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
bool ignoreInterfaceProvidedOptions,
llvm::function_ref<std::error_code(SubCompilerInstanceInfo&)> action) = 0;
virtual ~InterfaceSubContextDelegate() = default;

View File

@@ -108,6 +108,10 @@ public:
/// Include local definitions/references in the index data.
bool IndexIncludeLocals = false;
/// If building a module from interface, ignore compiler flags
/// specified in the swiftinterface.
bool IgnoreInterfaceProvidedOptions = false;
/// The module for which we should verify all of the generic signatures.
std::string VerifyGenericSignaturesInModule;

View File

@@ -300,6 +300,7 @@ struct ModuleInterfaceLoaderOptions {
bool disableImplicitSwiftModule = false;
bool disableBuildingInterface = false;
bool downgradeInterfaceVerificationError = false;
bool ignoreInterfaceProvidedOptions = false;
std::string mainExecutablePath;
ModuleInterfaceLoaderOptions(const FrontendOptions &Opts):
remarkOnRebuildFromInterface(Opts.RemarkOnRebuildFromModuleInterface),
@@ -307,6 +308,7 @@ struct ModuleInterfaceLoaderOptions {
disableImplicitSwiftModule(Opts.DisableImplicitModules),
disableBuildingInterface(Opts.DisableBuildingInterface),
downgradeInterfaceVerificationError(Opts.DowngradeInterfaceVerificationError),
ignoreInterfaceProvidedOptions(Opts.IgnoreInterfaceProvidedOptions),
mainExecutablePath(Opts.MainExecutablePath)
{
switch (Opts.RequestedAction) {
@@ -452,6 +454,7 @@ private:
llvm::StringSaver ArgSaver;
std::vector<StringRef> GenericArgs;
CompilerInvocation genericSubInvocation;
llvm::Triple ParentInvocationTarget;
template<typename ...ArgTypes>
InFlightDiagnostic diagnose(StringRef interfacePath,
@@ -473,7 +476,8 @@ private:
SmallVectorImpl<const char *> &SubArgs,
std::string &CompilerVersion,
StringRef interfacePath,
SourceLoc diagnosticLoc);
SourceLoc diagnosticLoc,
bool ignoreInterfaceProvidedOptions);
public:
InterfaceSubContextDelegateImpl(
SourceManager &SM, DiagnosticEngine *Diags,
@@ -488,6 +492,7 @@ public:
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
bool ignoreInterfaceProvidedOptions,
llvm::function_ref<std::error_code(ASTContext&, ModuleDecl*,
ArrayRef<StringRef>, ArrayRef<StringRef>,
StringRef)> action) override;
@@ -495,6 +500,7 @@ public:
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
bool ignoreInterfaceProvidedOptions,
llvm::function_ref<std::error_code(SubCompilerInstanceInfo&)> action) override;
~InterfaceSubContextDelegateImpl() = default;

View File

@@ -877,6 +877,10 @@ def compile_module_from_interface :
HelpText<"Treat the (single) input as a swiftinterface and produce a module">,
ModeOpt;
def ignore_interface_provided_options :
Flag<["-"], "ignore-interface-provided-options">,
HelpText<"Ignore all module flags specified in the swiftinterface being built">;
def build_module_from_parseable_interface :
Flag<["-"], "build-module-from-parseable-interface">,
Alias<compile_module_from_interface>,

View File

@@ -83,6 +83,7 @@ bool ArgsToFrontendOptionsConverter::convert(
Opts.EnablePrivateImports |= Args.hasArg(OPT_enable_private_imports);
Opts.EnableLibraryEvolution |= Args.hasArg(OPT_enable_library_evolution);
Opts.FrontendParseableOutput |= Args.hasArg(OPT_frontend_parseable_output);
Opts.IgnoreInterfaceProvidedOptions |= Args.hasArg(OPT_ignore_interface_provided_options);
// FIXME: Remove this flag
Opts.EnableLibraryEvolution |= Args.hasArg(OPT_enable_resilience);
@@ -233,6 +234,9 @@ bool ArgsToFrontendOptionsConverter::convert(
if (checkUnusedSupplementaryOutputPaths())
return true;
if (checkBuildFromInterfaceOnlyOptions())
return true;
if (FrontendOptions::doesActionGenerateIR(Opts.RequestedAction)) {
if (Args.hasArg(OPT_experimental_skip_non_inlinable_function_bodies) ||
Args.hasArg(OPT_experimental_skip_all_function_bodies) ||
@@ -615,6 +619,17 @@ bool ArgsToFrontendOptionsConverter::
return false;
}
bool ArgsToFrontendOptionsConverter::checkBuildFromInterfaceOnlyOptions()
const {
if (Opts.RequestedAction != FrontendOptions::ActionType::CompileModuleFromInterface &&
Opts.IgnoreInterfaceProvidedOptions) {
Diags.diagnose(SourceLoc(),
diag::error_cannot_ignore_interface_options_in_mode);
return true;
}
return false;
}
bool ArgsToFrontendOptionsConverter::checkUnusedSupplementaryOutputPaths()
const {
if (!FrontendOptions::canActionEmitDependencies(Opts.RequestedAction) &&

View File

@@ -55,6 +55,8 @@ private:
bool checkForUnusedOutputPaths() const;
bool checkBuildFromInterfaceOnlyOptions() const;
public:
ArgsToFrontendOptionsConverter(DiagnosticEngine &Diags,
const llvm::opt::ArgList &Args,

View File

@@ -180,7 +180,9 @@ struct ErrorDowngradeConsumerRAII: DiagnosticConsumer {
};
bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
StringRef OutPath, bool ShouldSerializeDeps,
StringRef OutPath,
bool ShouldSerializeDeps,
bool IgnoreInterfaceProvidedOptions,
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
ArrayRef<std::string> CompiledCandidates) {
@@ -200,6 +202,7 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
interfacePath,
OutPath,
diagnosticLoc,
IgnoreInterfaceProvidedOptions,
[&](SubCompilerInstanceInfo &info) {
auto &SubInstance = *info.Instance;
auto subInvocation = SubInstance.getInvocation();
@@ -320,6 +323,7 @@ bool ModuleInterfaceBuilder::buildSwiftModuleInternal(
bool ModuleInterfaceBuilder::buildSwiftModule(StringRef OutPath,
bool ShouldSerializeDeps,
bool IgnoreInterfaceProvidedOptions,
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
llvm::function_ref<void()> RemarkRebuild,
ArrayRef<std::string> CompiledCandidates) {
@@ -327,8 +331,8 @@ bool ModuleInterfaceBuilder::buildSwiftModule(StringRef OutPath,
if (RemarkRebuild) {
RemarkRebuild();
}
return buildSwiftModuleInternal(OutPath, ShouldSerializeDeps, ModuleBuffer,
CompiledCandidates);
return buildSwiftModuleInternal(OutPath, ShouldSerializeDeps, IgnoreInterfaceProvidedOptions,
ModuleBuffer, CompiledCandidates);
};
if (disableInterfaceFileLock) {
return build();

View File

@@ -86,7 +86,9 @@ private:
SmallVectorImpl<SerializationOptions::FileDependency> &Deps,
bool IsHashBased);
bool buildSwiftModuleInternal(StringRef OutPath, bool ShouldSerializeDeps,
bool buildSwiftModuleInternal(StringRef OutPath,
bool ShouldSerializeDeps,
bool IgnoreInterfaceProvidedOptions,
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
ArrayRef<std::string> CandidateModules);
public:
@@ -116,7 +118,9 @@ public:
extraDependencies.push_back(path);
}
bool buildSwiftModule(StringRef OutPath, bool ShouldSerializeDeps,
bool buildSwiftModule(StringRef OutPath,
bool ShouldSerializeDeps,
bool ignoreInterfaceProvidedOptions,
std::unique_ptr<llvm::MemoryBuffer> *ModuleBuffer,
llvm::function_ref<void()> RemarkRebuild = nullptr,
ArrayRef<std::string> CandidateModules = {});

View File

@@ -1018,6 +1018,7 @@ class ModuleInterfaceLoaderImpl {
builder.addExtraDependency(modulePath);
failed = builder.buildSwiftModule(cachedOutputPath,
/*shouldSerializeDeps*/true,
Opts.ignoreInterfaceProvidedOptions,
&moduleBuffer, remarkRebuild);
}
if (!failed) {
@@ -1051,7 +1052,10 @@ class ModuleInterfaceLoaderImpl {
// calculated using the canonical interface file path to make sure we
// can find it from the canonical interface file.
auto failedAgain = fallbackBuilder.buildSwiftModule(cachedOutputPath,
/*shouldSerializeDeps*/true, &moduleBuffer, remarkRebuild);
/*shouldSerializeDeps*/true,
Opts.ignoreInterfaceProvidedOptions,
&moduleBuffer,
remarkRebuild);
if (failedAgain)
return std::make_error_code(std::errc::invalid_argument);
assert(moduleBuffer);
@@ -1233,6 +1237,7 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
// FIXME: We really only want to serialize 'important' dependencies here, if
// we want to ship the built swiftmodules to another machine.
auto failed = builder.buildSwiftModule(OutPath, /*shouldSerializeDeps*/true,
LoaderOpts.ignoreInterfaceProvidedOptions,
/*ModuleBuffer*/nullptr, nullptr,
SearchPathOpts.CandidateCompiledModules);
if (!failed)
@@ -1253,6 +1258,7 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
// FIXME: We really only want to serialize 'important' dependencies here, if
// we want to ship the built swiftmodules to another machine.
return backupBuilder.buildSwiftModule(OutPath, /*shouldSerializeDeps*/true,
LoaderOpts.ignoreInterfaceProvidedOptions,
/*ModuleBuffer*/nullptr, nullptr,
SearchPathOpts.CandidateCompiledModules);
}
@@ -1359,7 +1365,8 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
SmallVectorImpl<const char *> &SubArgs,
std::string &CompilerVersion,
StringRef interfacePath,
SourceLoc diagnosticLoc) {
SourceLoc diagnosticLoc,
bool ignoreInterfaceProvidedOptions) {
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath);
if (!FileOrError) {
@@ -1379,11 +1386,14 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
diag::error_extracting_version_from_module_interface);
return true;
}
if (!ignoreInterfaceProvidedOptions) {
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver, SubArgs)) {
diagnose(interfacePath, diagnosticLoc,
diag::error_extracting_version_from_module_interface);
return true;
}
}
assert(VersMatches.size() == 2);
// FIXME We should diagnose this at a location that makes sense:
auto Vers = swift::version::Version(VersMatches[1], SourceLoc(), Diags);
@@ -1463,6 +1473,9 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
genericSubInvocation.getFrontendOptions().DisableImplicitModules = true;
GenericArgs.push_back("-disable-implicit-swift-modules");
}
// Save the parent invocation's Target Triple
ParentInvocationTarget = langOpts.Target;
// Pass down -explicit-swift-module-map-file
// FIXME: we shouldn't need this. Remove it?
StringRef explicitSwiftModuleMap = searchPathOpts.ExplicitSwiftModuleMap;
@@ -1600,9 +1613,11 @@ InterfaceSubContextDelegateImpl::runInSubContext(StringRef moduleName,
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
bool ignoreInterfaceProvidedOptions,
llvm::function_ref<std::error_code(ASTContext&, ModuleDecl*, ArrayRef<StringRef>,
ArrayRef<StringRef>, StringRef)> action) {
return runInSubCompilerInstance(moduleName, interfacePath, outputPath, diagLoc,
ignoreInterfaceProvidedOptions,
[&](SubCompilerInstanceInfo &info){
return action(info.Instance->getASTContext(),
info.Instance->getMainModule(),
@@ -1617,6 +1632,7 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
StringRef interfacePath,
StringRef outputPath,
SourceLoc diagLoc,
bool ignoreInterfaceProvidedOptions,
llvm::function_ref<std::error_code(SubCompilerInstanceInfo&)> action) {
// We are about to mess up the compiler invocation by using the compiler
// arguments in the textual interface file. So copy to use a new compiler
@@ -1674,9 +1690,11 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
SubArgs,
CompilerVersion,
interfacePath,
diagLoc)) {
diagLoc,
ignoreInterfaceProvidedOptions)) {
return std::make_error_code(std::errc::not_supported);
}
// Insert arguments collected from the interface file.
BuildArgs.insert(BuildArgs.end(), SubArgs.begin(), SubArgs.end());
if (subInvocation.parseArgs(SubArgs, *Diags)) {
@@ -1696,6 +1714,10 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
== originalTargetTriple.getEnvironment()) {
parsedTargetTriple.setArchName(originalTargetTriple.getArchName());
subInvocation.setTargetTriple(parsedTargetTriple.str());
// Overload the target in the BuildArgs as well
BuildArgs.push_back("-target");
BuildArgs.push_back(parsedTargetTriple.str());
}
CompilerInstance subInstance;

View File

@@ -111,6 +111,7 @@ ErrorOr<ModuleDependencies> ModuleDependencyScanner::scanInterfaceFile(
moduleInterfacePath.str(),
StringRef(),
SourceLoc(),
false,
[&](ASTContext &Ctx, ModuleDecl *mainMod,
ArrayRef<StringRef> Args,
ArrayRef<StringRef> PCMArgs, StringRef Hash) {

View File

@@ -0,0 +1,12 @@
// swift-interface-format-version: 1.0
// swift-module-flags: -module-name DoesNotIgnoreFlags -module-interface-preserve-types-as-written
// REQUIRES: OS=macosx
// RUN: %empty-directory(%t)
// Without '-ignore-interface-provided-options' this job fails because of the mismatch in 'module-name'
// RUN: %target-swift-frontend -compile-module-from-interface -module-name IgnoresFlags -ignore-interface-provided-options -o %/t/IgnoresFlags.swiftmodule %s -verify
import Swift
extension Int {
public static var fortytwo: Int = 42
}