This is an archive of the discontinued LLVM Phabricator instance.

Refactor how the MSVC toolchain searches for a compatibility version.
ClosedPublic

Authored by dlj on Dec 6 2016, 12:02 PM.

Details

Summary

The MSVC toolchain and Clang driver combination currently uses a fairly complex
sequence of steps to determine the MS compatibility version to pass to cc1.
There is some oddness in this sequence currently, with some code which inspects
flags in the toolchain, and some code which inspects the triple and local
environment in the driver code.

This change is an attempt to consolidate most of this logic so that
Win32-specific code lives in MSVCToolChain.cpp. I'm not 100% happy with the
split, so any suggestions are welcome.

There are a few things you might want to watch for for specifically:

  • On all platforms, if MSVC compatibility flags are provided (and valid), use those.
  • The fallback sequence should be the same as before, but is now consolidated into MSVCToolChain::getMSVCVersion:
    • Otherwise, try to use the Triple.
    • Otherwise, on Windows, check the executable.
    • Otherwise, on Windows or with --fms-extensions, default to 18.
    • Otherwise, we can't determine the version.
  • MSVCToolChain::ComputeEffectiveTriple no longer calls the base ToolChain::ComputeEffectiveClangTriple. The only thing it would change for Windows the architecture, which we don't care about for the compatibility version.
    • I'm not sure whether this is philosophically correct (but it should be easy to add back to MSVCToolChain::getMSVCVersionFromTriple if not).
    • Previously, Tools.cpp just called getTriple() anyhow, so it doesn't look like the effective triple was always being used previously anyhow.

Diff Detail

Repository
rL LLVM

Event Timeline

dlj updated this revision to Diff 80461.Dec 6 2016, 12:02 PM
dlj retitled this revision from to Refactor how the MSVC toolchain searches for a compatibility version..
dlj updated this object.
dlj added reviewers: rnk, hans, compnerd, llvm-commits.
dlj added a comment.Dec 6 2016, 12:05 PM

FYI to reviewers: I talked to Reid about this and sent this mostly for preliminary comments. If this approach seems OK, I'll flesh out some of the testing first, to ensure this doesn't break any corner cases.

rnk edited edge metadata.Dec 6 2016, 1:11 PM

This seems like a nice refactoring, and I'm pretty sure there's no real functional change in practice.

include/clang/Driver/ToolChain.h
446 ↗(On Diff #80461)

This isn't a cheap operation, and we don't cache it. Let's call it something like computeMSVCVersion. I don't want us to read the version out of cl.exe more than once. Besides, it mirrors ComputeLLVMTriple etc.

lib/Driver/MSVCToolChain.cpp
476–478 ↗(On Diff #80461)

I know this is more of an RFC patch, but I'll note we prefer static on free functions in case you hadn't encountered that http://llvm.org/docs/CodingStandards.html#id53

Also, this is poorly named. It's really building a version tuple from an unseparated, possibly full, version number. So, maybe inferMSVCVersionSeparators or separateMSVCFullVersion or something?

lib/Driver/Tools.cpp
5739 ↗(On Diff #80461)

This comment got separated from the the relevant default some time ago. Can you move it to the return VersionTuple(18)?

Nice refactor. I've been knee-deep in this code before, and it looks right to me.

dlj updated this revision to Diff 80524.Dec 6 2016, 6:16 PM
dlj edited edge metadata.

Addressed comments, moved code for failing tests I couldn't figure out before.

dlj updated this revision to Diff 80526.Dec 6 2016, 6:22 PM
dlj marked 3 inline comments as done.

Address more comments.

dlj added a comment.Dec 6 2016, 6:23 PM

As it turns out, the flags are needed for non-MSVC toolchains as well (which was confusing me with broken tests). I've moved some of the args logic out of MSVCToolChain.cpp to ToolChain.cpp.

rnk added a comment.Dec 7 2016, 9:00 AM

Can you update the commit message to outline the new algorithm? I think it's the same, except on all platforms, -fmsc-version and -fms-compatibility version are considered. Only with the MSVC toolchain do we go to the triple step, then the exe, then default to 18 with -fms-extensions. I guess this lets people compile code for Linux while pretending to be MSVC.

lib/Driver/MSVCToolChain.cpp
476 ↗(On Diff #80526)

This function isn't doing the separation. Whatever code does the repeated mod 100 division is the separation code. This is more getMSVCVersionFromTriple.

lib/Driver/ToolChain.cpp
725 ↗(On Diff #80526)

This thing is separateMSVCFullVersion.

dlj marked 2 inline comments as done.Dec 7 2016, 10:01 AM
In D27477#615983, @rnk wrote:

Can you update the commit message to outline the new algorithm? I think it's the same, except on all platforms, -fmsc-version and -fms-compatibility version are considered. Only with the MSVC toolchain do we go to the triple step, then the exe, then default to 18 with -fms-extensions. I guess this lets people compile code for Linux while pretending to be MSVC.

Right, so I think that there is actually *no* change from the previous behavior. The tests in Misc/diag-format.c in particular failed without this (MSVC2010 needs to be detected for the off-by-one in the diagnostics). The only code path that didn't appear to be tested was what I'm adding in https://reviews.llvm.org/D27498.

It might make sense for the MSVC logic to only live in the MSVC toolchain, and I'd be happy to move it there if you agree, but I'd prefer to do that as a follow-up, since this is already sort of non-trivial.

lib/Driver/MSVCToolChain.cpp
476 ↗(On Diff #80526)

Ah, sorry about that... I misunderstood your previous comment.

dlj updated this revision to Diff 80622.Dec 7 2016, 10:03 AM
dlj marked an inline comment as done.

Updated for rnk's comments.

dlj updated this object.Dec 7 2016, 10:07 AM
rnk accepted this revision.Dec 7 2016, 1:21 PM
rnk edited edge metadata.

lgtm

This revision is now accepted and ready to land.Dec 7 2016, 1:21 PM
This revision was automatically updated to reflect the committed changes.