This is a reasonably non-intrusive change, which I've verified works for both x86 and x64 DevDiv-internal builds.
The idea is to change bool IsVS2017OrNewer into a 3-state ToolsetLayout VSLayout. Either a build is DevDiv-internal, released VS 2017 or newer, or released VS 2015 or older. When looking at the directory structure, if instead of "VC" we see "x86ret", "x86chk", "amd64ret", or "amd64chk", we recognize this as a DevDiv-internal build.
After we get past the directory structure validation, we use this knowledge to regenerate paths appropriately. llvmArchToDevDivInternalArch() knows how we use "i386" subdirectories, and MSVCToolChain::getSubDirectoryPath() uses that. It also knows that DevDiv-internal builds have an "inc" subdirectory instead of "include".
This may still not be the "right" fix in any sense, but I believe that it's non-intrusive in the sense that if the special directory names aren't found, no codepaths are affected. (ToolsetLayout::OlderVS and ToolsetLayout::VS2017OrNewer correspond to IsVS2017OrNewer being false or true, respectively.) I searched for all references to IsVS2017OrNewer, which are places where Clang cares about VS's directory structure, and the only one that isn't being patched is some logic to deal with cross-compilation. I'm fine with that not working for DevDiv-internal builds for the moment (we typically test the native compilers), so I added a comment.
Is there still time to get a patch like this into 5.0.0, or is it too late?
Perhaps remove the else and grab the subdir name only once before doing comparisons.