Prabhuk updated this revision to Diff 522644.
Prabhuk added a comment.
Herald added a reviewer: jdoerfert.
Herald added a reviewer: sscalpone.
Herald added subscribers: jplehr, sstefan1.

Added UEFI toolchain. Constructing linker and started a WIP UEFI toolchain to 
break away from MSVC toolchain.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D131594/new/

https://reviews.llvm.org/D131594

Files:
  clang/lib/Basic/Targets.cpp
  clang/lib/Basic/Targets/OSTargets.h
  clang/lib/Basic/Targets/X86.h
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChains/UEFI.cpp
  clang/lib/Driver/ToolChains/UEFI.h
  llvm/include/llvm/TargetParser/Triple.h
  llvm/lib/TargetParser/Triple.cpp

Index: llvm/lib/TargetParser/Triple.cpp
===================================================================
--- llvm/lib/TargetParser/Triple.cpp
+++ llvm/lib/TargetParser/Triple.cpp
@@ -238,6 +238,7 @@
   case RTEMS: return "rtems";
   case Solaris: return "solaris";
   case TvOS: return "tvos";
+  case UEFI: return "uefi";
   case WASI: return "wasi";
   case WatchOS: return "watchos";
   case Win32: return "windows";
@@ -588,6 +589,7 @@
     .StartsWith("netbsd", Triple::NetBSD)
     .StartsWith("openbsd", Triple::OpenBSD)
     .StartsWith("solaris", Triple::Solaris)
+    .StartsWith("uefi", Triple::UEFI)
     .StartsWith("win32", Triple::Win32)
     .StartsWith("windows", Triple::Win32)
     .StartsWith("zos", Triple::ZOS)
Index: llvm/include/llvm/TargetParser/Triple.h
===================================================================
--- llvm/include/llvm/TargetParser/Triple.h
+++ llvm/include/llvm/TargetParser/Triple.h
@@ -199,6 +199,7 @@
     NetBSD,
     OpenBSD,
     Solaris,
+    UEFI,
     Win32,
     ZOS,
     Haiku,
Index: clang/lib/Driver/ToolChains/UEFI.h
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/UEFI.h
@@ -0,0 +1,58 @@
+//===--- UEFI.h - UEFI ToolChain Implementations ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_UEFI_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_UEFI_H
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+namespace tools {
+namespace uefi {
+class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
+public:
+  Linker(const ToolChain &TC) : Tool("uefi::Linker", "lld-link", TC) {}
+
+  bool hasIntegratedCPP() const override { return false; }
+  bool isLinkJob() const override { return true; }
+
+  void ConstructJob(Compilation &C, const JobAction &JA,
+                    const InputInfo &Output, const InputInfoList &Inputs,
+                    const llvm::opt::ArgList &TCArgs,
+                    const char *LinkingOutput) const override;
+};
+} // end namespace uefi
+} // end namespace tools
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY UEFI : public ToolChain {
+public:
+  UEFI(const Driver &D, const llvm::Triple &Triple,
+       const llvm::opt::ArgList &Args);
+
+protected:
+  Tool *buildLinker() const override;
+
+public:
+  bool HasNativeLLVMSupport() const override { return true; }
+  bool IsIntegratedAssemblerDefault() const override { return true; }
+  bool IsUnwindTablesDefault(const llvm::opt::ArgList &Args) const {
+    return true;
+  }
+  bool isPICDefault() const override { return true; }
+  bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
+    return false;
+  }
+  bool isPICDefaultForced() const override { return true; }
+};
+} // namespace toolchains
+} // namespace driver
+} // namespace clang
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_UEFI_H
Index: clang/lib/Driver/ToolChains/UEFI.cpp
===================================================================
--- /dev/null
+++ clang/lib/Driver/ToolChains/UEFI.cpp
@@ -0,0 +1,437 @@
+//===--- UEFI.h - UEFI ToolChain Implementations ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UEFI.h"
+#include "CommonArgs.h"
+#include "Darwin.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Version.h"
+#include "clang/Config/config.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Process.h"
+#include "llvm/Support/VirtualFileSystem.h"
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang;
+using namespace llvm::opt;
+
+UEFI::UEFI(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
+    : ToolChain(D, Triple, Args) {
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
+}
+Tool *UEFI::buildLinker() const { return new tools::uefi::Linker(*this); }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void tools::uefi::Linker::ConstructJob(Compilation &C, const JobAction &JA,
+                                       const InputInfo &Output,
+                                       const InputInfoList &Inputs,
+                                       const ArgList &Args,
+                                       const char *LinkingOutput) const {
+    ArgStringList CmdArgs;
+
+  auto &TC = static_cast<const toolchains::UEFI &>(getToolChain());
+
+  assert((Output.isFilename() || Output.isNothing()) && "invalid output");
+  if (Output.isFilename())
+    CmdArgs.push_back(
+        Args.MakeArgString(std::string("-out:") + Output.getFilename()));
+
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
+      !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) {
+    CmdArgs.push_back("-defaultlib:libcmt");
+    CmdArgs.push_back("-defaultlib:oldnames");
+  }
+
+  // If the VC environment hasn't been configured (perhaps because the user
+  // did not run vcvarsall), try to build a consistent link environment.  If
+  // the environment variable is set however, assume the user knows what
+  // they're doing. If the user passes /vctoolsdir or /winsdkdir, trust that
+  // over env vars.
+  if (const Arg *A = Args.getLastArg(options::OPT__SLASH_diasdkdir,
+                                     options::OPT__SLASH_winsysroot)) {
+    // cl.exe doesn't find the DIA SDK automatically, so this too requires
+    // explicit flags and doesn't automatically look in "DIA SDK" relative
+    // to the path we found for VCToolChainPath.
+    llvm::SmallString<128> DIAPath(A->getValue());
+    if (A->getOption().getID() == options::OPT__SLASH_winsysroot)
+      llvm::sys::path::append(DIAPath, "DIA SDK");
+
+    // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
+    llvm::sys::path::append(DIAPath, "lib",
+                            llvm::archToLegacyVCArch(TC.getArch()));
+    CmdArgs.push_back(Args.MakeArgString(Twine("-libpath:") + DIAPath));
+  }
+//  if (!llvm::sys::Process::GetEnv("LIB") ||
+//      Args.getLastArg(options::OPT__SLASH_vctoolsdir,
+//                      options::OPT__SLASH_winsysroot)) {
+//    CmdArgs.push_back(Args.MakeArgString(
+//        Twine("-libpath:") +
+//        TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib)));
+//    CmdArgs.push_back(Args.MakeArgString(
+//        Twine("-libpath:") +
+//        TC.getSubDirectoryPath(llvm::SubDirectoryType::Lib, "atlmfc")));
+//  }
+//  if (!llvm::sys::Process::GetEnv("LIB") ||
+//      Args.getLastArg(options::OPT__SLASH_winsdkdir,
+//                      options::OPT__SLASH_winsysroot)) {
+//    if (TC.useUniversalCRT()) {
+//      std::string UniversalCRTLibPath;
+//      if (TC.getUniversalCRTLibraryPath(Args, UniversalCRTLibPath))
+//        CmdArgs.push_back(
+//            Args.MakeArgString(Twine("-libpath:") + UniversalCRTLibPath));
+//    }
+//    std::string WindowsSdkLibPath;
+//    if (TC.getWindowsSDKLibraryPath(Args, WindowsSdkLibPath))
+//      CmdArgs.push_back(
+//          Args.MakeArgString(std::string("-libpath:") + WindowsSdkLibPath));
+//  }
+
+//  if (C.getDriver().IsFlangMode()) {
+//    addFortranRuntimeLibraryPath(TC, Args, CmdArgs);
+//    addFortranRuntimeLibs(TC, CmdArgs);
+//
+//    // Inform the MSVC linker that we're generating a console application, i.e.
+//    // one with `main` as the "user-defined" entry point. The `main` function is
+//    // defined in flang's runtime libraries.
+//    CmdArgs.push_back("/subsystem:console");
+//  }
+
+  // Add the compiler-rt library directories to libpath if they exist to help
+  // the linker find the various sanitizer, builtin, and profiling runtimes.
+  for (const auto &LibPath : TC.getLibraryPaths()) {
+    if (TC.getVFS().exists(LibPath))
+      CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
+  }
+  auto CRTPath = TC.getCompilerRTPath();
+  if (TC.getVFS().exists(CRTPath))
+    CmdArgs.push_back(Args.MakeArgString("-libpath:" + CRTPath));
+
+  if (!C.getDriver().IsCLMode() && Args.hasArg(options::OPT_L))
+    for (const auto &LibPath : Args.getAllArgValues(options::OPT_L))
+      CmdArgs.push_back(Args.MakeArgString("-libpath:" + LibPath));
+
+  CmdArgs.push_back("-nologo");
+
+  if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7))
+    CmdArgs.push_back("-debug");
+
+  // If we specify /hotpatch, let the linker add padding in front of each
+  // function, like MSVC does.
+  if (Args.hasArg(options::OPT_fms_hotpatch, options::OPT__SLASH_hotpatch))
+    CmdArgs.push_back("-functionpadmin");
+
+  // Pass on /Brepro if it was passed to the compiler.
+  // Note that /Brepro maps to -mno-incremental-linker-compatible.
+  bool DefaultIncrementalLinkerCompatible =
+      C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment();
+  if (!Args.hasFlag(options::OPT_mincremental_linker_compatible,
+                    options::OPT_mno_incremental_linker_compatible,
+                    DefaultIncrementalLinkerCompatible))
+    CmdArgs.push_back("-Brepro");
+
+  bool DLL = Args.hasArg(options::OPT__SLASH_LD, options::OPT__SLASH_LDd,
+                         options::OPT_shared);
+  if (DLL) {
+    CmdArgs.push_back(Args.MakeArgString("-dll"));
+
+    SmallString<128> ImplibName(Output.getFilename());
+    llvm::sys::path::replace_extension(ImplibName, "lib");
+    CmdArgs.push_back(Args.MakeArgString(std::string("-implib:") + ImplibName));
+  }
+
+  if (TC.getSanitizerArgs(Args).needsFuzzer()) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(
+          Args.MakeArgString(std::string("-wholearchive:") +
+                             TC.getCompilerRTArgString(Args, "fuzzer")));
+    CmdArgs.push_back(Args.MakeArgString("-debug"));
+    // Prevent the linker from padding sections we use for instrumentation
+    // arrays.
+    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
+  }
+
+  if (TC.getSanitizerArgs(Args).needsAsanRt()) {
+    CmdArgs.push_back(Args.MakeArgString("-debug"));
+    CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
+    if (TC.getSanitizerArgs(Args).needsSharedRt() ||
+        Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
+      for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
+        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
+      // Make sure the dynamic runtime thunk is not optimized out at link time
+      // to ensure proper SEH handling.
+      CmdArgs.push_back(Args.MakeArgString(
+          TC.getArch() == llvm::Triple::x86
+              ? "-include:___asan_seh_interceptor"
+              : "-include:__asan_seh_interceptor"));
+      // Make sure the linker consider all object files from the dynamic runtime
+      // thunk.
+      CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
+          TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk")));
+    } else if (DLL) {
+      CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dll_thunk"));
+    } else {
+      for (const auto &Lib : {"asan", "asan_cxx"}) {
+        CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
+        // Make sure the linker consider all object files from the static lib.
+        // This is necessary because instrumented dlls need access to all the
+        // interface exported by the static lib in the main executable.
+        CmdArgs.push_back(Args.MakeArgString(std::string("-wholearchive:") +
+            TC.getCompilerRT(Args, Lib)));
+      }
+    }
+  }
+
+  Args.AddAllArgValues(CmdArgs, options::OPT__SLASH_link);
+
+  // Control Flow Guard checks
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_guard)) {
+    StringRef GuardArgs = A->getValue();
+    if (GuardArgs.equals_insensitive("cf") ||
+        GuardArgs.equals_insensitive("cf,nochecks")) {
+      // MSVC doesn't yet support the "nochecks" modifier.
+      CmdArgs.push_back("-guard:cf");
+    } else if (GuardArgs.equals_insensitive("cf-")) {
+      CmdArgs.push_back("-guard:cf-");
+    } else if (GuardArgs.equals_insensitive("ehcont")) {
+      CmdArgs.push_back("-guard:ehcont");
+    } else if (GuardArgs.equals_insensitive("ehcont-")) {
+      CmdArgs.push_back("-guard:ehcont-");
+    }
+  }
+
+  if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
+                   options::OPT_fno_openmp, false)) {
+    CmdArgs.push_back("-nodefaultlib:vcomp.lib");
+    CmdArgs.push_back("-nodefaultlib:vcompd.lib");
+    CmdArgs.push_back(Args.MakeArgString(std::string("-libpath:") +
+                                         TC.getDriver().Dir + "/../lib"));
+    switch (TC.getDriver().getOpenMPRuntime(Args)) {
+    case Driver::OMPRT_OMP:
+      CmdArgs.push_back("-defaultlib:libomp.lib");
+      break;
+    case Driver::OMPRT_IOMP5:
+      CmdArgs.push_back("-defaultlib:libiomp5md.lib");
+      break;
+    case Driver::OMPRT_GOMP:
+      break;
+    case Driver::OMPRT_Unknown:
+      // Already diagnosed.
+      break;
+    }
+  }
+
+  // Add compiler-rt lib in case if it was explicitly
+  // specified as an argument for --rtlib option.
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
+  }
+
+  // Add filenames, libraries, and other linker inputs.
+  for (const auto &Input : Inputs) {
+    if (Input.isFilename()) {
+      CmdArgs.push_back(Input.getFilename());
+      continue;
+    }
+
+    const Arg &A = Input.getInputArg();
+
+    // Render -l options differently for the MSVC linker.
+    if (A.getOption().matches(options::OPT_l)) {
+      StringRef Lib = A.getValue();
+      const char *LinkLibArg;
+      if (Lib.endswith(".lib"))
+        LinkLibArg = Args.MakeArgString(Lib);
+      else
+        LinkLibArg = Args.MakeArgString(Lib + ".lib");
+      CmdArgs.push_back(LinkLibArg);
+      continue;
+    }
+
+    // Otherwise, this is some other kind of linker input option like -Wl, -z,
+    // or -L. Render it, even if MSVC doesn't understand it.
+    A.renderAsInput(Args, CmdArgs);
+  }
+
+  addHIPRuntimeLibArgs(TC, Args, CmdArgs);
+
+  TC.addProfileRTLibs(Args, CmdArgs);
+
+  std::vector<const char *> Environment;
+
+  // We need to special case some linker paths.  In the case of lld, we need to
+  // translate 'lld' into 'lld-link', and in the case of the regular msvc
+  // linker, we need to use a special search algorithm.
+  llvm::SmallString<128> linkPath;
+  StringRef Linker
+    = Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER);
+  if (Linker.empty())
+    Linker = "link";
+  if (Linker.equals_insensitive("lld"))
+    Linker = "lld-link";
+
+  if (Linker.equals_insensitive("link")) {
+    // If we're using the MSVC linker, it's not sufficient to just use link
+    // from the program PATH, because other environments like GnuWin32 install
+    // their own link.exe which may come first.
+    linkPath = FindVisualStudioExecutable(TC, "link.exe");
+
+    if (!TC.FoundMSVCInstall() && !canExecute(TC.getVFS(), linkPath)) {
+      llvm::SmallString<128> ClPath;
+      ClPath = TC.GetProgramPath("cl.exe");
+      if (canExecute(TC.getVFS(), ClPath)) {
+        linkPath = llvm::sys::path::parent_path(ClPath);
+        llvm::sys::path::append(linkPath, "link.exe");
+        if (!canExecute(TC.getVFS(), linkPath))
+          C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
+      } else {
+        C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found);
+      }
+    }
+
+#ifdef _WIN32
+    // When cross-compiling with VS2017 or newer, link.exe expects to have
+    // its containing bin directory at the top of PATH, followed by the
+    // native target bin directory.
+    // e.g. when compiling for x86 on an x64 host, PATH should start with:
+    // /bin/Hostx64/x86;/bin/Hostx64/x64
+    // This doesn't attempt to handle llvm::ToolsetLayout::DevDivInternal.
+    if (TC.getIsVS2017OrNewer() &&
+        llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) {
+      auto HostArch = llvm::Triple(llvm::sys::getProcessTriple()).getArch();
+
+      auto EnvBlockWide =
+          std::unique_ptr<wchar_t[], decltype(&FreeEnvironmentStringsW)>(
+              GetEnvironmentStringsW(), FreeEnvironmentStringsW);
+      if (!EnvBlockWide)
+        goto SkipSettingEnvironment;
+
+      size_t EnvCount = 0;
+      size_t EnvBlockLen = 0;
+      while (EnvBlockWide[EnvBlockLen] != L'\0') {
+        ++EnvCount;
+        EnvBlockLen += std::wcslen(&EnvBlockWide[EnvBlockLen]) +
+                       1 /*string null-terminator*/;
+      }
+      ++EnvBlockLen; // add the block null-terminator
+
+      std::string EnvBlock;
+      if (!llvm::convertUTF16ToUTF8String(
+              llvm::ArrayRef<char>(reinterpret_cast<char *>(EnvBlockWide.get()),
+                                   EnvBlockLen * sizeof(EnvBlockWide[0])),
+              EnvBlock))
+        goto SkipSettingEnvironment;
+
+      Environment.reserve(EnvCount);
+
+      // Now loop over each string in the block and copy them into the
+      // environment vector, adjusting the PATH variable as needed when we
+      // find it.
+      for (const char *Cursor = EnvBlock.data(); *Cursor != '\0';) {
+        llvm::StringRef EnvVar(Cursor);
+        if (EnvVar.startswith_insensitive("path=")) {
+          constexpr size_t PrefixLen = 5; // strlen("path=")
+          Environment.push_back(Args.MakeArgString(
+              EnvVar.substr(0, PrefixLen) +
+              TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin) +
+              llvm::Twine(llvm::sys::EnvPathSeparator) +
+              TC.getSubDirectoryPath(llvm::SubDirectoryType::Bin, HostArch) +
+              (EnvVar.size() > PrefixLen
+                   ? llvm::Twine(llvm::sys::EnvPathSeparator) +
+                         EnvVar.substr(PrefixLen)
+                   : "")));
+        } else {
+          Environment.push_back(Args.MakeArgString(EnvVar));
+        }
+        Cursor += EnvVar.size() + 1 /*null-terminator*/;
+      }
+    }
+  SkipSettingEnvironment:;
+#endif
+  } else {
+    linkPath = TC.GetProgramPath(Linker.str().c_str());
+  }
+
+  auto LinkCmd = std::make_unique<Command>(
+      JA, *this, ResponseFileSupport::AtFileUTF16(),
+      Args.MakeArgString(linkPath), CmdArgs, Inputs, Output);
+  if (!Environment.empty())
+    LinkCmd->setEnvironment(Environment);
+  C.addCommand(std::move(LinkCmd));
+}
+
+MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
+                             const ArgList &Args)
+    : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
+      RocmInstallation(D, Triple, Args) {
+  getProgramPaths().push_back(getDriver().getInstalledDir());
+  if (getDriver().getInstalledDir() != getDriver().Dir)
+    getProgramPaths().push_back(getDriver().Dir);
+
+  std::optional<llvm::StringRef> VCToolsDir, VCToolsVersion;
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir))
+    VCToolsDir = A->getValue();
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsversion))
+    VCToolsVersion = A->getValue();
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkdir))
+    WinSdkDir = A->getValue();
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsdkversion))
+    WinSdkVersion = A->getValue();
+  if (Arg *A = Args.getLastArg(options::OPT__SLASH_winsysroot))
+    WinSysRoot = A->getValue();
+
+  // Check the command line first, that's the user explicitly telling us what to
+  // use. Check the environment next, in case we're being invoked from a VS
+  // command prompt. Failing that, just try to find the newest Visual Studio
+  // version we can and use its default VC toolchain.
+  llvm::findVCToolChainViaCommandLine(getVFS(), VCToolsDir, VCToolsVersion,
+                                      WinSysRoot, VCToolChainPath, VSLayout) ||
+      llvm::findVCToolChainViaEnvironment(getVFS(), VCToolChainPath,
+                                          VSLayout) ||
+      llvm::findVCToolChainViaSetupConfig(getVFS(), VCToolChainPath,
+                                          VSLayout) ||
+      llvm::findVCToolChainViaRegistry(VCToolChainPath, VSLayout);
+
+}
Index: clang/lib/Driver/Driver.cpp
===================================================================
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -6147,6 +6147,10 @@
     case llvm::Triple::Mesa3D:
       TC = std::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args);
       break;
+    case llvm::Triple::UEFI:
+      TC = std::make_unique<toolchains::MSVCToolChain>(*this, Target, Args);
+      ////TODO(prabhukr): Replace with a new UEFI toolchain
+      break;
     case llvm::Triple::Win32:
       switch (Target.getEnvironment()) {
       default:
Index: clang/lib/Basic/Targets/X86.h
===================================================================
--- clang/lib/Basic/Targets/X86.h
+++ clang/lib/Basic/Targets/X86.h
@@ -808,6 +808,61 @@
   }
 };
 
+// x86-64 UEFI target
+class LLVM_LIBRARY_VISIBILITY UEFIX86_64TargetInfo
+    : public UEFITargetInfo<X86_64TargetInfo> {
+public:
+  UEFIX86_64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+      : UEFITargetInfo<X86_64TargetInfo>(Triple, Opts) {
+    LongWidth = LongAlign = 32;
+    DoubleAlign = LongLongAlign = 64;
+    IntMaxType = SignedLongLong;
+    Int64Type = SignedLongLong;
+    SizeType = UnsignedLongLong;
+    PtrDiffType = SignedLongLong;
+    IntPtrType = SignedLongLong;
+    LongDoubleWidth = LongDoubleAlign = 64;
+    LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+  }
+
+  void getTargetDefines(const LangOptions &Opts,
+                        MacroBuilder &Builder) const override {
+    Builder.defineMacro("_M_X64", "100");
+    Builder.defineMacro("_M_AMD64", "100");
+  }
+
+  BuiltinVaListKind getBuiltinVaListKind() const override {
+    return TargetInfo::CharPtrBuiltinVaList;
+  }
+
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+    switch (CC) {
+    case CC_X86StdCall:
+    case CC_X86ThisCall:
+    case CC_X86FastCall:
+      return CCCR_Ignore;
+    case CC_C:
+    case CC_X86VectorCall:
+    case CC_IntelOclBicc:
+    case CC_PreserveMost:
+    case CC_PreserveAll:
+    case CC_X86_64SysV:
+    case CC_Swift:
+    case CC_SwiftAsync:
+    case CC_X86RegCall:
+    case CC_OpenCLKernel:
+      return CCCR_OK;
+    default:
+      return CCCR_Warning;
+    }
+  }
+
+  TargetInfo::CallingConvKind
+  getCallingConvKind(bool ClangABICompat4) const override {
+    return CCK_MicrosoftWin64;
+  }
+};
+
 // x86-64 Windows target
 class LLVM_LIBRARY_VISIBILITY WindowsX86_64TargetInfo
     : public WindowsTargetInfo<X86_64TargetInfo> {
Index: clang/lib/Basic/Targets/OSTargets.h
===================================================================
--- clang/lib/Basic/Targets/OSTargets.h
+++ clang/lib/Basic/Targets/OSTargets.h
@@ -843,6 +843,23 @@
   }
 };
 
+// UEFI target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY UEFITargetInfo : public OSTargetInfo<Target> {
+protected:
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const override {
+    Builder.defineMacro("__UEFI__");
+  }
+
+public:
+  UEFITargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
+      : OSTargetInfo<Target>(Triple, Opts) {
+    this->WCharType = TargetInfo::UnsignedShort;
+    this->WIntType = TargetInfo::UnsignedShort;
+  }
+};
+
 void addWindowsDefines(const llvm::Triple &Triple, const LangOptions &Opts,
                        MacroBuilder &Builder);
 
Index: clang/lib/Basic/Targets.cpp
===================================================================
--- clang/lib/Basic/Targets.cpp
+++ clang/lib/Basic/Targets.cpp
@@ -641,6 +641,8 @@
     case llvm::Triple::Solaris:
       return std::make_unique<SolarisTargetInfo<X86_64TargetInfo>>(Triple,
                                                                    Opts);
+    case llvm::Triple::UEFI:
+      return std::make_unique<UEFIX86_64TargetInfo>(Triple, Opts);
     case llvm::Triple::Win32: {
       switch (Triple.getEnvironment()) {
       case llvm::Triple::Cygnus:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D13... Prabhu Karthikeyan Rajasekaran via Phabricator via cfe-commits
    • [PATCH... Prabhu Karthikeyan Rajasekaran via Phabricator via cfe-commits
    • [PATCH... Prabhu Karthikeyan Rajasekaran via Phabricator via cfe-commits
    • [PATCH... Prabhu Karthikeyan Rajasekaran via Phabricator via cfe-commits

Reply via email to