[swiftinterface] Improve target overwrite for the swiftinterface

In certain cases (e.g. using arm64e interface to build arm64 target),
the target needs to be updated when building swiftinterface. Push the
target overwrite as early as possible to swiftinterface parsing by
providing a preferred target to relevant functions. In such cases, the
wrong target is never observed by other functions to avoid errors like
the sub-invocation was partially setup for the wrong target.
This commit is contained in:
Steven Wu
2024-02-15 13:26:04 -08:00
parent cdeef58e0f
commit 9f736811f0
4 changed files with 37 additions and 66 deletions

View File

@@ -1433,12 +1433,10 @@ bool ModuleInterfaceLoader::buildSwiftModuleFromSwiftInterface(
SearchPathOpts.CandidateCompiledModules);
}
static bool readSwiftInterfaceVersionAndArgs(SourceManager &SM,
DiagnosticEngine &Diags,
llvm::StringSaver &ArgSaver,
SwiftInterfaceInfo &interfaceInfo,
StringRef interfacePath,
SourceLoc diagnosticLoc) {
static bool readSwiftInterfaceVersionAndArgs(
SourceManager &SM, DiagnosticEngine &Diags, llvm::StringSaver &ArgSaver,
SwiftInterfaceInfo &interfaceInfo, StringRef interfacePath,
SourceLoc diagnosticLoc, llvm::Triple preferredTarget) {
llvm::vfs::FileSystem &fs = *SM.getFileSystem();
auto FileOrError = swift::vfs::getFileOrSTDIN(fs, interfacePath);
if (!FileOrError) {
@@ -1461,7 +1459,8 @@ static bool readSwiftInterfaceVersionAndArgs(SourceManager &SM,
}
if (extractCompilerFlagsFromInterface(interfacePath, SB, ArgSaver,
interfaceInfo.Arguments)) {
interfaceInfo.Arguments,
preferredTarget)) {
InterfaceSubContextDelegateImpl::diagnose(
interfacePath, diagnosticLoc, SM, &Diags,
diag::error_extracting_version_from_module_interface);
@@ -1543,9 +1542,10 @@ bool ModuleInterfaceLoader::buildExplicitSwiftModuleFromSwiftInterface(
llvm::BumpPtrAllocator alloc;
llvm::StringSaver ArgSaver(alloc);
SwiftInterfaceInfo InterfaceInfo;
readSwiftInterfaceVersionAndArgs(Instance.getSourceMgr(), Instance.getDiags(),
ArgSaver, InterfaceInfo, interfacePath,
SourceLoc());
readSwiftInterfaceVersionAndArgs(
Instance.getSourceMgr(), Instance.getDiags(), ArgSaver, InterfaceInfo,
interfacePath, SourceLoc(),
Instance.getInvocation().getLangOptions().Target);
auto Builder = ExplicitModuleInterfaceBuilder(
Instance, &Instance.getDiags(), Instance.getSourceMgr(),
@@ -1707,7 +1707,8 @@ bool InterfaceSubContextDelegateImpl::extractSwiftInterfaceVersionAndArgs(
CompilerInvocation &subInvocation, SwiftInterfaceInfo &interfaceInfo,
StringRef interfacePath, SourceLoc diagnosticLoc) {
if (readSwiftInterfaceVersionAndArgs(SM, *Diags, ArgSaver, interfaceInfo,
interfacePath, diagnosticLoc))
interfacePath, diagnosticLoc,
subInvocation.getLangOptions().Target))
return true;
// Prior to Swift 5.9, swiftinterfaces were always built (accidentally) with
@@ -1795,9 +1796,6 @@ InterfaceSubContextDelegateImpl::InterfaceSubContextDelegateImpl(
GenericArgs.push_back("-application-extension");
}
// Save the parent invocation's Target Triple
ParentInvocationTarget = langOpts.Target;
// Pass down -explicit-swift-module-map-file
StringRef explicitSwiftModuleMap = searchPathOpts.ExplicitSwiftModuleMap;
genericSubInvocation.getSearchPathOptions().ExplicitSwiftModuleMap =
@@ -2060,31 +2058,6 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
BuildArgs.insert(BuildArgs.end(), interfaceInfo.Arguments.begin(),
interfaceInfo.Arguments.end());
// If the target triple parsed from the Swift interface file differs
// only in subarchitecture from the original target triple, then
// we have loaded a Swift interface from a different-but-compatible
// architecture slice. Use the original subarchitecture.
llvm::Triple parsedTargetTriple(subInvocation.getTargetTriple());
if (parsedTargetTriple.getSubArch() != originalTargetTriple.getSubArch() &&
parsedTargetTriple.getArch() == originalTargetTriple.getArch() &&
parsedTargetTriple.getVendor() == originalTargetTriple.getVendor() &&
parsedTargetTriple.getOS() == originalTargetTriple.getOS() &&
parsedTargetTriple.getEnvironment()
== originalTargetTriple.getEnvironment()) {
parsedTargetTriple.setArchName(originalTargetTriple.getArchName());
subInvocation.setTargetTriple(parsedTargetTriple.str());
}
// Find and overload all "-target" to be parsedTargetTriple. This make sure
// the build command for the interface is the same no matter what the parent
// triple is so there is no need to spawn identical jobs.
assert(llvm::find(BuildArgs, "-target") != BuildArgs.end() &&
"missing target option");
for (unsigned idx = 0, end = BuildArgs.size(); idx < end; ++idx) {
if (BuildArgs[idx] == "-target" && ++idx < end)
BuildArgs[idx] = parsedTargetTriple.str();
}
// restore `StrictImplicitModuleContext`
subInvocation.getFrontendOptions().StrictImplicitModuleContext =
StrictImplicitModuleContext;