Skip to content

Commit 2dcb33b

Browse files
committed
Frontend: allow specifying a different target triple for internal clang instance to use
Before this change, we always use the Swift target triple to instantiate the internal Clang instance. When loading a Swift module from the textual interface, we may pick up a lower target triple to use to build the Swift module because the target is hard-coded in the textual interface file. This implies we may end up building multiple versions of the same Clang module, one for each target triple of the loading Swift module. This change adds a new frontend flag -clang-target to allow clients to specify a consistent clang target to use across the Swift module boundaries. This value won't change because it's not part of .swiftinterface files. swift-driver should pass down -clang-target for each frontend invocation, and its value should be identical to -target. Related to: rdar://72480261
1 parent dd543e6 commit 2dcb33b

File tree

7 files changed

+70
-1
lines changed

7 files changed

+70
-1
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ namespace swift {
9999
/// performed.
100100
llvm::Optional<llvm::Triple> TargetVariant;
101101

102+
/// The target triple to instantiate the internal clang instance.
103+
/// When not specified, the compiler will use the value of -target to
104+
/// instantiate the clang instance.
105+
/// This is mainly used to avoid lowering the target triple to use for clang when
106+
/// importing a .swiftinterface whose -target value may be different from
107+
/// the loading module.
108+
/// The lowering triple may result in multiple versions of the same Clang
109+
/// modules being built.
110+
llvm::Optional<llvm::Triple> ClangTarget;
111+
102112
/// The SDK version, if known.
103113
Optional<llvm::VersionTuple> SDKVersion;
104114

include/swift/Option/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1082,6 +1082,10 @@ def target_variant : Separate<["-"], "target-variant">,
10821082
HelpText<"Generate 'zippered' code for macCatalyst that can run on the specified"
10831083
" variant target triple in addition to the main -target triple">;
10841084

1085+
def clang_target : Separate<["-"], "clang-target">,
1086+
Flags<[FrontendOption, SwiftAPIExtractOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption]>,
1087+
HelpText<"Separately set the target we should use for internal Clang instance">;
1088+
10851089
def profile_generate : Flag<["-"], "profile-generate">,
10861090
Flags<[FrontendOption, NoInteractiveOption]>,
10871091
HelpText<"Generate instrumented code to collect execution counts">;

lib/ClangImporter/ClangImporter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,11 @@ importer::addCommonInvocationArguments(
730730
std::vector<std::string> &invocationArgStrs,
731731
ASTContext &ctx) {
732732
using ImporterImpl = ClangImporter::Implementation;
733-
const llvm::Triple &triple = ctx.LangOpts.Target;
733+
llvm::Triple triple = ctx.LangOpts.Target;
734+
// Use clang specific target triple if given.
735+
if (ctx.LangOpts.ClangTarget.hasValue()) {
736+
triple = ctx.LangOpts.ClangTarget.getValue();
737+
}
734738
SearchPathOptions &searchPathOpts = ctx.SearchPathOpts;
735739
const ClangImporterOptions &importerOpts = ctx.ClangImporterOpts;
736740

lib/Frontend/CompilerInvocation.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,20 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
686686
Opts.TargetVariant = llvm::Triple(A->getValue());
687687
}
688688

689+
// Collect -clang-target value if specified in the front-end invocation.
690+
// Usually, the driver will pass down a clang target with the
691+
// exactly same value as the main target, so we could dignose the usage of
692+
// unavailable APIs.
693+
// The reason we cannot infer clang target from -target is that not all
694+
// front-end invocation will include a -target to start with. For instance,
695+
// when compiling a Swift module from a textual interface, -target isn't
696+
// necessary because the textual interface hardcoded the proper target triple
697+
// to use. Inferring -clang-target there will always give us the default
698+
// target triple.
699+
if (const Arg *A = Args.getLastArg(OPT_clang_target)) {
700+
Opts.ClangTarget = llvm::Triple(A->getValue());
701+
}
702+
689703
Opts.EnableCXXInterop |= Args.hasArg(OPT_enable_cxx_interop);
690704
Opts.EnableObjCInterop =
691705
Args.hasFlag(OPT_enable_objc_interop, OPT_disable_objc_interop,

lib/Frontend/ModuleInterfaceLoader.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1269,6 +1269,17 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface(
12691269
GenericArgs.push_back(triple);
12701270
}
12711271

1272+
if (LangOpts.ClangTarget.hasValue()) {
1273+
genericSubInvocation.getLangOptions().ClangTarget = LangOpts.ClangTarget;
1274+
auto triple = ArgSaver.save(genericSubInvocation.getLangOptions()
1275+
.ClangTarget->getTriple());
1276+
assert(!triple.empty());
1277+
// In explicit module build, all PCMs will be built using the given clang target.
1278+
// So the Swift interface should know that as well to load these PCMs properly.
1279+
GenericArgs.push_back("-clang-target");
1280+
GenericArgs.push_back(triple);
1281+
}
1282+
12721283
// Inherit the Swift language version
12731284
genericSubInvocation.getLangOptions().EffectiveLanguageVersion =
12741285
LangOpts.EffectiveLanguageVersion;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-module-flags: -module-name XWithTarget -target x86_64-apple-macosx10.9
3+
import Swift
4+
@_exported import X
5+
public func overlayFuncX() { }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// REQUIRES: VENDOR=apple
2+
// RUN: %empty-directory(%t.module-cache)
3+
// 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
4+
5+
// Without -clang-target, we build two X.pcm
6+
// RUN: find %t.module-cache -name "X-*.pcm" | count 2
7+
8+
// RUN: %empty-directory(%t.module-cache)
9+
// 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
10+
11+
// With -clang-target, we build one X.pcm
12+
// RUN: find %t.module-cache -name "X-*.pcm" | count 1
13+
14+
// 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
15+
// RUN: %FileCheck %s < %t.deps.json
16+
17+
// CHECK: "-clang-target"
18+
// CHECK-NEXT: "x86_64-apple-macosx10.14"
19+
20+
import X
21+
import XWithTarget

0 commit comments

Comments
 (0)