diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains/MSVC.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains/MSVC.cpp | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 6b3c00e2ab6d..f4b7a57e0bb7 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -66,6 +66,20 @@ using namespace llvm::opt; static bool getSystemRegistryString(const char *keyPath, const char *valueName, std::string &value, std::string *phValue); +// Check command line arguments to try and find a toolchain. +static bool +findVCToolChainViaCommandLine(const ArgList &Args, std::string &Path, + MSVCToolChain::ToolsetLayout &VSLayout) { + // Don't validate the input; trust the value supplied by the user. + // The primary motivation is to prevent unnecessary file and registry access. + if (Arg *A = Args.getLastArg(options::OPT__SLASH_vctoolsdir)) { + Path = A->getValue(); + VSLayout = MSVCToolChain::ToolsetLayout::VS2017OrNewer; + return true; + } + return false; +} + // Check various environment variables to try and find a toolchain. static bool findVCToolChainViaEnvironment(std::string &Path, MSVCToolChain::ToolsetLayout &VSLayout) { @@ -319,8 +333,10 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(std::string("-out:") + Output.getFilename())); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && - !C.getDriver().IsCLMode()) + !C.getDriver().IsCLMode()) { CmdArgs.push_back("-defaultlib:libcmt"); + CmdArgs.push_back("-defaultlib:oldnames"); + } if (!llvm::sys::Process::GetEnv("LIB")) { // If the VC environment hasn't been configured (perhaps because the user @@ -366,8 +382,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-nologo"); - if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7, - options::OPT__SLASH_Zd)) + if (Args.hasArg(options::OPT_g_Group, options::OPT__SLASH_Z7)) CmdArgs.push_back("-debug"); // Pass on /Brepro if it was passed to the compiler. @@ -592,9 +607,9 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, linkPath = TC.GetProgramPath(Linker.str().c_str()); } - auto LinkCmd = - std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileUTF16(), - Args.MakeArgString(linkPath), CmdArgs, Inputs); + auto LinkCmd = std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileUTF16(), + Args.MakeArgString(linkPath), CmdArgs, Inputs, Output); if (!Environment.empty()) LinkCmd->setEnvironment(Environment); C.addCommand(std::move(LinkCmd)); @@ -734,9 +749,9 @@ std::unique_ptr<Command> visualstudio::Compiler::GetCommand( CmdArgs.push_back(Fo); std::string Exec = FindVisualStudioExecutable(getToolChain(), "cl.exe"); - return std::make_unique<Command>(JA, *this, - ResponseFileSupport::AtFileUTF16(), - Args.MakeArgString(Exec), CmdArgs, Inputs); + return std::make_unique<Command>( + JA, *this, ResponseFileSupport::AtFileUTF16(), Args.MakeArgString(Exec), + CmdArgs, Inputs, Output); } MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, @@ -747,11 +762,12 @@ MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple, if (getDriver().getInstalledDir() != getDriver().Dir) getProgramPaths().push_back(getDriver().Dir); - // Check the environment first, since that's probably the user telling us - // what they want to use. - // Failing that, just try to find the newest Visual Studio version we can - // and use its default VC toolchain. - findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) || + // Check the command line first, that's the user explicitly telling us what to + // use. Check the environment next, in case we're being invoked from a VS + // command prompt. Failing that, just try to find the newest Visual Studio + // version we can and use its default VC toolchain. + findVCToolChainViaCommandLine(Args, VCToolChainPath, VSLayout) || + findVCToolChainViaEnvironment(VCToolChainPath, VSLayout) || findVCToolChainViaSetupConfig(VCToolChainPath, VSLayout) || findVCToolChainViaRegistry(VCToolChainPath, VSLayout); } @@ -1263,15 +1279,18 @@ void MSVCToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, return; // Honor %INCLUDE%. It should know essential search paths with vcvarsall.bat. - if (llvm::Optional<std::string> cl_include_dir = - llvm::sys::Process::GetEnv("INCLUDE")) { - SmallVector<StringRef, 8> Dirs; - StringRef(*cl_include_dir) - .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false); - for (StringRef Dir : Dirs) - addSystemInclude(DriverArgs, CC1Args, Dir); - if (!Dirs.empty()) - return; + // Skip if the user expressly set a vctoolsdir + if (!DriverArgs.getLastArg(options::OPT__SLASH_vctoolsdir)) { + if (llvm::Optional<std::string> cl_include_dir = + llvm::sys::Process::GetEnv("INCLUDE")) { + SmallVector<StringRef, 8> Dirs; + StringRef(*cl_include_dir) + .split(Dirs, ";", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + for (StringRef Dir : Dirs) + addSystemInclude(DriverArgs, CC1Args, Dir); + if (!Dirs.empty()) + return; + } } // When built with access to the proper Windows APIs, try to actually find |