diff options
Diffstat (limited to 'clang/lib/Driver')
-rw-r--r-- | clang/lib/Driver/MSVCToolChain.cpp | 44 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.h | 1 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.h | 3 |
4 files changed, 56 insertions, 6 deletions
diff --git a/clang/lib/Driver/MSVCToolChain.cpp b/clang/lib/Driver/MSVCToolChain.cpp index acfb507fea5..4f38ec52f53 100644 --- a/clang/lib/Driver/MSVCToolChain.cpp +++ b/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" @@ -37,6 +38,8 @@ #define NOMINMAX #endif #include <windows.h> + + #pragma comment(lib, "version.lib") #endif using namespace clang::driver; @@ -457,6 +460,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. @@ -618,7 +660,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; diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index b8fe086380f..5e1e6ca2f22 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -1028,6 +1028,7 @@ public: bool getVisualStudioInstallDir(std::string &path) const; bool getVisualStudioBinariesFolder(const char *clangProgramPath, std::string &path) const; + VersionTuple getMSVCVersionFromExe() const override; std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType) const override; diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index cbc2e6575c5..c408e6c79e0 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -3293,7 +3293,7 @@ static void appendUserToPath(SmallVectorImpl<char> &Result) { Result.append(UID.begin(), UID.end()); } -VersionTuple visualstudio::getMSVCVersion(const Driver *D, +VersionTuple visualstudio::getMSVCVersion(const Driver *D, const ToolChain &TC, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, bool IsWindowsMSVC) { @@ -3335,8 +3335,14 @@ VersionTuple visualstudio::getMSVCVersion(const Driver *D, if (Major || Minor || Micro) return VersionTuple(Major, Minor, Micro); - // FIXME: Consider bumping this to 19 (MSVC2015) soon. - return VersionTuple(18); + if (IsWindowsMSVC) { + VersionTuple MSVT = TC.getMSVCVersionFromExe(); + if (!MSVT.empty()) + return MSVT; + + // FIXME: Consider bumping this to 19 (MSVC2015) soon. + return VersionTuple(18); + } } return VersionTuple(); } @@ -5226,7 +5232,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fms-compatibility-version=18.00 is default. VersionTuple MSVT = visualstudio::getMSVCVersion( - &D, getToolChain().getTriple(), Args, IsWindowsMSVC); + &D, getToolChain(), getToolChain().getTriple(), Args, IsWindowsMSVC); if (!MSVT.empty()) CmdArgs.push_back( Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString())); diff --git a/clang/lib/Driver/Tools.h b/clang/lib/Driver/Tools.h index c9d5c2238d6..723b1dcfa9b 100644 --- a/clang/lib/Driver/Tools.h +++ b/clang/lib/Driver/Tools.h @@ -682,7 +682,8 @@ public: /// Visual studio tools. namespace visualstudio { -VersionTuple getMSVCVersion(const Driver *D, const llvm::Triple &Triple, +VersionTuple getMSVCVersion(const Driver *D, const ToolChain &TC, + const llvm::Triple &Triple, const llvm::opt::ArgList &Args, bool IsWindowsMSVC); class LLVM_LIBRARY_VISIBILITY Linker : public Tool { |