diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index dbb6313525518..c396499a3741c 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -149,6 +149,7 @@ namespace swift { /// The lowering triple may result in multiple versions of the same Clang /// modules being built. std::optional ClangTarget; + std::optional ClangTargetVariant; /// The SDK version, if known. std::optional SDKVersion; @@ -808,6 +809,8 @@ namespace swift { hashValue = llvm::hash_combine(hashValue, TargetVariant.value().str()); if (ClangTarget.has_value()) hashValue = llvm::hash_combine(hashValue, ClangTarget.value().str()); + if (ClangTargetVariant.has_value()) + hashValue = llvm::hash_combine(hashValue, ClangTargetVariant.value().str()); if (SDKVersion.has_value()) hashValue = llvm::hash_combine(hashValue, SDKVersion.value().getAsString()); if (VariantSDKVersion.has_value()) diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index d5f1eccc580db..807bc417b5eac 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1533,6 +1533,11 @@ def clang_target : Separate<["-"], "clang-target">, Flags<[FrontendOption, SwiftSymbolGraphExtractOption, SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, HelpText<"Separately set the target we should use for internal Clang instance">; +def clang_target_variant : Separate<["-"], "clang-target-variant">, + Flags<[FrontendOption, SwiftSymbolGraphExtractOption, + SwiftAPIDigesterOption, SwiftSynthesizeInterfaceOption]>, + HelpText<"Separately set the target we should use for internal Clang instance" + " for the 'zippered' code for macCatalyst">; def disable_clang_target : Flag<["-"], "disable-clang-target">, Flags<[NewDriverOnlyOption]>, diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 0166a56e59e3b..d17e7cbb40a4e 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -866,6 +866,8 @@ importer::addCommonInvocationArguments( // Passing the -target-variant along to clang causes clang's // CodeGenerator to emit zippered .o files. invocationArgStrs.push_back("-darwin-target-variant"); + if (ctx.LangOpts.ClangTargetVariant.has_value() && !ignoreClangTarget) + variantTriple = ctx.LangOpts.ClangTargetVariant.value(); invocationArgStrs.push_back(variantTriple->str()); } @@ -1202,8 +1204,11 @@ std::optional> ClangImporter::getClangCC1Arguments( } // If clang target is ignored, using swift target. - if (ignoreClangTarget) + if (ignoreClangTarget) { CI->getTargetOpts().Triple = ctx.LangOpts.Target.str(); + if (ctx.LangOpts.TargetVariant.has_value()) + CI->getTargetOpts().DarwinTargetVariantTriple = ctx.LangOpts.TargetVariant->str(); + } // Forward the index store path. That information is not passed to scanner // and it is cached invariant so we don't want to re-scan if that changed. diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 90057f7a30bc2..6bc3a26805c22 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1433,9 +1433,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, // 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)) { + if (const Arg *A = Args.getLastArg(OPT_clang_target)) Opts.ClangTarget = llvm::Triple(A->getValue()); - } + if (const Arg *A = Args.getLastArg(OPT_clang_target_variant)) + Opts.ClangTargetVariant = llvm::Triple(A->getValue()); Opts.setCxxInteropFromArgs(Args, Diags); diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 1e64de754512d..40421eef6237e 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -246,6 +246,11 @@ SerializationOptions CompilerInvocation::computeSerializationOptions( serializationOpts.ExtraClangOptions.push_back("--target=" + LangOpts.ClangTarget->str()); } + if (LangOpts.ClangTargetVariant && + !getClangImporterOptions().DirectClangCC1ModuleBuild) { + serializationOpts.ExtraClangOptions.push_back("-darwin-target-variant"); + serializationOpts.ExtraClangOptions.push_back(LangOpts.ClangTargetVariant->str()); + } if (LangOpts.EnableAppExtensionRestrictions) { serializationOpts.ExtraClangOptions.push_back("-fapplication-extension"); } diff --git a/lib/Frontend/ModuleInterfaceLoader.cpp b/lib/Frontend/ModuleInterfaceLoader.cpp index 096f3adc14ec6..78151d14a56a0 100644 --- a/lib/Frontend/ModuleInterfaceLoader.cpp +++ b/lib/Frontend/ModuleInterfaceLoader.cpp @@ -1668,6 +1668,15 @@ void InterfaceSubContextDelegateImpl::inheritOptionsForBuildingInterface( GenericArgs.push_back(triple); } + if (LangOpts.ClangTargetVariant.has_value()) { + genericSubInvocation.getLangOptions().ClangTargetVariant = LangOpts.ClangTargetVariant; + auto variantTriple = ArgSaver.save(genericSubInvocation.getLangOptions() + .ClangTargetVariant->getTriple()); + assert(!variantTriple.empty()); + GenericArgs.push_back("-clang-target-variant"); + GenericArgs.push_back(variantTriple); + } + // Inherit the target SDK name and version if (!LangOpts.SDKName.empty()) { genericSubInvocation.getLangOptions().SDKName = LangOpts.SDKName; diff --git a/test/ScanDependencies/clang-target-variant.swift b/test/ScanDependencies/clang-target-variant.swift new file mode 100644 index 0000000000000..3dad67e6db9f0 --- /dev/null +++ b/test/ScanDependencies/clang-target-variant.swift @@ -0,0 +1,23 @@ +// REQUIRES: objc_interop +// REQUIRES: OS=macosx + +// RUN: %empty-directory(%t) +// RUN: %empty-directory(%t/module-cache) + +// RUN: %target-swift-frontend -scan-dependencies -enable-objc-interop -module-load-mode prefer-interface -module-cache-path %t.module-cache %s -o %t.deps.json -I %S/Inputs/CHeaders -I %S/Inputs/Swift -target arm64e-apple-ios16.4-macabi -clang-target arm64e-apple-ios17.0-macabi -target-variant arm64e-apple-macosx14.4 -clang-target-variant arm64e-apple-macosx15.0 + +// RUN: %validate-json %t.deps.json | %FileCheck %s + +// Ensure the flag affects Clang dependencies in the expected way +// CHECK: "clang": "X" +// CHECK: "modulePath": "{{.*}}X-{{.*}}.pcm" +// CHECK: "-darwin-target-variant-triple" +// CHECK-NEXT: "-Xcc" +// CHECK-NEXT: "arm64e-apple-macosx15.0" + +// Ensure the flag is propagated to Swift dependencies +// CHECK: "-clang-target-variant" +// CHECK-NEXT: "arm64e-apple-macosx15.0" + +import X +