This patch extends clang frontend to add metadata that can be used to emit macho files with two build version load commands.
It utilizes "darwin.target_variant.triple" and "darwin.target_variant.SDK Version" metadata names for that.
MachO uses two build version load commands to represent an object file / binary that is targeting both the macOS target,
and the Mac Catalyst target. At runtime, a dynamic library that supports both targets can be loaded from either a native
macOS or a Mac Catalyst app on a macOS system. We want to add support to this to upstream to LLVM to be able to build
compiler-rt for both targets, to finish the complete support for the Mac Catalyst platform, which is right now targetable
by upstream clang, but the compiler-rt bits aren't supported because of the lack of this multiple build version support.
Differential Revision: https://reviews.llvm.org/D115415
unsigned MaxOpenCLWorkGroupSize;
+ Optional<llvm::Triple> DarwinTargetVariantTriple;
+
// TargetInfo Constructor. Default initializes all fields.
TargetInfo(const llvm::Triple &T);
/// Whether target allows debuginfo types for decl only variables/functions.
virtual bool allowDebugInfoForExternalRef() const { return false; }
+ /// Returns the darwin target variant triple, the variant of the deployment
+ /// target for which the code is being compiled.
+ const llvm::Triple *getDarwinTargetVariantTriple() const {
+ return DarwinTargetVariantTriple ? DarwinTargetVariantTriple.getPointer()
+ : nullptr;
+ }
+
+ /// Returns the version of the darwin target variant SDK which was used during
+ /// the compilation if one was specified, or an empty version otherwise.
+ const Optional<VersionTuple> getDarwinTargetVariantSDKVersion() const {
+ return !getTargetOpts().DarwinTargetVariantSDKVersion.empty()
+ ? getTargetOpts().DarwinTargetVariantSDKVersion
+ : Optional<VersionTuple>();
+ }
+
protected:
/// Copy type and layout related info.
void copyAuxTarget(const TargetInfo *Aux);
/// * CUDA compilation uses it to control parts of CUDA compilation
/// in clang that depend on specific version of the CUDA SDK.
llvm::VersionTuple SDKVersion;
+
+ /// The name of the darwin target- ariant triple to compile for.
+ std::string DarwinTargetVariantTriple;
+
+ /// The version of the darwin target variant SDK which was used during the
+ /// compilation.
+ llvm::VersionTuple DarwinTargetVariantSDKVersion;
};
} // end namespace clang
MarshallingInfoString<TargetOpts<"ABI">>;
def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">,
HelpText<"The version of target SDK used for compilation">;
+def darwin_target_variant_triple : Separate<["-"], "darwin-target-variant-triple">,
+ HelpText<"Specify the darwin target variant triple">,
+ MarshallingInfoString<TargetOpts<"DarwinTargetVariantTriple">>,
+ Normalizer<"normalizeTriple">;
+def darwin_target_variant_sdk_version_EQ : Joined<["-"],
+ "darwin-target-variant-sdk-version=">,
+ HelpText<"The version of darwin target variant SDK used for compilation">;
}
Target->setCommandLineOpenCLOpts();
Target->setMaxAtomicWidth();
+ if (!Opts->DarwinTargetVariantTriple.empty())
+ Target->DarwinTargetVariantTriple =
+ llvm::Triple(Opts->DarwinTargetVariantTriple);
+
if (!Target->validateTarget(Diags))
return nullptr;
const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
if (!SDKVersion.empty())
M->setSDKVersion(SDKVersion);
+ if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
+ M->setDarwinTargetVariantTriple(TVT->getTriple());
+ if (auto TVSDKVersion =
+ Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
+ M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
PreprocessorOpts, CodeGenOpts,
*M, Diags, CoverageInfo));
if (!Opts.SDKVersion.empty())
GenerateArg(Args, OPT_target_sdk_version_EQ, Opts.SDKVersion.getAsString(),
SA);
+ if (!Opts.DarwinTargetVariantSDKVersion.empty())
+ GenerateArg(Args, OPT_darwin_target_variant_sdk_version_EQ,
+ Opts.DarwinTargetVariantSDKVersion.getAsString(), SA);
}
static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
else
Opts.SDKVersion = Version;
}
+ if (Arg *A =
+ Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
+ llvm::VersionTuple Version;
+ if (Version.tryParse(A->getValue()))
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ else
+ Opts.DarwinTargetVariantSDKVersion = Version;
+ }
return Diags.getNumErrors() == NumErrorsBefore;
}
--- /dev/null
+// RUN: %clang_cc1 -triple x86_64-apple-macos11 -darwin-target-variant-triple x86_64-apple-ios14-macabi -target-sdk-version=11.1 -darwin-target-variant-sdk-version=14.1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: !llvm.module.flags = !{!0, !1, !2
+// CHECK: !0 = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 1]}
+// CHECK: !1 = !{i32 4, !"darwin.target_variant.triple", !"x86_64-apple-ios14-macabi"}
+// CHECK: !2 = !{i32 2, !"darwin.target_variant.SDK Version", [2 x i32] [i32 14, i32 1]}
/// @returns a string containing the target variant triple.
StringRef getDarwinTargetVariantTriple() const;
+ /// Set the target variant triple which is a string describing a variant of
+ /// the target host platform.
+ void setDarwinTargetVariantTriple(StringRef T);
+
/// Get the target variant version build SDK version metadata.
///
/// An empty version is returned if no such metadata is attached.
VersionTuple getDarwinTargetVariantSDKVersion() const;
+
+ /// Set the target variant version build SDK version metadata.
+ void setDarwinTargetVariantSDKVersion(VersionTuple Version);
};
/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the
addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align);
}
-void Module::setSDKVersion(const VersionTuple &V) {
+static void addSDKVersionMD(const VersionTuple &V, Module &M, StringRef Name) {
SmallVector<unsigned, 3> Entries;
Entries.push_back(V.getMajor());
if (auto Minor = V.getMinor()) {
// Ignore the 'build' component as it can't be represented in the object
// file.
}
- addModuleFlag(ModFlagBehavior::Warning, "SDK Version",
- ConstantDataArray::get(Context, Entries));
+ M.addModuleFlag(Module::ModFlagBehavior::Warning, Name,
+ ConstantDataArray::get(M.getContext(), Entries));
+}
+
+void Module::setSDKVersion(const VersionTuple &V) {
+ addSDKVersionMD(V, *this, "SDK Version");
}
static VersionTuple getSDKVersionMD(Metadata *MD) {
return "";
}
+void Module::setDarwinTargetVariantTriple(StringRef T) {
+ addModuleFlag(ModFlagBehavior::Override, "darwin.target_variant.triple",
+ MDString::get(getContext(), T));
+}
+
VersionTuple Module::getDarwinTargetVariantSDKVersion() const {
return getSDKVersionMD(getModuleFlag("darwin.target_variant.SDK Version"));
}
+
+void Module::setDarwinTargetVariantSDKVersion(VersionTuple Version) {
+ addSDKVersionMD(Version, *this, "darwin.target_variant.SDK Version");
+}