diff options
Diffstat (limited to 'clang/lib/Driver/ToolChain.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChain.cpp | 111 |
1 files changed, 82 insertions, 29 deletions
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 7a4319ea680f..bc70205a6c01 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -36,6 +36,7 @@ #include "llvm/Option/Option.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FileUtilities.h" #include "llvm/Support/Path.h" #include "llvm/Support/TargetParser.h" #include "llvm/Support/VersionTuple.h" @@ -88,6 +89,33 @@ ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, addIfExists(getFilePaths(), getArchSpecificLibPath()); } +llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>> +ToolChain::executeToolChainProgram(StringRef Executable) const { + llvm::SmallString<64> OutputFile; + llvm::sys::fs::createTemporaryFile("toolchain-program", "txt", OutputFile); + llvm::FileRemover OutputRemover(OutputFile.c_str()); + std::optional<llvm::StringRef> Redirects[] = { + {""}, + OutputFile.str(), + {""}, + }; + + std::string ErrorMessage; + if (llvm::sys::ExecuteAndWait(Executable, {}, {}, Redirects, + /* SecondsToWait */ 0, + /*MemoryLimit*/ 0, &ErrorMessage)) + return llvm::createStringError(std::error_code(), + Executable + ": " + ErrorMessage); + + llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf = + llvm::MemoryBuffer::getFile(OutputFile.c_str()); + if (!OutputBuf) + return llvm::createStringError(OutputBuf.getError(), + "Failed to read stdout of " + Executable + + ": " + OutputBuf.getError().message()); + return std::move(*OutputBuf); +} + void ToolChain::setTripleEnvironment(llvm::Triple::EnvironmentType Env) { Triple.setEnvironment(Env); if (EffectiveTriple != llvm::Triple()) @@ -150,9 +178,9 @@ ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const { } const XRayArgs& ToolChain::getXRayArgs() const { - if (!XRayArguments.get()) + if (!XRayArguments) XRayArguments.reset(new XRayArgs(*this, Args)); - return *XRayArguments.get(); + return *XRayArguments; } namespace { @@ -185,11 +213,11 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) { {"clang-dxc", "--driver-mode=dxc"}, }; - for (size_t i = 0; i < llvm::array_lengthof(DriverSuffixes); ++i) { - StringRef Suffix(DriverSuffixes[i].Suffix); + for (const auto &DS : DriverSuffixes) { + StringRef Suffix(DS.Suffix); if (ProgName.endswith(Suffix)) { Pos = ProgName.size() - Suffix.size(); - return &DriverSuffixes[i]; + return &DS; } } return nullptr; @@ -198,7 +226,7 @@ static 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. static std::string normalizeProgramName(llvm::StringRef Argv0) { - std::string ProgName = std::string(llvm::sys::path::stem(Argv0)); + std::string ProgName = std::string(llvm::sys::path::filename(Argv0)); if (is_style_windows(llvm::sys::path::Style::native)) { // Transform to lowercase for case insensitive file systems. std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), @@ -217,6 +245,13 @@ static const DriverSuffix *parseDriverSuffix(StringRef ProgName, size_t &Pos) { // added via -target as implicit first argument. const DriverSuffix *DS = FindDriverSuffix(ProgName, Pos); + if (!DS && ProgName.endswith(".exe")) { + // Try again after stripping the executable suffix: + // clang++.exe -> clang++ + ProgName = ProgName.drop_back(StringRef(".exe").size()); + DS = FindDriverSuffix(ProgName, Pos); + } + if (!DS) { // Try again after stripping any trailing version number: // clang++3.5 -> clang++ @@ -287,8 +322,9 @@ std::string ToolChain::getInputFilename(const InputInfo &Input) const { return Input.getFilename(); } -bool ToolChain::IsUnwindTablesDefault(const ArgList &Args) const { - return false; +ToolChain::UnwindTableLevel +ToolChain::getDefaultUnwindTableLevel(const ArgList &Args) const { + return UnwindTableLevel::None; } Tool *ToolChain::getClang() const { @@ -351,12 +387,6 @@ Tool *ToolChain::getOffloadBundler() const { return OffloadBundler.get(); } -Tool *ToolChain::getOffloadWrapper() const { - if (!OffloadWrapper) - OffloadWrapper.reset(new tools::OffloadWrapper(*this)); - return OffloadWrapper.get(); -} - Tool *ToolChain::getOffloadPackager() const { if (!OffloadPackager) OffloadPackager.reset(new tools::OffloadPackager(*this)); @@ -393,7 +423,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { case Action::CompileJobClass: case Action::PrecompileJobClass: - case Action::HeaderModulePrecompileJobClass: case Action::PreprocessJobClass: case Action::ExtractAPIJobClass: case Action::AnalyzeJobClass: @@ -406,8 +435,6 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { case Action::OffloadUnbundlingJobClass: return getOffloadBundler(); - case Action::OffloadWrapperJobClass: - return getOffloadWrapper(); case Action::OffloadPackagerJobClass: return getOffloadPackager(); case Action::LinkerWrapperJobClass: @@ -422,6 +449,9 @@ static StringRef getArchNameForCompilerRTLib(const ToolChain &TC, const llvm::Triple &Triple = TC.getTriple(); bool IsWindows = Triple.isOSWindows(); + if (TC.isBareMetal()) + return Triple.getArchName(); + if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) return (arm::getARMFloatABI(TC, Args) == arm::FloatABI::Hard && !IsWindows) ? "armhf" @@ -459,7 +489,10 @@ StringRef ToolChain::getOSLibName() const { std::string ToolChain::getCompilerRTPath() const { SmallString<128> Path(getDriver().ResourceDir); - if (Triple.isOSUnknown()) { + if (isBareMetal()) { + llvm::sys::path::append(Path, "lib", getOSLibName()); + Path += SelectedMultilib.gccSuffix(); + } else if (Triple.isOSUnknown()) { llvm::sys::path::append(Path, "lib"); } else { llvm::sys::path::append(Path, "lib", getOSLibName()); @@ -622,13 +655,18 @@ std::string ToolChain::GetLinkerPath(bool *LinkerIsLLD) const { // --ld-path= takes precedence over -fuse-ld= and specifies the executable // name. -B, COMPILER_PATH and PATH and consulted if the value does not // contain a path component separator. + // -fuse-ld=lld can be used with --ld-path= to inform clang that the binary + // that --ld-path= points to is lld. if (const Arg *A = Args.getLastArg(options::OPT_ld_path_EQ)) { std::string Path(A->getValue()); if (!Path.empty()) { if (llvm::sys::path::parent_path(Path).empty()) Path = GetProgramPath(A->getValue()); - if (llvm::sys::fs::can_execute(Path)) + if (llvm::sys::fs::can_execute(Path)) { + if (LinkerIsLLD) + *LinkerIsLLD = UseLinker == "lld"; return std::string(Path); + } } getDriver().Diag(diag::err_drv_invalid_linker_name) << A->getAsString(Args); return GetProgramPath(getDefaultLinker()); @@ -805,6 +843,9 @@ void ToolChain::addClangTargetOptions( const ArgList &DriverArgs, ArgStringList &CC1Args, Action::OffloadKind DeviceOffloadKind) const {} +void ToolChain::addClangCC1ASTargetOptions(const ArgList &Args, + ArgStringList &CC1ASArgs) const {} + void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {} void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args, @@ -991,8 +1032,15 @@ void ToolChain::AddClangCXXStdlibIsystemArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { DriverArgs.ClaimAllArgs(options::OPT_stdlibxx_isystem); - if (!DriverArgs.hasArg(options::OPT_nostdinc, options::OPT_nostdincxx, - options::OPT_nostdlibinc)) + // This intentionally only looks at -nostdinc++, and not -nostdinc or + // -nostdlibinc. The purpose of -stdlib++-isystem is to support toolchain + // setups with non-standard search logic for the C++ headers, while still + // allowing users of the toolchain to bring their own C++ headers. Such a + // toolchain likely also has non-standard search logic for the C headers and + // uses -nostdinc to suppress the default logic, but -stdlib++-isystem should + // still work in that case and only be suppressed by an explicit -nostdinc++ + // in a project using the toolchain. + if (!DriverArgs.hasArg(options::OPT_nostdincxx)) for (const auto &P : DriverArgs.getAllArgValues(options::OPT_stdlibxx_isystem)) addSystemInclude(DriverArgs, CC1Args, P); @@ -1066,6 +1114,11 @@ bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args, return false; } +Expected<SmallVector<std::string>> +ToolChain::getSystemGPUArchs(const llvm::opt::ArgList &Args) const { + return SmallVector<std::string>(); +} + SanitizerMask ToolChain::getSupportedSanitizers() const { // Return sanitizers which don't require runtime support and are not // platform dependent. @@ -1075,7 +1128,7 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { ~SanitizerKind::Function) | (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero | - SanitizerKind::UnsignedIntegerOverflow | + SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow | SanitizerKind::UnsignedShiftBase | SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | SanitizerKind::LocalBounds; if (getTriple().getArch() == llvm::Triple::x86 || @@ -1098,7 +1151,7 @@ void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const {} llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12> -ToolChain::getHIPDeviceLibs(const ArgList &DriverArgs) const { +ToolChain::getDeviceLibs(const ArgList &DriverArgs) const { return {}; } @@ -1280,17 +1333,17 @@ llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs( DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); bool Modified = false; - bool IsGPU = OFK == Action::OFK_Cuda || OFK == Action::OFK_HIP; + bool IsDevice = OFK != Action::OFK_None && OFK != Action::OFK_Host; for (Arg *A : Args) { bool NeedTrans = false; bool Skip = false; if (A->getOption().matches(options::OPT_Xarch_device)) { - NeedTrans = IsGPU; - Skip = !IsGPU; + NeedTrans = IsDevice; + Skip = !IsDevice; } else if (A->getOption().matches(options::OPT_Xarch_host)) { - NeedTrans = !IsGPU; - Skip = IsGPU; - } else if (A->getOption().matches(options::OPT_Xarch__) && IsGPU) { + NeedTrans = !IsDevice; + Skip = IsDevice; + } else if (A->getOption().matches(options::OPT_Xarch__) && IsDevice) { // Do not translate -Xarch_ options for non CUDA/HIP toolchain since // they may need special translation. // Skip this argument unless the architecture matches BoundArch |