diff options
Diffstat (limited to 'lib/Driver/Driver.cpp')
-rw-r--r-- | lib/Driver/Driver.cpp | 115 |
1 files changed, 71 insertions, 44 deletions
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index a784e218f1..06c0e3bdb3 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1,9 +1,8 @@ //===--- Driver.cpp - Clang GCC Compatible Driver -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -39,6 +38,7 @@ #include "ToolChains/NetBSD.h" #include "ToolChains/OpenBSD.h" #include "ToolChains/PS4CPU.h" +#include "ToolChains/PPCLinux.h" #include "ToolChains/RISCVToolchain.h" #include "ToolChains/Solaris.h" #include "ToolChains/TCE.h" @@ -90,6 +90,33 @@ using namespace clang::driver; using namespace clang; using namespace llvm::opt; +// static +std::string Driver::GetResourcesPath(StringRef BinaryPath, + StringRef CustomResourceDir) { + // Since the resource directory is embedded in the module hash, it's important + // that all places that need it call this function, so that they get the + // exact same string ("a/../b/" and "b/" get different hashes, for example). + + // Dir is bin/ or lib/, depending on where BinaryPath is. + std::string Dir = llvm::sys::path::parent_path(BinaryPath); + + SmallString<128> P(Dir); + if (CustomResourceDir != "") { + llvm::sys::path::append(P, CustomResourceDir); + } else { + // On Windows, libclang.dll is in bin/. + // On non-Windows, libclang.so/.dylib is in lib/. + // With a static-library build of libclang, LibClangPath will contain the + // path of the embedding binary, which for LLVM binaries will be in bin/. + // ../lib gets us to lib/ in both cases. + P = llvm::sys::path::parent_path(Dir); + llvm::sys::path::append(P, Twine("lib") + CLANG_LIBDIR_SUFFIX, "clang", + CLANG_VERSION_STRING); + } + + return P.str(); +} + Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) @@ -120,17 +147,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, #endif // Compute the path to the resource directory. - StringRef ClangResourceDir(CLANG_RESOURCE_DIR); - SmallString<128> P(Dir); - if (ClangResourceDir != "") { - llvm::sys::path::append(P, ClangResourceDir); - } else { - StringRef ClangLibdirSuffix(CLANG_LIBDIR_SUFFIX); - P = llvm::sys::path::parent_path(Dir); - llvm::sys::path::append(P, Twine("lib") + ClangLibdirSuffix, "clang", - CLANG_VERSION_STRING); - } - ResourceDir = P.str(); + ResourceDir = GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR); } void Driver::ParseDriverMode(StringRef ProgramName, @@ -230,8 +247,9 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings, : diag::err_drv_unknown_argument; Diags.Report(DiagID) << ArgString; } else { - DiagID = IsCLMode() ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion - : diag::err_drv_unknown_argument_with_suggestion; + DiagID = IsCLMode() + ? diag::warn_drv_unknown_argument_clang_cl_with_suggestion + : diag::err_drv_unknown_argument_with_suggestion; Diags.Report(DiagID) << ArgString << Nearest; } ContainsError |= Diags.getDiagnosticLevel(DiagID, SourceLocation()) > @@ -1401,11 +1419,13 @@ void Driver::generateCompilationDiagnostics( } void Driver::setUpResponseFiles(Compilation &C, Command &Cmd) { - // Since commandLineFitsWithinSystemLimits() may underestimate system's capacity - // if the tool does not support response files, there is a chance/ that things - // will just work without a response file, so we silently just skip it. + // Since commandLineFitsWithinSystemLimits() may underestimate system's + // capacity if the tool does not support response files, there is a chance/ + // that things will just work without a response file, so we silently just + // skip it. if (Cmd.getCreator().getResponseFilesSupport() == Tool::RF_None || - llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(), Cmd.getArguments())) + llvm::sys::commandLineFitsWithinSystemLimits(Cmd.getExecutable(), + Cmd.getArguments())) return; std::string TmpName = GetTemporaryPath("response", "txt"); @@ -1559,8 +1579,7 @@ void Driver::HandleAutocompletions(StringRef PassedFlags) const { // We want to show cc1-only options only when clang is invoked with -cc1 or // -Xclang. - if (std::find(Flags.begin(), Flags.end(), "-Xclang") != Flags.end() || - std::find(Flags.begin(), Flags.end(), "-cc1") != Flags.end()) + if (llvm::is_contained(Flags, "-Xclang") || llvm::is_contained(Flags, "-cc1")) DisableFlags &= ~options::NoDriverOption; StringRef Cur; @@ -1625,11 +1644,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { if (C.getArgs().hasArg(options::OPT_dumpversion)) { // Since -dumpversion is only implemented for pedantic GCC compatibility, we // return an answer which matches our definition of __VERSION__. - // - // If we want to return a more correct answer some day, then we should - // introduce a non-pedantically GCC compatible mode to Clang in which we - // provide sensible definitions for -dumpversion, __VERSION__, etc. - llvm::outs() << "4.2.1\n"; + llvm::outs() << CLANG_VERSION_STRING << "\n"; return false; } @@ -1680,7 +1695,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { bool separator = false; for (const std::string &Path : TC.getProgramPaths()) { if (separator) - llvm::outs() << ':'; + llvm::outs() << llvm::sys::EnvPathSeparator; llvm::outs() << Path; separator = true; } @@ -1691,7 +1706,7 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { for (const std::string &Path : TC.getFilePaths()) { // Always print a separator. ResourceDir was the first item shown. - llvm::outs() << ':'; + llvm::outs() << llvm::sys::EnvPathSeparator; // Interpretation of leading '=' is needed only for NetBSD. if (Path[0] == '=') llvm::outs() << sysroot << Path.substr(1); @@ -2019,7 +2034,8 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, Arg *Previous = nullptr; bool ShowNote = false; - for (Arg *A : Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { + for (Arg *A : + Args.filtered(options::OPT__SLASH_TC, options::OPT__SLASH_TP)) { if (Previous) { Diag(clang::diag::warn_drv_overriding_flag_option) << Previous->getSpelling() << A->getSpelling(); @@ -2278,6 +2294,9 @@ class OffloadingActionBuilder final { /// Flag that is set to true if this builder acted on the current input. bool IsActive = false; + + /// Flag for -fgpu-rdc. + bool Relocatable = false; public: CudaActionBuilderBase(Compilation &C, DerivedArgList &Args, const Driver::InputList &Inputs, @@ -2323,6 +2342,12 @@ class OffloadingActionBuilder final { // If this is an unbundling action use it as is for each CUDA toolchain. if (auto *UA = dyn_cast<OffloadUnbundlingJobAction>(HostAction)) { + + // If -fgpu-rdc is disabled, should not unbundle since there is no + // device code to link. + if (!Relocatable) + return ABRT_Inactive; + CudaDeviceActions.clear(); auto *IA = cast<InputAction>(UA->getInputs().back()); std::string FileName = IA->getInputArg().getAsString(Args); @@ -2394,6 +2419,9 @@ class OffloadingActionBuilder final { !C.hasOffloadToolChain<Action::OFK_HIP>()) return false; + Relocatable = Args.hasFlag(options::OPT_fgpu_rdc, + options::OPT_fno_gpu_rdc, /*Default=*/false); + const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>(); assert(HostTC && "No toolchain for host compilation."); if (HostTC->getTriple().isNVPTX() || @@ -2579,13 +2607,11 @@ class OffloadingActionBuilder final { class HIPActionBuilder final : public CudaActionBuilderBase { /// The linker inputs obtained for each device arch. SmallVector<ActionList, 8> DeviceLinkerInputs; - bool Relocatable; public: HIPActionBuilder(Compilation &C, DerivedArgList &Args, const Driver::InputList &Inputs) - : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP), - Relocatable(false) {} + : CudaActionBuilderBase(C, Args, Inputs, Action::OFK_HIP) {} bool canUseBundlerUnbundler() const override { return true; } @@ -2690,13 +2716,6 @@ class OffloadingActionBuilder final { ++I; } } - - bool initialize() override { - Relocatable = Args.hasFlag(options::OPT_fgpu_rdc, - options::OPT_fno_gpu_rdc, /*Default=*/false); - - return CudaActionBuilderBase::initialize(); - } }; /// OpenMP action builder. The host bitcode is passed to the device frontend @@ -4244,10 +4263,12 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, Arg *A = C.getArgs().getLastArg(options::OPT_fcrash_diagnostics_dir); if (CCGenDiagnostics && A) { SmallString<128> CrashDirectory(A->getValue()); + if (!getVFS().exists(CrashDirectory)) + llvm::sys::fs::create_directories(CrashDirectory); llvm::sys::path::append(CrashDirectory, Split.first); const char *Middle = Suffix ? "-%%%%%%." : "-%%%%%%"; - std::error_code EC = - llvm::sys::fs::createUniqueFile(CrashDirectory + Middle + Suffix, TmpName); + std::error_code EC = llvm::sys::fs::createUniqueFile( + CrashDirectory + Middle + Suffix, TmpName); if (EC) { Diag(clang::diag::err_unable_to_make_temp) << EC.message(); return ""; @@ -4558,6 +4579,11 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, !Target.hasEnvironment()) TC = llvm::make_unique<toolchains::MipsLLVMToolChain>(*this, Target, Args); + else if (Target.getArch() == llvm::Triple::ppc || + Target.getArch() == llvm::Triple::ppc64 || + Target.getArch() == llvm::Triple::ppc64le) + TC = llvm::make_unique<toolchains::PPCLinuxToolChain>(*this, Target, + Args); else TC = llvm::make_unique<toolchains::Linux>(*this, Target, Args); break; @@ -4750,7 +4776,8 @@ bool Driver::GetReleaseVersion(StringRef Str, return false; } -std::pair<unsigned, unsigned> Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const { +std::pair<unsigned, unsigned> +Driver::getIncludeExcludeOptionFlagMasks(bool IsClCompatMode) const { unsigned IncludedFlagsBitmask = 0; unsigned ExcludedFlagsBitmask = options::NoDriverOption; |