diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Driver/MSVCToolChain.cpp | 40 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChain.cpp | 54 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.h | 7 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 72 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.h | 4 |
5 files changed, 93 insertions, 84 deletions
diff --git a/clang/lib/Driver/MSVCToolChain.cpp b/clang/lib/Driver/MSVCToolChain.cpp index c6902fabe98..95cf056f7a7 100644 --- a/clang/lib/Driver/MSVCToolChain.cpp +++ b/clang/lib/Driver/MSVCToolChain.cpp @@ -16,6 +16,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" @@ -472,6 +473,14 @@ bool MSVCToolChain::getVisualStudioBinariesFolder(const char *clangProgramPath, return true; } +VersionTuple MSVCToolChain::getMSVCVersionFromTriple() const { + unsigned Major, Minor, Micro; + getTriple().getEnvironmentVersion(Major, Minor, Micro); + if (Major || Minor || Micro) + return VersionTuple(Major, Minor, Micro); + return VersionTuple(); +} + VersionTuple MSVCToolChain::getMSVCVersionFromExe() const { VersionTuple Version; #ifdef USE_WIN32 @@ -668,21 +677,34 @@ void MSVCToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, // FIXME: There should probably be logic here to find libc++ on Windows. } +VersionTuple MSVCToolChain::computeMSVCVersion(const Driver *D, + const ArgList &Args) const { + bool IsWindowsMSVC = getTriple().isWindowsMSVCEnvironment(); + VersionTuple MSVT = ToolChain::computeMSVCVersion(D, Args); + if (MSVT.empty()) MSVT = getMSVCVersionFromTriple(); + if (MSVT.empty() && IsWindowsMSVC) MSVT = getMSVCVersionFromExe(); + if (MSVT.empty() && + Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, + IsWindowsMSVC)) { + // -fms-compatibility-version=18.00 is default. + // FIXME: Consider bumping this to 19 (MSVC2015) soon. + MSVT = VersionTuple(18); + } + return MSVT; +} + std::string MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args, types::ID InputType) const { - std::string TripleStr = - ToolChain::ComputeEffectiveClangTriple(Args, InputType); - llvm::Triple Triple(TripleStr); - VersionTuple MSVT = - tools::visualstudio::getMSVCVersion(/*D=*/nullptr, *this, Triple, Args, - /*IsWindowsMSVC=*/true); - if (MSVT.empty()) - return TripleStr; - + // The MSVC version doesn't care about the architecture, even though it + // may look at the triple internally. + VersionTuple MSVT = computeMSVCVersion(/*D=*/nullptr, Args); MSVT = VersionTuple(MSVT.getMajor(), MSVT.getMinor().getValueOr(0), MSVT.getSubminor().getValueOr(0)); + // For the rest of the triple, however, a computed architecture name may + // be needed. + llvm::Triple Triple(ToolChain::ComputeEffectiveClangTriple(Args, InputType)); if (Triple.getEnvironment() == llvm::Triple::MSVC) { StringRef ObjFmt = Triple.getEnvironmentName().split('-').second; if (ObjFmt.empty()) diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 262eec12e09..5c6d0625835 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -721,3 +721,57 @@ void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs, void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const {} + +static VersionTuple separateMSVCFullVersion(unsigned Version) { + if (Version < 100) + return VersionTuple(Version); + + if (Version < 10000) + return VersionTuple(Version / 100, Version % 100); + + unsigned Build = 0, Factor = 1; + for (; Version > 10000; Version = Version / 10, Factor = Factor * 10) + Build = Build + (Version % 10) * Factor; + return VersionTuple(Version / 100, Version % 100, Build); +} + +VersionTuple +ToolChain::computeMSVCVersion(const Driver *D, + const llvm::opt::ArgList &Args) const { + const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version); + const Arg *MSCompatibilityVersion = + Args.getLastArg(options::OPT_fms_compatibility_version); + + if (MSCVersion && MSCompatibilityVersion) { + if (D) + D->Diag(diag::err_drv_argument_not_allowed_with) + << MSCVersion->getAsString(Args) + << MSCompatibilityVersion->getAsString(Args); + return VersionTuple(); + } + + if (MSCompatibilityVersion) { + VersionTuple MSVT; + if (MSVT.tryParse(MSCompatibilityVersion->getValue())) { + if (D) + D->Diag(diag::err_drv_invalid_value) + << MSCompatibilityVersion->getAsString(Args) + << MSCompatibilityVersion->getValue(); + } else { + return MSVT; + } + } + + if (MSCVersion) { + unsigned Version = 0; + if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version)) { + if (D) + D->Diag(diag::err_drv_invalid_value) + << MSCVersion->getAsString(Args) << MSCVersion->getValue(); + } else { + return separateMSVCFullVersion(Version); + } + } + + return VersionTuple(); +} diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index 1c1ee21c6d6..2abbd037281 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -1140,7 +1140,9 @@ public: bool getVisualStudioInstallDir(std::string &path) const; bool getVisualStudioBinariesFolder(const char *clangProgramPath, std::string &path) const; - VersionTuple getMSVCVersionFromExe() const override; + VersionTuple + computeMSVCVersion(const Driver *D, + const llvm::opt::ArgList &Args) const override; std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType) const override; @@ -1156,6 +1158,9 @@ protected: Tool *buildLinker() const override; Tool *buildAssembler() const override; +private: + VersionTuple getMSVCVersionFromTriple() const; + VersionTuple getMSVCVersionFromExe() const; }; class LLVM_LIBRARY_VISIBILITY CrossWindowsToolChain : public Generic_GCC { diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 8a38fc8896a..ae38723fd7b 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -3552,19 +3552,6 @@ static void addDashXForInput(const ArgList &Args, const InputInfo &Input, CmdArgs.push_back(types::getTypeName(Input.getType())); } -static VersionTuple getMSCompatibilityVersion(unsigned Version) { - if (Version < 100) - return VersionTuple(Version); - - if (Version < 10000) - return VersionTuple(Version / 100, Version % 100); - - unsigned Build = 0, Factor = 1; - for (; Version > 10000; Version = Version / 10, Factor = Factor * 10) - Build = Build + (Version % 10) * Factor; - return VersionTuple(Version / 100, Version % 100, Build); -} - // Claim options we don't want to warn if they are unused. We do this for // options that build systems might add but are unused when assembling or only // running the preprocessor for example. @@ -3608,60 +3595,6 @@ static void appendUserToPath(SmallVectorImpl<char> &Result) { Result.append(UID.begin(), UID.end()); } -VersionTuple visualstudio::getMSVCVersion(const Driver *D, const ToolChain &TC, - const llvm::Triple &Triple, - const llvm::opt::ArgList &Args, - bool IsWindowsMSVC) { - if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, - IsWindowsMSVC) || - Args.hasArg(options::OPT_fmsc_version) || - Args.hasArg(options::OPT_fms_compatibility_version)) { - const Arg *MSCVersion = Args.getLastArg(options::OPT_fmsc_version); - const Arg *MSCompatibilityVersion = - Args.getLastArg(options::OPT_fms_compatibility_version); - - if (MSCVersion && MSCompatibilityVersion) { - if (D) - D->Diag(diag::err_drv_argument_not_allowed_with) - << MSCVersion->getAsString(Args) - << MSCompatibilityVersion->getAsString(Args); - return VersionTuple(); - } - - if (MSCompatibilityVersion) { - VersionTuple MSVT; - if (MSVT.tryParse(MSCompatibilityVersion->getValue()) && D) - D->Diag(diag::err_drv_invalid_value) - << MSCompatibilityVersion->getAsString(Args) - << MSCompatibilityVersion->getValue(); - return MSVT; - } - - if (MSCVersion) { - unsigned Version = 0; - if (StringRef(MSCVersion->getValue()).getAsInteger(10, Version) && D) - D->Diag(diag::err_drv_invalid_value) << MSCVersion->getAsString(Args) - << MSCVersion->getValue(); - return getMSCompatibilityVersion(Version); - } - - unsigned Major, Minor, Micro; - Triple.getEnvironmentVersion(Major, Minor, Micro); - if (Major || Minor || Micro) - return VersionTuple(Major, Minor, Micro); - - if (IsWindowsMSVC) { - VersionTuple MSVT = TC.getMSVCVersionFromExe(); - if (!MSVT.empty()) - return MSVT; - - // FIXME: Consider bumping this to 19 (MSVC2015) soon. - return VersionTuple(18); - } - } - return VersionTuple(); -} - static Arg *getLastProfileUseArg(const ArgList &Args) { auto *ProfileUseArg = Args.getLastArg( options::OPT_fprofile_instr_use, options::OPT_fprofile_instr_use_EQ, @@ -5867,9 +5800,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_ms_extensions, true)))) CmdArgs.push_back("-fms-compatibility"); - // -fms-compatibility-version=18.00 is default. - VersionTuple MSVT = visualstudio::getMSVCVersion( - &D, getToolChain(), getToolChain().getTriple(), Args, IsWindowsMSVC); + VersionTuple MSVT = + getToolChain().computeMSVCVersion(&getToolChain().getDriver(), Args); if (!MSVT.empty()) CmdArgs.push_back( Args.MakeArgString("-fms-compatibility-version=" + MSVT.getAsString())); diff --git a/clang/lib/Driver/Tools.h b/clang/lib/Driver/Tools.h index 4aa92b7dc2e..98dcf841169 100644 --- a/clang/lib/Driver/Tools.h +++ b/clang/lib/Driver/Tools.h @@ -725,10 +725,6 @@ public: /// Visual studio tools. namespace visualstudio { -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 { public: Linker(const ToolChain &TC) |