//===------ DarwinToolChains.cpp - Job invocations (Darwin-specific) ------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "ToolChains.h"

#include "swift/AST/DiagnosticsDriver.h"
#include "swift/AST/PlatformKind.h"
#include "swift/Basic/Dwarf.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/Platform.h"
#include "swift/Basic/Range.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/TaskQueue.h"
#include "swift/Config.h"
#include "swift/Driver/Compilation.h"
#include "clang/Driver/DarwinSDKInfo.h"
#include "swift/Driver/Driver.h"
#include "swift/Driver/Job.h"
#include "swift/Option/Options.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/VersionTuple.h"

using namespace swift;
using namespace swift::driver;
using namespace llvm::opt;

std::string
toolchains::Darwin::findProgramRelativeToSwiftImpl(StringRef name) const {
  StringRef swiftPath = getDriver().getSwiftProgramPath();
  StringRef swiftBinDir = llvm::sys::path::parent_path(swiftPath);

  // See if we're in an Xcode toolchain.
  bool hasToolchain = false;
  llvm::SmallString<128> path{swiftBinDir};
  llvm::sys::path::remove_filename(path); // bin
  llvm::sys::path::remove_filename(path); // usr
  if (llvm::sys::path::extension(path) == ".xctoolchain") {
    hasToolchain = true;
    llvm::sys::path::remove_filename(path); // *.xctoolchain
    llvm::sys::path::remove_filename(path); // Toolchains
    llvm::sys::path::append(path, "usr", "bin");
  }

  StringRef paths[] = {swiftBinDir, path};
  auto pathsRef = llvm::makeArrayRef(paths);
  if (!hasToolchain)
    pathsRef = pathsRef.drop_back();

  auto result = llvm::sys::findProgramByName(name, pathsRef);
  if (result)
    return result.get();
  return {};
}

ToolChain::InvocationInfo
toolchains::Darwin::constructInvocation(const InterpretJobAction &job,
                                        const JobContext &context) const {
  InvocationInfo II = ToolChain::constructInvocation(job, context);

  SmallVector<std::string, 4> runtimeLibraryPaths;
  getRuntimeLibraryPaths(runtimeLibraryPaths, context.Args, context.OI.SDKPath,
                         /*Shared=*/true);

  addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_LIBRARY_PATH",
                                     ":", options::OPT_L, context.Args,
                                     runtimeLibraryPaths);
  addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "DYLD_FRAMEWORK_PATH",
                                     ":", options::OPT_F, context.Args);
  // FIXME: Add options::OPT_Fsystem paths to DYLD_FRAMEWORK_PATH as well.
  return II;
}

static StringRef
getDarwinLibraryNameSuffixForTriple(const llvm::Triple &triple) {
  const DarwinPlatformKind kind = getDarwinPlatformKind(triple);
  switch (kind) {
  case DarwinPlatformKind::MacOS:
    return "osx";
  case DarwinPlatformKind::IPhoneOS:
    // Here we return "osx" under the assumption that all the
    // darwin runtime libraries are zippered and so the "osx" variants
    // should be used for macCatalyst targets.
    if (tripleIsMacCatalystEnvironment(triple))
        return "osx";
    return "ios";
  case DarwinPlatformKind::IPhoneOSSimulator:
    return "iossim";
  case DarwinPlatformKind::TvOS:
    return "tvos";
  case DarwinPlatformKind::TvOSSimulator:
    return "tvossim";
  case DarwinPlatformKind::WatchOS:
    return "watchos";
  case DarwinPlatformKind::WatchOSSimulator:
    return "watchossim";
  }
  llvm_unreachable("Unsupported Darwin platform");
}

std::string toolchains::Darwin::sanitizerRuntimeLibName(StringRef Sanitizer,
                                                        bool shared) const {
  return (Twine("libclang_rt.") + Sanitizer + "_" +
          getDarwinLibraryNameSuffixForTriple(this->getTriple()) +
          (shared ? "_dynamic.dylib" : ".a"))
      .str();
}

static void addLinkRuntimeLibRPath(const ArgList &Args,
                                   ArgStringList &Arguments,
                                   StringRef DarwinLibName,
                                   const ToolChain &TC) {
  // Adding the rpaths might negatively interact when other rpaths are involved,
  // so we should make sure we add the rpaths last, after all user-specified
  // rpaths. This is currently true from this place, but we need to be
  // careful if this function is ever called before user's rpaths are emitted.
  assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");

  // Add @executable_path to rpath to support having the dylib copied with
  // the executable.
  Arguments.push_back("-rpath");
  Arguments.push_back("@executable_path");

  // Add the path to the resource dir to rpath to support using the dylib
  // from the default location without copying.

  SmallString<128> ClangLibraryPath;
  TC.getClangLibraryPath(Args, ClangLibraryPath);

  Arguments.push_back("-rpath");
  Arguments.push_back(Args.MakeArgString(ClangLibraryPath));
}

static void addLinkSanitizerLibArgsForDarwin(const ArgList &Args,
                                             ArgStringList &Arguments,
                                             StringRef Sanitizer,
                                             const ToolChain &TC,
                                             bool shared = true) {
  // Sanitizer runtime libraries requires C++.
  Arguments.push_back("-lc++");
  // Add explicit dependency on -lc++abi, as -lc++ doesn't re-export
  // all RTTI-related symbols that are used.
  Arguments.push_back("-lc++abi");

  auto LibName = TC.sanitizerRuntimeLibName(Sanitizer, shared);
  TC.addLinkRuntimeLib(Args, Arguments, LibName);

  if (shared)
    addLinkRuntimeLibRPath(Args, Arguments, LibName, TC);
}

/// Runs <code>xcrun -f clang</code> in order to find the location of Clang for
/// the currently active Xcode.
///
/// We get the "currently active" part by passing through the DEVELOPER_DIR
/// environment variable (along with the rest of the environment).
static bool findXcodeClangPath(llvm::SmallVectorImpl<char> &path) {
  assert(path.empty());

  auto xcrunPath = llvm::sys::findProgramByName("xcrun");
  if (!xcrunPath.getError()) {
    // Explicitly ask for the default toolchain so that we don't find a Clang
    // included with an open-source toolchain.
    const char *args[] = {"-toolchain", "default", "-f", "clang", nullptr};
    sys::TaskQueue queue;
    queue.addTask(xcrunPath->c_str(), args, /*Env=*/llvm::None,
                  /*Context=*/nullptr,
                  /*SeparateErrors=*/true);
    queue.execute(nullptr,
                  [&path](sys::ProcessId PID, int returnCode, StringRef output,
                          StringRef errors,
                          sys::TaskProcessInformation ProcInfo,
                          void *unused) -> sys::TaskFinishedResponse {
                    if (returnCode == 0) {
                      output = output.rtrim();
                      path.append(output.begin(), output.end());
                    }
                    return sys::TaskFinishedResponse::ContinueExecution;
                  });
  }

  return !path.empty();
}

static bool findXcodeClangLibPath(const Twine &libName,
                                  llvm::SmallVectorImpl<char> &path) {
  assert(path.empty());

  if (!findXcodeClangPath(path)) {
    return false;
  }
  llvm::sys::path::remove_filename(path); // 'clang'
  llvm::sys::path::remove_filename(path); // 'bin'
  llvm::sys::path::append(path, "lib", libName);
  return true;
}

static void addVersionString(const ArgList &inputArgs, ArgStringList &arguments,
                             unsigned major, unsigned minor, unsigned micro) {
  llvm::SmallString<8> buf;
  llvm::raw_svector_ostream os{buf};
  os << major << '.' << minor << '.' << micro;
  arguments.push_back(inputArgs.MakeArgString(os.str()));
}

/// Returns true if the compiler depends on features provided by the ObjC
/// runtime that are not present on the deployment target indicated by
/// \p triple.
static bool wantsObjCRuntime(const llvm::Triple &triple) {
  assert((!triple.isTvOS() || triple.isiOS()) &&
         "tvOS is considered a kind of iOS");

  // When updating the versions listed here, please record the most recent
  // feature being depended on and when it was introduced:
  //
  // - Make assigning 'nil' to an NSMutableDictionary subscript delete the
  //   entry, like it does for Swift.Dictionary, rather than trap.
  if (triple.isiOS())
    return triple.isOSVersionLT(9);
  if (triple.isMacOSX())
    return triple.isMacOSXVersionLT(10, 11);
  if (triple.isWatchOS())
    return false;
  llvm_unreachable("unknown Darwin OS");
}

void
toolchains::Darwin::addLinkerInputArgs(InvocationInfo &II,
                                       const JobContext &context) const {
  ArgStringList &Arguments = II.Arguments;
  if (context.shouldUseInputFileList()) {
    Arguments.push_back("-filelist");
    Arguments.push_back(context.getTemporaryFilePath("inputs", "LinkFileList"));
    II.FilelistInfos.push_back(
        {Arguments.back(), context.OI.CompilerOutputType,
         FilelistInfo::WhichFiles::InputJobsAndSourceInputActions});
  } else {
    addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
                           file_types::TY_Object);
    addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
                           file_types::TY_LLVM_BC);
    addInputsOfType(Arguments, context.InputActions, file_types::TY_Object);
    addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC);
  }


  if (context.OI.CompilerMode == OutputInfo::Mode::SingleCompile)
    addInputsOfType(Arguments, context.Inputs, context.Args,
                    file_types::TY_SwiftModuleFile, "-add_ast_path");
  else
    addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
                           file_types::TY_SwiftModuleFile, "-add_ast_path");

  // Add all .swiftmodule file inputs as arguments, preceded by the
  // "-add_ast_path" linker option.
  addInputsOfType(Arguments, context.InputActions,
                  file_types::TY_SwiftModuleFile, "-add_ast_path");
}

static void findARCLiteLibPath(const toolchains::Darwin &TC,
                               llvm::SmallVectorImpl<char> &ARCLiteLib) {
  auto& D = TC.getDriver();
  llvm::sys::path::append(ARCLiteLib, D.getSwiftProgramPath());
  
  llvm::sys::path::remove_filename(ARCLiteLib); // 'swift'
  llvm::sys::path::remove_filename(ARCLiteLib); // 'bin'
  llvm::sys::path::append(ARCLiteLib, "lib", "arc");

  if (!llvm::sys::fs::is_directory(ARCLiteLib)) {
    // If we don't have a 'lib/arc/' directory, find the "arclite" library
    // relative to the Clang in the active Xcode.
    ARCLiteLib.clear();
    findXcodeClangLibPath("arc", ARCLiteLib);
  }
}

void
toolchains::Darwin::addArgsToLinkARCLite(ArgStringList &Arguments,
                                         const JobContext &context) const {
  if (!context.Args.hasFlag(options::OPT_link_objc_runtime,
                            options::OPT_no_link_objc_runtime,
                            /*Default=*/wantsObjCRuntime(getTriple())))
    return;

  llvm::SmallString<128> ARCLiteLib;
  findARCLiteLibPath(*this, ARCLiteLib);

  if (!ARCLiteLib.empty()) {
    llvm::sys::path::append(ARCLiteLib, "libarclite_");
    ARCLiteLib += getPlatformNameForTriple(getTriple());
    ARCLiteLib += ".a";

    Arguments.push_back("-force_load");
    Arguments.push_back(context.Args.MakeArgString(ARCLiteLib));

    // Arclite depends on CoreFoundation.
    Arguments.push_back("-framework");
    Arguments.push_back("CoreFoundation");
  }
}

void toolchains::Darwin::addLTOLibArgs(ArgStringList &Arguments,
                                       const JobContext &context) const {
  llvm::SmallString<128> LTOLibPath;
  if (findXcodeClangLibPath("libLTO.dylib", LTOLibPath)) {
    Arguments.push_back("-lto_library");
    Arguments.push_back(context.Args.MakeArgString(LTOLibPath));
  }
}

void
toolchains::Darwin::addSanitizerArgs(ArgStringList &Arguments,
                                     const DynamicLinkJobAction &job,
                                     const JobContext &context) const {
  // Linking sanitizers will add rpaths, which might negatively interact when
  // other rpaths are involved, so we should make sure we add the rpaths after
  // all user-specified rpaths.
  if (context.OI.SelectedSanitizers & SanitizerKind::Address)
    addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "asan", *this);

  if (context.OI.SelectedSanitizers & SanitizerKind::Thread)
    addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "tsan", *this);

  if (context.OI.SelectedSanitizers & SanitizerKind::Undefined)
    addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "ubsan", *this);

  // Only link in libFuzzer for executables.
  if (job.getKind() == LinkKind::Executable &&
      (context.OI.SelectedSanitizers & SanitizerKind::Fuzzer))
    addLinkSanitizerLibArgsForDarwin(context.Args, Arguments, "fuzzer", *this,
                                     /*shared=*/false);
}

namespace {

enum class BackDeployLibFilter {
  executable,
  all
};

// Whether the given job matches the backward-deployment library filter.
bool jobMatchesFilter(LinkKind jobKind, BackDeployLibFilter filter) {
  switch (filter) {
  case BackDeployLibFilter::executable:
    return jobKind == LinkKind::Executable;
    
  case BackDeployLibFilter::all:
    return true;
  }
  llvm_unreachable("unhandled back deploy lib filter!");
}

}

void
toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
                                        const DynamicLinkJobAction &job,
                                        const JobContext &context) const {

  // Link compatibility libraries, if we're deploying back to OSes that
  // have an older Swift runtime.
  SmallString<128> SharedResourceDirPath;
  getResourceDirPath(SharedResourceDirPath, context.Args, /*Shared=*/true);
  Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
  
  if (context.Args.hasArg(options::OPT_runtime_compatibility_version)) {
    auto value = context.Args.getLastArgValue(
                                    options::OPT_runtime_compatibility_version);
    if (value.equals("5.0")) {
      runtimeCompatibilityVersion = llvm::VersionTuple(5, 0);
    } else if (value.equals("5.1")) {
      runtimeCompatibilityVersion = llvm::VersionTuple(5, 1);
    } else if (value.equals("none")) {
      runtimeCompatibilityVersion = None;
    } else {
      // TODO: diagnose unknown runtime compatibility version?
    }
  } else if (job.getKind() == LinkKind::Executable) {
    runtimeCompatibilityVersion
                   = getSwiftRuntimeCompatibilityVersionForTarget(getTriple());
  }
  
  if (runtimeCompatibilityVersion) {
    auto addBackDeployLib = [&](llvm::VersionTuple version,
                                BackDeployLibFilter filter,
                                StringRef libraryName) {
      if (*runtimeCompatibilityVersion > version)
        return;

      if (!jobMatchesFilter(job.getKind(), filter))
        return;
      
      SmallString<128> BackDeployLib;
      BackDeployLib.append(SharedResourceDirPath);
      llvm::sys::path::append(BackDeployLib, "lib" + libraryName + ".a");
      
      if (llvm::sys::fs::exists(BackDeployLib)) {
        Arguments.push_back("-force_load");
        Arguments.push_back(context.Args.MakeArgString(BackDeployLib));
      }
    };

    #define BACK_DEPLOYMENT_LIB(Version, Filter, LibraryName) \
      addBackDeployLib(                                       \
          llvm::VersionTuple Version, BackDeployLibFilter::Filter, LibraryName);
    #include "swift/Frontend/BackDeploymentLibs.def"
  }
    
  // Add the runtime library link path, which is platform-specific and found
  // relative to the compiler.
  SmallVector<std::string, 4> RuntimeLibPaths;
  getRuntimeLibraryPaths(RuntimeLibPaths, context.Args,
                         context.OI.SDKPath, /*Shared=*/true);

  for (auto path : RuntimeLibPaths) {
    Arguments.push_back("-L");
    Arguments.push_back(context.Args.MakeArgString(path));
  }

  // SWIFT_ENABLE_TENSORFLOW
  // NOTE(TF-797): default true for toolchain stdlib rpath to prevent linker
  // issues. This works around the fact that TensorFlow/Python modules do not
  // exist in `/usr/lib/swift` on Darwin platforms.
  // Relevant Swift-in-Darwin-OSs patch:
  // https://github.com/apple/swift/pull/24787.
  if (!context.Args.hasArg(options::OPT_no_stdlib_rpath) &&
      context.Args.hasFlag(options::OPT_toolchain_stdlib_rpath,
                           options::OPT_no_toolchain_stdlib_rpath, true)) {
  // SWIFT_ENABLE_TENSORFLOW END
    // If the user has explicitly asked for a toolchain stdlib, we should
    // provide one using -rpath. This used to be the default behaviour but it
    // was considered annoying in at least the SwiftPM scenario (see
    // https://bugs.swift.org/browse/SR-1967) and is obsolete in all scenarios
    // of deploying for Swift-in-the-OS. We keep it here as an optional
    // behaviour so that people downloading snapshot toolchains for testing new
    // stdlibs will be able to link to the stdlib bundled in that toolchain.
    for (auto path : RuntimeLibPaths) {
      Arguments.push_back("-rpath");
      Arguments.push_back(context.Args.MakeArgString(path));
    }
  } else if (!tripleRequiresRPathForSwiftInOS(getTriple()) ||
             context.Args.hasArg(options::OPT_no_stdlib_rpath)) {
    // If targeting an OS with Swift in /usr/lib/swift, the LC_ID_DYLIB
    // install_name the stdlib will be an absolute path like
    // /usr/lib/swift/libswiftCore.dylib, and we do not need to provide an rpath
    // at all.
    //
    // Also, if the user explicitly asks for no rpath entry, we assume they know
    // what they're doing and do not add one here.
  } else {
    // The remaining cases are back-deploying (to OSs predating
    // Swift-in-the-OS). In these cases, the stdlib will be giving us (via
    // stdlib/linker-support/magic-symbols-for-install-name.c) an LC_ID_DYLIB
    // install_name that is rpath-relative, like @rpath/libswiftCore.dylib.
    //
    // If we're linking an app bundle, it's possible there's an embedded stdlib
    // in there, in which case we'd want to put @executable_path/../Frameworks
    // in the rpath to find and prefer it, but (a) we don't know when we're
    // linking an app bundle and (b) we probably _never_ will be because Xcode
    // links using clang, not the swift driver.
    //
    // So that leaves us with the case of linking a command-line app. These are
    // only supported by installing a secondary package that puts some frozen
    // Swift-in-OS libraries in the /usr/lib/swift location. That's the best we
    // can give for rpath, though it might fail at runtime if the support
    // package isn't installed.
    Arguments.push_back("-rpath");
    Arguments.push_back(context.Args.MakeArgString("/usr/lib/swift"));
    // We don't need an rpath for /System/iOSSupport/usr/lib/swift because...
    assert(!tripleIsMacCatalystEnvironment(getTriple())
           && "macCatalyst not supported without Swift-in-the-OS");
  }
}

void
toolchains::Darwin::addProfileGenerationArgs(ArgStringList &Arguments,
                                             const JobContext &context) const {
  const llvm::Triple &Triple = getTriple();
  if (context.Args.hasArg(options::OPT_profile_generate)) {
    SmallString<128> LibProfile;
    getClangLibraryPath(context.Args, LibProfile);

    StringRef RT;
    if (Triple.isiOS()) {
      if (Triple.isTvOS())
        RT = "tvos";
      else
        RT = "ios";
    } else if (Triple.isWatchOS()) {
      RT = "watchos";
    } else {
      assert(Triple.isMacOSX());
      RT = "osx";
    }

    StringRef Sim;
    if (Triple.isSimulatorEnvironment()) {
      Sim = "sim";
    }

    llvm::sys::path::append(LibProfile,
                            "libclang_rt.profile_" + RT + Sim + ".a");

    // FIXME: Continue accepting the old path for simulator libraries for now.
    if (!Sim.empty() && !llvm::sys::fs::exists(LibProfile)) {
      llvm::sys::path::remove_filename(LibProfile);
      llvm::sys::path::append(LibProfile, "libclang_rt.profile_" + RT + ".a");
    }

    Arguments.push_back(context.Args.MakeArgString(LibProfile));
  }
}

Optional<llvm::VersionTuple>
toolchains::Darwin::getTargetSDKVersion(const llvm::Triple &triple) const {
  if (!SDKInfo)
    return None;
  return swift::getTargetSDKVersion(*SDKInfo, triple);
}

void
toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments,
                                            const JobContext &context) const {
  auto addPlatformVersionArg = [&](const llvm::Triple &triple) {
    // Compute the name of the platform for the linker.
    const char *platformName;
    if (tripleIsMacCatalystEnvironment(triple)) {
      platformName = "mac-catalyst";
    } else {
      switch (getDarwinPlatformKind(triple)) {
      case DarwinPlatformKind::MacOS:
        platformName = "macos";
        break;
      case DarwinPlatformKind::IPhoneOS:
        platformName = "ios";
        break;
      case DarwinPlatformKind::IPhoneOSSimulator:
        platformName = "ios-simulator";
        break;
      case DarwinPlatformKind::TvOS:
        platformName = "tvos";
        break;
      case DarwinPlatformKind::TvOSSimulator:
        platformName = "tvos-simulator";
        break;
      case DarwinPlatformKind::WatchOS:
        platformName = "watchos";
        break;
      case DarwinPlatformKind::WatchOSSimulator:
        platformName = "watchos-simulator";
        break;
      }
    }

    // Compute the platform version.
    unsigned major, minor, micro;
    if (tripleIsMacCatalystEnvironment(triple)) {
      triple.getiOSVersion(major, minor, micro);

      // Mac Catalyst on arm was introduced with an iOS deployment target of
      // 14.0; the linker doesn't want to see a deployment target before that.
      if (major < 14 && triple.isAArch64()) {
        major = 14;
        minor = 0;
        micro = 0;
      }

      // Mac Catalyst was introduced with an iOS deployment target of 13.0;
      // the linker doesn't want to see a deployment target before that.
      if (major < 13) {
        major = 13;
        minor = 0;
        micro = 0;
      }
    } else {
      switch (getDarwinPlatformKind((triple))) {
      case DarwinPlatformKind::MacOS:
        triple.getMacOSXVersion(major, minor, micro);

        // The first deployment of arm64 for macOS is version 10.16;
        if (triple.isAArch64() && major <= 10 && minor < 16) {
          llvm::VersionTuple firstMacARM64e(10, 16, 0);
          firstMacARM64e = canonicalizePlatformVersion(PlatformKind::macOS,
                                                       firstMacARM64e);
          major = firstMacARM64e.getMajor();
          minor = firstMacARM64e.getMinor().getValueOr(0);
          micro = firstMacARM64e.getSubminor().getValueOr(0);
        }

        break;
      case DarwinPlatformKind::IPhoneOS:
      case DarwinPlatformKind::IPhoneOSSimulator:
      case DarwinPlatformKind::TvOS:
      case DarwinPlatformKind::TvOSSimulator:
        triple.getiOSVersion(major, minor, micro);

        // The first deployment of arm64 simulators is iOS/tvOS 14.0;
        // the linker doesn't want to see a deployment target before that.
        if (triple.isSimulatorEnvironment() && triple.isAArch64() &&
            major < 14) {
          major = 14;
          minor = 0;
          micro = 0;
        }

        break;
      case DarwinPlatformKind::WatchOS:
      case DarwinPlatformKind::WatchOSSimulator:
        triple.getOSVersion(major, minor, micro);
        break;
      }
    }

    // Compute the SDK version.
    unsigned sdkMajor = 0, sdkMinor = 0, sdkMicro = 0;
    if (auto sdkVersion = getTargetSDKVersion(triple)) {
      sdkMajor = sdkVersion->getMajor();
      sdkMinor = sdkVersion->getMinor().getValueOr(0);
      sdkMicro = sdkVersion->getSubminor().getValueOr(0);
    }

    Arguments.push_back("-platform_version");
    Arguments.push_back(platformName);
    addVersionString(context.Args, Arguments, major, minor, micro);
    addVersionString(context.Args, Arguments, sdkMajor, sdkMinor, sdkMicro);
  };

  addPlatformVersionArg(getTriple());

  if (auto targetVariant = getTargetVariant()) {
    assert(triplesAreValidForZippering(getTriple(), *targetVariant));
    addPlatformVersionArg(*targetVariant);
  }
}

void toolchains::Darwin::addCommonFrontendArgs(
    const OutputInfo &OI, const CommandOutput &output,
    const llvm::opt::ArgList &inputArgs,
    llvm::opt::ArgStringList &arguments) const {
  ToolChain::addCommonFrontendArgs(OI, output, inputArgs, arguments);

  if (auto sdkVersion = getTargetSDKVersion(getTriple())) {
    arguments.push_back("-target-sdk-version");
    arguments.push_back(inputArgs.MakeArgString(sdkVersion->getAsString()));
  }

  if (auto targetVariant = getTargetVariant()) {
    if (auto variantSDKVersion = getTargetSDKVersion(*targetVariant)) {
      arguments.push_back("-target-variant-sdk-version");
      arguments.push_back(
          inputArgs.MakeArgString(variantSDKVersion->getAsString()));
    }
  }
}

ToolChain::InvocationInfo
toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
                                        const JobContext &context) const {
  assert(context.Output.getPrimaryOutputType() == file_types::TY_Image &&
         "Invalid linker output type.");

  if (context.Args.hasFlag(options::OPT_static_executable,
                           options::OPT_no_static_executable, false)) {
    llvm::report_fatal_error("-static-executable is not supported on Darwin");
  }

  const llvm::Triple &Triple = getTriple();

  // Configure the toolchain.
  // By default, use the system `ld` to link.
  const char *LD = "ld";
  if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) {
    StringRef toolchainPath(A->getValue());

    // If there is a 'ld' in the toolchain folder, use that instead.
    if (auto toolchainLD =
            llvm::sys::findProgramByName("ld", {toolchainPath})) {
      LD = context.Args.MakeArgString(toolchainLD.get());
    }
  }

  InvocationInfo II = {LD};
  ArgStringList &Arguments = II.Arguments;

  addLinkerInputArgs(II, context);

  switch (job.getKind()) {
  case LinkKind::None:
    llvm_unreachable("invalid link kind");
  case LinkKind::Executable:
    // The default for ld; no extra flags necessary.
    break;
  case LinkKind::DynamicLibrary:
    Arguments.push_back("-dylib");
    break;
  case LinkKind::StaticLibrary:
    llvm_unreachable("the dynamic linker cannot build static libraries");
  }

  assert(Triple.isOSDarwin());

  // FIXME: If we used Clang as a linker instead of going straight to ld,
  // we wouldn't have to replicate a bunch of Clang's logic here.

  // Always link the regular compiler_rt if it's present.
  //
  // Note: Normally we'd just add this unconditionally, but it's valid to build
  // Swift and use it as a linker without building compiler_rt.
  SmallString<128> CompilerRTPath;
  getClangLibraryPath(context.Args, CompilerRTPath);
  llvm::sys::path::append(
      CompilerRTPath,
      Twine("libclang_rt.") +
        getDarwinLibraryNameSuffixForTriple(Triple) +
        ".a");
  if (llvm::sys::fs::exists(CompilerRTPath))
    Arguments.push_back(context.Args.MakeArgString(CompilerRTPath));

  addArgsToLinkARCLite(Arguments, context);

  if (job.shouldPerformLTO()) {
    addLTOLibArgs(Arguments, context);
  }

  for (const Arg *arg :
       context.Args.filtered(options::OPT_F, options::OPT_Fsystem)) {
    Arguments.push_back("-F");
    Arguments.push_back(arg->getValue());
  }

  if (context.Args.hasArg(options::OPT_enable_app_extension)) {
    // Keep this string fixed in case the option used by the
    // compiler itself changes.
    Arguments.push_back("-application_extension");
  }

  addSanitizerArgs(Arguments, job, context);

  if (context.Args.hasArg(options::OPT_embed_bitcode,
                          options::OPT_embed_bitcode_marker)) {
    Arguments.push_back("-bitcode_bundle");
  }

  if (!context.OI.SDKPath.empty()) {
    Arguments.push_back("-syslibroot");
    Arguments.push_back(context.Args.MakeArgString(context.OI.SDKPath));
  }

  Arguments.push_back("-lobjc");
  Arguments.push_back("-lSystem");

  Arguments.push_back("-arch");
  Arguments.push_back(context.Args.MakeArgString(getTriple().getArchName()));

  // On Darwin, we only support libc++.
  if (context.Args.hasArg(options::OPT_enable_experimental_cxx_interop)) {
    Arguments.push_back("-lc++");
  }

  addArgsToLinkStdlib(Arguments, job, context);

  addProfileGenerationArgs(Arguments, context);
  addDeploymentTargetArgs(Arguments, context);

  Arguments.push_back("-no_objc_category_merging");

  // These custom arguments should be right before the object file at the end.
  context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group);
  context.Args.AddAllArgValues(Arguments, options::OPT_Xlinker);

  // This should be the last option, for convenience in checking output.
  Arguments.push_back("-o");
  Arguments.push_back(
      context.Args.MakeArgString(context.Output.getPrimaryOutputFilename()));

  return II;
}


ToolChain::InvocationInfo
toolchains::Darwin::constructInvocation(const StaticLinkJobAction &job,
                                        const JobContext &context) const {
   assert(context.Output.getPrimaryOutputType() == file_types::TY_Image &&
         "Invalid linker output type.");

  // Configure the toolchain.
  const char *LibTool = "libtool";

  InvocationInfo II = {LibTool};
  ArgStringList &Arguments = II.Arguments;

  Arguments.push_back("-static");

  if (context.shouldUseInputFileList()) {
    Arguments.push_back("-filelist");
    Arguments.push_back(context.getTemporaryFilePath("inputs", "LinkFileList"));
    II.FilelistInfos.push_back({Arguments.back(), context.OI.CompilerOutputType,
                                FilelistInfo::WhichFiles::InputJobs});
  } else {
    addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
                           file_types::TY_Object);
    addPrimaryInputsOfType(Arguments, context.Inputs, context.Args,
                           file_types::TY_LLVM_BC);
  }

  addInputsOfType(Arguments, context.InputActions, file_types::TY_Object);
  addInputsOfType(Arguments, context.InputActions, file_types::TY_LLVM_BC);

  Arguments.push_back("-o");

  Arguments.push_back(
      context.Args.MakeArgString(context.Output.getPrimaryOutputFilename()));

  return II;
}

bool toolchains::Darwin::shouldStoreInvocationInDebugInfo() const {
  // This matches the behavior in Clang (see
  // clang/lib/driver/ToolChains/Darwin.cpp).
  if (const char *S = ::getenv("RC_DEBUG_OPTIONS"))
    return S[0] != '\0';
  return false;
}

static void validateLinkObjcRuntimeARCLiteLib(const toolchains::Darwin &TC,
                                              DiagnosticEngine &diags,
                                              const llvm::opt::ArgList &args) {
  auto Triple = TC.getTriple();
  if (args.hasFlag(options::OPT_link_objc_runtime,
                   options::OPT_no_link_objc_runtime,
                   /*Default=*/wantsObjCRuntime(Triple))) {
    llvm::SmallString<128> ARCLiteLib;
    findARCLiteLibPath(TC, ARCLiteLib);
    
    if (ARCLiteLib.empty()) {
      diags.diagnose(SourceLoc(),
                     diag::warn_arclite_not_found_when_link_objc_runtime);
    }
  }
}

static void validateDeploymentTarget(const toolchains::Darwin &TC,
                                     DiagnosticEngine &diags,
                                     const llvm::opt::ArgList &args) {
  // Check minimum supported OS versions.
  auto triple = TC.getTriple();
  if (triple.isMacOSX()) {
    if (triple.isMacOSXVersionLT(10, 9))
      diags.diagnose(SourceLoc(), diag::error_os_minimum_deployment,
                     "OS X 10.9");
  } else if (triple.isiOS()) {
    if (triple.isTvOS()) {
      if (triple.isOSVersionLT(9, 0)) {
        diags.diagnose(SourceLoc(), diag::error_os_minimum_deployment,
                       "tvOS 9.0");
        return;
      }
    }
    if (triple.isOSVersionLT(7))
      diags.diagnose(SourceLoc(), diag::error_os_minimum_deployment,
                     "iOS 7");
    if (triple.isArch32Bit() && !triple.isOSVersionLT(11)) {
      diags.diagnose(SourceLoc(), diag::error_ios_maximum_deployment_32,
                     triple.getOSMajorVersion());
    }
  } else if (triple.isWatchOS()) {
    if (triple.isOSVersionLT(2, 0)) {
      diags.diagnose(SourceLoc(), diag::error_os_minimum_deployment,
                     "watchOS 2.0");
      return;
    }
  }
}

static void validateTargetVariant(const toolchains::Darwin &TC,
                                  DiagnosticEngine &diags,
                                  const llvm::opt::ArgList &args,
                                  StringRef defaultTarget) {
  if (TC.getTargetVariant().hasValue()) {
    auto target = TC.getTriple();
    auto variant = *TC.getTargetVariant();

    if (!triplesAreValidForZippering(target, variant)) {
      diags.diagnose(SourceLoc(), diag::error_unsupported_target_variant,
                    variant.str(),
                    variant.isiOS());
    }
  }
}

void 
toolchains::Darwin::validateArguments(DiagnosticEngine &diags,
                                      const llvm::opt::ArgList &args,
                                      StringRef defaultTarget) const {
  // Validating arclite library path when link-objc-runtime.
  validateLinkObjcRuntimeARCLiteLib(*this, diags, args);
  
  // Validating apple platforms deployment targets.
  validateDeploymentTarget(*this, diags, args);
  validateTargetVariant(*this, diags, args, defaultTarget);

  // Validating darwin unsupported -static-stdlib argument.
  if (args.hasArg(options::OPT_static_stdlib)) {
    diags.diagnose(SourceLoc(), diag::error_darwin_static_stdlib_not_supported);
  }

  // If a C++ standard library is specified, it has to be libc++.
  if (auto arg = args.getLastArg(options::OPT_experimental_cxx_stdlib)) {
    if (StringRef(arg->getValue()) != "libc++") {
      diags.diagnose(SourceLoc(), diag::error_darwin_only_supports_libcxx); 
    }
  }
}

void
toolchains::Darwin::validateOutputInfo(DiagnosticEngine &diags,
                                       const OutputInfo &outputInfo) const {
  // If we have been provided with an SDK, go read the SDK information.
  if (!outputInfo.SDKPath.empty()) {
    auto SDKInfoOrErr = clang::driver::parseDarwinSDKInfo(
        *llvm::vfs::getRealFileSystem(), outputInfo.SDKPath);
    if (SDKInfoOrErr) {
      SDKInfo = *SDKInfoOrErr;
    } else {
      llvm::consumeError(SDKInfoOrErr.takeError());
      diags.diagnose(SourceLoc(), diag::warn_drv_darwin_sdk_invalid_settings);
    }
  }
}
