diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-07-28 11:06:01 +0000 |
commit | 486754660bb926339aefcf012a3f848592babb8b (patch) | |
tree | ecdbc446c9876f4f120f701c243373cd3cb43db3 /lib/Driver/ToolChain.cpp | |
parent | 55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff) |
Notes
Diffstat (limited to 'lib/Driver/ToolChain.cpp')
-rw-r--r-- | lib/Driver/ToolChain.cpp | 124 |
1 files changed, 76 insertions, 48 deletions
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index f96a1182e3cab..d62ba1253348f 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -1,4 +1,4 @@ -//===--- ToolChain.cpp - Collections of tools for one platform ------------===// +//===- ToolChain.cpp - Collections of tools for one platform --------------===// // // The LLVM Compiler Infrastructure // @@ -8,33 +8,45 @@ //===----------------------------------------------------------------------===// #include "clang/Driver/ToolChain.h" -#include "ToolChains/CommonArgs.h" +#include "InputInfo.h" #include "ToolChains/Arch/ARM.h" #include "ToolChains/Clang.h" #include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/Sanitizers.h" #include "clang/Basic/VirtualFileSystem.h" #include "clang/Config/config.h" #include "clang/Driver/Action.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Job.h" #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" #include "clang/Driver/XRayArgs.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/MC/MCTargetOptions.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" +#include "llvm/Option/OptTable.h" #include "llvm/Option/Option.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/VersionTuple.h" +#include <cassert> +#include <cstddef> +#include <cstring> +#include <string> -using namespace clang::driver; -using namespace clang::driver::tools; using namespace clang; +using namespace driver; +using namespace tools; using namespace llvm; using namespace llvm::opt; @@ -49,33 +61,24 @@ static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args, // Explicit rtti/no-rtti args if (CachedRTTIArg) { if (CachedRTTIArg->getOption().matches(options::OPT_frtti)) - return ToolChain::RM_EnabledExplicitly; + return ToolChain::RM_Enabled; else - return ToolChain::RM_DisabledExplicitly; + return ToolChain::RM_Disabled; } // -frtti is default, except for the PS4 CPU. - if (!Triple.isPS4CPU()) - return ToolChain::RM_EnabledImplicitly; - - // On the PS4, turning on c++ exceptions turns on rtti. - // We're assuming that, if we see -fexceptions, rtti gets turned on. - Arg *Exceptions = Args.getLastArgNoClaim( - options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions, - options::OPT_fexceptions, options::OPT_fno_exceptions); - if (Exceptions && - (Exceptions->getOption().matches(options::OPT_fexceptions) || - Exceptions->getOption().matches(options::OPT_fcxx_exceptions))) - return ToolChain::RM_EnabledImplicitly; - - return ToolChain::RM_DisabledImplicitly; + return (Triple.isPS4CPU()) ? ToolChain::RM_Disabled : ToolChain::RM_Enabled; } ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, const ArgList &Args) : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)), - CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)), - EffectiveTriple() { + CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, D.getTargetTriple(), "lib"); + if (getVFS().exists(P)) + getFilePaths().push_back(P.str()); + std::string CandidateLibPath = getArchSpecificLibPath(); if (getVFS().exists(CandidateLibPath)) getFilePaths().push_back(CandidateLibPath); @@ -87,8 +90,7 @@ void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) { EffectiveTriple.setEnvironment(Env); } -ToolChain::~ToolChain() { -} +ToolChain::~ToolChain() = default; vfs::FileSystem &ToolChain::getVFS() const { return getDriver().getVFS(); } @@ -115,12 +117,15 @@ const XRayArgs& ToolChain::getXRayArgs() const { } namespace { + struct DriverSuffix { const char *Suffix; const char *ModeFlag; }; -const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) { +} // namespace + +static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) { // A list of known driver suffixes. Suffixes are compared against the // program name in order. If there is a match, the frontend type is updated as // necessary by applying the ModeFlag. @@ -151,16 +156,16 @@ const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) { /// Normalize the program name from argv[0] by stripping the file extension if /// present and lower-casing the string on Windows. -std::string normalizeProgramName(llvm::StringRef Argv0) { +static std::string normalizeProgramName(llvm::StringRef Argv0) { std::string ProgName = llvm::sys::path::stem(Argv0); -#ifdef LLVM_ON_WIN32 +#ifdef _WIN32 // Transform to lowercase for case insensitive file systems. std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower); #endif return ProgName; } -const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) { +static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) { // Try to infer frontend type and default target from the program name by // comparing it against DriverSuffixes in order. @@ -185,7 +190,6 @@ const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) { } return DS; } -} // anonymous namespace ParsedClangName ToolChain::getTargetAndModeFromProgramName(StringRef PN) { @@ -193,7 +197,7 @@ ToolChain::getTargetAndModeFromProgramName(StringRef PN) { size_t SuffixPos; const DriverSuffix *DS = parseDriverSuffix(ProgName, SuffixPos); if (!DS) - return ParsedClangName(); + return {}; size_t SuffixEnd = SuffixPos + strlen(DS->Suffix); size_t LastComponent = ProgName.rfind('-', SuffixPos); @@ -323,13 +327,27 @@ static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, return llvm::Triple::getArchTypeName(TC.getArch()); } +StringRef ToolChain::getOSLibName() const { + switch (Triple.getOS()) { + case llvm::Triple::FreeBSD: + return "freebsd"; + case llvm::Triple::NetBSD: + return "netbsd"; + case llvm::Triple::OpenBSD: + return "openbsd"; + case llvm::Triple::Solaris: + return "sunos"; + default: + return getOS(); + } +} + std::string ToolChain::getCompilerRTPath() const { SmallString<128> Path(getDriver().ResourceDir); if (Triple.isOSUnknown()) { llvm::sys::path::append(Path, "lib"); } else { - StringRef OSLibName = Triple.isOSFreeBSD() ? "freebsd" : getOS(); - llvm::sys::path::append(Path, "lib", OSLibName); + llvm::sys::path::append(Path, "lib", getOSLibName()); } return Path.str(); } @@ -337,15 +355,23 @@ std::string ToolChain::getCompilerRTPath() const { std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, bool Shared) const { const llvm::Triple &TT = getTriple(); - const char *Env = TT.isAndroid() ? "-android" : ""; bool IsITANMSVCWindows = TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment(); - StringRef Arch = getArchNameForCompilerRTLib(*this, Args); const char *Prefix = IsITANMSVCWindows ? "" : "lib"; const char *Suffix = Shared ? (Triple.isOSWindows() ? ".dll" : ".so") : (IsITANMSVCWindows ? ".lib" : ".a"); + const Driver &D = getDriver(); + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, D.getTargetTriple(), "lib"); + if (getVFS().exists(P)) { + llvm::sys::path::append(P, Prefix + Twine("clang_rt.") + Component + Suffix); + return P.str(); + } + + StringRef Arch = getArchNameForCompilerRTLib(*this, Args); + const char *Env = TT.isAndroid() ? "-android" : ""; SmallString<128> Path(getCompilerRTPath()); llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" + Arch + Env + Suffix); @@ -360,8 +386,7 @@ const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, std::string ToolChain::getArchSpecificLibPath() const { SmallString<128> Path(getDriver().ResourceDir); - StringRef OSLibName = getTriple().isOSFreeBSD() ? "freebsd" : getOS(); - llvm::sys::path::append(Path, "lib", OSLibName, + llvm::sys::path::append(Path, "lib", getOSLibName(), llvm::Triple::getArchTypeName(getArch())); return Path.str(); } @@ -403,7 +428,7 @@ std::string ToolChain::GetLinkerPath() const { if (llvm::sys::path::is_absolute(UseLinker)) { // If we're passed what looks like an absolute path, don't attempt to // second-guess that. - if (llvm::sys::fs::exists(UseLinker)) + if (llvm::sys::fs::can_execute(UseLinker)) return UseLinker; } else if (UseLinker.empty() || UseLinker == "ld") { // If we're passed -fuse-ld= with no argument, or with the argument ld, @@ -418,7 +443,7 @@ std::string ToolChain::GetLinkerPath() const { LinkerName.append(UseLinker); std::string LinkerPath(GetProgramPath(LinkerName.c_str())); - if (llvm::sys::fs::exists(LinkerPath)) + if (llvm::sys::fs::can_execute(LinkerPath)) return LinkerPath; } @@ -459,8 +484,6 @@ ObjCRuntime ToolChain::getDefaultObjCRuntime(bool isNonFragile) const { llvm::ExceptionHandling ToolChain::GetExceptionModel(const llvm::opt::ArgList &Args) const { - if (Triple.isOSWindows() && Triple.getArch() != llvm::Triple::x86) - return llvm::ExceptionHandling::WinEH; return llvm::ExceptionHandling::None; } @@ -576,7 +599,7 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, // CollectArgsForIntegratedAssembler but we can't change the ArchName at // that point. There is no assembler equivalent of -mno-thumb, -marm, or // -mno-arm. - for (const Arg *A : + for (const auto *A : Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { for (StringRef Value : A->getValues()) { if (Value == "-mthumb") @@ -660,7 +683,7 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ return GetDefaultCXXStdlibType(); } -/// \brief Utility function to add a system include directory to CC1 arguments. +/// Utility function to add a system include directory to CC1 arguments. /*static*/ void ToolChain::addSystemInclude(const ArgList &DriverArgs, ArgStringList &CC1Args, const Twine &Path) { @@ -668,7 +691,7 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ CC1Args.push_back(DriverArgs.MakeArgString(Path)); } -/// \brief Utility function to add a system include directory with extern "C" +/// Utility function to add a system include directory with extern "C" /// semantics to CC1 arguments. /// /// Note that this should be used rarely, and only for directories that @@ -690,11 +713,11 @@ void ToolChain::addExternCSystemIncludeIfExists(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, Path); } -/// \brief Utility function to add a list of system include directories to CC1. +/// Utility function to add a list of system include directories to CC1. /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs, ArgStringList &CC1Args, ArrayRef<StringRef> Paths) { - for (StringRef Path : Paths) { + for (const auto Path : Paths) { CC1Args.push_back("-internal-isystem"); CC1Args.push_back(DriverArgs.MakeArgString(Path)); } @@ -776,7 +799,9 @@ bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args, SanitizerMask ToolChain::getSupportedSanitizers() const { // Return sanitizers which don't require runtime support and are not // platform dependent. + using namespace SanitizerKind; + SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) | CFICastStrict | UnsignedIntegerOverflow | Nullability | LocalBounds; @@ -787,6 +812,9 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { getTriple().getArch() == llvm::Triple::wasm32 || getTriple().getArch() == llvm::Triple::wasm64) Res |= CFIICall; + if (getTriple().getArch() == llvm::Triple::x86_64 || + getTriple().getArch() == llvm::Triple::aarch64) + Res |= ShadowCallStack; return Res; } @@ -858,7 +886,7 @@ llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs( bool Modified = false; // Handle -Xopenmp-target flags - for (Arg *A : Args) { + for (auto *A : Args) { // Exclude flags which may only apply to the host toolchain. // Do not exclude flags when the host triple (AuxTriple) // matches the current toolchain triple. If it is not present |