diff options
| author | 2017-01-14 19:55:43 +0000 | |
|---|---|---|
| committer | 2017-01-14 19:55:43 +0000 | |
| commit | bd3306aecb3a15e8967143b8cdbbccf2b1b19b74 (patch) | |
| tree | 309a8132b44564b9e634c0da6815187ce8eab27c /gnu/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp | |
| parent | killp -a should not kill the window if only one pane. (diff) | |
| download | wireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.tar.xz wireguard-openbsd-bd3306aecb3a15e8967143b8cdbbccf2b1b19b74.zip | |
Import LLVM 3.9.1 including clang and lld.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp | 135 |
1 files changed, 110 insertions, 25 deletions
diff --git a/gnu/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp b/gnu/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp index 68747155b81..b8de5ad4918 100644 --- a/gnu/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp +++ b/gnu/llvm/tools/clang/lib/Driver/MSVCToolChain.cpp @@ -19,6 +19,7 @@ #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/Process.h" @@ -71,6 +72,11 @@ 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; } @@ -89,23 +95,31 @@ bool MSVCToolChain::isPICDefaultForced() const { #ifdef USE_WIN32 static bool readFullStringValue(HKEY hkey, const char *valueName, std::string &value) { - // FIXME: We should be using the W versions of the registry functions, but - // doing so requires UTF8 / UTF16 conversions similar to how we handle command - // line arguments. The UTF8 conversion functions are not exposed publicly - // from LLVM though, so in order to do this we will probably need to create - // a registry abstraction in LLVMSupport that is Windows only. + 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 = RegQueryValueEx(hkey, valueName, NULL, &type, NULL, &valueSize); - if (result != ERROR_SUCCESS || type != REG_SZ) + 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 = RegQueryValueEx(hkey, valueName, NULL, NULL, &buffer[0], &valueSize); - if (result == ERROR_SUCCESS) - value.assign(reinterpret_cast<const char *>(buffer.data())); - return result; + 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)); + // 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 @@ -141,19 +155,20 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName, nextKey++; size_t partialKeyLength = keyEnd - keyPath; char partialKey[256]; - if (partialKeyLength > sizeof(partialKey)) - partialKeyLength = sizeof(partialKey); + if (partialKeyLength >= sizeof(partialKey)) + partialKeyLength = sizeof(partialKey) - 1; strncpy(partialKey, keyPath, partialKeyLength); partialKey[partialKeyLength] = '\0'; HKEY hTopKey = NULL; - lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ | KEY_WOW64_32KEY, - &hTopKey); + 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; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL, - NULL, NULL, NULL) == ERROR_SUCCESS; index++) { + for (index = 0; RegEnumKeyExA(hTopKey, index, keyName, &size, NULL, NULL, + NULL, NULL) == ERROR_SUCCESS; + index++) { const char *sp = keyName; while (*sp && !isDigit(*sp)) sp++; @@ -172,8 +187,8 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName, bestName = keyName; // Append rest of key. bestName.append(nextKey); - lResult = RegOpenKeyEx(hTopKey, bestName.c_str(), 0, - KEY_READ | KEY_WOW64_32KEY, &hKey); + lResult = RegOpenKeyExA(hTopKey, bestName.c_str(), 0, + KEY_READ | KEY_WOW64_32KEY, &hKey); if (lResult == ERROR_SUCCESS) { lResult = readFullStringValue(hKey, valueName, value); if (lResult == ERROR_SUCCESS) { @@ -191,7 +206,7 @@ static bool getSystemRegistryString(const char *keyPath, const char *valueName, } } else { lResult = - RegOpenKeyEx(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); + RegOpenKeyExA(hRootKey, keyPath, 0, KEY_READ | KEY_WOW64_32KEY, &hKey); if (lResult == ERROR_SUCCESS) { lResult = readFullStringValue(hKey, valueName, value); if (lResult == ERROR_SUCCESS) @@ -402,7 +417,10 @@ bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath, SmallString<128> FilePath(PathSegment); llvm::sys::path::append(FilePath, "cl.exe"); - if (llvm::sys::fs::can_execute(FilePath.c_str()) && + // 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. @@ -452,6 +470,45 @@ bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath, return true; } +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. @@ -527,6 +584,10 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, "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; @@ -609,7 +670,7 @@ MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args, ToolChain::ComputeEffectiveClangTriple(Args, InputType); llvm::Triple Triple(TripleStr); VersionTuple MSVT = - tools::visualstudio::getMSVCVersion(/*D=*/nullptr, Triple, Args, + tools::visualstudio::getMSVCVersion(/*D=*/nullptr, *this, Triple, Args, /*IsWindowsMSVC=*/true); if (MSVT.empty()) return TripleStr; @@ -659,7 +720,8 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, DAL.AddFlagArg(A, Opts.getOption(options::OPT_fbuiltin)); DAL.AddJoinedArg(A, Opts.getOption(options::OPT_O), "2"); } - if (SupportsForcingFramePointer) + 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') @@ -669,8 +731,20 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, } break; case 'b': - if (I + 1 != E && isdigit(OptStr[I + 1])) + 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; @@ -701,6 +775,12 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, 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; } @@ -748,7 +828,12 @@ MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, continue; StringRef OptStr = A->getValue(); for (size_t I = 0, E = OptStr.size(); I != E; ++I) { - const char &OptChar = *(OptStr.data() + 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; } |
