Get default -fms-compatibility-version from cl.exe's version
-fms-compatibility-version was defaulting to 18 (VS 2013), which is a pain if your environment is pointing to version 19 (VS 2015) libraries.
If cl.exe can be found, this patch uses its version number as the default instead. It re-uses the existing code to find the Visual Studio binaries folder and WinAPI methods to check its version. You can still explicitly specify a compatibility version on the command line. If you don't have cl.exe, this should be a no-op and you'll get the old default of 18.
This affected the tests, which assumed that if you didn't specific a version, that it would default to 18, but this won't be true for all machines. So a couple test cases had to be eliminated and a couple others had to be tweaked to allow for various outputs.
Addresses: https://llvm.org/bugs/show_bug.cgi?id=27215
Differential Revision: http://reviews.llvm.org/D20136
llvm-svn: 269515
diff --git a/clang/lib/Driver/MSVCToolChain.cpp b/clang/lib/Driver/MSVCToolChain.cpp
index acfb507..4f38ec5 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 @@
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 @@
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;