Skip to content

[5.5] cherry-pick -clang-target related changes. #38420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ namespace swift {
/// performed.
llvm::Optional<llvm::Triple> TargetVariant;

/// The target triple to instantiate the internal clang instance.
/// When not specified, the compiler will use the value of -target to
/// instantiate the clang instance.
/// This is mainly used to avoid lowering the target triple to use for clang when
/// importing a .swiftinterface whose -target value may be different from
/// the loading module.
/// The lowering triple may result in multiple versions of the same Clang
/// modules being built.
llvm::Optional<llvm::Triple> ClangTarget;

/// The SDK version, if known.
Optional<llvm::VersionTuple> SDKVersion;

Expand Down
7 changes: 7 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,13 @@ def target_variant : Separate<["-"], "target-variant">,
HelpText<"Generate 'zippered' code for macCatalyst that can run on the specified"
" variant target triple in addition to the main -target triple">;

def clang_target : Separate<["-"], "clang-target">,
Flags<[FrontendOption, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption]>,
HelpText<"Separately set the target we should use for internal Clang instance">;

def disable_clang_target : Flag<["-"], "disable-clang-target">,
HelpText<"Disable a separately specified target triple for Clang instance to use">;

def profile_generate : Flag<["-"], "profile-generate">,
Flags<[FrontendOption, NoInteractiveOption]>,
HelpText<"Generate instrumented code to collect execution counts">;
Expand Down
6 changes: 5 additions & 1 deletion lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,11 @@ importer::addCommonInvocationArguments(
std::vector<std::string> &invocationArgStrs,
ASTContext &ctx) {
using ImporterImpl = ClangImporter::Implementation;
const llvm::Triple &triple = ctx.LangOpts.Target;
llvm::Triple triple = ctx.LangOpts.Target;
// Use clang specific target triple if given.
if (ctx.LangOpts.ClangTarget.hasValue()) {
triple = ctx.LangOpts.ClangTarget.getValue();
}
SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;
const ClangImporterOptions &importerOpts = ctx.ClangImporterOpts;

Expand Down
11 changes: 11 additions & 0 deletions lib/ClangImporter/ClangModuleDependencyScanner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ void ClangImporter::recordModuleDependencies(
while(It != allArgs.end()) {
StringRef arg = *It;
// Remove the -target arguments because we should use the target triple
// specified with `-clang-target` on the scanner invocation, or
// from the depending Swift modules.
if (arg == "-target") {
It += 2;
Expand All @@ -254,6 +255,16 @@ void ClangImporter::recordModuleDependencies(
swiftArgs.push_back(clangArg);
}

// If the scanner is invoked with '-clang-target', ensure this is the target
// used to build this PCM.
if (Impl.SwiftContext.LangOpts.ClangTarget.hasValue()) {
llvm::Triple triple = Impl.SwiftContext.LangOpts.ClangTarget.getValue();
swiftArgs.push_back("-Xcc");
swiftArgs.push_back("-target");
swiftArgs.push_back("-Xcc");
swiftArgs.push_back(triple.str());
}

// Swift frontend action: -emit-pcm
swiftArgs.push_back("-emit-pcm");
swiftArgs.push_back("-module-name");
Expand Down
13 changes: 9 additions & 4 deletions lib/DependencyScan/ScanDependencies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1033,11 +1033,16 @@ identifyMainModuleDependencies(CompilerInstance &instance) {
instance.getASTContext()
.LangOpts.EffectiveLanguageVersion.asAPINotesVersionString())
.str();

// Compute the dependencies of the main module.
auto mainDependencies = ModuleDependencies::forMainSwiftModule(
{// ExtraPCMArgs
"-Xcc", "-target", "-Xcc",
instance.getASTContext().LangOpts.Target.str(), "-Xcc", apinotesVer});
std::vector<StringRef> ExtraPCMArgs = {
"-Xcc", apinotesVer
};
if (!instance.getASTContext().LangOpts.ClangTarget.hasValue())
ExtraPCMArgs.insert(ExtraPCMArgs.begin(),
{"-Xcc", "-target", "-Xcc",
instance.getASTContext().LangOpts.Target.str()});
auto mainDependencies = ModuleDependencies::forMainSwiftModule(ExtraPCMArgs);

// Compute Implicit dependencies of the main module
{
Expand Down
14 changes: 14 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,20 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.TargetVariant = llvm::Triple(A->getValue());
}

// Collect -clang-target value if specified in the front-end invocation.
// Usually, the driver will pass down a clang target with the
// exactly same value as the main target, so we could dignose the usage of
// unavailable APIs.
// The reason we cannot infer clang target from -target is that not all
// front-end invocation will include a -target to start with. For instance,
// when compiling a Swift module from a textual interface, -target isn't
// necessary because the textual interface hardcoded the proper target triple
// to use. Inferring -clang-target there will always give us the default
// target triple.
if (const Arg *A = Args.getLastArg(OPT_clang_target)) {
Opts.ClangTarget = llvm::Triple(A->getValue());
}

Opts.EnableCXXInterop |= Args.hasArg(OPT_enable_cxx_interop);
Opts.EnableObjCInterop =
Args.hasFlag(OPT_enable_objc_interop, OPT_disable_objc_interop,
Expand Down
26 changes: 21 additions & 5 deletions lib/Frontend/ModuleInterfaceLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,17 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
GenericArgs.push_back(triple);
}

if (LangOpts.ClangTarget.hasValue()) {
genericSubInvocation.getLangOptions().ClangTarget = LangOpts.ClangTarget;
auto triple = ArgSaver.save(genericSubInvocation.getLangOptions()
.ClangTarget->getTriple());
assert(!triple.empty());
// In explicit module build, all PCMs will be built using the given clang target.
// So the Swift interface should know that as well to load these PCMs properly.
GenericArgs.push_back("-clang-target");
GenericArgs.push_back(triple);
}

// Inherit the Swift language version
genericSubInvocation.getLangOptions().EffectiveLanguageVersion =
LangOpts.EffectiveLanguageVersion;
Expand Down Expand Up @@ -1495,15 +1506,20 @@ InterfaceSubContextDelegateImpl::runInSubCompilerInstance(StringRef moduleName,
}
info.BuildArguments = BuildArgs;
info.Hash = CacheHash;
auto target = *(std::find(BuildArgs.rbegin(), BuildArgs.rend(), "-target") - 1);
auto target = *(std::find(BuildArgs.rbegin(), BuildArgs.rend(), "-target") - 1);
auto langVersion = *(std::find(BuildArgs.rbegin(), BuildArgs.rend(),
"-swift-version") - 1);
std::array<StringRef, 6> ExtraPCMArgs = {
// PCMs should use the target triple the interface will be using to build
"-Xcc", "-target", "-Xcc", target,

std::vector<StringRef> ExtraPCMArgs = {
// PCMs should use the effective Swift language version for apinotes.
"-Xcc", ArgSaver.save((llvm::Twine("-fapinotes-swift-version=") + langVersion).str())
"-Xcc",
ArgSaver.save((llvm::Twine("-fapinotes-swift-version=") + langVersion).str())
};
if (!subInvocation.getLangOptions().ClangTarget.hasValue()) {
ExtraPCMArgs.insert(ExtraPCMArgs.begin(), {"-Xcc", "-target",
"-Xcc", target});
}

info.ExtraPCMArgs = ExtraPCMArgs;
// Run the action under the sub compiler instance.
return action(info);
Expand Down
5 changes: 5 additions & 0 deletions test/ScanDependencies/Inputs/Swift/XWithTarget.swiftinterface
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// swift-interface-format-version: 1.0
// swift-module-flags: -module-name XWithTarget -target x86_64-apple-macosx10.9
import Swift
@_exported import X
public func overlayFuncX() { }
21 changes: 21 additions & 0 deletions test/ScanDependencies/clang-target.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// REQUIRES: VENDOR=apple
// RUN: %empty-directory(%t.module-cache)
// RUN: %target-swift-frontend -emit-module -o %t.foo.swiftmodule -module-cache-path %t.module-cache -I %S/Inputs/CHeaders -I %S/Inputs/Swift %s -target x86_64-apple-macosx10.14

// Without -clang-target, we build two X.pcm
// RUN: find %t.module-cache -name "X-*.pcm" | count 2

// RUN: %empty-directory(%t.module-cache)
// RUN: %target-swift-frontend -emit-module -o %t.foo.swiftmodule -module-cache-path %t.module-cache -I %S/Inputs/CHeaders -I %S/Inputs/Swift %s -target x86_64-apple-macosx10.14 -clang-target x86_64-apple-macosx10.14

// With -clang-target, we build one X.pcm
// RUN: find %t.module-cache -name "X-*.pcm" | count 1

// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t.module-cache %s -o %t.deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -target x86_64-apple-macosx10.14 -clang-target x86_64-apple-macosx10.14
// RUN: %FileCheck %s < %t.deps.json

// CHECK: "-clang-target"
// CHECK-NEXT: "x86_64-apple-macosx10.14"

import X
import XWithTarget
20 changes: 14 additions & 6 deletions test/ScanDependencies/module_deps.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// RUN: %empty-directory(%t)
// RUN: mkdir -p %t/clang-module-cache
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4

// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -emit-dependencies -emit-dependencies-path %t/deps.d -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4
// Check the contents of the JSON output
// RUN: %FileCheck %s < %t/deps.json
// RUN: %FileCheck -check-prefix CHECK_NO_CLANG_TARGET %s < %t/deps.json

// Check the contents of the JSON output
// RUN: %FileCheck %s -check-prefix CHECK-NO-SEARCH-PATHS < %t/deps.json
Expand All @@ -20,6 +20,11 @@
// RUN: %target-codesign %t/main
// RUN: %target-run %t/main %t/deps.json

// Ensure that scanning with `-clang-target` makes sure that Swift modules' respecitve PCM-dependency-build-argument sets do not contain target triples.
// RUN: %target-swift-frontend -scan-dependencies -module-cache-path %t/clang-module-cache %s -o %t/deps_clang_target.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -import-objc-header %S/Inputs/CHeaders/Bridging.h -swift-version 4 -clang-target %target-cpu-apple-macosx10.14
// Check the contents of the JSON output
// RUN: %FileCheck -check-prefix CHECK_CLANG_TARGET %s < %t/deps_clang_target.json

// REQUIRES: executable_test
// REQUIRES: objc_interop

Expand Down Expand Up @@ -174,10 +179,13 @@ import SubE
// CHECK: "-swift-version"
// CHECK: "5"
// CHECK: ],
// CHECK" "extraPcmArgs": [
// CHECK" "-target",
// CHECK" "-fapinotes-swift-version=5"
// CHECK" ]
// CHECK_NO_CLANG_TARGET: "extraPcmArgs": [
// CHECK_NO_CLANG_TARGET-NEXT: "-Xcc",
// CHECK_NO_CLANG_TARGET-NEXT: "-target",
// CHECK_CLANG_TARGET: "extraPcmArgs": [
// CHECK_CLANG_TARGET-NEXT: "-Xcc",
// CHECK_CLANG_TARGET-NEXT: "-fapinotes-swift-version={{.*}}"
// CHECK_CLANG_TARGET-NEXT: ]

/// --------Swift module Swift
// CHECK-LABEL: "modulePath": "Swift.swiftmodule",
Expand Down