arphaman created this revision. arphaman added reviewers: steven_wu, ab, dexonsmith. Herald added subscribers: jkorous, mgorny.
This patch is a follow-up to the LLVM SDK Version metadata support: https://reviews.llvm.org/D55612. This patch adds support for reading the `SDKSettings.json` file in the Darwin driver. This file is used by the driver to determine the SDK's version, and it uses that information to pass it down to the compiler using the new `-target-sdk-version=`. This option is then used to set the appropriate `SDK Version` module metadata introduced in https://reviews.llvm.org/D55612. Repository: rC Clang https://reviews.llvm.org/D55673 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Basic/TargetInfo.h include/clang/Basic/TargetOptions.h include/clang/Driver/CC1Options.td include/clang/Driver/DarwinSDKInfo.h lib/CodeGen/ModuleBuilder.cpp lib/Driver/CMakeLists.txt lib/Driver/DarwinSDKInfo.cpp lib/Driver/ToolChains/Darwin.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/darwin-sdk-version.c test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json test/Driver/darwin-sdk-version.c
Index: test/Driver/darwin-sdk-version.c =================================================================== --- /dev/null +++ test/Driver/darwin-sdk-version.c @@ -0,0 +1,25 @@ +// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %S/Inputs/MacOSX10.14.sdk -c -### %s 2>&1 \ +// RUN: | FileCheck %s +// RUN: env SDKROOT=%S/Inputs/MacOSX10.14.sdk %clang -target x86_64-apple-macosx10.13 -c -### %s 2>&1 \ +// RUN: | FileCheck %s +// +// RUN: rm -rf %t/SDKs/MacOSX10.14.sdk +// RUN: mkdir -p %t/SDKs/MacOSX10.14.sdk +// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %t/SDKs/MacOSX10.14.sdk -c -### %s 2>&1 \ +// RUN: | FileCheck --check-prefix=NO_VERSION %s +// +// RUN: rm -rf %t/SDKs/MacOSX10.14.sdk +// RUN: mkdir -p %t/SDKs/MacOSX10.14.sdk +// RUN: echo '{broken json' > %t/SDKs/MacOSX10.14.sdk/SDKSettings.json +// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %t/SDKs/MacOSX10.14.sdk -c -### %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=NO_VERSION,ERROR %s +// +// RUN: rm -rf %t/SDKs/MacOSX10.14.sdk +// RUN: mkdir -p %t/SDKs/MacOSX10.14.sdk +// RUN: echo '{"Version":1}' > %t/SDKs/MacOSX10.14.sdk/SDKSettings.json +// RUN: %clang -target x86_64-apple-macosx10.13 -isysroot %t/SDKs/MacOSX10.14.sdk -c -### %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=NO_VERSION,ERROR %s + +// CHECK: -target-sdk-version=10.14 +// NO_VERSION-NOT: target-sdk-version +// ERROR: warning: SDK settings were ignored as 'SDKSettings.json' could not be parsed Index: test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json =================================================================== --- /dev/null +++ test/Driver/Inputs/MacOSX10.14.sdk/SDKSettings.json @@ -0,0 +1 @@ +{"Version":"10.14"} Index: test/CodeGen/darwin-sdk-version.c =================================================================== --- /dev/null +++ test/CodeGen/darwin-sdk-version.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14 -target-sdk-version=10.14.1 -emit-llvm -o - %s | FileCheck %s + +// CHECK: !llvm.module.flags = !{!0 +// CHECK: !0 = !{i32 2, !"SDK Version", [3 x i32] [i32 10, i32 14, i32 1]} Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -3188,6 +3188,14 @@ Opts.ForceEnableInt128 = Args.hasArg(OPT_fforce_enable_int128); Opts.NVPTXUseShortPointers = Args.hasFlag( options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false); + if (Arg *A = Args.getLastArg(options::OPT_target_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.SDKVersion = Version; + } } bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, Index: lib/Driver/ToolChains/Darwin.cpp =================================================================== --- lib/Driver/ToolChains/Darwin.cpp +++ lib/Driver/ToolChains/Darwin.cpp @@ -13,6 +13,7 @@ #include "clang/Basic/AlignedAllocation.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Driver/Compilation.h" +#include "clang/Driver/DarwinSDKInfo.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" @@ -2037,6 +2038,22 @@ return TargetVersion < alignedAllocMinVersion(OS); } +static Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS, + const ArgList &Args, + const Driver &TheDriver) { + const Arg *A = Args.getLastArg(options::OPT_isysroot); + if (!A) + return None; + StringRef isysroot = A->getValue(); + auto SDKInfoOrErr = driver::parseDarwinSDKInfo(VFS, isysroot); + if (!SDKInfoOrErr) { + llvm::consumeError(SDKInfoOrErr.takeError()); + TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings); + return None; + } + return *SDKInfoOrErr; +} + void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const { @@ -2046,6 +2063,15 @@ options::OPT_fno_aligned_allocation) && isAlignedAllocationUnavailable()) CC1Args.push_back("-faligned-alloc-unavailable"); + + // Read the SDKSettings.json file for more information, like the SDK version + // that we can pass down to the compiler. + if (auto SDKInfo = parseSDKSettings(getVFS(), DriverArgs, getDriver())) { + std::string Arg; + llvm::raw_string_ostream OS(Arg); + OS << "-target-sdk-version=" << SDKInfo->getVersion(); + CC1Args.push_back(DriverArgs.MakeArgString(OS.str())); + } } DerivedArgList * Index: lib/Driver/DarwinSDKInfo.cpp =================================================================== --- /dev/null +++ lib/Driver/DarwinSDKInfo.cpp @@ -0,0 +1,44 @@ +//===--- DarwinSDKInfo.cpp - SDK Information parser for darwin - ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Driver/DarwinSDKInfo.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/JSON.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver; +using namespace clang; + +Expected<Optional<DarwinSDKInfo>> +driver::parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, StringRef SDKRootPath) { + llvm::SmallString<256> Filepath = SDKRootPath; + llvm::sys::path::append(Filepath, "SDKSettings.json"); + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File = + VFS.getBufferForFile(Filepath); + if (!File) { + // If the file couldn't be read, assume it just doesn't exist. + return None; + } + Expected<llvm::json::Value> Result = + llvm::json::parse(File.get()->getBuffer()); + if (!Result) + return Result.takeError(); + + if (const auto *Obj = Result->getAsObject()) { + auto VersionString = Obj->getString("Version"); + if (VersionString) { + VersionTuple Version; + if (!Version.tryParse(*VersionString)) + return DarwinSDKInfo(Version); + } + } + return llvm::make_error<llvm::StringError>("invalid SDKSettings.json", + llvm::inconvertibleErrorCode()); +} Index: lib/Driver/CMakeLists.txt =================================================================== --- lib/Driver/CMakeLists.txt +++ lib/Driver/CMakeLists.txt @@ -12,6 +12,7 @@ add_clang_library(clangDriver Action.cpp Compilation.cpp + DarwinSDKInfo.cpp Distro.cpp Driver.cpp DriverOptions.cpp Index: lib/CodeGen/ModuleBuilder.cpp =================================================================== --- lib/CodeGen/ModuleBuilder.cpp +++ lib/CodeGen/ModuleBuilder.cpp @@ -132,6 +132,9 @@ M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple()); M->setDataLayout(Ctx->getTargetInfo().getDataLayout()); + const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion(); + if (!SDKVersion.empty()) + M->setSDKVersion(SDKVersion); Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags, CoverageInfo)); Index: include/clang/Driver/DarwinSDKInfo.h =================================================================== --- /dev/null +++ include/clang/Driver/DarwinSDKInfo.h @@ -0,0 +1,42 @@ +//===--- DarwinSDKInfo.h - SDK Information parser for darwin ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H +#define LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H + +#include "clang/Basic/LLVM.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/VersionTuple.h" +#include "llvm/Support/VirtualFileSystem.h" + +namespace clang { +namespace driver { + +/// The information about the darwin SDK that was used during this compilation. +class DarwinSDKInfo { +public: + DarwinSDKInfo(llvm::VersionTuple Version) : Version(Version) {} + + const llvm::VersionTuple &getVersion() const { return Version; } + +private: + llvm::VersionTuple Version; +}; + +/// Parse the SDK information from the SDKSettings.json file. +/// +/// \returns an error if the SDKSettings.json file is invalid, None if the +/// SDK has no SDKSettings.json, or a valid \c DarwinSDKInfo otherwise. +Expected<Optional<DarwinSDKInfo>> parseDarwinSDKInfo(llvm::vfs::FileSystem &VFS, + StringRef SDKRootPath); + +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_DRIVER_DARWIN_SDK_INFO_H Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -27,6 +27,8 @@ HelpText<"Specify target triple (e.g. i686-apple-darwin9)">; def target_abi : Separate<["-"], "target-abi">, HelpText<"Target a particular ABI type">; +def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">, + HelpText<"The version of target SDK used for compilation">; } Index: include/clang/Basic/TargetOptions.h =================================================================== --- include/clang/Basic/TargetOptions.h +++ include/clang/Basic/TargetOptions.h @@ -15,10 +15,11 @@ #ifndef LLVM_CLANG_BASIC_TARGETOPTIONS_H #define LLVM_CLANG_BASIC_TARGETOPTIONS_H -#include <string> -#include <vector> #include "clang/Basic/OpenCLOptions.h" +#include "llvm/Support/VersionTuple.h" #include "llvm/Target/TargetOptions.h" +#include <string> +#include <vector> namespace clang { @@ -73,6 +74,9 @@ // "default" for the case when the user has not explicitly specified a // code model. std::string CodeModel; + + /// The version of the SDK which was used during the compilation. + VersionTuple SDKVersion; }; } // end namespace clang Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -1321,6 +1321,12 @@ return None; } + /// \returns The version of the SDK which was used during the compilation if + /// one was specified, or an empty version otherwise. + const llvm::VersionTuple &getSDKVersion() const { + return getTargetOpts().SDKVersion; + } + /// Check the target is valid after it is fully initialized. virtual bool validateTarget(DiagnosticsEngine &Diags) const { return true; Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -405,4 +405,8 @@ def warn_drv_moutline_unsupported_opt : Warning< "The '%0' architecture does not support -moutline; flag ignored">, InGroup<OptionIgnored>; + +def warn_drv_darwin_sdk_invalid_settings : Warning< + "SDK settings were ignored as 'SDKSettings.json' could not be parsed">, + InGroup<DiagGroup<"darwin-sdk-settings">>; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits