summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp892
1 files changed, 0 insertions, 892 deletions
diff --git a/contrib/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp b/contrib/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp
deleted file mode 100644
index 17fd6ac..0000000
--- a/contrib/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp
+++ /dev/null
@@ -1,892 +0,0 @@
-//===--- ToolChains.cpp - ToolChain Implementations -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ToolChains.h"
-#include "Tools.h"
-#include "clang/Basic/CharInfo.h"
-#include "clang/Basic/Version.h"
-#include "clang/Driver/Compilation.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/Options.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Config/llvm-config.h"
-#include "llvm/Option/Arg.h"
-#include "llvm/Option/ArgList.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Process.h"
-#include <cstdio>
-
-// Include the necessary headers to interface with the Windows registry and
-// environment.
-#if defined(LLVM_ON_WIN32)
-#define USE_WIN32
-#endif
-
-#ifdef USE_WIN32
- #define WIN32_LEAN_AND_MEAN
- #define NOGDI
- #ifndef NOMINMAX
- #define NOMINMAX
- #endif
- #include <windows.h>
-#endif
-
-using namespace clang::driver;
-using namespace clang::driver::toolchains;
-using namespace clang;
-using namespace llvm::opt;
-
-MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
- const ArgList &Args)
- : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) {
- getProgramPaths().push_back(getDriver().getInstalledDir());
- if (getDriver().getInstalledDir() != getDriver().Dir)
- getProgramPaths().push_back(getDriver().Dir);
-}
-
-Tool *MSVCToolChain::buildLinker() const {
- return new tools::visualstudio::Linker(*this);
-}
-
-Tool *MSVCToolChain::buildAssembler() const {
- if (getTriple().isOSBinFormatMachO())
- return new tools::darwin::Assembler(*this);
- getDriver().Diag(clang::diag::err_no_external_assembler);
- return nullptr;
-}
-
-bool MSVCToolChain::IsIntegratedAssemblerDefault() const {
- return true;
-}
-
-bool MSVCToolChain::IsUnwindTablesDefault() const {
- // Emit unwind tables by default on Win64. All non-x86_32 Windows platforms
- // such as ARM and PPC actually require unwind tables, but LLVM doesn't know
- // how to generate them yet.
-
- // Don't emit unwind tables by default for MachO targets.
- if (getTriple().isOSBinFormatMachO())
- return false;
-
- return getArch() == llvm::Triple::x86_64;
-}
-
-bool MSVCToolChain::isPICDefault() const {
- return getArch() == llvm::Triple::x86_64;
-}
-
-bool MSVCToolChain::isPIEDefault() const {
- return false;
-}
-
-bool MSVCToolChain::isPICDefaultForced() const {
- return getArch() == llvm::Triple::x86_64;
-}
-
-void MSVCToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- CudaInstallation.AddCudaIncludeArgs(DriverArgs, CC1Args);
-}
-
-void MSVCToolChain::printVerboseInfo(raw_ostream &OS) const {
- CudaInstallation.print(OS);
-}
-
-#ifdef USE_WIN32
-static bool readFullStringValue(HKEY hkey, const char *valueName,
- std::string &value) {
- std::wstring WideValueName;
- if (!llvm::ConvertUTF8toWide(valueName, WideValueName))
- return false;
-
- DWORD result = 0;
- DWORD valueSize = 0;
- DWORD type = 0;
- // First just query for the required size.
- result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, &type, NULL,
- &valueSize);
- if (result != ERROR_SUCCESS || type != REG_SZ || !valueSize)
- return false;
- std::vector<BYTE> buffer(valueSize);
- result = RegQueryValueExW(hkey, WideValueName.c_str(), NULL, NULL, &buffer[0],
- &valueSize);
- if (result == ERROR_SUCCESS) {
- std::wstring WideValue(reinterpret_cast<const wchar_t *>(buffer.data()),
- valueSize / sizeof(wchar_t));
- if (valueSize && WideValue.back() == L'\0') {
- WideValue.pop_back();
- }
- // The destination buffer must be empty as an invariant of the conversion
- // function; but this function is sometimes called in a loop that passes in
- // the same buffer, however. Simply clear it out so we can overwrite it.
- value.clear();
- return llvm::convertWideToUTF8(WideValue, value);
- }
- return false;
-}
-#endif
-
-/// \brief Read registry string.
-/// This also supports a means to look for high-versioned keys by use
-/// of a $VERSION placeholder in the key path.
-/// $VERSION in the key path is a placeholder for the version number,
-/// causing the highest value path to be searched for and used.
-/// I.e. "SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
-/// There can be additional characters in the component. Only the numeric
-/// characters are compared. This function only searches HKLM.
-static bool getSystemRegistryString(const char *keyPath, const char *valueName,
- std::string &value, std::string *phValue) {
-#ifndef USE_WIN32
- return false;
-#else
- HKEY hRootKey = HKEY_LOCAL_MACHINE;
- HKEY hKey = NULL;
- long lResult;
- bool returnValue = false;
-
- const char *placeHolder = strstr(keyPath, "$VERSION");
- std::string bestName;
- // If we have a $VERSION placeholder, do the highest-version search.
- if (placeHolder) {
- const char *keyEnd = placeHolder - 1;
- const char *nextKey = placeHolder;
- // Find end of previous key.
- while ((keyEnd > keyPath) && (*keyEnd != '\\'))
- keyEnd--;
- // Find end of key containing $VERSION.
- while (*nextKey && (*nextKey != '\\'))
- nextKey++;
- size_t partialKeyLength = keyEnd - keyPath;
- char partialKey[256];
- if (partialKeyLength >= sizeof(partialKey))
- partialKeyLength = sizeof(partialKey) - 1;
- strncpy(partialKey, keyPath, partialKeyLength);
- partialKey[partialKeyLength] = '\0';
- HKEY hTopKey = NULL;
- lResult = RegOpenKeyExA(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY,
- &hTopKey);
- if (lResult == ERROR_SUCCESS) {
- char keyName[256];
- double bestValue = 0.0;
- DWORD index, size = sizeof(keyName) - 1;
- for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL,
- NULL, NULL) == ERROR_SUCCESS;
- index++) {
- const char *sp = keyName;
- while (*sp && !isDigit(*sp))
- sp++;
- if (!*sp)
- continue;
- const char *ep = sp + 1;
- while (*ep && (isDigit(*ep) || (*ep == '.')))
- ep++;
- char numBuf[32];
- strncpy(numBuf, sp, sizeof(numBuf) - 1);
- numBuf[sizeof(numBuf) - 1] = '\0';
- double dvalue = strtod(numBuf, NULL);
- if (dvalue > bestValue) {
- // Test that InstallDir is indeed there before keeping this index.
- // Open the chosen key path remainder.
- bestName = keyName;
- // Append rest of key.
- bestName.append(nextKey);
- lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0,
- KEY_READ | KEY_WOW64_32KEY, &hKey);
- if (lResult == ERROR_SUCCESS) {
- if (readFullStringValue(hKey, valueName, value)) {
- bestValue = dvalue;
- if (phValue)
- *phValue = bestName;
- returnValue = true;
- }
- RegCloseKey(hKey);
- }
- }
- size = sizeof(keyName) - 1;
- }
- RegCloseKey(hTopKey);
- }
- } else {
- lResult =
- RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey);
- if (lResult == ERROR_SUCCESS) {
- if (readFullStringValue(hKey, valueName, value))
- returnValue = true;
- if (phValue)
- phValue->clear();
- RegCloseKey(hKey);
- }
- }
- return returnValue;
-#endif // USE_WIN32
-}
-
-// Convert LLVM's ArchType
-// to the corresponding name of Windows SDK libraries subfolder
-static StringRef getWindowsSDKArch(llvm::Triple::ArchType Arch) {
- switch (Arch) {
- case llvm::Triple::x86:
- return "x86";
- case llvm::Triple::x86_64:
- return "x64";
- case llvm::Triple::arm:
- return "arm";
- default:
- return "";
- }
-}
-
-// Find the most recent version of Universal CRT or Windows 10 SDK.
-// vcvarsqueryregistry.bat from Visual Studio 2015 sorts entries in the include
-// directory by name and uses the last one of the list.
-// So we compare entry names lexicographically to find the greatest one.
-static bool getWindows10SDKVersion(const std::string &SDKPath,
- std::string &SDKVersion) {
- SDKVersion.clear();
-
- std::error_code EC;
- llvm::SmallString<128> IncludePath(SDKPath);
- llvm::sys::path::append(IncludePath, "Include");
- for (llvm::sys::fs::directory_iterator DirIt(IncludePath, EC), DirEnd;
- DirIt != DirEnd && !EC; DirIt.increment(EC)) {
- if (!llvm::sys::fs::is_directory(DirIt->path()))
- continue;
- StringRef CandidateName = llvm::sys::path::filename(DirIt->path());
- // If WDK is installed, there could be subfolders like "wdf" in the
- // "Include" directory.
- // Allow only directories which names start with "10.".
- if (!CandidateName.startswith("10."))
- continue;
- if (CandidateName > SDKVersion)
- SDKVersion = CandidateName;
- }
-
- return !SDKVersion.empty();
-}
-
-/// \brief Get Windows SDK installation directory.
-bool MSVCToolChain::getWindowsSDKDir(std::string &Path, int &Major,
- std::string &WindowsSDKIncludeVersion,
- std::string &WindowsSDKLibVersion) const {
- std::string RegistrySDKVersion;
- // Try the Windows registry.
- if (!getSystemRegistryString(
- "SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
- "InstallationFolder", Path, &RegistrySDKVersion))
- return false;
- if (Path.empty() || RegistrySDKVersion.empty())
- return false;
-
- WindowsSDKIncludeVersion.clear();
- WindowsSDKLibVersion.clear();
- Major = 0;
- std::sscanf(RegistrySDKVersion.c_str(), "v%d.", &Major);
- if (Major <= 7)
- return true;
- if (Major == 8) {
- // Windows SDK 8.x installs libraries in a folder whose names depend on the
- // version of the OS you're targeting. By default choose the newest, which
- // usually corresponds to the version of the OS you've installed the SDK on.
- const char *Tests[] = {"winv6.3", "win8", "win7"};
- for (const char *Test : Tests) {
- llvm::SmallString<128> TestPath(Path);
- llvm::sys::path::append(TestPath, "Lib", Test);
- if (llvm::sys::fs::exists(TestPath.c_str())) {
- WindowsSDKLibVersion = Test;
- break;
- }
- }
- return !WindowsSDKLibVersion.empty();
- }
- if (Major == 10) {
- if (!getWindows10SDKVersion(Path, WindowsSDKIncludeVersion))
- return false;
- WindowsSDKLibVersion = WindowsSDKIncludeVersion;
- return true;
- }
- // Unsupported SDK version
- return false;
-}
-
-// Gets the library path required to link against the Windows SDK.
-bool MSVCToolChain::getWindowsSDKLibraryPath(std::string &path) const {
- std::string sdkPath;
- int sdkMajor = 0;
- std::string windowsSDKIncludeVersion;
- std::string windowsSDKLibVersion;
-
- path.clear();
- if (!getWindowsSDKDir(sdkPath, sdkMajor, windowsSDKIncludeVersion,
- windowsSDKLibVersion))
- return false;
-
- llvm::SmallString<128> libPath(sdkPath);
- llvm::sys::path::append(libPath, "Lib");
- if (sdkMajor <= 7) {
- switch (getArch()) {
- // In Windows SDK 7.x, x86 libraries are directly in the Lib folder.
- case llvm::Triple::x86:
- break;
- case llvm::Triple::x86_64:
- llvm::sys::path::append(libPath, "x64");
- break;
- case llvm::Triple::arm:
- // It is not necessary to link against Windows SDK 7.x when targeting ARM.
- return false;
- default:
- return false;
- }
- } else {
- const StringRef archName = getWindowsSDKArch(getArch());
- if (archName.empty())
- return false;
- llvm::sys::path::append(libPath, windowsSDKLibVersion, "um", archName);
- }
-
- path = libPath.str();
- return true;
-}
-
-// Check if the Include path of a specified version of Visual Studio contains
-// specific header files. If not, they are probably shipped with Universal CRT.
-bool clang::driver::toolchains::MSVCToolChain::useUniversalCRT(
- std::string &VisualStudioDir) const {
- llvm::SmallString<128> TestPath(VisualStudioDir);
- llvm::sys::path::append(TestPath, "VC\\include\\stdlib.h");
-
- return !llvm::sys::fs::exists(TestPath);
-}
-
-bool MSVCToolChain::getUniversalCRTSdkDir(std::string &Path,
- std::string &UCRTVersion) const {
- // vcvarsqueryregistry.bat for Visual Studio 2015 queries the registry
- // for the specific key "KitsRoot10". So do we.
- if (!getSystemRegistryString(
- "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", "KitsRoot10",
- Path, nullptr))
- return false;
-
- return getWindows10SDKVersion(Path, UCRTVersion);
-}
-
-bool MSVCToolChain::getUniversalCRTLibraryPath(std::string &Path) const {
- std::string UniversalCRTSdkPath;
- std::string UCRTVersion;
-
- Path.clear();
- if (!getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion))
- return false;
-
- StringRef ArchName = getWindowsSDKArch(getArch());
- if (ArchName.empty())
- return false;
-
- llvm::SmallString<128> LibPath(UniversalCRTSdkPath);
- llvm::sys::path::append(LibPath, "Lib", UCRTVersion, "ucrt", ArchName);
-
- Path = LibPath.str();
- return true;
-}
-
-// Get the location to use for Visual Studio binaries. The location priority
-// is: %VCINSTALLDIR% > %PATH% > newest copy of Visual Studio installed on
-// system (as reported by the registry).
-bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath,
- std::string &path) const {
- path.clear();
-
- SmallString<128> BinDir;
-
- // First check the environment variables that vsvars32.bat sets.
- llvm::Optional<std::string> VcInstallDir =
- llvm::sys::Process::GetEnv("VCINSTALLDIR");
- if (VcInstallDir.hasValue()) {
- BinDir = VcInstallDir.getValue();
- llvm::sys::path::append(BinDir, "bin");
- } else {
- // Next walk the PATH, trying to find a cl.exe in the path. If we find one,
- // use that. However, make sure it's not clang's cl.exe.
- llvm::Optional<std::string> OptPath = llvm::sys::Process::GetEnv("PATH");
- if (OptPath.hasValue()) {
- const char EnvPathSeparatorStr[] = {llvm::sys::EnvPathSeparator, '\0'};
- SmallVector<StringRef, 8> PathSegments;
- llvm::SplitString(OptPath.getValue(), PathSegments, EnvPathSeparatorStr);
-
- for (StringRef PathSegment : PathSegments) {
- if (PathSegment.empty())
- continue;
-
- SmallString<128> FilePath(PathSegment);
- llvm::sys::path::append(FilePath, "cl.exe");
- // Checking if cl.exe exists is a small optimization over calling
- // can_execute, which really only checks for existence but will also do
- // extra checks for cl.exe.exe. These add up when walking a long path.
- if (llvm::sys::fs::exists(FilePath.c_str()) &&
- !llvm::sys::fs::equivalent(FilePath.c_str(), clangProgramPath)) {
- // If we found it on the PATH, use it exactly as is with no
- // modifications.
- path = PathSegment;
- return true;
- }
- }
- }
-
- std::string installDir;
- // With no VCINSTALLDIR and nothing on the PATH, if we can't find it in the
- // registry then we have no choice but to fail.
- if (!getVisualStudioInstallDir(installDir))
- return false;
-
- // Regardless of what binary we're ultimately trying to find, we make sure
- // that this is a Visual Studio directory by checking for cl.exe. We use
- // cl.exe instead of other binaries like link.exe because programs such as
- // GnuWin32 also have a utility called link.exe, so cl.exe is the least
- // ambiguous.
- BinDir = installDir;
- llvm::sys::path::append(BinDir, "VC", "bin");
- SmallString<128> ClPath(BinDir);
- llvm::sys::path::append(ClPath, "cl.exe");
-
- if (!llvm::sys::fs::can_execute(ClPath.c_str()))
- return false;
- }
-
- if (BinDir.empty())
- return false;
-
- switch (getArch()) {
- case llvm::Triple::x86:
- break;
- case llvm::Triple::x86_64:
- llvm::sys::path::append(BinDir, "amd64");
- break;
- case llvm::Triple::arm:
- llvm::sys::path::append(BinDir, "arm");
- break;
- default:
- // Whatever this is, Visual Studio doesn't have a toolchain for it.
- return false;
- }
- path = BinDir.str();
- return true;
-}
-
-VersionTuple MSVCToolChain::getMSVCVersionFromTriple() const {
- unsigned Major, Minor, Micro;
- getTriple().getEnvironmentVersion(Major, Minor, Micro);
- if (Major || Minor || Micro)
- return VersionTuple(Major, Minor, Micro);
- return VersionTuple();
-}
-
-VersionTuple MSVCToolChain::getMSVCVersionFromExe() const {
- VersionTuple Version;
-#ifdef USE_WIN32
- std::string BinPath;
- if (!getVisualStudioBinariesFolder("", BinPath))
- return Version;
- SmallString<128> ClExe(BinPath);
- llvm::sys::path::append(ClExe, "cl.exe");
-
- std::wstring ClExeWide;
- if (!llvm::ConvertUTF8toWide(ClExe.c_str(), ClExeWide))
- return Version;
-
- const DWORD VersionSize = ::GetFileVersionInfoSizeW(ClExeWide.c_str(),
- nullptr);
- if (VersionSize == 0)
- return Version;
-
- SmallVector<uint8_t, 4 * 1024> VersionBlock(VersionSize);
- if (!::GetFileVersionInfoW(ClExeWide.c_str(), 0, VersionSize,
- VersionBlock.data()))
- return Version;
-
- VS_FIXEDFILEINFO *FileInfo = nullptr;
- UINT FileInfoSize = 0;
- if (!::VerQueryValueW(VersionBlock.data(), L"\\",
- reinterpret_cast<LPVOID *>(&FileInfo), &FileInfoSize) ||
- FileInfoSize < sizeof(*FileInfo))
- return Version;
-
- const unsigned Major = (FileInfo->dwFileVersionMS >> 16) & 0xFFFF;
- const unsigned Minor = (FileInfo->dwFileVersionMS ) & 0xFFFF;
- const unsigned Micro = (FileInfo->dwFileVersionLS >> 16) & 0xFFFF;
-
- Version = VersionTuple(Major, Minor, Micro);
-#endif
- return Version;
-}
-
-// Get Visual Studio installation directory.
-bool MSVCToolChain::getVisualStudioInstallDir(std::string &path) const {
- // First check the environment variables that vsvars32.bat sets.
- if (llvm::Optional<std::string> VcInstallDir =
- llvm::sys::Process::GetEnv("VCINSTALLDIR")) {
- path = std::move(*VcInstallDir);
- path = path.substr(0, path.find("\\VC"));
- return true;
- }
-
- std::string vsIDEInstallDir;
- std::string vsExpressIDEInstallDir;
- // Then try the windows registry.
- bool hasVCDir =
- getSystemRegistryString("SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
- "InstallDir", vsIDEInstallDir, nullptr);
- if (hasVCDir && !vsIDEInstallDir.empty()) {
- path = vsIDEInstallDir.substr(0, vsIDEInstallDir.find("\\Common7\\IDE"));
- return true;
- }
-
- bool hasVCExpressDir =
- getSystemRegistryString("SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
- "InstallDir", vsExpressIDEInstallDir, nullptr);
- if (hasVCExpressDir && !vsExpressIDEInstallDir.empty()) {
- path = vsExpressIDEInstallDir.substr(
- 0, vsIDEInstallDir.find("\\Common7\\IDE"));
- return true;
- }
-
- // Try the environment.
- std::string vcomntools;
- if (llvm::Optional<std::string> vs120comntools =
- llvm::sys::Process::GetEnv("VS120COMNTOOLS"))
- vcomntools = std::move(*vs120comntools);
- else if (llvm::Optional<std::string> vs100comntools =
- llvm::sys::Process::GetEnv("VS100COMNTOOLS"))
- vcomntools = std::move(*vs100comntools);
- else if (llvm::Optional<std::string> vs90comntools =
- llvm::sys::Process::GetEnv("VS90COMNTOOLS"))
- vcomntools = std::move(*vs90comntools);
- else if (llvm::Optional<std::string> vs80comntools =
- llvm::sys::Process::GetEnv("VS80COMNTOOLS"))
- vcomntools = std::move(*vs80comntools);
-
- // Find any version we can.
- if (!vcomntools.empty()) {
- size_t p = vcomntools.find("\\Common7\\Tools");
- if (p != std::string::npos)
- vcomntools.resize(p);
- path = std::move(vcomntools);
- return true;
- }
- return false;
-}
-
-void MSVCToolChain::AddSystemIncludeWithSubfolder(
- const ArgList &DriverArgs, ArgStringList &CC1Args,
- const std::string &folder, const Twine &subfolder1, const Twine &subfolder2,
- const Twine &subfolder3) const {
- llvm::SmallString<128> path(folder);
- llvm::sys::path::append(path, subfolder1, subfolder2, subfolder3);
- addSystemInclude(DriverArgs, CC1Args, path);
-}
-
-void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- if (DriverArgs.hasArg(options::OPT_nostdinc))
- return;
-
- if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
- AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, getDriver().ResourceDir,
- "include");
- }
-
- // Add %INCLUDE%-like directories from the -imsvc flag.
- for (const auto &Path : DriverArgs.getAllArgValues(options::OPT__SLASH_imsvc))
- addSystemInclude(DriverArgs, CC1Args, Path);
-
- if (DriverArgs.hasArg(options::OPT_nostdlibinc))
- return;
-
- // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat.
- if (llvm::Optional<std::string> cl_include_dir =
- llvm::sys::Process::GetEnv("INCLUDE")) {
- SmallVector<StringRef, 8> Dirs;
- StringRef(*cl_include_dir)
- .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
- for (StringRef Dir : Dirs)
- addSystemInclude(DriverArgs, CC1Args, Dir);
- if (!Dirs.empty())
- return;
- }
-
- std::string VSDir;
-
- // When built with access to the proper Windows APIs, try to actually find
- // the correct include paths first.
- if (getVisualStudioInstallDir(VSDir)) {
- AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, VSDir, "VC\\include");
-
- if (useUniversalCRT(VSDir)) {
- std::string UniversalCRTSdkPath;
- std::string UCRTVersion;
- if (getUniversalCRTSdkDir(UniversalCRTSdkPath, UCRTVersion)) {
- AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, UniversalCRTSdkPath,
- "Include", UCRTVersion, "ucrt");
- }
- }
-
- std::string WindowsSDKDir;
- int major;
- std::string windowsSDKIncludeVersion;
- std::string windowsSDKLibVersion;
- if (getWindowsSDKDir(WindowsSDKDir, major, windowsSDKIncludeVersion,
- windowsSDKLibVersion)) {
- if (major >= 8) {
- // Note: windowsSDKIncludeVersion is empty for SDKs prior to v10.
- // Anyway, llvm::sys::path::append is able to manage it.
- AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
- "include", windowsSDKIncludeVersion,
- "shared");
- AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
- "include", windowsSDKIncludeVersion,
- "um");
- AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
- "include", windowsSDKIncludeVersion,
- "winrt");
- } else {
- AddSystemIncludeWithSubfolder(DriverArgs, CC1Args, WindowsSDKDir,
- "include");
- }
- } else {
- addSystemInclude(DriverArgs, CC1Args, VSDir);
- }
- return;
- }
-
-#if defined(LLVM_ON_WIN32)
- // As a fallback, select default install paths.
- // FIXME: Don't guess drives and paths like this on Windows.
- const StringRef Paths[] = {
- "C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
- "C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
- "C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
- "C:/Program Files/Microsoft Visual Studio 8/VC/include",
- "C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include"
- };
- addSystemIncludes(DriverArgs, CC1Args, Paths);
-#endif
-}
-
-void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
- ArgStringList &CC1Args) const {
- // FIXME: There should probably be logic here to find libc++ on Windows.
-}
-
-VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D,
- const ArgList &Args) const {
- bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment();
- VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args);
- if (MSVT.empty()) MSVT = getMSVCVersionFromTriple();
- if (MSVT.empty() && IsWindowsMSVC) MSVT = getMSVCVersionFromExe();
- if (MSVT.empty() &&
- Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
- IsWindowsMSVC)) {
- // -fms-compatibility-version=18.00 is default.
- // FIXME: Consider bumping this to 19 (MSVC2015) soon.
- MSVT = VersionTuple(18);
- }
- return MSVT;
-}
-
-std::string
-MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
- types::ID InputType) const {
- // The MSVC version doesn't care about the architecture, even though it
- // may look at the triple internally.
- VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args);
- MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0),
- MSVT.getSubminor().getValueOr(0));
-
- // For the rest of the triple, however, a computed architecture name may
- // be needed.
- llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType));
- if (Triple.getEnvironment() == llvm::Triple::MSVC) {
- StringRef ObjFmt = Triple.getEnvironmentName().split('-').second;
- if (ObjFmt.empty())
- Triple.setEnvironmentName((Twine("msvc") + MSVT.getAsString()).str());
- else
- Triple.setEnvironmentName(
- (Twine("msvc") + MSVT.getAsString() + Twine('-') + ObjFmt).str());
- }
- return Triple.getTriple();
-}
-
-SanitizerMask MSVCToolChain::getSupportedSanitizers() const {
- SanitizerMask Res = ToolChain::getSupportedSanitizers();
- Res |= SanitizerKind::Address;
- return Res;
-}
-
-static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL,
- bool SupportsForcingFramePointer,
- const char *ExpandChar, const OptTable &Opts) {
- assert(A->getOption().matches(options::OPT__SLASH_O));
-
- StringRef OptStr = A->getValue();
- for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
- const char &OptChar = *(OptStr.data() + I);
- switch (OptChar) {
- default:
- break;
- case '1':
- case '2':
- case 'x':
- case 'd':
- if (&OptChar == ExpandChar) {
- if (OptChar == 'd') {
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_O0));
- } else {
- if (OptChar == '1') {
- DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
- } else if (OptChar == '2' || OptChar == 'x') {
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
- DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
- }
- if (SupportsForcingFramePointer &&
- !DAL.hasArgNoClaim(options::OPT_fno_omit_frame_pointer))
- DAL.AddFlagArg(A,
- Opts.getOption(options::OPT_fomit_frame_pointer));
- if (OptChar == '1' || OptChar == '2')
- DAL.AddFlagArg(A,
- Opts.getOption(options::OPT_ffunction_sections));
- }
- }
- break;
- case 'b':
- if (I + 1 != E && isdigit(OptStr[I + 1])) {
- switch (OptStr[I + 1]) {
- case '0':
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
- break;
- case '1':
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
- break;
- case '2':
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
- break;
- }
- ++I;
- }
- break;
- case 'g':
- break;
- case 'i':
- if (I + 1 != E && OptStr[I + 1] == '-') {
- ++I;
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_builtin));
- } else {
- DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin));
- }
- break;
- case 's':
- DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "s");
- break;
- case 't':
- DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2");
- break;
- case 'y': {
- bool OmitFramePointer = true;
- if (I + 1 != E && OptStr[I + 1] == '-') {
- OmitFramePointer = false;
- ++I;
- }
- if (SupportsForcingFramePointer) {
- if (OmitFramePointer)
- DAL.AddFlagArg(A,
- Opts.getOption(options::OPT_fomit_frame_pointer));
- else
- DAL.AddFlagArg(
- A, Opts.getOption(options::OPT_fno_omit_frame_pointer));
- } else {
- // Don't warn about /Oy- in 64-bit builds (where
- // SupportsForcingFramePointer is false). The flag having no effect
- // there is a compiler-internal optimization, and people shouldn't have
- // to special-case their build files for 64-bit clang-cl.
- A->claim();
- }
- break;
- }
- }
- }
-}
-
-static void TranslateDArg(Arg *A, llvm::opt::DerivedArgList &DAL,
- const OptTable &Opts) {
- assert(A->getOption().matches(options::OPT_D));
-
- StringRef Val = A->getValue();
- size_t Hash = Val.find('#');
- if (Hash == StringRef::npos || Hash > Val.find('=')) {
- DAL.append(A);
- return;
- }
-
- std::string NewVal = Val;
- NewVal[Hash] = '=';
- DAL.AddJoinedArg(A, Opts.getOption(options::OPT_D), NewVal);
-}
-
-llvm::opt::DerivedArgList *
-MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
- StringRef BoundArch, Action::OffloadKind) const {
- DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs());
- const OptTable &Opts = getDriver().getOpts();
-
- // /Oy and /Oy- only has an effect under X86-32.
- bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86;
-
- // The -O[12xd] flag actually expands to several flags. We must desugar the
- // flags so that options embedded can be negated. For example, the '-O2' flag
- // enables '-Oy'. Expanding '-O2' into its constituent flags allows us to
- // correctly handle '-O2 -Oy-' where the trailing '-Oy-' disables a single
- // aspect of '-O2'.
- //
- // Note that this expansion logic only applies to the *last* of '[12xd]'.
-
- // First step is to search for the character we'd like to expand.
- const char *ExpandChar = nullptr;
- for (Arg *A : Args) {
- if (!A->getOption().matches(options::OPT__SLASH_O))
- continue;
- StringRef OptStr = A->getValue();
- for (size_t I = 0, E = OptStr.size(); I != E; ++I) {
- char OptChar = OptStr[I];
- char PrevChar = I > 0 ? OptStr[I - 1] : '0';
- if (PrevChar == 'b') {
- // OptChar does not expand; it's an argument to the previous char.
- continue;
- }
- if (OptChar == '1' || OptChar == '2' || OptChar == 'x' || OptChar == 'd')
- ExpandChar = OptStr.data() + I;
- }
- }
-
- for (Arg *A : Args) {
- if (A->getOption().matches(options::OPT__SLASH_O)) {
- // The -O flag actually takes an amalgam of other options. For example,
- // '/Ogyb2' is equivalent to '/Og' '/Oy' '/Ob2'.
- TranslateOptArg(A, *DAL, SupportsForcingFramePointer, ExpandChar, Opts);
- } else if (A->getOption().matches(options::OPT_D)) {
- // Translate -Dfoo#bar into -Dfoo=bar.
- TranslateDArg(A, *DAL, Opts);
- } else {
- DAL->append(A);
- }
- }
-
- return DAL;
-}
OpenPOWER on IntegriCloud