Index: lib/Driver/MSVCToolChain.cpp =================================================================== --- lib/Driver/MSVCToolChain.cpp +++ lib/Driver/MSVCToolChain.cpp @@ -37,6 +37,8 @@ #define NOMINMAX #endif #include + + #pragma comment(lib, "version.lib") #endif using namespace clang::driver; @@ -457,6 +459,42 @@ 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"); + + const DWORD VersionSize = ::GetFileVersionInfoSizeA(ClExe.c_str(), nullptr); + if (VersionSize == 0) { + return Version; + } + std::vector VersionBlock(VersionSize); + if (!::GetFileVersionInfoA(ClExe.c_str(), 0, VersionSize, + VersionBlock.data())) { + return Version; + } + VS_FIXEDFILEINFO *FileInfo = nullptr; + UINT FileInfoSize = 0; + if (!::VerQueryValueA(VersionBlock.data(), "\\", + reinterpret_cast(&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 +656,7 @@ 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; Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -1016,6 +1016,7 @@ bool getVisualStudioInstallDir(std::string &path) const; bool getVisualStudioBinariesFolder(const char *clangProgramPath, std::string &path) const; + VersionTuple getMSVCVersionFromExe() const; std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType) const override; Index: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -682,7 +682,8 @@ /// 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 { Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3291,7 +3291,7 @@ 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) { @@ -3333,8 +3333,15 @@ if (Major || Minor || Micro) return VersionTuple(Major, Minor, Micro); - // FIXME: Consider bumping this to 19 (MSVC2015) soon. - return VersionTuple(18); + if (IsWindowsMSVC) { + const auto &MSVC = static_cast(TC); + VersionTuple MSVT = MSVC.getMSVCVersionFromExe(); + if (!MSVT.empty()) + return MSVT; + + // FIXME: Consider bumping this to 19 (MSVC2015) soon. + return VersionTuple(18); + } } return VersionTuple(); } @@ -5224,7 +5231,7 @@ // -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())); Index: test/Driver/cl-options.c =================================================================== --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -387,7 +387,7 @@ // RTTI-NOT: "-fno-rtti" // thread safe statics are off for versions < 19. -// RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=NoThreadSafeStatics %s +// RUN: %clang_cl /c -### -fms-compatibility-version=18 -- %s 2>&1 | FileCheck -check-prefix=NoThreadSafeStatics %s // RUN: %clang_cl /Zc:threadSafeInit /Zc:threadSafeInit- /c -### -- %s 2>&1 | FileCheck -check-prefix=NoThreadSafeStatics %s // NoThreadSafeStatics: "-fno-threadsafe-statics" Index: test/Driver/msc-version.c =================================================================== --- test/Driver/msc-version.c +++ test/Driver/msc-version.c @@ -1,15 +1,4 @@ // -// Verify defaults -// - -// RUN: %clang -target i686-windows -fms-compatibility -dM -E -