diff options
Diffstat (limited to 'lib/Driver')
104 files changed, 2493 insertions, 1285 deletions
diff --git a/lib/Driver/Action.cpp b/lib/Driver/Action.cpp index d4c7040a233c..47b03f6643b8 100644 --- a/lib/Driver/Action.cpp +++ b/lib/Driver/Action.cpp @@ -1,9 +1,8 @@ //===- Action.cpp - Abstract compilation steps ----------------------------===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/Compilation.cpp b/lib/Driver/Compilation.cpp index 982d7ecad962..5f3026e6ce50 100644 --- a/lib/Driver/Compilation.cpp +++ b/lib/Driver/Compilation.cpp @@ -1,9 +1,8 @@ //===- Compilation.cpp - Compilation Task Implementation ------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -154,30 +153,28 @@ int Compilation::ExecuteCommand(const Command &C, if ((getDriver().CCPrintOptions || getArgs().hasArg(options::OPT_v)) && !getDriver().CCGenDiagnostics) { raw_ostream *OS = &llvm::errs(); + std::unique_ptr<llvm::raw_fd_ostream> OwnedStream; // Follow gcc implementation of CC_PRINT_OPTIONS; we could also cache the // output stream. if (getDriver().CCPrintOptions && getDriver().CCPrintOptionsFilename) { std::error_code EC; - OS = new llvm::raw_fd_ostream(getDriver().CCPrintOptionsFilename, EC, - llvm::sys::fs::F_Append | - llvm::sys::fs::F_Text); + OwnedStream.reset(new llvm::raw_fd_ostream( + getDriver().CCPrintOptionsFilename, EC, + llvm::sys::fs::F_Append | llvm::sys::fs::F_Text)); if (EC) { getDriver().Diag(diag::err_drv_cc_print_options_failure) << EC.message(); FailingCommand = &C; - delete OS; return 1; } + OS = OwnedStream.get(); } if (getDriver().CCPrintOptions) *OS << "[Logging clang options]"; C.Print(*OS, "\n", /*Quote=*/getDriver().CCPrintOptions); - - if (OS != &llvm::errs()) - delete OS; } std::string Error; diff --git a/lib/Driver/DarwinSDKInfo.cpp b/lib/Driver/DarwinSDKInfo.cpp index 547978b2f973..761c6717266b 100644 --- a/lib/Driver/DarwinSDKInfo.cpp +++ b/lib/Driver/DarwinSDKInfo.cpp @@ -1,9 +1,8 @@ //===--- DarwinSDKInfo.cpp - SDK Information parser for darwin - ----------===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/Distro.cpp b/lib/Driver/Distro.cpp index 396d0bee5603..f2a3074d1e70 100644 --- a/lib/Driver/Distro.cpp +++ b/lib/Driver/Distro.cpp @@ -1,9 +1,8 @@ //===--- Distro.cpp - Linux distribution detection support ------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -52,6 +51,7 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) { .Case("bionic", Distro::UbuntuBionic) .Case("cosmic", Distro::UbuntuCosmic) .Case("disco", Distro::UbuntuDisco) + .Case("eoan", Distro::UbuntuEoan) .Default(Distro::UnknownDistro); if (Version != Distro::UnknownDistro) return Version; @@ -94,6 +94,8 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) { return Distro::DebianStretch; case 10: return Distro::DebianBuster; + case 11: + return Distro::DebianBullseye; default: return Distro::UnknownDistro; } @@ -103,6 +105,8 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) { .Case("wheezy/sid", Distro::DebianWheezy) .Case("jessie/sid", Distro::DebianJessie) .Case("stretch/sid", Distro::DebianStretch) + .Case("buster/sid", Distro::DebianBuster) + .Case("bullseye/sid", Distro::DebianBullseye) .Default(Distro::UnknownDistro); } diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index a784e218f139..396ddf4dd816 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) @@ -106,7 +133,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, // Provide a sane fallback if no VFS is specified. if (!this->VFS) - this->VFS = llvm::vfs::getRealFileSystem(); + this->VFS = llvm::vfs::createPhysicalFileSystem().release(); Name = llvm::sys::path::filename(ClangExecutable); Dir = llvm::sys::path::parent_path(ClangExecutable); @@ -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()) > @@ -262,11 +280,13 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL, // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler. } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) || + (PhaseArg = DAL.getLastArg(options::OPT_print_supported_cpus)) || (PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) || (PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) || (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) || (PhaseArg = DAL.getLastArg(options::OPT__migrate)) || + (PhaseArg = DAL.getLastArg(options::OPT_emit_iterface_stubs)) || (PhaseArg = DAL.getLastArg(options::OPT__analyze, options::OPT__analyze_auto)) || (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) { @@ -946,6 +966,9 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions) : std::move(*CLOptions)); + // The args for config files or /clang: flags belong to different InputArgList + // objects than Args. This copies an Arg from one of those other InputArgLists + // to the ownership of Args. auto appendOneArg = [&Args](const Arg *Opt, const Arg *BaseArg) { unsigned Index = Args.MakeIndex(Opt->getSpelling()); Arg *Copy = new llvm::opt::Arg(Opt->getOption(), Opt->getSpelling(), @@ -987,6 +1010,11 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) { } } + // Check for working directory option before accessing any files + if (Arg *WD = Args.getLastArg(options::OPT_working_directory)) + if (VFS->setCurrentWorkingDirectory(WD->getValue())) + Diag(diag::err_drv_unable_to_set_working_directory) << WD->getValue(); + // FIXME: This stuff needs to go into the Compilation, not the driver. bool CCCPrintPhases; @@ -1401,11 +1429,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 +1589,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 +1654,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; } @@ -1651,7 +1676,8 @@ bool Driver::HandleImmediateArgs(const Compilation &C) { } if (C.getArgs().hasArg(options::OPT_v) || - C.getArgs().hasArg(options::OPT__HASH_HASH_HASH)) { + C.getArgs().hasArg(options::OPT__HASH_HASH_HASH) || + C.getArgs().hasArg(options::OPT_print_supported_cpus)) { PrintVersion(C, llvm::errs()); SuppressMissingInputWarning = true; } @@ -1680,7 +1706,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 +1717,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); @@ -1960,31 +1986,20 @@ void Driver::BuildUniversalActions(Compilation &C, const ToolChain &TC, } } -/// Check that the file referenced by Value exists. If it doesn't, -/// issue a diagnostic and return false. -static bool DiagnoseInputExistence(const Driver &D, const DerivedArgList &Args, - StringRef Value, types::ID Ty) { - if (!D.getCheckInputsExist()) +bool Driver::DiagnoseInputExistence(const DerivedArgList &Args, StringRef Value, + types::ID Ty, bool TypoCorrect) const { + if (!getCheckInputsExist()) return true; // stdin always exists. if (Value == "-") return true; - SmallString<64> Path(Value); - if (Arg *WorkDir = Args.getLastArg(options::OPT_working_directory)) { - if (!llvm::sys::path::is_absolute(Path)) { - SmallString<64> Directory(WorkDir->getValue()); - llvm::sys::path::append(Directory, Value); - Path.assign(Directory); - } - } - - if (D.getVFS().exists(Path)) + if (getVFS().exists(Value)) return true; - if (D.IsCLMode()) { - if (!llvm::sys::path::is_absolute(Twine(Path)) && + if (IsCLMode()) { + if (!llvm::sys::path::is_absolute(Twine(Value)) && llvm::sys::Process::FindInEnvPath("LIB", Value)) return true; @@ -1996,7 +2011,26 @@ static bool DiagnoseInputExistence(const Driver &D, const DerivedArgList &Args, } } - D.Diag(clang::diag::err_drv_no_such_file) << Path; + if (TypoCorrect) { + // Check if the filename is a typo for an option flag. OptTable thinks + // that all args that are not known options and that start with / are + // filenames, but e.g. `/diagnostic:caret` is more likely a typo for + // the option `/diagnostics:caret` than a reference to a file in the root + // directory. + unsigned IncludedFlagsBitmask; + unsigned ExcludedFlagsBitmask; + std::tie(IncludedFlagsBitmask, ExcludedFlagsBitmask) = + getIncludeExcludeOptionFlagMasks(IsCLMode()); + std::string Nearest; + if (getOpts().findNearest(Value, Nearest, IncludedFlagsBitmask, + ExcludedFlagsBitmask) <= 1) { + Diag(clang::diag::err_drv_no_such_file_with_suggestion) + << Value << Nearest; + return false; + } + } + + Diag(clang::diag::err_drv_no_such_file) << Value; return false; } @@ -2019,7 +2053,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(); @@ -2084,6 +2119,12 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, Diag(clang::diag::warn_drv_treating_input_as_cxx) << getTypeName(OldTy) << getTypeName(Ty); } + + // If running with -fthinlto-index=, extensions that normally identify + // native object files actually identify LLVM bitcode files. + if (Args.hasArgNoClaim(options::OPT_fthinlto_index_EQ) && + Ty == types::TY_Object) + Ty = types::TY_LLVM_BC; } // -ObjC and -ObjC++ override the default language, but only for "source @@ -2112,19 +2153,21 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, } } - if (DiagnoseInputExistence(*this, Args, Value, Ty)) + if (DiagnoseInputExistence(Args, Value, Ty, /*TypoCorrect=*/true)) Inputs.push_back(std::make_pair(Ty, A)); } else if (A->getOption().matches(options::OPT__SLASH_Tc)) { StringRef Value = A->getValue(); - if (DiagnoseInputExistence(*this, Args, Value, types::TY_C)) { + if (DiagnoseInputExistence(Args, Value, types::TY_C, + /*TypoCorrect=*/false)) { Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue()); Inputs.push_back(std::make_pair(types::TY_C, InputArg)); } A->claim(); } else if (A->getOption().matches(options::OPT__SLASH_Tp)) { StringRef Value = A->getValue(); - if (DiagnoseInputExistence(*this, Args, Value, types::TY_CXX)) { + if (DiagnoseInputExistence(Args, Value, types::TY_CXX, + /*TypoCorrect=*/false)) { Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue()); Inputs.push_back(std::make_pair(types::TY_CXX, InputArg)); } @@ -2146,7 +2189,7 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, Diag(clang::diag::err_drv_unknown_language) << A->getValue(); InputType = types::TY_Object; } - } else if (A->getOption().getID() == options::OPT__SLASH_U) { + } else if (A->getOption().getID() == options::OPT_U) { assert(A->getNumValues() == 1 && "The /U option has one value."); StringRef Val = A->getValue(0); if (Val.find_first_of("/\\") != StringRef::npos) { @@ -2278,6 +2321,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 +2369,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 +2446,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 +2634,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 +2743,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 @@ -3341,6 +3387,18 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, Args.ClaimAllArgs(options::OPT_cl_compile_Group); } + // If --print-supported-cpus, -mcpu=? or -mtune=? is specified, build a custom + // Compile phase that prints out supported cpu models and quits. + if (Arg *A = Args.getLastArg(options::OPT_print_supported_cpus)) { + // Use the -mcpu=? flag as the dummy input to cc1. + Actions.clear(); + Action *InputAc = C.MakeAction<InputAction>(*A, types::TY_C); + Actions.push_back( + C.MakeAction<PrecompileJobAction>(InputAc, types::TY_Nothing)); + for (auto &I : Inputs) + I.second->claim(); + } + // Claim ignored clang-cl options. Args.ClaimAllArgs(options::OPT_cl_ignored_Group); @@ -3426,6 +3484,8 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile); if (Args.hasArg(options::OPT_verify_pch)) return C.MakeAction<VerifyPCHJobAction>(Input, types::TY_Nothing); + if (Args.hasArg(options::OPT_emit_iterface_stubs)) + return C.MakeAction<CompileJobAction>(Input, types::TY_IFS); return C.MakeAction<CompileJobAction>(Input, types::TY_LLVM_BC); } case phases::Backend: { @@ -3963,9 +4023,9 @@ InputInfo Driver::BuildJobsForActionNoCache( Input.claim(); if (Input.getOption().matches(options::OPT_INPUT)) { const char *Name = Input.getValue(); - return InputInfo(A, Name, /* BaseInput = */ Name); + return InputInfo(A, Name, /* _BaseInput = */ Name); } - return InputInfo(A, &Input, /* BaseInput = */ ""); + return InputInfo(A, &Input, /* _BaseInput = */ ""); } if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) { @@ -4244,10 +4304,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 ""; @@ -4401,6 +4463,11 @@ std::string Driver::GetFilePath(StringRef Name, const ToolChain &TC) const { if (llvm::sys::fs::exists(Twine(P))) return P.str(); + SmallString<128> D(Dir); + llvm::sys::path::append(D, "..", Name); + if (llvm::sys::fs::exists(Twine(D))) + return D.str(); + if (auto P = SearchPaths(TC.getLibraryPaths())) return *P; @@ -4558,6 +4625,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; @@ -4571,6 +4643,8 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, TC = llvm::make_unique<toolchains::Solaris>(*this, Target, Args); break; case llvm::Triple::AMDHSA: + case llvm::Triple::AMDPAL: + case llvm::Triple::Mesa3D: TC = llvm::make_unique<toolchains::AMDGPUToolChain>(*this, Target, Args); break; case llvm::Triple::Win32: @@ -4750,7 +4824,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; diff --git a/lib/Driver/DriverOptions.cpp b/lib/Driver/DriverOptions.cpp index 11e7e4c8fe2b..1ad188838eda 100644 --- a/lib/Driver/DriverOptions.cpp +++ b/lib/Driver/DriverOptions.cpp @@ -1,9 +1,8 @@ //===--- DriverOptions.cpp - Driver Options Table -------------------------===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/InputInfo.h b/lib/Driver/InputInfo.h index 0c36e817c135..a6b6f7f344bc 100644 --- a/lib/Driver/InputInfo.h +++ b/lib/Driver/InputInfo.h @@ -1,9 +1,8 @@ //===--- InputInfo.h - Input Source & Type Information ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp index 8d1dfbe12d73..0a95e49694f9 100644 --- a/lib/Driver/Job.cpp +++ b/lib/Driver/Job.cpp @@ -1,9 +1,8 @@ //===- Job.cpp - Command to Execute ---------------------------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -100,7 +99,7 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, } void Command::printArg(raw_ostream &OS, StringRef Arg, bool Quote) { - const bool Escape = Arg.find_first_of("\"\\$") != StringRef::npos; + const bool Escape = Arg.find_first_of(" \"\\$") != StringRef::npos; if (!Quote && !Escape) { OS << Arg; @@ -251,8 +250,8 @@ void Command::Print(raw_ostream &OS, const char *Terminator, bool Quote, } } - auto Found = std::find_if(InputFilenames.begin(), InputFilenames.end(), - [&Arg](StringRef IF) { return IF == Arg; }); + auto Found = llvm::find_if(InputFilenames, + [&Arg](StringRef IF) { return IF == Arg; }); if (Found != InputFilenames.end() && (i == 0 || StringRef(Args[i - 1]) != "-main-file-name")) { // Replace the input file name with the crashinfo's file name. diff --git a/lib/Driver/Multilib.cpp b/lib/Driver/Multilib.cpp index 178a60db60e5..303047e05f78 100644 --- a/lib/Driver/Multilib.cpp +++ b/lib/Driver/Multilib.cpp @@ -1,9 +1,8 @@ //===- Multilib.cpp - Multilib Implementation -----------------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -52,8 +51,9 @@ static void normalizePathSegment(std::string &Segment) { } Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix, - StringRef IncludeSuffix) - : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix) { + StringRef IncludeSuffix, int Priority) + : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix), + Priority(Priority) { normalizePathSegment(this->GCCSuffix); normalizePathSegment(this->OSSuffix); normalizePathSegment(this->IncludeSuffix); @@ -266,8 +266,19 @@ bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const { return true; } - // TODO: pick the "best" multlib when more than one is suitable - assert(false); + // Sort multilibs by priority and select the one with the highest priority. + llvm::sort(Filtered.begin(), Filtered.end(), + [](const Multilib &a, const Multilib &b) -> bool { + return a.priority() > b.priority(); + }); + + if (Filtered[0].priority() > Filtered[1].priority()) { + M = Filtered[0]; + return true; + } + + // TODO: We should consider returning llvm::Error rather than aborting. + assert(false && "More than one multilib with the same priority"); return false; } diff --git a/lib/Driver/Phases.cpp b/lib/Driver/Phases.cpp index 7ae270857f4d..5b776c63f713 100644 --- a/lib/Driver/Phases.cpp +++ b/lib/Driver/Phases.cpp @@ -1,9 +1,8 @@ //===--- Phases.cpp - Transformations on Driver Types ---------------------===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index 1a46073aaa37..6b6a9feec42c 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -1,9 +1,8 @@ //===--- SanitizerArgs.cpp - Arguments for sanitizer tools ---------------===// // -// 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 // //===----------------------------------------------------------------------===// #include "clang/Driver/SanitizerArgs.h" @@ -22,33 +21,55 @@ #include <memory> using namespace clang; -using namespace clang::SanitizerKind; using namespace clang::driver; using namespace llvm::opt; -enum : SanitizerMask { - NeedsUbsanRt = Undefined | Integer | ImplicitConversion | Nullability | CFI, - NeedsUbsanCxxRt = Vptr | CFI, - NotAllowedWithTrap = Vptr, - NotAllowedWithMinimalRuntime = Vptr, - RequiresPIE = DataFlow | HWAddress | Scudo, - NeedsUnwindTables = Address | HWAddress | Thread | Memory | DataFlow, - SupportsCoverage = Address | HWAddress | KernelAddress | KernelHWAddress | - Memory | KernelMemory | Leak | Undefined | Integer | - ImplicitConversion | Nullability | DataFlow | Fuzzer | - FuzzerNoLink, - RecoverableByDefault = Undefined | Integer | ImplicitConversion | Nullability, - Unrecoverable = Unreachable | Return, - AlwaysRecoverable = KernelAddress | KernelHWAddress, - LegacyFsanitizeRecoverMask = Undefined | Integer, - NeedsLTO = CFI, - TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow | - ImplicitConversion | Nullability | LocalBounds | CFI, - TrappingDefault = CFI, - CFIClasses = - CFIVCall | CFINVCall | CFIMFCall | CFIDerivedCast | CFIUnrelatedCast, - CompatibleWithMinimalRuntime = TrappingSupported | Scudo | ShadowCallStack, -}; +static const SanitizerMask NeedsUbsanRt = + SanitizerKind::Undefined | SanitizerKind::Integer | + SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | + SanitizerKind::CFI | SanitizerKind::FloatDivideByZero; +static const SanitizerMask NeedsUbsanCxxRt = + SanitizerKind::Vptr | SanitizerKind::CFI; +static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr; +static const SanitizerMask NotAllowedWithMinimalRuntime = + SanitizerKind::Function | SanitizerKind::Vptr; +static const SanitizerMask RequiresPIE = + SanitizerKind::DataFlow | SanitizerKind::HWAddress | SanitizerKind::Scudo; +static const SanitizerMask NeedsUnwindTables = + SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread | + SanitizerKind::Memory | SanitizerKind::DataFlow; +static const SanitizerMask SupportsCoverage = + SanitizerKind::Address | SanitizerKind::HWAddress | + SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress | + SanitizerKind::MemTag | SanitizerKind::Memory | + SanitizerKind::KernelMemory | SanitizerKind::Leak | + SanitizerKind::Undefined | SanitizerKind::Integer | + SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | + SanitizerKind::DataFlow | SanitizerKind::Fuzzer | + SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero; +static const SanitizerMask RecoverableByDefault = + SanitizerKind::Undefined | SanitizerKind::Integer | + SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | + SanitizerKind::FloatDivideByZero; +static const SanitizerMask Unrecoverable = + SanitizerKind::Unreachable | SanitizerKind::Return; +static const SanitizerMask AlwaysRecoverable = + SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress; +static const SanitizerMask LegacyFsanitizeRecoverMask = + SanitizerKind::Undefined | SanitizerKind::Integer; +static const SanitizerMask NeedsLTO = SanitizerKind::CFI; +static const SanitizerMask TrappingSupported = + (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | + SanitizerKind::UnsignedIntegerOverflow | SanitizerKind::ImplicitConversion | + SanitizerKind::Nullability | SanitizerKind::LocalBounds | + SanitizerKind::CFI | SanitizerKind::FloatDivideByZero; +static const SanitizerMask TrappingDefault = SanitizerKind::CFI; +static const SanitizerMask CFIClasses = + SanitizerKind::CFIVCall | SanitizerKind::CFINVCall | + SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast | + SanitizerKind::CFIUnrelatedCast; +static const SanitizerMask CompatibleWithMinimalRuntime = + TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack; enum CoverageFeature { CoverageFunc = 1 << 0, @@ -101,13 +122,17 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, struct Blacklist { const char *File; SanitizerMask Mask; - } Blacklists[] = {{"asan_blacklist.txt", Address}, - {"hwasan_blacklist.txt", HWAddress}, - {"msan_blacklist.txt", Memory}, - {"tsan_blacklist.txt", Thread}, - {"dfsan_abilist.txt", DataFlow}, - {"cfi_blacklist.txt", CFI}, - {"ubsan_blacklist.txt", Undefined | Integer | Nullability}}; + } Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address}, + {"hwasan_blacklist.txt", SanitizerKind::HWAddress}, + {"memtag_blacklist.txt", SanitizerKind::MemTag}, + {"msan_blacklist.txt", SanitizerKind::Memory}, + {"tsan_blacklist.txt", SanitizerKind::Thread}, + {"dfsan_abilist.txt", SanitizerKind::DataFlow}, + {"cfi_blacklist.txt", SanitizerKind::CFI}, + {"ubsan_blacklist.txt", + SanitizerKind::Undefined | SanitizerKind::Integer | + SanitizerKind::Nullability | + SanitizerKind::FloatDivideByZero}}; for (auto BL : Blacklists) { if (!(Kinds & BL.Mask)) @@ -117,7 +142,7 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, llvm::sys::path::append(Path, "share", BL.File); if (llvm::sys::fs::exists(Path)) BlacklistFiles.push_back(Path.str()); - else if (BL.Mask == CFI) + else if (BL.Mask == SanitizerKind::CFI) // If cfi_blacklist.txt cannot be found in the resource dir, driver // should fail. D.Diag(clang::diag::err_drv_no_such_file) << Path; @@ -137,10 +162,10 @@ static SanitizerMask setGroupBits(SanitizerMask Kinds) { static SanitizerMask parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args) { - SanitizerMask TrapRemove = 0; // During the loop below, the accumulated set of + SanitizerMask TrapRemove; // During the loop below, the accumulated set of // sanitizers disabled by the current sanitizer // argument or any argument after it. - SanitizerMask TrappingKinds = 0; + SanitizerMask TrappingKinds; SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported); for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend(); @@ -164,11 +189,12 @@ static SanitizerMask parseSanitizeTrapArgs(const Driver &D, options::OPT_fsanitize_undefined_trap_on_error)) { Arg->claim(); TrappingKinds |= - expandSanitizerGroups(UndefinedGroup & ~TrapRemove) & ~TrapRemove; + expandSanitizerGroups(SanitizerKind::UndefinedGroup & ~TrapRemove) & + ~TrapRemove; } else if (Arg->getOption().matches( options::OPT_fno_sanitize_undefined_trap_on_error)) { Arg->claim(); - TrapRemove |= expandSanitizerGroups(UndefinedGroup); + TrapRemove |= expandSanitizerGroups(SanitizerKind::UndefinedGroup); } } @@ -190,13 +216,13 @@ bool SanitizerArgs::needsUbsanRt() const { } bool SanitizerArgs::needsCfiRt() const { - return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && - !ImplicitCfiRuntime; + return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) && + CfiCrossDso && !ImplicitCfiRuntime; } bool SanitizerArgs::needsCfiDiagRt() const { - return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && - !ImplicitCfiRuntime; + return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) && + CfiCrossDso && !ImplicitCfiRuntime; } bool SanitizerArgs::requiresPIE() const { @@ -204,24 +230,26 @@ bool SanitizerArgs::requiresPIE() const { } bool SanitizerArgs::needsUnwindTables() const { - return Sanitizers.Mask & NeedsUnwindTables; + return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables); } -bool SanitizerArgs::needsLTO() const { return Sanitizers.Mask & NeedsLTO; } +bool SanitizerArgs::needsLTO() const { + return static_cast<bool>(Sanitizers.Mask & NeedsLTO); +} SanitizerArgs::SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args) { - SanitizerMask AllRemove = 0; // During the loop below, the accumulated set of + SanitizerMask AllRemove; // During the loop below, the accumulated set of // sanitizers disabled by the current sanitizer // argument or any argument after it. - SanitizerMask AllAddedKinds = 0; // Mask of all sanitizers ever enabled by + SanitizerMask AllAddedKinds; // Mask of all sanitizers ever enabled by // -fsanitize= flags (directly or via group // expansion), some of which may be disabled // later. Used to carefully prune // unused-argument diagnostics. - SanitizerMask DiagnosedKinds = 0; // All Kinds we have diagnosed up to now. + SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now. // Used to deduplicate diagnostics. - SanitizerMask Kinds = 0; + SanitizerMask Kinds; const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso, @@ -252,7 +280,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, if (RemoveObjectSizeAtO0) { AllRemove |= SanitizerKind::ObjectSize; - // The user explicitly enabled the object size sanitizer. Warn that + // The user explicitly enabled the object size sanitizer. Warn // that this does nothing at -O0. if (Add & SanitizerKind::ObjectSize) D.Diag(diag::warn_drv_object_size_disabled_O0) @@ -296,12 +324,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // identifiers. // Fixing both of those may require changes to the cross-DSO CFI // interface. - if (CfiCrossDso && (Add & CFIMFCall & ~DiagnosedKinds)) { + if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) { D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize=cfi-mfcall" << "-fsanitize-cfi-cross-dso"; - Add &= ~CFIMFCall; - DiagnosedKinds |= CFIMFCall; + Add &= ~SanitizerKind::CFIMFCall; + DiagnosedKinds |= SanitizerKind::CFIMFCall; } if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) { @@ -315,7 +343,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups // so we don't error out if -fno-rtti and -fsanitize=undefined were // passed. - if ((Add & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { + if ((Add & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) { assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) && "RTTI disabled without -fno-rtti option?"); @@ -330,7 +358,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } // Take out the Vptr sanitizer from the enabled sanitizers - AllRemove |= Vptr; + AllRemove |= SanitizerKind::Vptr; } Add = expandSanitizerGroups(Add); @@ -343,14 +371,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Add &= ~NotAllowedWithMinimalRuntime; } if (CfiCrossDso) - Add &= ~CFIMFCall; + Add &= ~SanitizerKind::CFIMFCall; Add &= Supported; - if (Add & Fuzzer) - Add |= FuzzerNoLink; + if (Add & SanitizerKind::Fuzzer) + Add |= SanitizerKind::FuzzerNoLink; // Enable coverage if the fuzzing flag is set. - if (Add & FuzzerNoLink) { + if (Add & SanitizerKind::FuzzerNoLink) { CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall | CoverageTraceCmp | CoveragePCTable; // Due to TLS differences, stack depth tracking is only enabled on Linux @@ -367,23 +395,39 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = { - std::make_pair(Address, Thread | Memory), - std::make_pair(Thread, Memory), - std::make_pair(Leak, Thread | Memory), - std::make_pair(KernelAddress, Address | Leak | Thread | Memory), - std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress), - std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory | - KernelAddress), - std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory | - KernelAddress | Efficiency), - std::make_pair(SafeStack, Address | HWAddress | Leak | Thread | Memory | - KernelAddress | Efficiency), - std::make_pair(KernelHWAddress, Address | HWAddress | Leak | Thread | - Memory | KernelAddress | Efficiency | - SafeStack), - std::make_pair(KernelMemory, Address | HWAddress | Leak | Thread | - Memory | KernelAddress | Efficiency | - Scudo | SafeStack)}; + std::make_pair(SanitizerKind::Address, + SanitizerKind::Thread | SanitizerKind::Memory), + std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory), + std::make_pair(SanitizerKind::Leak, + SanitizerKind::Thread | SanitizerKind::Memory), + std::make_pair(SanitizerKind::KernelAddress, + SanitizerKind::Address | SanitizerKind::Leak | + SanitizerKind::Thread | SanitizerKind::Memory), + std::make_pair(SanitizerKind::HWAddress, + SanitizerKind::Address | SanitizerKind::Thread | + SanitizerKind::Memory | SanitizerKind::KernelAddress), + std::make_pair(SanitizerKind::Scudo, + SanitizerKind::Address | SanitizerKind::HWAddress | + SanitizerKind::Leak | SanitizerKind::Thread | + SanitizerKind::Memory | SanitizerKind::KernelAddress), + std::make_pair(SanitizerKind::SafeStack, + SanitizerKind::Address | SanitizerKind::HWAddress | + SanitizerKind::Leak | SanitizerKind::Thread | + SanitizerKind::Memory | SanitizerKind::KernelAddress), + std::make_pair(SanitizerKind::KernelHWAddress, + SanitizerKind::Address | SanitizerKind::HWAddress | + SanitizerKind::Leak | SanitizerKind::Thread | + SanitizerKind::Memory | SanitizerKind::KernelAddress | + SanitizerKind::SafeStack), + std::make_pair(SanitizerKind::KernelMemory, + SanitizerKind::Address | SanitizerKind::HWAddress | + SanitizerKind::Leak | SanitizerKind::Thread | + SanitizerKind::Memory | SanitizerKind::KernelAddress | + SanitizerKind::Scudo | SanitizerKind::SafeStack), + std::make_pair(SanitizerKind::MemTag, + SanitizerKind::Address | SanitizerKind::KernelAddress | + SanitizerKind::HWAddress | + SanitizerKind::KernelHWAddress)}; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; @@ -399,8 +443,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // We disable the vptr sanitizer if it was enabled by group expansion but RTTI // is disabled. - if ((Kinds & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { - Kinds &= ~Vptr; + if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { + Kinds &= ~SanitizerKind::Vptr; } // Check that LTO is enabled if we need it. @@ -409,12 +453,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto"; } - if ((Kinds & ShadowCallStack) && + if ((Kinds & SanitizerKind::ShadowCallStack) && TC.getTriple().getArch() == llvm::Triple::aarch64 && !llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) && !Args.hasArg(options::OPT_ffixed_x18)) { D.Diag(diag::err_drv_argument_only_allowed_with) - << lastArgumentForMask(D, Args, Kinds & ShadowCallStack) + << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack) << "-ffixed-x18"; } @@ -422,12 +466,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // c++abi-specific parts of UBSan runtime, and they are not provided by the // toolchain. We don't have a good way to check the latter, so we just // check if the toolchan supports vptr. - if (~Supported & Vptr) { + if (~Supported & SanitizerKind::Vptr) { SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt; // The runtime library supports the Microsoft C++ ABI, but only well enough // for CFI. FIXME: Remove this once we support vptr on Windows. if (TC.getTriple().isOSWindows()) - KindsToDiagnose &= ~CFI; + KindsToDiagnose &= ~SanitizerKind::CFI; if (KindsToDiagnose) { SanitizerSet S; S.Mask = KindsToDiagnose; @@ -456,8 +500,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // Parse -f(no-)?sanitize-recover flags. SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable; - SanitizerMask DiagnosedUnrecoverableKinds = 0; - SanitizerMask DiagnosedAlwaysRecoverableKinds = 0; + SanitizerMask DiagnosedUnrecoverableKinds; + SanitizerMask DiagnosedAlwaysRecoverableKinds; for (const auto *Arg : Args) { const char *DeprecatedReplacement = nullptr; if (Arg->getOption().matches(options::OPT_fsanitize_recover)) { @@ -540,7 +584,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } // Parse -f[no-]sanitize-memory-track-origins[=level] options. - if (AllAddedKinds & Memory) { + if (AllAddedKinds & SanitizerKind::Memory) { if (Arg *A = Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ, options::OPT_fsanitize_memory_track_origins, @@ -568,19 +612,19 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, MsanUseAfterDtor = false; } - if (AllAddedKinds & Thread) { - TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access, - options::OPT_fno_sanitize_thread_memory_access, - TsanMemoryAccess); - TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit, - options::OPT_fno_sanitize_thread_func_entry_exit, - TsanFuncEntryExit); - TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics, - options::OPT_fno_sanitize_thread_atomics, - TsanAtomics); + if (AllAddedKinds & SanitizerKind::Thread) { + TsanMemoryAccess = Args.hasFlag( + options::OPT_fsanitize_thread_memory_access, + options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess); + TsanFuncEntryExit = Args.hasFlag( + options::OPT_fsanitize_thread_func_entry_exit, + options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit); + TsanAtomics = + Args.hasFlag(options::OPT_fsanitize_thread_atomics, + options::OPT_fno_sanitize_thread_atomics, TsanAtomics); } - if (AllAddedKinds & CFI) { + if (AllAddedKinds & SanitizerKind::CFI) { // Without PIE, external function address may resolve to a PLT record, which // can not be verified by the target module. NeedPIE |= CfiCrossDso; @@ -604,7 +648,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << "-fsanitize-minimal-runtime" << lastArgumentForMask(D, Args, IncompatibleMask); - SanitizerMask NonTrappingCfi = Kinds & CFI & ~TrappingKinds; + SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds; if (NonTrappingCfi) D.Diag(clang::diag::err_drv_argument_only_allowed_with) << "fsanitize-minimal-runtime" @@ -692,7 +736,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, ImplicitCfiRuntime = TC.getTriple().isAndroid(); - if (AllAddedKinds & Address) { + if (AllAddedKinds & SanitizerKind::Address) { NeedPIE |= TC.getTriple().isOSFuchsia(); if (Arg *A = Args.getLastArg(options::OPT_fsanitize_address_field_padding)) { @@ -714,7 +758,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, case options::OPT__SLASH_LDd: D.Diag(clang::diag::err_drv_argument_not_allowed_with) << WindowsDebugRTArg->getAsString(Args) - << lastArgumentForMask(D, Args, Address); + << lastArgumentForMask(D, Args, SanitizerKind::Address); D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime); } } @@ -733,17 +777,37 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002 AsanGlobalsDeadStripping = !TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSFuchsia() || + TC.getTriple().isPS4() || Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping); AsanUseOdrIndicator = Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator, options::OPT_fno_sanitize_address_use_odr_indicator, AsanUseOdrIndicator); + + if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) { + AsanInvalidPointerCmp = true; + } + + if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) { + AsanInvalidPointerSub = true; + } + } else { AsanUseAfterScope = false; + // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address. + SanitizerMask DetectInvalidPointerPairs = + SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract; + if (AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) { + TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with) + << lastArgumentForMask(D, Args, + SanitizerKind::PointerCompare | + SanitizerKind::PointerSubtract) + << "-fsanitize=address"; + } } - if (AllAddedKinds & HWAddress) { + if (AllAddedKinds & SanitizerKind::HWAddress) { if (Arg *HwasanAbiArg = Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) { HwasanAbi = HwasanAbiArg->getValue(); @@ -755,7 +819,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } } - if (AllAddedKinds & SafeStack) { + if (AllAddedKinds & SanitizerKind::SafeStack) { // SafeStack runtime is built into the system on Fuchsia. SafeStackRuntime = !TC.getTriple().isOSFuchsia(); } @@ -775,7 +839,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, static std::string toString(const clang::SanitizerSet &Sanitizers) { std::string Res; #define SANITIZER(NAME, ID) \ - if (Sanitizers.has(ID)) { \ + if (Sanitizers.has(SanitizerKind::ID)) { \ if (!Res.empty()) \ Res += ","; \ Res += NAME; \ @@ -927,6 +991,16 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, if (AsanUseOdrIndicator) CmdArgs.push_back("-fsanitize-address-use-odr-indicator"); + if (AsanInvalidPointerCmp) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-asan-detect-invalid-pointer-cmp"); + } + + if (AsanInvalidPointerSub) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-asan-detect-invalid-pointer-sub"); + } + if (!HwasanAbi.empty()) { CmdArgs.push_back("-default-function-attr"); CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi)); @@ -937,7 +1011,8 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, // https://github.com/google/sanitizers/issues/373 // We can't make this conditional on -fsanitize=leak, as that flag shouldn't // affect compilation. - if (Sanitizers.has(Memory) || Sanitizers.has(Address)) + if (Sanitizers.has(SanitizerKind::Memory) || + Sanitizers.has(SanitizerKind::Address)) CmdArgs.push_back("-fno-assume-sane-operator-new"); // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is @@ -960,18 +1035,14 @@ SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, A->getOption().matches(options::OPT_fsanitize_trap_EQ) || A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) && "Invalid argument in parseArgValues!"); - SanitizerMask Kinds = 0; + SanitizerMask Kinds; for (int i = 0, n = A->getNumValues(); i != n; ++i) { const char *Value = A->getValue(i); SanitizerMask Kind; // Special case: don't accept -fsanitize=all. if (A->getOption().matches(options::OPT_fsanitize_EQ) && 0 == strcmp("all", Value)) - Kind = 0; - // Similarly, don't accept -fsanitize=efficiency-all. - else if (A->getOption().matches(options::OPT_fsanitize_EQ) && - 0 == strcmp("efficiency-all", Value)) - Kind = 0; + Kind = SanitizerMask(); else Kind = parseSanitizerValue(Value, /*AllowGroups=*/true); diff --git a/lib/Driver/Tool.cpp b/lib/Driver/Tool.cpp index 818494662179..9ff6e863a124 100644 --- a/lib/Driver/Tool.cpp +++ b/lib/Driver/Tool.cpp @@ -1,9 +1,8 @@ //===--- Tool.cpp - Compilation Tools -------------------------------------===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index 88a627eab6de..b1fddb0af55d 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -1,9 +1,8 @@ //===- ToolChain.cpp - Collections of tools for one platform --------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -74,17 +73,13 @@ 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)) { - SmallString<128> P; - - P.assign(D.ResourceDir); - llvm::sys::path::append(P, D.getTargetTriple(), "lib"); - if (getVFS().exists(P)) - getLibraryPaths().push_back(P.str()); + if (D.CCCIsCXX()) { + if (auto CXXStdlibPath = getCXXStdlibPath()) + getFilePaths().push_back(*CXXStdlibPath); + } - P.assign(D.ResourceDir); - llvm::sys::path::append(P, Triple.str(), "lib"); - if (getVFS().exists(P)) - getLibraryPaths().push_back(P.str()); + if (auto RuntimePath = getRuntimePath()) + getLibraryPaths().push_back(*RuntimePath); std::string CandidateLibPath = getArchSpecificLibPath(); if (getVFS().exists(CandidateLibPath)) @@ -113,6 +108,10 @@ bool ToolChain::useRelaxRelocations() const { return ENABLE_X86_RELAX_RELOCATIONS; } +bool ToolChain::isNoExecStackDefault() const { + return false; +} + const SanitizerArgs& ToolChain::getSanitizerArgs() const { if (!SanitizerArguments.get()) SanitizerArguments.reset(new SanitizerArgs(*this, Args)); @@ -363,16 +362,27 @@ std::string ToolChain::getCompilerRTPath() const { } std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, - bool Shared) const { + FileType Type) const { const llvm::Triple &TT = getTriple(); bool IsITANMSVCWindows = TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment(); - const char *Prefix = IsITANMSVCWindows ? "" : "lib"; - const char *Suffix = Shared ? (Triple.isOSWindows() ? ".lib" : ".so") - : (IsITANMSVCWindows ? ".lib" : ".a"); - if (Shared && Triple.isWindowsGNUEnvironment()) - Suffix = ".dll.a"; + const char *Prefix = + IsITANMSVCWindows || Type == ToolChain::FT_Object ? "" : "lib"; + const char *Suffix; + switch (Type) { + case ToolChain::FT_Object: + Suffix = IsITANMSVCWindows ? ".obj" : ".o"; + break; + case ToolChain::FT_Static: + Suffix = IsITANMSVCWindows ? ".lib" : ".a"; + break; + case ToolChain::FT_Shared: + Suffix = Triple.isOSWindows() + ? (Triple.isWindowsGNUEnvironment() ? ".dll.a" : ".lib") + : ".so"; + break; + } for (const auto &LibPath : getLibraryPaths()) { SmallString<128> P(LibPath); @@ -391,8 +401,45 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, - bool Shared) const { - return Args.MakeArgString(getCompilerRT(Args, Component, Shared)); + FileType Type) const { + return Args.MakeArgString(getCompilerRT(Args, Component, Type)); +} + + +Optional<std::string> ToolChain::getRuntimePath() const { + SmallString<128> P; + + // First try the triple passed to driver as --target=<triple>. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", D.getTargetTriple()); + if (getVFS().exists(P)) + return llvm::Optional<std::string>(P.str()); + + // Second try the normalized triple. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, "lib", Triple.str()); + if (getVFS().exists(P)) + return llvm::Optional<std::string>(P.str()); + + return None; +} + +Optional<std::string> ToolChain::getCXXStdlibPath() const { + SmallString<128> P; + + // First try the triple passed to driver as --target=<triple>. + P.assign(D.Dir); + llvm::sys::path::append(P, "..", "lib", D.getTargetTriple(), "c++"); + if (getVFS().exists(P)) + return llvm::Optional<std::string>(P.str()); + + // Second try the normalized triple. + P.assign(D.Dir); + llvm::sys::path::append(P, "..", "lib", Triple.str(), "c++"); + if (getVFS().exists(P)) + return llvm::Optional<std::string>(P.str()); + + return None; } std::string ToolChain::getArchSpecificLibPath() const { @@ -403,12 +450,18 @@ std::string ToolChain::getArchSpecificLibPath() const { } bool ToolChain::needsProfileRT(const ArgList &Args) { + if (Args.hasArg(options::OPT_noprofilelib)) + return false; + if (needsGCovInstrumentation(Args) || Args.hasArg(options::OPT_fprofile_generate) || Args.hasArg(options::OPT_fprofile_generate_EQ) || + Args.hasArg(options::OPT_fcs_profile_generate) || + Args.hasArg(options::OPT_fcs_profile_generate_EQ) || Args.hasArg(options::OPT_fprofile_instr_generate) || Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || - Args.hasArg(options::OPT_fcreate_profile)) + Args.hasArg(options::OPT_fcreate_profile) || + Args.hasArg(options::OPT_forder_file_instrumentation)) return true; return false; @@ -680,6 +733,33 @@ ToolChain::RuntimeLibType ToolChain::GetRuntimeLibType( return GetDefaultRuntimeLibType(); } +ToolChain::UnwindLibType ToolChain::GetUnwindLibType( + const ArgList &Args) const { + const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ); + StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_UNWINDLIB; + + if (LibName == "none") + return ToolChain::UNW_None; + else if (LibName == "platform" || LibName == "") { + ToolChain::RuntimeLibType RtLibType = GetRuntimeLibType(Args); + if (RtLibType == ToolChain::RLT_CompilerRT) + return ToolChain::UNW_None; + else if (RtLibType == ToolChain::RLT_Libgcc) + return ToolChain::UNW_Libgcc; + } else if (LibName == "libunwind") { + if (GetRuntimeLibType(Args) == RLT_Libgcc) + getDriver().Diag(diag::err_drv_incompatible_unwindlib); + return ToolChain::UNW_CompilerRT; + } else if (LibName == "libgcc") + return ToolChain::UNW_Libgcc; + + if (A) + getDriver().Diag(diag::err_drv_invalid_unwindlib_name) + << A->getAsString(Args); + + return GetDefaultUnwindLibType(); +} + ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{ const Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); StringRef LibName = A ? A->getValue() : CLANG_DEFAULT_CXX_STDLIB; @@ -777,10 +857,6 @@ void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args, void ToolChain::AddFilePathLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - for (const auto &LibPath : getLibraryPaths()) - if(LibPath.length() > 0) - CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); - for (const auto &LibPath : getFilePaths()) if(LibPath.length() > 0) CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); @@ -819,21 +895,24 @@ 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 | - ImplicitConversion | Nullability | LocalBounds; + SanitizerMask Res = (SanitizerKind::Undefined & ~SanitizerKind::Vptr & + ~SanitizerKind::Function) | + (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | + SanitizerKind::CFICastStrict | + SanitizerKind::FloatDivideByZero | + SanitizerKind::UnsignedIntegerOverflow | + SanitizerKind::ImplicitConversion | + SanitizerKind::Nullability | SanitizerKind::LocalBounds; if (getTriple().getArch() == llvm::Triple::x86 || getTriple().getArch() == llvm::Triple::x86_64 || getTriple().getArch() == llvm::Triple::arm || getTriple().getArch() == llvm::Triple::aarch64 || getTriple().getArch() == llvm::Triple::wasm32 || getTriple().getArch() == llvm::Triple::wasm64) - Res |= CFIICall; + Res |= SanitizerKind::CFIICall; if (getTriple().getArch() == llvm::Triple::x86_64 || getTriple().getArch() == llvm::Triple::aarch64) - Res |= ShadowCallStack; + Res |= SanitizerKind::ShadowCallStack; return Res; } diff --git a/lib/Driver/ToolChains/AMDGPU.cpp b/lib/Driver/ToolChains/AMDGPU.cpp index a421a09891cd..df4e7ee202bf 100644 --- a/lib/Driver/ToolChains/AMDGPU.cpp +++ b/lib/Driver/ToolChains/AMDGPU.cpp @@ -1,9 +1,8 @@ //===--- AMDGPU.cpp - AMDGPU ToolChain Implementations ----------*- C++ -*-===// // -// 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,14 +38,18 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, void amdgpu::getAMDGPUTargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector<StringRef> &Features) { - if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) { - StringRef value = dAbi->getValue(); - if (value == "1.0") { - Features.push_back("+amdgpu-debugger-insert-nops"); - Features.push_back("+amdgpu-debugger-emit-prologue"); - } else { - D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args); - } + if (const Arg *dAbi = Args.getLastArg(options::OPT_mamdgpu_debugger_abi)) + D.Diag(diag::err_drv_clang_unsupported) << dAbi->getAsString(Args); + + if (Args.getLastArg(options::OPT_mwavefrontsize64)) { + Features.push_back("-wavefrontsize16"); + Features.push_back("-wavefrontsize32"); + Features.push_back("+wavefrontsize64"); + } + if (Args.getLastArg(options::OPT_mno_wavefrontsize64)) { + Features.push_back("-wavefrontsize16"); + Features.push_back("+wavefrontsize32"); + Features.push_back("-wavefrontsize64"); } handleTargetFeaturesGroup( @@ -109,5 +112,6 @@ void AMDGPUToolChain::addClangTargetOptions( options::OPT_fvisibility_ms_compat)) { CC1Args.push_back("-fvisibility"); CC1Args.push_back("hidden"); + CC1Args.push_back("-fapply-global-visibility-to-externs"); } } diff --git a/lib/Driver/ToolChains/AMDGPU.h b/lib/Driver/ToolChains/AMDGPU.h index 9d38eeedf59d..5585cc534861 100644 --- a/lib/Driver/ToolChains/AMDGPU.h +++ b/lib/Driver/ToolChains/AMDGPU.h @@ -1,9 +1,8 @@ //===--- AMDGPU.h - AMDGPU ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -56,8 +55,10 @@ protected: public: AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); - unsigned GetDefaultDwarfVersion() const override { return 2; } + unsigned GetDefaultDwarfVersion() const override { return 5; } bool IsIntegratedAssemblerDefault() const override { return true; } + bool IsMathErrnoDefault() const override { return false; } + llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Action::OffloadKind DeviceOffloadKind) const override; diff --git a/lib/Driver/ToolChains/AVR.cpp b/lib/Driver/ToolChains/AVR.cpp index 877009af8a30..4a60d9ec589b 100644 --- a/lib/Driver/ToolChains/AVR.cpp +++ b/lib/Driver/ToolChains/AVR.cpp @@ -1,9 +1,8 @@ //===--- AVR.cpp - AVR ToolChain Implementations ----------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -11,7 +10,14 @@ #include "CommonArgs.h" #include "InputInfo.h" #include "clang/Driver/Compilation.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Options.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MC/SubtargetFeature.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/FileSystem.h" using namespace clang::driver; using namespace clang::driver::toolchains; @@ -19,12 +25,76 @@ using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; +namespace { + +// TODO: Consider merging this into the AVR device table +// array in Targets/AVR.cpp. +llvm::Optional<StringRef> GetMcuFamilyName(StringRef MCU) { + return llvm::StringSwitch<llvm::Optional<StringRef>>(MCU) + .Case("atmega328", Optional<StringRef>("avr5")) + .Case("atmega328p", Optional<StringRef>("avr5")) + .Default(Optional<StringRef>()); +} + +const StringRef PossibleAVRLibcLocations[] = { + "/usr/avr", + "/usr/lib/avr", +}; + +} // end anonymous namespace + /// AVR Toolchain AVRToolChain::AVRToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : Generic_ELF(D, Triple, Args) { } + : Generic_ELF(D, Triple, Args), LinkStdlib(false) { + GCCInstallation.init(Triple, Args); + + // Only add default libraries if the user hasn't explicitly opted out. + if (!Args.hasArg(options::OPT_nostdlib) && + !Args.hasArg(options::OPT_nodefaultlibs) && + !Args.hasArg(options::OPT_c /* does not apply when not linking */)) { + std::string CPU = getCPUName(Args, Triple); + + if (CPU.empty()) { + // We cannot link any standard libraries without an MCU specified. + D.Diag(diag::warn_drv_avr_mcu_not_specified); + } else { + Optional<StringRef> FamilyName = GetMcuFamilyName(CPU); + Optional<std::string> AVRLibcRoot = findAVRLibcInstallation(); + + if (!FamilyName.hasValue()) { + // We do not have an entry for this CPU in the family + // mapping table yet. + D.Diag(diag::warn_drv_avr_family_linking_stdlibs_not_implemented) + << CPU; + } else if (!GCCInstallation.isValid()) { + // No avr-gcc found and so no runtime linked. + D.Diag(diag::warn_drv_avr_gcc_not_found); + } else if (!AVRLibcRoot.hasValue()) { + // No avr-libc found and so no runtime linked. + D.Diag(diag::warn_drv_avr_libc_not_found); + } else { // We have enough information to link stdlibs + std::string GCCRoot = GCCInstallation.getInstallPath(); + std::string LibcRoot = AVRLibcRoot.getValue(); + + getFilePaths().push_back(LibcRoot + std::string("/lib/") + + std::string(*FamilyName)); + getFilePaths().push_back(LibcRoot + std::string("/lib/") + + std::string(*FamilyName)); + getFilePaths().push_back(GCCRoot + std::string("/") + + std::string(*FamilyName)); + + LinkStdlib = true; + } + } + + if (!LinkStdlib) + D.Diag(diag::warn_drv_avr_stdlib_not_linked); + } +} + Tool *AVRToolChain::buildLinker() const { - return new tools::AVR::Linker(*this); + return new tools::AVR::Linker(getTriple(), *this, LinkStdlib); } void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, @@ -32,13 +102,58 @@ void AVR::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { + // Compute information about the target AVR. + std::string CPU = getCPUName(Args, getToolChain().getTriple()); + llvm::Optional<StringRef> FamilyName = GetMcuFamilyName(CPU); std::string Linker = getToolChain().GetProgramPath(getShortName()); ArgStringList CmdArgs; AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); + + // Enable garbage collection of unused sections. + CmdArgs.push_back("--gc-sections"); + + // Add library search paths before we specify libraries. + Args.AddAllArgs(CmdArgs, options::OPT_L); + getToolChain().AddFilePathLibArgs(Args, CmdArgs); + + // If the family name is known, we can link with the device-specific libgcc. + // Without it, libgcc will simply not be linked. This matches avr-gcc + // behavior. + if (LinkStdlib) { + assert(!CPU.empty() && "CPU name must be known in order to link stdlibs"); + + // Add the object file for the CRT. + std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o"); + CmdArgs.push_back(Args.MakeArgString(CrtFileName)); + + CmdArgs.push_back("-lgcc"); + CmdArgs.push_back("-lm"); + CmdArgs.push_back("-lc"); + + // Add the link library specific to the MCU. + CmdArgs.push_back(Args.MakeArgString(std::string("-l") + CPU)); + + // Specify the family name as the emulation mode to use. + // This is almost always required because otherwise avr-ld + // will assume 'avr2' and warn about the program being larger + // than the bare minimum supports. + CmdArgs.push_back(Args.MakeArgString(std::string("-m") + *FamilyName)); + } + C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker), CmdArgs, Inputs)); } -// AVR tools end. + +llvm::Optional<std::string> AVRToolChain::findAVRLibcInstallation() const { + for (StringRef PossiblePath : PossibleAVRLibcLocations) { + // Return the first avr-libc installation that exists. + if (llvm::sys::fs::is_directory(PossiblePath)) + return Optional<std::string>(std::string(PossiblePath)); + } + + return llvm::None; +} diff --git a/lib/Driver/ToolChains/AVR.h b/lib/Driver/ToolChains/AVR.h index a7479a7f5652..d244fc4f90e9 100644 --- a/lib/Driver/ToolChains/AVR.h +++ b/lib/Driver/ToolChains/AVR.h @@ -1,9 +1,8 @@ //===--- AVR.h - AVR Tool and ToolChain Implementations ---------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -20,11 +19,21 @@ namespace driver { namespace toolchains { class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF { -protected: - Tool *buildLinker() const override; public: AVRToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); + +protected: + Tool *buildLinker() const override; + +private: + /// Whether libgcc, libct, and friends should be linked. + /// + /// This is not done if the user does not specify a + /// microcontroller on the command line. + bool LinkStdlib; + + llvm::Optional<std::string> findAVRLibcInstallation() const; }; } // end namespace toolchains @@ -33,13 +42,20 @@ namespace tools { namespace AVR { class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { public: - Linker(const ToolChain &TC) : GnuTool("AVR::Linker", "avr-ld", TC) {} + Linker(const llvm::Triple &Triple, const ToolChain &TC, bool LinkStdlib) + : GnuTool("AVR::Linker", "avr-ld", TC), Triple(Triple), + LinkStdlib(LinkStdlib) {} + bool hasIntegratedCPP() const override { return false; } bool isLinkJob() const override { return true; } void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override; + +protected: + const llvm::Triple &Triple; + bool LinkStdlib; }; } // end namespace AVR } // end namespace tools diff --git a/lib/Driver/ToolChains/Ananas.cpp b/lib/Driver/ToolChains/Ananas.cpp index 006fdc029ef8..e3511198cb2d 100644 --- a/lib/Driver/ToolChains/Ananas.cpp +++ b/lib/Driver/ToolChains/Ananas.cpp @@ -1,9 +1,8 @@ //===--- Ananas.cpp - Ananas ToolChain Implementations ------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Ananas.h b/lib/Driver/ToolChains/Ananas.h index 2563dd2d49a9..5e45b47fc108 100644 --- a/lib/Driver/ToolChains/Ananas.h +++ b/lib/Driver/ToolChains/Ananas.h @@ -1,9 +1,8 @@ //===--- Ananas.h - Ananas ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/AArch64.cpp b/lib/Driver/ToolChains/Arch/AArch64.cpp index 71e55fe79e27..35d11f4e2d3b 100644 --- a/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -1,9 +1,8 @@ //===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -195,6 +194,18 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, Features.push_back("-neon"); } + if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { + StringRef Mtp = A->getValue(); + if (Mtp == "el3") + Features.push_back("+tpidr-el3"); + else if (Mtp == "el2") + Features.push_back("+tpidr-el2"); + else if (Mtp == "el1") + Features.push_back("+tpidr-el1"); + else if (Mtp != "el0") + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); + } + // En/disable crc if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) { if (A->getOption().matches(options::OPT_mcrc)) @@ -208,7 +219,7 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, // TargetParser rewrite. const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16"); const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml"); - if (std::find(Features.begin(), Features.end(), "+v8.4a") != Features.end()) { + if (llvm::is_contained(Features, "+v8.4a")) { const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(), "+fullfp16"); if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) { // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml. @@ -218,8 +229,7 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, } else goto fp16_fml_fallthrough; - } - else { + } else { fp16_fml_fallthrough: // In both of these cases, putting the 'other' feature on the end of the vector will // result in the same effect as placing it immediately after the current feature. @@ -336,12 +346,57 @@ fp16_fml_fallthrough: if (Args.hasArg(options::OPT_ffixed_x7)) Features.push_back("+reserve-x7"); + if (Args.hasArg(options::OPT_ffixed_x9)) + Features.push_back("+reserve-x9"); + + if (Args.hasArg(options::OPT_ffixed_x10)) + Features.push_back("+reserve-x10"); + + if (Args.hasArg(options::OPT_ffixed_x11)) + Features.push_back("+reserve-x11"); + + if (Args.hasArg(options::OPT_ffixed_x12)) + Features.push_back("+reserve-x12"); + + if (Args.hasArg(options::OPT_ffixed_x13)) + Features.push_back("+reserve-x13"); + + if (Args.hasArg(options::OPT_ffixed_x14)) + Features.push_back("+reserve-x14"); + + if (Args.hasArg(options::OPT_ffixed_x15)) + Features.push_back("+reserve-x15"); + if (Args.hasArg(options::OPT_ffixed_x18)) Features.push_back("+reserve-x18"); if (Args.hasArg(options::OPT_ffixed_x20)) Features.push_back("+reserve-x20"); + if (Args.hasArg(options::OPT_ffixed_x21)) + Features.push_back("+reserve-x21"); + + if (Args.hasArg(options::OPT_ffixed_x22)) + Features.push_back("+reserve-x22"); + + if (Args.hasArg(options::OPT_ffixed_x23)) + Features.push_back("+reserve-x23"); + + if (Args.hasArg(options::OPT_ffixed_x24)) + Features.push_back("+reserve-x24"); + + if (Args.hasArg(options::OPT_ffixed_x25)) + Features.push_back("+reserve-x25"); + + if (Args.hasArg(options::OPT_ffixed_x26)) + Features.push_back("+reserve-x26"); + + if (Args.hasArg(options::OPT_ffixed_x27)) + Features.push_back("+reserve-x27"); + + if (Args.hasArg(options::OPT_ffixed_x28)) + Features.push_back("+reserve-x28"); + if (Args.hasArg(options::OPT_fcall_saved_x8)) Features.push_back("+call-saved-x8"); diff --git a/lib/Driver/ToolChains/Arch/AArch64.h b/lib/Driver/ToolChains/Arch/AArch64.h index 5f6148ebd6c4..713af870d69f 100644 --- a/lib/Driver/ToolChains/Arch/AArch64.h +++ b/lib/Driver/ToolChains/Arch/AArch64.h @@ -1,9 +1,8 @@ //===--- AArch64.h - AArch64-specific (not ARM) Tool Helpers ----*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp index f55efc1a22e3..d1db583e5280 100644 --- a/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/lib/Driver/ToolChains/Arch/ARM.cpp @@ -1,9 +1,8 @@ //===--- ARM.cpp - ARM (not AArch64) Helpers for Tools ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -73,15 +72,13 @@ static void getARMFPUFeatures(const Driver &D, const Arg *A, // Decode ARM features from string like +[no]featureA+[no]featureB+... static bool DecodeARMFeatures(const Driver &D, StringRef text, + StringRef CPU, llvm::ARM::ArchKind ArchKind, std::vector<StringRef> &Features) { SmallVector<StringRef, 8> Split; text.split(Split, StringRef("+"), -1, false); for (StringRef Feature : Split) { - StringRef FeatureName = llvm::ARM::getArchExtFeature(Feature); - if (!FeatureName.empty()) - Features.push_back(FeatureName); - else + if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features)) return false; } return true; @@ -89,6 +86,7 @@ static bool DecodeARMFeatures(const Driver &D, StringRef text, static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU, std::vector<StringRef> &Features) { + CPU = CPU.split("+").first; if (CPU != "generic") { llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU); unsigned Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind); @@ -100,14 +98,16 @@ static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU, // getARMArch is used here instead of just checking the -march value in order // to handle -march=native correctly. static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args, - llvm::StringRef ArchName, + llvm::StringRef ArchName, llvm::StringRef CPUName, std::vector<StringRef> &Features, const llvm::Triple &Triple) { std::pair<StringRef, StringRef> Split = ArchName.split("+"); std::string MArch = arm::getARMArch(ArchName, Triple); - if (llvm::ARM::parseArch(MArch) == llvm::ARM::ArchKind::INVALID || - (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features))) + llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch); + if (ArchKind == llvm::ARM::ArchKind::INVALID || + (Split.second.size() && !DecodeARMFeatures( + D, Split.second, CPUName, ArchKind, Features))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); } @@ -119,8 +119,11 @@ static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args, std::pair<StringRef, StringRef> Split = CPUName.split("+"); std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); - if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() || - (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features))) + llvm::ARM::ArchKind ArchKind = + arm::getLLVMArchKindForARM(CPU, ArchName, Triple); + if (ArchKind == llvm::ARM::ArchKind::INVALID || + (Split.second.size() && !DecodeARMFeatures( + D, Split.second, CPU, ArchKind, Features))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); } @@ -249,7 +252,7 @@ arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) { ABI = FloatABI::SoftFP; break; case llvm::Triple::Android: - ABI = (SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft; + ABI = (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft; break; default: // Assume "soft", but warn the user we are guessing. @@ -286,6 +289,13 @@ void arm::getARMTargetFeatures(const ToolChain &TC, const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; + // This vector will accumulate features from the architecture + // extension suffixes on -mcpu and -march (e.g. the 'bar' in + // -mcpu=foo+bar). We want to apply those after the features derived + // from the FPU, in case -mfpu generates a negative feature which + // the +bar is supposed to override. + std::vector<StringRef> ExtensionFeatures; + if (!ForAS) { // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these // yet (it uses the -mfloat-abi and -msoft-float options), and it is @@ -327,34 +337,35 @@ void arm::getARMTargetFeatures(const ToolChain &TC, if (ThreadPointer == arm::ReadTPMode::Cp15) Features.push_back("+read-tp-hard"); - // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); + const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); StringRef ArchName; + StringRef CPUName; + + // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=. + if (WaCPU) { + if (CPUArg) + D.Diag(clang::diag::warn_drv_unused_argument) + << CPUArg->getAsString(Args); + CPUName = StringRef(WaCPU->getValue()).substr(6); + CPUArg = WaCPU; + } else if (CPUArg) + CPUName = CPUArg->getValue(); + + // Check -march. ClangAs gives preference to -Wa,-march=. if (WaArch) { if (ArchArg) D.Diag(clang::diag::warn_drv_unused_argument) << ArchArg->getAsString(Args); ArchName = StringRef(WaArch->getValue()).substr(7); - checkARMArchName(D, WaArch, Args, ArchName, Features, Triple); + checkARMArchName(D, WaArch, Args, ArchName, CPUName, + ExtensionFeatures, Triple); // FIXME: Set Arch. D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args); } else if (ArchArg) { ArchName = ArchArg->getValue(); - checkARMArchName(D, ArchArg, Args, ArchName, Features, Triple); - } - - // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=. - const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); - StringRef CPUName; - if (WaCPU) { - if (CPUArg) - D.Diag(clang::diag::warn_drv_unused_argument) - << CPUArg->getAsString(Args); - CPUName = StringRef(WaCPU->getValue()).substr(6); - checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Features, Triple); - } else if (CPUArg) { - CPUName = CPUArg->getValue(); - checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Features, Triple); + checkARMArchName(D, ArchArg, Args, ArchName, CPUName, + ExtensionFeatures, Triple); } // Add CPU features for generic CPUs @@ -365,9 +376,16 @@ void arm::getARMTargetFeatures(const ToolChain &TC, Features.push_back( Args.MakeArgString((F.second ? "+" : "-") + F.first())); } else if (!CPUName.empty()) { + // This sets the default features for the specified CPU. We certainly don't + // want to override the features that have been explicitly specified on the + // command line. Therefore, process them directly instead of appending them + // at the end later. DecodeARMFeaturesFromCPU(D, CPUName, Features); } + if (CPUArg) + checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, + ExtensionFeatures, Triple); // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=. const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ); if (WaFPU) { @@ -379,14 +397,18 @@ void arm::getARMTargetFeatures(const ToolChain &TC, } else if (FPUArg) { getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features); } else if (Triple.isAndroid() && getARMSubArchVersionNumber(Triple) >= 7) { - // Android mandates minimum FPU requirements based on OS version. - const char *AndroidFPU = - Triple.isAndroidVersionLT(23) ? "vfpv3-d16" : "neon"; + const char *AndroidFPU = "neon"; if (!llvm::ARM::getFPUFeatures(llvm::ARM::parseFPU(AndroidFPU), Features)) D.Diag(clang::diag::err_drv_clang_unsupported) << std::string("-mfpu=") + AndroidFPU; } + // Now we've finished accumulating features from arch, cpu and fpu, + // we can append the ones for architecture extensions that we + // collected separately. + Features.insert(std::end(Features), + std::begin(ExtensionFeatures), std::end(ExtensionFeatures)); + // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=. const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ); if (WaHDiv) { @@ -431,16 +453,20 @@ fp16_fml_fallthrough: if (ABI == arm::FloatABI::Soft) { llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features); - // Disable hardware FP features which have been enabled. - // FIXME: Disabling vfp2 and neon should be enough as all the other - // features are dependent on these 2 features in LLVM. However + // Disable all features relating to hardware FP. + // FIXME: Disabling fpregs should be enough all by itself, since all + // the other FP features are dependent on it. However // there is currently no easy way to test this in clang, so for // now just be explicit and disable all known dependent features // as well. - for (std::string Feature : {"vfp2", "vfp3", "vfp4", "fp-armv8", "fullfp16", - "neon", "crypto", "dotprod", "fp16fml"}) - if (std::find(std::begin(Features), std::end(Features), "+" + Feature) != std::end(Features)) - Features.push_back(Args.MakeArgString("-" + Feature)); + for (std::string Feature : { + "vfp2", "vfp2sp", "vfp2d16", "vfp2d16sp", + "vfp3", "vfp3sp", "vfp3d16", "vfp3d16sp", + "vfp4", "vfp4sp", "vfp4d16", "vfp4d16sp", + "fp-armv8", "fp-armv8sp", "fp-armv8d16", "fp-armv8d16sp", + "fullfp16", "neon", "crypto", "dotprod", "fp16fml", + "fp64", "d32", "fpregs"}) + Features.push_back(Args.MakeArgString("-" + Feature)); } // En/disable crc code generation. @@ -471,6 +497,10 @@ fp16_fml_fallthrough: } } + // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later. + if (Args.getLastArg(options::OPT_mcmse)) + Features.push_back("+8msecext"); + // Look for the last occurrence of -mlong-calls or -mno-long-calls. If // neither options are specified, see if we are compiling for kernel/kext and // decide whether to pass "+long-calls" based on the OS and its version. @@ -618,11 +648,12 @@ std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch, return getARMCPUForMArch(Arch, Triple); } -/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular -/// CPU (or Arch, if CPU is generic). -// FIXME: This is redundant with -mcpu, why does LLVM use this. -StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, - const llvm::Triple &Triple) { +/// getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a +/// particular CPU (or Arch, if CPU is generic). This is needed to +/// pass to functions like llvm::ARM::getDefaultFPU which need an +/// ArchKind as well as a CPU name. +llvm::ARM::ArchKind arm::getLLVMArchKindForARM(StringRef CPU, StringRef Arch, + const llvm::Triple &Triple) { llvm::ARM::ArchKind ArchKind; if (CPU == "generic") { std::string ARMArch = tools::arm::getARMArch(Arch, Triple); @@ -638,6 +669,15 @@ StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, ? llvm::ARM::ArchKind::ARMV7K : llvm::ARM::parseCPUArch(CPU); } + return ArchKind; +} + +/// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular +/// CPU (or Arch, if CPU is generic). +// FIXME: This is redundant with -mcpu, why does LLVM use this. +StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch, + const llvm::Triple &Triple) { + llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple); if (ArchKind == llvm::ARM::ArchKind::INVALID) return ""; return llvm::ARM::getSubArch(ArchKind); diff --git a/lib/Driver/ToolChains/Arch/ARM.h b/lib/Driver/ToolChains/Arch/ARM.h index 9f0dc4ea2e25..5640f8371262 100644 --- a/lib/Driver/ToolChains/Arch/ARM.h +++ b/lib/Driver/ToolChains/Arch/ARM.h @@ -1,9 +1,8 @@ //===--- ARM.h - ARM-specific (not AArch64) Tool Helpers --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -14,6 +13,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Option/Option.h" +#include "llvm/Support/TargetParser.h" #include <string> #include <vector> @@ -26,6 +26,8 @@ std::string getARMTargetCPU(StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple); const std::string getARMArch(llvm::StringRef Arch, const llvm::Triple &Triple); StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple); +llvm::ARM::ArchKind getLLVMArchKindForARM(StringRef CPU, StringRef Arch, + const llvm::Triple &Triple); StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple); diff --git a/lib/Driver/ToolChains/Arch/Mips.cpp b/lib/Driver/ToolChains/Arch/Mips.cpp index e10a5e1c773f..b512ff64b0c6 100644 --- a/lib/Driver/ToolChains/Arch/Mips.cpp +++ b/lib/Driver/ToolChains/Arch/Mips.cpp @@ -1,9 +1,8 @@ //===--- Mips.cpp - Tools Implementations -----------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -247,7 +246,6 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, if (IsN64 && NonPIC && (!ABICallsArg || UseAbiCalls)) { D.Diag(diag::warn_drv_unsupported_pic_with_mabicalls) << LastPICArg->getAsString(Args) << (!ABICallsArg ? 0 : 1); - NonPIC = false; } if (ABICallsArg && !UseAbiCalls && IsPIC) { diff --git a/lib/Driver/ToolChains/Arch/Mips.h b/lib/Driver/ToolChains/Arch/Mips.h index a232ddbc8f3d..23e0cf79e154 100644 --- a/lib/Driver/ToolChains/Arch/Mips.h +++ b/lib/Driver/ToolChains/Arch/Mips.h @@ -1,9 +1,8 @@ //===--- Mips.h - Mips-specific Tool Helpers ----------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/PPC.cpp b/lib/Driver/ToolChains/Arch/PPC.cpp index 791f1206cf25..30f1a0d9022c 100644 --- a/lib/Driver/ToolChains/Arch/PPC.cpp +++ b/lib/Driver/ToolChains/Arch/PPC.cpp @@ -1,9 +1,8 @@ //===--- PPC.cpp - PPC Helpers for Tools ------------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -116,7 +115,7 @@ ppc::ReadGOTPtrMode ppc::getPPCReadGOTPtrMode(const Driver &D, const llvm::Tripl const ArgList &Args) { if (Args.getLastArg(options::OPT_msecure_plt)) return ppc::ReadGOTPtrMode::SecurePlt; - if (Triple.isOSOpenBSD()) + if (Triple.isOSNetBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) return ppc::ReadGOTPtrMode::SecurePlt; else return ppc::ReadGOTPtrMode::Bss; diff --git a/lib/Driver/ToolChains/Arch/PPC.h b/lib/Driver/ToolChains/Arch/PPC.h index 4f3cd688ca39..e1c943955e81 100644 --- a/lib/Driver/ToolChains/Arch/PPC.h +++ b/lib/Driver/ToolChains/Arch/PPC.h @@ -1,9 +1,8 @@ //===--- PPC.h - PPC-specific Tool Helpers ----------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/RISCV.cpp b/lib/Driver/ToolChains/Arch/RISCV.cpp index 1321fedcec51..b6768de4d299 100644 --- a/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -1,9 +1,8 @@ //===--- RISCV.cpp - RISCV Helpers for Tools --------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -55,20 +54,14 @@ static bool isSupportedExtension(StringRef Ext) { static bool getExtensionVersion(const Driver &D, StringRef MArch, StringRef Ext, StringRef In, std::string &Major, std::string &Minor) { - auto I = In.begin(); - auto E = In.end(); - - while (I != E && isDigit(*I)) - Major.append(1, *I++); - + Major = In.take_while(isDigit); + In = In.substr(Major.size()); if (Major.empty()) return true; - if (I != E && *I == 'p') { - ++I; - - while (I != E && isDigit(*I)) - Minor.append(1, *I++); + if (In.consume_front("p")) { + Minor = In.take_while(isDigit); + In = In.substr(Major.size()); // Expected 'p' to be followed by minor version number. if (Minor.empty()) { @@ -111,17 +104,13 @@ static void getExtensionFeatures(const Driver &D, SmallVector<StringRef, 8> Split; Exts.split(Split, StringRef("_")); - SmallVector<StringRef, 3> Prefix; - Prefix.push_back("x"); - Prefix.push_back("s"); - Prefix.push_back("sx"); + SmallVector<StringRef, 3> Prefix{"x", "s", "sx"}; auto I = Prefix.begin(); auto E = Prefix.end(); SmallVector<StringRef, 8> AllExts; for (StringRef Ext : Split) { - if (Ext.empty()) { D.Diag(diag::err_drv_invalid_riscv_arch_name) << MArch << "extension name missing after separator '_'"; @@ -171,7 +160,7 @@ static void getExtensionFeatures(const Driver &D, } // Check if duplicated extension. - if (std::find(AllExts.begin(), AllExts.end(), Ext) != AllExts.end()) { + if (llvm::is_contained(AllExts, Ext)) { std::string Error = "duplicated "; Error += Desc; D.Diag(diag::err_drv_invalid_riscv_ext_arch_name) @@ -206,11 +195,9 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const ArgList &Args, StringRef MArch = A->getValue(); // RISC-V ISA strings must be lowercase. - if (std::any_of(std::begin(MArch), std::end(MArch), - [](char c) { return isupper(c); })) { - - D.Diag(diag::err_drv_invalid_riscv_arch_name) << MArch - << "string must be lowercase"; + if (llvm::any_of(MArch, [](char c) { return isupper(c); })) { + D.Diag(diag::err_drv_invalid_riscv_arch_name) + << MArch << "string must be lowercase"; return; } @@ -222,7 +209,7 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const ArgList &Args, return; } - bool HasRV64 = MArch.startswith("rv64") ? true : false; + bool HasRV64 = MArch.startswith("rv64"); // The canonical order specified in ISA manual. // Ref: Table 22.1 in RISC-V User-Level ISA V2.2 @@ -365,6 +352,20 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const ArgList &Args, getExtensionFeatures(D, Args, Features, MArch, OtherExts); } + // -mrelax is default, unless -mno-relax is specified. + if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) + Features.push_back("+relax"); + else + Features.push_back("-relax"); + + // GCC Compatibility: -mno-save-restore is default, unless -msave-restore is + // specified... + if (Args.hasFlag(options::OPT_msave_restore, options::OPT_mno_save_restore, false)) { + // ... but we don't support -msave-restore, so issue a warning. + D.Diag(diag::warn_drv_clang_unsupported) + << Args.getLastArg(options::OPT_msave_restore)->getAsString(Args); + } + // Now add any that the user explicitly requested on the command line, // which may override the defaults. handleTargetFeaturesGroup(Args, Features, options::OPT_m_riscv_Features_Group); diff --git a/lib/Driver/ToolChains/Arch/RISCV.h b/lib/Driver/ToolChains/Arch/RISCV.h index beda14979fab..443526900aae 100644 --- a/lib/Driver/ToolChains/Arch/RISCV.h +++ b/lib/Driver/ToolChains/Arch/RISCV.h @@ -1,9 +1,8 @@ //===--- RISCV.h - RISCV-specific Tool Helpers ------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/Sparc.cpp b/lib/Driver/ToolChains/Arch/Sparc.cpp index c177031b9f75..043b7f257c01 100644 --- a/lib/Driver/ToolChains/Arch/Sparc.cpp +++ b/lib/Driver/ToolChains/Arch/Sparc.cpp @@ -1,9 +1,8 @@ //===--- Sparc.cpp - Tools Implementations ----------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/Sparc.h b/lib/Driver/ToolChains/Arch/Sparc.h index 082b2808a946..d12a9a70e264 100644 --- a/lib/Driver/ToolChains/Arch/Sparc.h +++ b/lib/Driver/ToolChains/Arch/Sparc.h @@ -1,9 +1,8 @@ //===--- Sparc.h - Sparc-specific Tool Helpers ----------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/SystemZ.cpp b/lib/Driver/ToolChains/Arch/SystemZ.cpp index 6ee724d00802..ca60b85cf8a0 100644 --- a/lib/Driver/ToolChains/Arch/SystemZ.cpp +++ b/lib/Driver/ToolChains/Arch/SystemZ.cpp @@ -1,9 +1,8 @@ //===--- SystemZ.cpp - SystemZ Helpers for Tools ----------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/SystemZ.h b/lib/Driver/ToolChains/Arch/SystemZ.h index 521f8c2aad02..11d77fa01cc8 100644 --- a/lib/Driver/ToolChains/Arch/SystemZ.h +++ b/lib/Driver/ToolChains/Arch/SystemZ.h @@ -1,9 +1,8 @@ //===--- SystemZ.h - SystemZ-specific Tool Helpers --------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Arch/X86.cpp b/lib/Driver/ToolChains/Arch/X86.cpp index 45648945d5ef..34be226b69e9 100644 --- a/lib/Driver/ToolChains/Arch/X86.cpp +++ b/lib/Driver/ToolChains/Arch/X86.cpp @@ -1,9 +1,8 @@ //===--- X86.cpp - X86 Helpers for Tools ------------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -136,6 +135,7 @@ void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, if (ArchType == llvm::Triple::x86_64) { Features.push_back("+sse4.2"); Features.push_back("+popcnt"); + Features.push_back("+cx16"); } else Features.push_back("+ssse3"); } diff --git a/lib/Driver/ToolChains/Arch/X86.h b/lib/Driver/ToolChains/Arch/X86.h index 20bf27a2b6bc..9f9c2b8c4b49 100644 --- a/lib/Driver/ToolChains/Arch/X86.h +++ b/lib/Driver/ToolChains/Arch/X86.h @@ -1,9 +1,8 @@ //===--- X86.h - X86-specific Tool Helpers ----------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/BareMetal.cpp b/lib/Driver/ToolChains/BareMetal.cpp index 31d16922cc43..1544727050f4 100644 --- a/lib/Driver/ToolChains/BareMetal.cpp +++ b/lib/Driver/ToolChains/BareMetal.cpp @@ -1,9 +1,8 @@ -//===--- BaremMetal.cpp - Bare Metal ToolChain ------------------*- C++ -*-===// +//===-- BareMetal.cpp - Bare Metal ToolChain --------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/BareMetal.h b/lib/Driver/ToolChains/BareMetal.h index 43a6a8b4bec3..4c0c739307b1 100644 --- a/lib/Driver/ToolChains/BareMetal.h +++ b/lib/Driver/ToolChains/BareMetal.h @@ -1,9 +1,8 @@ //===--- BareMetal.h - Bare Metal Tool and ToolChain -------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index 75f16898dfaf..cb861f27aeda 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -1,9 +1,8 @@ -//===--- LLVM.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===// +//===-- Clang.cpp - Clang+LLVM ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -502,6 +501,8 @@ static codegenoptions::DebugInfoKind DebugLevelToInfoKind(const Arg &A) { return codegenoptions::LimitedDebugInfo; } +enum class FramePointerKind { None, NonLeaf, All }; + static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { switch (Triple.getArch()){ default: @@ -516,13 +517,20 @@ static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { static bool useFramePointerForTargetByDefault(const ArgList &Args, const llvm::Triple &Triple) { + if (Args.hasArg(options::OPT_pg)) + return true; + switch (Triple.getArch()) { case llvm::Triple::xcore: case llvm::Triple::wasm32: case llvm::Triple::wasm64: + case llvm::Triple::msp430: // XCore never wants frame pointers, regardless of OS. // WebAssembly never wants frame pointers. return false; + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: case llvm::Triple::riscv32: case llvm::Triple::riscv64: return !areOptimizationsEnabled(Args); @@ -542,9 +550,6 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, case llvm::Triple::mips64el: case llvm::Triple::mips: case llvm::Triple::mipsel: - case llvm::Triple::ppc: - case llvm::Triple::ppc64: - case llvm::Triple::ppc64le: case llvm::Triple::systemz: case llvm::Triple::x86: case llvm::Triple::x86_64: @@ -574,40 +579,34 @@ static bool useFramePointerForTargetByDefault(const ArgList &Args, return true; } -static bool shouldUseFramePointer(const ArgList &Args, - const llvm::Triple &Triple) { - if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer, - options::OPT_fomit_frame_pointer)) - return A->getOption().matches(options::OPT_fno_omit_frame_pointer) || - mustUseNonLeafFramePointerForTarget(Triple); - - if (Args.hasArg(options::OPT_pg)) - return true; - - return useFramePointerForTargetByDefault(Args, Triple); -} - -static bool shouldUseLeafFramePointer(const ArgList &Args, - const llvm::Triple &Triple) { - if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer, - options::OPT_momit_leaf_frame_pointer)) - return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer); - - if (Args.hasArg(options::OPT_pg)) - return true; - - if (Triple.isPS4CPU()) - return false; - - return useFramePointerForTargetByDefault(Args, Triple); +static FramePointerKind getFramePointerKind(const ArgList &Args, + const llvm::Triple &Triple) { + Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer, + options::OPT_fno_omit_frame_pointer); + bool OmitFP = A && A->getOption().matches(options::OPT_fomit_frame_pointer); + bool NoOmitFP = + A && A->getOption().matches(options::OPT_fno_omit_frame_pointer); + if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) || + (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) { + if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer, + options::OPT_mno_omit_leaf_frame_pointer, + Triple.isPS4CPU())) + return FramePointerKind::NonLeaf; + return FramePointerKind::All; + } + return FramePointerKind::None; } /// Add a CC1 option to specify the debug compilation directory. -static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs) { - SmallString<128> cwd; - if (!llvm::sys::fs::current_path(cwd)) { +static void addDebugCompDirArg(const ArgList &Args, ArgStringList &CmdArgs, + const llvm::vfs::FileSystem &VFS) { + if (Arg *A = Args.getLastArg(options::OPT_fdebug_compilation_dir)) { CmdArgs.push_back("-fdebug-compilation-dir"); - CmdArgs.push_back(Args.MakeArgString(cwd)); + CmdArgs.push_back(A->getValue()); + } else if (llvm::ErrorOr<std::string> CWD = + VFS.getCurrentWorkingDirectory()) { + CmdArgs.push_back("-fdebug-compilation-dir"); + CmdArgs.push_back(Args.MakeArgString(*CWD)); } } @@ -624,7 +623,8 @@ static void addDebugPrefixMapArg(const Driver &D, const ArgList &Args, ArgString } /// Vectorize at all optimization levels greater than 1 except for -Oz. -/// For -Oz the loop vectorizer is disable, while the slp vectorizer is enabled. +/// For -Oz the loop vectorizer is disabled, while the slp vectorizer is +/// enabled. static bool shouldEnableVectorizerAtOLevel(const ArgList &Args, bool isSlpVec) { if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { if (A->getOption().matches(options::OPT_O4) || @@ -718,8 +718,9 @@ static void appendUserToPath(SmallVectorImpl<char> &Result) { Result.append(UID.begin(), UID.end()); } -static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, - const InputInfo &Output, const ArgList &Args, +static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, + const Driver &D, const InputInfo &Output, + const ArgList &Args, ArgStringList &CmdArgs) { auto *PGOGenerateArg = Args.getLastArg(options::OPT_fprofile_generate, @@ -729,6 +730,13 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, PGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)) PGOGenerateArg = nullptr; + auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate, + options::OPT_fcs_profile_generate_EQ, + options::OPT_fno_profile_generate); + if (CSPGOGenerateArg && + CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)) + CSPGOGenerateArg = nullptr; + auto *ProfileGenerateArg = Args.getLastArg( options::OPT_fprofile_instr_generate, options::OPT_fprofile_instr_generate_EQ, @@ -752,6 +760,10 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, D.Diag(diag::err_drv_argument_not_allowed_with) << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling(); + if (CSPGOGenerateArg && PGOGenerateArg) + D.Diag(diag::err_drv_argument_not_allowed_with) + << CSPGOGenerateArg->getSpelling() << PGOGenerateArg->getSpelling(); + if (ProfileGenerateArg) { if (ProfileGenerateArg->getOption().matches( options::OPT_fprofile_instr_generate_EQ)) @@ -759,13 +771,33 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, ProfileGenerateArg->getValue())); // The default is to use Clang Instrumentation. CmdArgs.push_back("-fprofile-instrument=clang"); + if (TC.getTriple().isWindowsMSVCEnvironment()) { + // Add dependent lib for clang_rt.profile + CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + + TC.getCompilerRT(Args, "profile"))); + } } + Arg *PGOGenArg = nullptr; if (PGOGenerateArg) { + assert(!CSPGOGenerateArg); + PGOGenArg = PGOGenerateArg; CmdArgs.push_back("-fprofile-instrument=llvm"); - if (PGOGenerateArg->getOption().matches( - options::OPT_fprofile_generate_EQ)) { - SmallString<128> Path(PGOGenerateArg->getValue()); + } + if (CSPGOGenerateArg) { + assert(!PGOGenerateArg); + PGOGenArg = CSPGOGenerateArg; + CmdArgs.push_back("-fprofile-instrument=csllvm"); + } + if (PGOGenArg) { + if (TC.getTriple().isWindowsMSVCEnvironment()) { + CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" + + TC.getCompilerRT(Args, "profile"))); + } + if (PGOGenArg->getOption().matches( + PGOGenerateArg ? options::OPT_fprofile_generate_EQ + : options::OPT_fcs_profile_generate_EQ)) { + SmallString<128> Path(PGOGenArg->getValue()); llvm::sys::path::append(Path, "default_%m.profraw"); CmdArgs.push_back( Args.MakeArgString(Twine("-fprofile-instrument-path=") + Path)); @@ -840,13 +872,8 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D, else OutputFilename = llvm::sys::path::filename(Output.getBaseInput()); SmallString<128> CoverageFilename = OutputFilename; - if (llvm::sys::path::is_relative(CoverageFilename)) { - SmallString<128> Pwd; - if (!llvm::sys::fs::current_path(Pwd)) { - llvm::sys::path::append(Pwd, CoverageFilename); - CoverageFilename.swap(Pwd); - } - } + if (llvm::sys::path::is_relative(CoverageFilename)) + (void)D.getVFS().makeAbsolute(CoverageFilename); llvm::sys::path::replace_extension(CoverageFilename, "gcno"); CmdArgs.push_back(Args.MakeArgString(CoverageFilename)); @@ -972,7 +999,7 @@ static void RenderDebugInfoCompressionArgs(const ArgList &Args, if (checkDebugInfoOption(A, Args, D, TC)) { if (A->getOption().getID() == options::OPT_gz) { if (llvm::zlib::isAvailable()) - CmdArgs.push_back("-compress-debug-sections"); + CmdArgs.push_back("--compress-debug-sections"); else D.Diag(diag::warn_debug_compression_unavailable); return; @@ -980,11 +1007,11 @@ static void RenderDebugInfoCompressionArgs(const ArgList &Args, StringRef Value = A->getValue(); if (Value == "none") { - CmdArgs.push_back("-compress-debug-sections=none"); + CmdArgs.push_back("--compress-debug-sections=none"); } else if (Value == "zlib" || Value == "zlib-gnu") { if (llvm::zlib::isAvailable()) { CmdArgs.push_back( - Args.MakeArgString("-compress-debug-sections=" + Twine(Value))); + Args.MakeArgString("--compress-debug-sections=" + Twine(Value))); } else { D.Diag(diag::warn_debug_compression_unavailable); } @@ -1116,6 +1143,24 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, if (JA.isOffloading(Action::OFK_Cuda)) getToolChain().AddCudaIncludeArgs(Args, CmdArgs); + // If we are offloading to a target via OpenMP we need to include the + // openmp_wrappers folder which contains alternative system headers. + if (JA.isDeviceOffloading(Action::OFK_OpenMP) && + getToolChain().getTriple().isNVPTX()){ + if (!Args.hasArg(options::OPT_nobuiltininc)) { + // Add openmp_wrappers/* to our system include path. This lets us wrap + // standard library headers. + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + llvm::sys::path::append(P, "openmp_wrappers"); + CmdArgs.push_back("-internal-isystem"); + CmdArgs.push_back(Args.MakeArgString(P)); + } + + CmdArgs.push_back("-include"); + CmdArgs.push_back("__clang_openmp_math_declares.h"); + } + // Add -i* options, and automatically translate to // -include-pch/-include-pth for transparent PCH support. It's // wonky, but we include looking for .gch so we can support seamless @@ -1364,6 +1409,9 @@ void Clang::AddARMTargetArgs(const llvm::Triple &Triple, const ArgList &Args, if (!Args.hasFlag(options::OPT_mimplicit_float, options::OPT_mno_implicit_float, true)) CmdArgs.push_back("-no-implicit-float"); + + if (Args.getLastArg(options::OPT_mcmse)) + CmdArgs.push_back("-mcmse"); } void Clang::RenderTargetOptions(const llvm::Triple &EffectiveTriple, @@ -1716,6 +1764,14 @@ void Clang::AddMIPSTargetArgs(const ArgList &Args, } else D.Diag(diag::warn_target_unsupported_compact_branches) << CPUName; } + + if (Arg *A = Args.getLastArg(options::OPT_mrelax_pic_calls, + options::OPT_mno_relax_pic_calls)) { + if (A->getOption().matches(options::OPT_mno_relax_pic_calls)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-mips-jalr-reloc=0"); + } + } } void Clang::AddPPCTargetArgs(const ArgList &Args, @@ -1747,12 +1803,21 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, break; } - if (Arg *A = Args.getLastArg(options::OPT_mabi_EQ)) - // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore - // the option if given as we don't have backend support for any targets - // that don't use the altivec abi. - if (StringRef(A->getValue()) != "altivec") + bool IEEELongDouble = false; + for (const Arg *A : Args.filtered(options::OPT_mabi_EQ)) { + StringRef V = A->getValue(); + if (V == "ieeelongdouble") + IEEELongDouble = true; + else if (V == "ibmlongdouble") + IEEELongDouble = false; + else if (V != "altivec") + // The ppc64 linux abis are all "altivec" abis by default. Accept and ignore + // the option if given as we don't have backend support for any targets + // that don't use the altivec abi. ABIName = A->getValue(); + } + if (IEEELongDouble) + CmdArgs.push_back("-mabi=ieeelongdouble"); ppc::FloatABI FloatABI = ppc::getPPCFloatABI(getToolChain().getDriver(), Args); @@ -2023,6 +2088,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, bool TakeNextArg = false; bool UseRelaxRelocations = C.getDefaultToolChain().useRelaxRelocations(); + bool UseNoExecStack = C.getDefaultToolChain().isNoExecStackDefault(); const char *MipsTargetFeature = nullptr; for (const Arg *A : Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { @@ -2104,7 +2170,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } else if (Value == "--fatal-warnings") { CmdArgs.push_back("-massembler-fatal-warnings"); } else if (Value == "--noexecstack") { - CmdArgs.push_back("-mnoexecstack"); + UseNoExecStack = true; } else if (Value.startswith("-compress-debug-sections") || Value.startswith("--compress-debug-sections") || Value == "-nocompress-debug-sections" || @@ -2167,6 +2233,8 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, } if (UseRelaxRelocations) CmdArgs.push_back("--mrelax-relocations"); + if (UseNoExecStack) + CmdArgs.push_back("-mnoexecstack"); if (MipsTargetFeature != nullptr) { CmdArgs.push_back("-target-feature"); CmdArgs.push_back(MipsTargetFeature); @@ -2676,7 +2744,7 @@ static void RenderModulesOptions(Compilation &C, const Driver &D, } } - HaveModules = HaveClangModules; + HaveModules |= HaveClangModules; if (Args.hasArg(options::OPT_fmodules_ts)) { CmdArgs.push_back("-fmodules-ts"); HaveModules = true; @@ -2837,9 +2905,7 @@ static void RenderCharacterOptions(const ArgList &Args, const llvm::Triple &T, } // The default depends on the language standard. - if (const Arg *A = - Args.getLastArg(options::OPT_fchar8__t, options::OPT_fno_char8__t)) - A->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_fchar8__t, options::OPT_fno_char8__t); if (const Arg *A = Args.getLastArg(options::OPT_fshort_wchar, options::OPT_fno_short_wchar)) { @@ -2905,7 +2971,7 @@ static void RenderObjCOptions(const ToolChain &TC, const Driver &D, // We default off for Objective-C, on for Objective-C++. if (Args.hasFlag(options::OPT_fobjc_arc_exceptions, options::OPT_fno_objc_arc_exceptions, - /*default=*/types::isCXX(Input.getType()))) + /*Default=*/types::isCXX(Input.getType()))) CmdArgs.push_back("-fobjc-arc-exceptions"); } @@ -3125,35 +3191,24 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, SplitDWARFInlining = false; } - if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { - if (checkDebugInfoOption(A, Args, D, TC)) { - // If the last option explicitly specified a debug-info level, use it. - if (A->getOption().matches(options::OPT_gN_Group)) { - DebugInfoKind = DebugLevelToInfoKind(*A); - // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses. - // But -gsplit-dwarf is not a g_group option, hence we have to check the - // order explicitly. If -gsplit-dwarf wins, we fix DebugInfoKind later. - // This gets a bit more complicated if you've disabled inline info in - // the skeleton CUs (SplitDWARFInlining) - then there's value in - // composing split-dwarf and line-tables-only, so let those compose - // naturally in that case. And if you just turned off debug info, - // (-gsplit-dwarf -g0) - do that. - if (DwarfFission != DwarfFissionKind::None) { - if (A->getIndex() > SplitDWARFArg->getIndex()) { - if (DebugInfoKind == codegenoptions::NoDebugInfo || - DebugInfoKind == codegenoptions::DebugDirectivesOnly || - (DebugInfoKind == codegenoptions::DebugLineTablesOnly && - SplitDWARFInlining)) - DwarfFission = DwarfFissionKind::None; - } else if (SplitDWARFInlining) - DebugInfoKind = codegenoptions::NoDebugInfo; - } - } else { - // For any other 'g' option, use Limited. - DebugInfoKind = codegenoptions::LimitedDebugInfo; - } - } else { - DebugInfoKind = codegenoptions::LimitedDebugInfo; + if (const Arg *A = + Args.getLastArg(options::OPT_g_Group, options::OPT_gsplit_dwarf, + options::OPT_gsplit_dwarf_EQ)) { + DebugInfoKind = codegenoptions::LimitedDebugInfo; + + // If the last option explicitly specified a debug-info level, use it. + if (checkDebugInfoOption(A, Args, D, TC) && + A->getOption().matches(options::OPT_gN_Group)) { + DebugInfoKind = DebugLevelToInfoKind(*A); + // For -g0 or -gline-tables-only, drop -gsplit-dwarf. This gets a bit more + // complicated if you've disabled inline info in the skeleton CUs + // (SplitDWARFInlining) - then there's value in composing split-dwarf and + // line-tables-only, so let those compose naturally in that case. + if (DebugInfoKind == codegenoptions::NoDebugInfo || + DebugInfoKind == codegenoptions::DebugDirectivesOnly || + (DebugInfoKind == codegenoptions::DebugLineTablesOnly && + SplitDWARFInlining)) + DwarfFission = DwarfFissionKind::None; } } @@ -3228,32 +3283,18 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D, } } - // -gsplit-dwarf should turn on -g and enable the backend dwarf - // splitting and extraction. - // FIXME: Currently only works on Linux and Fuchsia. - if (T.isOSLinux() || T.isOSFuchsia()) { - if (!SplitDWARFInlining) - CmdArgs.push_back("-fno-split-dwarf-inlining"); - - if (DwarfFission != DwarfFissionKind::None) { - if (DebugInfoKind == codegenoptions::NoDebugInfo) - DebugInfoKind = codegenoptions::LimitedDebugInfo; - - if (DwarfFission == DwarfFissionKind::Single) - CmdArgs.push_back("-enable-split-dwarf=single"); - else - CmdArgs.push_back("-enable-split-dwarf"); - } - } + if (T.isOSBinFormatELF() && !SplitDWARFInlining) + CmdArgs.push_back("-fno-split-dwarf-inlining"); // After we've dealt with all combinations of things that could // make DebugInfoKind be other than None or DebugLineTablesOnly, // figure out if we need to "upgrade" it to standalone debug info. // We parse these two '-f' options whether or not they will be used, // to claim them even if you wrote "-fstandalone-debug -gline-tables-only" - bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug, - options::OPT_fno_standalone_debug, - TC.GetDefaultStandaloneDebug()); + bool NeedFullDebug = Args.hasFlag( + options::OPT_fstandalone_debug, options::OPT_fno_standalone_debug, + DebuggerTuning == llvm::DebuggerKind::LLDB || + TC.GetDefaultStandaloneDebug()); if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug)) (void)checkDebugInfoOption(A, Args, D, TC); if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug) @@ -3416,19 +3457,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } const llvm::Triple *AuxTriple = IsCuda ? TC.getAuxTriple() : nullptr; - bool IsWindowsGNU = RawTriple.isWindowsGNUEnvironment(); - bool IsWindowsCygnus = RawTriple.isWindowsCygwinEnvironment(); bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment(); bool IsIAMCU = RawTriple.isOSIAMCU(); // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in // device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not // Windows), we need to pass Windows-specific flags to cc1. - if (IsCuda || IsHIP) { + if (IsCuda || IsHIP) IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment(); - IsWindowsGNU |= AuxTriple && AuxTriple->isWindowsGNUEnvironment(); - IsWindowsCygnus |= AuxTriple && AuxTriple->isWindowsCygwinEnvironment(); - } // C++ is not supported for IAMCU. if (IsIAMCU && types::isCXX(Input.getType())) @@ -3457,13 +3493,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, NormalizedTriple = C.getSingleOffloadToolChain<Action::OFK_Host>() ->getTriple() .normalize(); - else + else { + // Host-side compilation. NormalizedTriple = (IsCuda ? C.getSingleOffloadToolChain<Action::OFK_Cuda>() : C.getSingleOffloadToolChain<Action::OFK_HIP>()) ->getTriple() .normalize(); - + if (IsCuda) { + // We need to figure out which CUDA version we're compiling for, as that + // determines how we load and launch GPU kernels. + auto *CTC = static_cast<const toolchains::CudaToolChain *>( + C.getSingleOffloadToolChain<Action::OFK_Cuda>()); + assert(CTC && "Expected valid CUDA Toolchain."); + if (CTC && CTC->CudaInstallation.version() != CudaVersion::UNKNOWN) + CmdArgs.push_back(Args.MakeArgString( + Twine("-target-sdk-version=") + + CudaVersionToString(CTC->CudaInstallation.version()))); + } + } CmdArgs.push_back("-aux-triple"); CmdArgs.push_back(Args.MakeArgString(NormalizedTriple)); } @@ -3539,6 +3587,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } else if (JA.getType() == types::TY_LLVM_BC || JA.getType() == types::TY_LTO_BC) { CmdArgs.push_back("-emit-llvm-bc"); + } else if (JA.getType() == types::TY_IFS) { + StringRef StubFormat = + llvm::StringSwitch<StringRef>( + Args.hasArg(options::OPT_iterface_stub_version_EQ) + ? Args.getLastArgValue(options::OPT_iterface_stub_version_EQ) + : "") + .Case("experimental-yaml-elf-v1", "experimental-yaml-elf-v1") + .Case("experimental-tapi-elf-v1", "experimental-tapi-elf-v1") + .Default(""); + + if (StubFormat.empty()) + D.Diag(diag::err_drv_invalid_value) + << "Must specify a valid interface stub format type using " + << "-interface-stub-version=<experimental-tapi-elf-v1 | " + "experimental-yaml-elf-v1>"; + + CmdArgs.push_back("-emit-interface-stubs"); + CmdArgs.push_back( + Args.MakeArgString(Twine("-interface-stub-version=") + StubFormat)); } else if (JA.getType() == types::TY_PP_Asm) { CmdArgs.push_back("-S"); } else if (JA.getType() == types::TY_AST) { @@ -3580,8 +3647,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (const Arg *A = Args.getLastArg(options::OPT_fthinlto_index_EQ)) { if (!types::isLLVMIR(Input.getType())) - D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args) - << "-x ir"; + D.Diag(diag::err_drv_arg_requires_bitcode_input) << A->getAsString(Args); Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ); } @@ -3597,6 +3663,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Disable all llvm IR level optimizations. CmdArgs.push_back("-disable-llvm-passes"); + // Render target options such as -fuse-init-array on modern ELF platforms. + TC.addClangTargetOptions(Args, CmdArgs, JA.getOffloadingDeviceKind()); + // reject options that shouldn't be supported in bitcode // also reject kernel/kext static const constexpr unsigned kBitcodeOptionBlacklist[] = { @@ -3638,9 +3707,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_mllvm, }; for (const auto &A : Args) - if (std::find(std::begin(kBitcodeOptionBlacklist), - std::end(kBitcodeOptionBlacklist), - A->getOption().getID()) != + if (llvm::find(kBitcodeOptionBlacklist, A->getOption().getID()) != std::end(kBitcodeOptionBlacklist)) D.Diag(diag::err_drv_unsupported_embed_bitcode) << A->getSpelling(); @@ -3790,6 +3857,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-pic-is-pie"); } + if (RelocationModel == llvm::Reloc::ROPI || + RelocationModel == llvm::Reloc::ROPI_RWPI) + CmdArgs.push_back("-fropi"); + if (RelocationModel == llvm::Reloc::RWPI || + RelocationModel == llvm::Reloc::ROPI_RWPI) + CmdArgs.push_back("-frwpi"); + if (Arg *A = Args.getLastArg(options::OPT_meabi)) { CmdArgs.push_back("-meabi"); CmdArgs.push_back(A->getValue()); @@ -3872,8 +3946,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasFlag(options::OPT_mrtd, options::OPT_mno_rtd, false)) CmdArgs.push_back("-fdefault-calling-conv=stdcall"); - if (shouldUseFramePointer(Args, RawTriple)) + FramePointerKind FPKeepKind = getFramePointerKind(Args, RawTriple); + if (FPKeepKind != FramePointerKind::None) { CmdArgs.push_back("-mdisable-fp-elim"); + if (FPKeepKind == FramePointerKind::NonLeaf) + CmdArgs.push_back("-momit-leaf-frame-pointer"); + } if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, options::OPT_fno_zero_initialized_in_bss)) CmdArgs.push_back("-mno-zero-initialized-in-bss"); @@ -3925,6 +4003,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, RenderFloatingPointOptions(TC, D, OFastEnabled, Args, CmdArgs); + if (Arg *A = Args.getLastArg(options::OPT_mlong_double_64, + options::OPT_mlong_double_128)) { + if (TC.getArch() == llvm::Triple::x86 || + TC.getArch() == llvm::Triple::x86_64 || + TC.getArch() == llvm::Triple::ppc || TC.getTriple().isPPC64()) + A->render(Args, CmdArgs); + else + D.Diag(diag::err_drv_unsupported_opt_for_target) + << A->getAsString(Args) << TripleStr; + } + // Decide whether to use verbose asm. Verbose assembly is the default on // toolchains which have the integrated assembler on by default. bool IsIntegratedAssemblerDefault = TC.IsIntegratedAssemblerDefault(); @@ -4028,14 +4117,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Add the split debug info name to the command lines here so we // can propagate it to the backend. bool SplitDWARF = (DwarfFission != DwarfFissionKind::None) && - (RawTriple.isOSLinux() || RawTriple.isOSFuchsia()) && + TC.getTriple().isOSBinFormatELF() && (isa<AssembleJobAction>(JA) || isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)); - const char *SplitDWARFOut; if (SplitDWARF) { + const char *SplitDWARFOut = SplitDebugName(Args, Input, Output); CmdArgs.push_back("-split-dwarf-file"); - SplitDWARFOut = SplitDebugName(Args, Output); CmdArgs.push_back(SplitDWARFOut); + if (DwarfFission == DwarfFissionKind::Split) { + CmdArgs.push_back("-split-dwarf-output"); + CmdArgs.push_back(SplitDWARFOut); + } } // Pass the linker version in use. @@ -4044,9 +4136,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(A->getValue()); } - if (!shouldUseLeafFramePointer(Args, RawTriple)) - CmdArgs.push_back("-momit-leaf-frame-pointer"); - // Explicitly error on some things we know we don't support and can't just // ignore. if (!Args.hasArg(options::OPT_fallow_unsupported)) { @@ -4100,20 +4189,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_unique_section_names, true)) CmdArgs.push_back("-fno-unique-section-names"); - if (auto *A = Args.getLastArg( - options::OPT_finstrument_functions, - options::OPT_finstrument_functions_after_inlining, - options::OPT_finstrument_function_entry_bare)) - A->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_finstrument_functions, + options::OPT_finstrument_functions_after_inlining, + options::OPT_finstrument_function_entry_bare); // NVPTX doesn't support PGO or coverage. There's no runtime support for // sampling, overhead of call arc collection is way too high and there's no // way to collect the output. if (!Triple.isNVPTX()) - addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs); + addPGOAndCoverageFlags(TC, C, D, Output, Args, CmdArgs); - if (auto *ABICompatArg = Args.getLastArg(options::OPT_fclang_abi_compat_EQ)) - ABICompatArg->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_fclang_abi_compat_EQ); // Add runtime flag for PS4 when PGO, coverage, or sanitizers are enabled. if (RawTriple.isPS4CPU() && @@ -4198,7 +4284,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // If a std is supplied, only add -trigraphs if it follows the // option. bool ImplyVCPPCXXVer = false; - if (Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi)) { + const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi); + if (Std) { if (Std->getOption().matches(options::OPT_ansi)) if (types::isCXX(InputType)) CmdArgs.push_back("-std=c++98"); @@ -4274,7 +4361,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fno-autolink"); // Add in -fdebug-compilation-dir if necessary. - addDebugCompDirArg(Args, CmdArgs); + addDebugCompDirArg(Args, CmdArgs, D.getVFS()); addDebugPrefixMapArg(D, Args, CmdArgs); @@ -4437,6 +4524,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_version_EQ); Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_number_of_sm_EQ); Args.AddAllArgs(CmdArgs, options::OPT_fopenmp_cuda_blocks_per_sm_EQ); + Args.AddAllArgs(CmdArgs, + options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ); if (Args.hasFlag(options::OPT_fopenmp_optimistic_collapse, options::OPT_fno_openmp_optimistic_collapse, /*Default=*/false)) @@ -4495,7 +4584,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_print_source_range_info); Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_parseable_fixits); Args.AddLastArg(CmdArgs, options::OPT_ftime_report); + Args.AddLastArg(CmdArgs, options::OPT_ftime_trace); Args.AddLastArg(CmdArgs, options::OPT_ftrapv); + Args.AddLastArg(CmdArgs, options::OPT_malign_double); if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) { CmdArgs.push_back("-ftrapv-handler"); @@ -4584,6 +4675,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Forward -f options with positive and negative forms; we translate // these by hand. if (Arg *A = getLastProfileSampleUseArg(Args)) { + auto *PGOArg = Args.getLastArg( + options::OPT_fprofile_generate, options::OPT_fprofile_generate_EQ, + options::OPT_fcs_profile_generate, options::OPT_fcs_profile_generate_EQ, + options::OPT_fprofile_use, options::OPT_fprofile_use_EQ); + if (PGOArg) + D.Diag(diag::err_drv_argument_not_allowed_with) + << "SampleUse with PGO options"; + StringRef fname = A->getValue(); if (!llvm::sys::fs::exists(fname)) D.Diag(diag::err_drv_no_such_file) << fname; @@ -4623,9 +4722,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_fdouble_square_bracket_attributes, options::OPT_fno_double_square_bracket_attributes); - bool HaveModules = false; - RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules); - // -faccess-control is default. if (Args.hasFlag(options::OPT_fno_access_control, options::OPT_faccess_control, false)) @@ -4653,7 +4749,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag( options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, !RawTriple.isOSWindows() && - RawTriple.getOS() != llvm::Triple::Solaris && TC.getArch() != llvm::Triple::xcore && ((RawTriple.getVendor() != llvm::Triple::MipsTechnologies) || RawTriple.hasEnvironment())) || @@ -4692,6 +4787,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (ImplyVCPPCXXVer) { StringRef LanguageStandard; if (const Arg *StdArg = Args.getLastArg(options::OPT__SLASH_std)) { + Std = StdArg; LanguageStandard = llvm::StringSwitch<StringRef>(StdArg->getValue()) .Case("c++14", "-std=c++14") .Case("c++17", "-std=c++17") @@ -4741,9 +4837,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fgnu-keywords default varies depending on language; only pass if // specified. - if (Arg *A = Args.getLastArg(options::OPT_fgnu_keywords, - options::OPT_fno_gnu_keywords)) - A->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_fgnu_keywords, + options::OPT_fno_gnu_keywords); if (Args.hasFlag(options::OPT_fgnu89_inline, options::OPT_fno_gnu89_inline, false)) @@ -4752,10 +4847,15 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fno_inline)) CmdArgs.push_back("-fno-inline"); - if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions, - options::OPT_finline_hint_functions, - options::OPT_fno_inline_functions)) - InlineArg->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_finline_functions, + options::OPT_finline_hint_functions, + options::OPT_fno_inline_functions); + + // FIXME: Find a better way to determine whether the language has modules + // support by default, or just assume that all languages do. + bool HaveModules = + Std && (Std->containsValue("c++2a") || Std->containsValue("c++latest")); + RenderModulesOptions(C, D, Args, Input, Output, CmdArgs, HaveModules); Args.AddLastArg(CmdArgs, options::OPT_fexperimental_new_pass_manager, options::OPT_fno_experimental_new_pass_manager); @@ -4944,12 +5044,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, ParseMPreferVectorWidth(D, Args, CmdArgs); - if (Arg *A = Args.getLastArg(options::OPT_fshow_overloads_EQ)) - A->render(Args, CmdArgs); - - if (Arg *A = Args.getLastArg( - options::OPT_fsanitize_undefined_strip_path_components_EQ)) - A->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_fshow_overloads_EQ); + Args.AddLastArg(CmdArgs, + options::OPT_fsanitize_undefined_strip_path_components_EQ); // -fdollars-in-identifiers default varies depending on platform and // language; only pass if specified. @@ -4973,8 +5070,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, options::OPT_fno_apple_pragma_pack, false)) CmdArgs.push_back("-fapple-pragma-pack"); + // Remarks can be enabled with any of the `-f.*optimization-record.*` flags. if (Args.hasFlag(options::OPT_fsave_optimization_record, options::OPT_foptimization_record_file_EQ, + options::OPT_fno_save_optimization_record, false) || + Args.hasFlag(options::OPT_fsave_optimization_record_EQ, + options::OPT_fno_save_optimization_record, false) || + Args.hasFlag(options::OPT_foptimization_record_passes_EQ, options::OPT_fno_save_optimization_record, false)) { CmdArgs.push_back("-opt-record-file"); @@ -5006,9 +5108,28 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } - llvm::sys::path::replace_extension(F, "opt.yaml"); + std::string Extension = "opt."; + if (const Arg *A = + Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) + Extension += A->getValue(); + else + Extension += "yaml"; + + llvm::sys::path::replace_extension(F, Extension); CmdArgs.push_back(Args.MakeArgString(F)); } + + if (const Arg *A = + Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) { + CmdArgs.push_back("-opt-record-passes"); + CmdArgs.push_back(A->getValue()); + } + + if (const Arg *A = + Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) { + CmdArgs.push_back("-opt-record-format"); + CmdArgs.push_back(A->getValue()); + } } bool RewriteImports = Args.hasFlag(options::OPT_frewrite_imports, @@ -5058,6 +5179,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->claim(); } + // Forward -fpass-plugin=name.so to -cc1. + for (const Arg *A : Args.filtered(options::OPT_fpass_plugin_EQ)) { + CmdArgs.push_back( + Args.MakeArgString(Twine("-fpass-plugin=") + A->getValue())); + A->claim(); + } + // Setup statistics file output. SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D); if (!StatsFile.empty()) @@ -5104,30 +5232,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, isa<CompileJobAction>(JA)) CmdArgs.push_back("-disable-llvm-passes"); - if (Output.getType() == types::TY_Dependencies) { - // Handled with other dependency code. - } else if (Output.isFilename()) { - CmdArgs.push_back("-o"); - CmdArgs.push_back(Output.getFilename()); - } else { - assert(Output.isNothing() && "Invalid output."); - } - - addDashXForInput(Args, Input, CmdArgs); - - ArrayRef<InputInfo> FrontendInputs = Input; - if (IsHeaderModulePrecompile) - FrontendInputs = ModuleHeaderInputs; - else if (Input.isNothing()) - FrontendInputs = {}; - - for (const InputInfo &Input : FrontendInputs) { - if (Input.isFilename()) - CmdArgs.push_back(Input.getFilename()); - else - Input.getInputArg().renderAsInput(Args, CmdArgs); - } - Args.AddAllArgs(CmdArgs, options::OPT_undef); const char *Exec = D.getClangProgramPath(); @@ -5271,6 +5375,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } + if (Args.hasArg(options::OPT_forder_file_instrumentation)) { + CmdArgs.push_back("-forder-file-instrumentation"); + // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is + // on, we need to pass these flags as linker flags and that will be handled + // outside of the compiler. + if (!D.isUsingLTO()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-enable-order-file-instrumentation"); + } + } + if (Arg *A = Args.getLastArg(options::OPT_fforce_enable_int128, options::OPT_fno_force_enable_int128)) { if (A->getOption().matches(options::OPT_fforce_enable_int128)) @@ -5314,6 +5429,40 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, TC.useIntegratedAs())) CmdArgs.push_back("-faddrsig"); + if (Arg *A = Args.getLastArg(options::OPT_fsymbol_partition_EQ)) { + std::string Str = A->getAsString(Args); + if (!TC.getTriple().isOSBinFormatELF()) + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Str << TC.getTripleString(); + CmdArgs.push_back(Args.MakeArgString(Str)); + } + + // Add the "-o out -x type src.c" flags last. This is done primarily to make + // the -cc1 command easier to edit when reproducing compiler crashes. + if (Output.getType() == types::TY_Dependencies) { + // Handled with other dependency code. + } else if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } else { + assert(Output.isNothing() && "Invalid output."); + } + + addDashXForInput(Args, Input, CmdArgs); + + ArrayRef<InputInfo> FrontendInputs = Input; + if (IsHeaderModulePrecompile) + FrontendInputs = ModuleHeaderInputs; + else if (Input.isNothing()) + FrontendInputs = {}; + + for (const InputInfo &Input : FrontendInputs) { + if (Input.isFilename()) + CmdArgs.push_back(Input.getFilename()); + else + Input.getInputArg().renderAsInput(Args, CmdArgs); + } + // Finally add the compile command to the compilation. if (Args.hasArg(options::OPT__SLASH_fallback) && Output.getType() == types::TY_Object && @@ -5340,7 +5489,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } if (Arg *A = Args.getLastArg(options::OPT_pg)) - if (!shouldUseFramePointer(Args, Triple)) + if (FPKeepKind == FramePointerKind::None) D.Diag(diag::err_drv_argument_not_allowed_with) << "-fomit-frame-pointer" << A->getAsString(Args); @@ -5552,7 +5701,7 @@ static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) { // The default is that /GX is not specified. if (EHArgs.empty() && Args.hasFlag(options::OPT__SLASH_GX, options::OPT__SLASH_GX_, - /*default=*/false)) { + /*Default=*/false)) { EH.Synch = true; EH.NoUnwindC = true; } @@ -5617,18 +5766,17 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back("--dependent-lib=oldnames"); } - if (Arg *A = Args.getLastArg(options::OPT_show_includes)) - A->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_show_includes); // This controls whether or not we emit RTTI data for polymorphic types. if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR, - /*default=*/false)) + /*Default=*/false)) CmdArgs.push_back("-fno-rtti-data"); // This controls whether or not we emit stack-protector instrumentation. // In MSVC, Buffer Security Check (/GS) is on by default. if (Args.hasFlag(options::OPT__SLASH_GS, options::OPT__SLASH_GS_, - /*default=*/true)) { + /*Default=*/true)) { CmdArgs.push_back("-stack-protector"); CmdArgs.push_back(Args.MakeArgString(Twine(LangOptions::SSPStrong))); } @@ -5747,8 +5895,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, CmdArgs.push_back(DCCFlag); } - if (Arg *A = Args.getLastArg(options::OPT_vtordisp_mode_EQ)) - A->render(Args, CmdArgs); + Args.AddLastArg(CmdArgs, options::OPT_vtordisp_mode_EQ); if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) { CmdArgs.push_back("-fdiagnostics-format"); @@ -5845,6 +5992,15 @@ void ClangAs::AddX86TargetArgs(const ArgList &Args, } } +void ClangAs::AddRISCVTargetArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + const llvm::Triple &Triple = getToolChain().getTriple(); + StringRef ABIName = riscv::getRISCVABI(Args, Triple); + + CmdArgs.push_back("-target-abi"); + CmdArgs.push_back(ABIName.data()); +} + void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, @@ -5932,7 +6088,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, DebugInfoKind = (WantDebug ? codegenoptions::LimitedDebugInfo : codegenoptions::NoDebugInfo); // Add the -fdebug-compilation-dir flag if needed. - addDebugCompDirArg(Args, CmdArgs); + addDebugCompDirArg(Args, CmdArgs, C.getDriver().getVFS()); addDebugPrefixMapArg(getToolChain().getDriver(), Args, CmdArgs); @@ -6014,6 +6170,11 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-arm-add-build-attributes"); } break; + + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: + AddRISCVTargetArgs(Args, CmdArgs); + break; } // Consume all the warning flags. Usually this would be handled more @@ -6034,10 +6195,10 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA, const llvm::Triple &T = getToolChain().getTriple(); Arg *A; - if ((getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split) && - (T.isOSLinux() || T.isOSFuchsia())) { - CmdArgs.push_back("-split-dwarf-file"); - CmdArgs.push_back(SplitDebugName(Args, Output)); + if (getDebugFissionKind(D, Args, A) == DwarfFissionKind::Split && + T.isOSBinFormatELF()) { + CmdArgs.push_back("-split-dwarf-output"); + CmdArgs.push_back(SplitDebugName(Args, Input, Output)); } assert(Input.isFilename() && "Invalid input."); diff --git a/lib/Driver/ToolChains/Clang.h b/lib/Driver/ToolChains/Clang.h index df67fb2cb331..fc4f5ecdd28a 100644 --- a/lib/Driver/ToolChains/Clang.h +++ b/lib/Driver/ToolChains/Clang.h @@ -1,9 +1,8 @@ //===--- Clang.h - Clang Tool and ToolChain Implementations ====-*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -120,6 +119,8 @@ public: llvm::opt::ArgStringList &CmdArgs) const; void AddX86TargetArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + void AddRISCVTargetArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; bool hasGoodDiagnostics() const override { return true; } bool hasIntegratedAssembler() const override { return false; } bool hasIntegratedCPP() const override { return false; } diff --git a/lib/Driver/ToolChains/CloudABI.cpp b/lib/Driver/ToolChains/CloudABI.cpp index 80f9fc493fd8..cc1ac3ab7e79 100644 --- a/lib/Driver/ToolChains/CloudABI.cpp +++ b/lib/Driver/ToolChains/CloudABI.cpp @@ -1,9 +1,8 @@ //===--- CloudABI.cpp - CloudABI ToolChain Implementations ------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/CloudABI.h b/lib/Driver/ToolChains/CloudABI.h index 7464c5954555..cc381c2b1e1f 100644 --- a/lib/Driver/ToolChains/CloudABI.h +++ b/lib/Driver/ToolChains/CloudABI.h @@ -1,9 +1,8 @@ //===--- CloudABI.h - CloudABI ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index d7e316befa61..99691cb43dc4 100644 --- a/lib/Driver/ToolChains/CommonArgs.cpp +++ b/lib/Driver/ToolChains/CommonArgs.cpp @@ -1,9 +1,8 @@ //===--- CommonArgs.cpp - Args handling for multiple toolchains -*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -444,6 +443,35 @@ void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName)); } + auto *CSPGOGenerateArg = Args.getLastArg(options::OPT_fcs_profile_generate, + options::OPT_fcs_profile_generate_EQ, + options::OPT_fno_profile_generate); + if (CSPGOGenerateArg && + CSPGOGenerateArg->getOption().matches(options::OPT_fno_profile_generate)) + CSPGOGenerateArg = nullptr; + + auto *ProfileUseArg = getLastProfileUseArg(Args); + + if (CSPGOGenerateArg) { + CmdArgs.push_back(Args.MakeArgString("-plugin-opt=cs-profile-generate")); + if (CSPGOGenerateArg->getOption().matches( + options::OPT_fcs_profile_generate_EQ)) { + SmallString<128> Path(CSPGOGenerateArg->getValue()); + llvm::sys::path::append(Path, "default_%m.profraw"); + CmdArgs.push_back( + Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") + Path)); + } else + CmdArgs.push_back( + Args.MakeArgString("-plugin-opt=cs-profile-path=default_%m.profraw")); + } else if (ProfileUseArg) { + SmallString<128> Path( + ProfileUseArg->getNumValues() == 0 ? "" : ProfileUseArg->getValue()); + if (Path.empty() || llvm::sys::fs::is_directory(Path)) + llvm::sys::path::append(Path, "default.profdata"); + CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=cs-profile-path=") + + Path)); + } + // Need this flag to turn on new pass manager via Gold plugin. if (Args.hasFlag(options::OPT_fexperimental_new_pass_manager, options::OPT_fno_experimental_new_pass_manager, @@ -511,7 +539,8 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, // Wrap any static runtimes that must be forced into executable in // whole-archive. if (IsWhole) CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back(TC.getCompilerRTArgString(Args, Sanitizer, IsShared)); + CmdArgs.push_back(TC.getCompilerRTArgString( + Args, Sanitizer, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static)); if (IsWhole) CmdArgs.push_back("--no-whole-archive"); if (IsShared) { @@ -541,40 +570,6 @@ static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, return false; } -static void addSanitizerLibPath(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs, StringRef Name) { - for (const auto &LibPath : TC.getLibraryPaths()) { - if (!LibPath.empty()) { - SmallString<128> P(LibPath); - llvm::sys::path::append(P, Name); - if (TC.getVFS().exists(P)) - CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + P)); - } - } -} - -void tools::addSanitizerPathLibArgs(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs) { - const SanitizerArgs &SanArgs = TC.getSanitizerArgs(); - if (SanArgs.needsAsanRt()) { - addSanitizerLibPath(TC, Args, CmdArgs, "asan"); - } - if (SanArgs.needsHwasanRt()) { - addSanitizerLibPath(TC, Args, CmdArgs, "hwasan"); - } - if (SanArgs.needsLsanRt()) { - addSanitizerLibPath(TC, Args, CmdArgs, "lsan"); - } - if (SanArgs.needsMsanRt()) { - addSanitizerLibPath(TC, Args, CmdArgs, "msan"); - } - if (SanArgs.needsTsanRt()) { - addSanitizerLibPath(TC, Args, CmdArgs, "tsan"); - } -} - - - void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) { // Force linking against the system libraries sanitizers depends on @@ -689,8 +684,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, NonWholeStaticRuntimes.push_back("stats"); RequiredSymbols.push_back("__sanitizer_stats_register"); } - if (SanArgs.needsEsanRt()) - StaticRuntimes.push_back("esan"); if (SanArgs.needsScudoRt()) { if (SanArgs.requiresMinimalRuntime()) { StaticRuntimes.push_back("scudo_minimal"); @@ -758,9 +751,9 @@ bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringLis if (TC.getXRayArgs().needsXRayRt()) { CmdArgs.push_back("-whole-archive"); - CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray", false)); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, "xray")); for (const auto &Mode : TC.getXRayArgs().modeList()) - CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode, false)); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, Mode)); CmdArgs.push_back("-no-whole-archive"); return true; } @@ -789,18 +782,26 @@ bool tools::areOptimizationsEnabled(const ArgList &Args) { return false; } -const char *tools::SplitDebugName(const ArgList &Args, +const char *tools::SplitDebugName(const ArgList &Args, const InputInfo &Input, const InputInfo &Output) { - SmallString<128> F(Output.isFilename() - ? Output.getFilename() - : llvm::sys::path::stem(Output.getBaseInput())); - if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ)) if (StringRef(A->getValue()) == "single") - return Args.MakeArgString(F); + return Args.MakeArgString(Output.getFilename()); - llvm::sys::path::replace_extension(F, "dwo"); - return Args.MakeArgString(F); + Arg *FinalOutput = Args.getLastArg(options::OPT_o); + if (FinalOutput && Args.hasArg(options::OPT_c)) { + SmallString<128> T(FinalOutput->getValue()); + llvm::sys::path::replace_extension(T, "dwo"); + return Args.MakeArgString(T); + } else { + // Use the compilation dir. + SmallString<128> T( + Args.getLastArgValue(options::OPT_fdebug_compilation_dir)); + SmallString<128> F(llvm::sys::path::stem(Input.getBaseInput())); + llvm::sys::path::replace_extension(F, "dwo"); + T += F; + return Args.MakeArgString(F); + } } void tools::SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, @@ -1132,46 +1133,72 @@ bool tools::isObjCAutoRefCount(const ArgList &Args) { return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false); } -static void AddLibgcc(const llvm::Triple &Triple, const Driver &D, - ArgStringList &CmdArgs, const ArgList &Args) { - bool isAndroid = Triple.isAndroid(); - bool isCygMing = Triple.isOSCygMing(); - bool IsIAMCU = Triple.isOSIAMCU(); - bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) || - Args.hasArg(options::OPT_static); - - bool SharedLibgcc = Args.hasArg(options::OPT_shared_libgcc); - bool UnspecifiedLibgcc = !StaticLibgcc && !SharedLibgcc; +enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc }; - // Gcc adds libgcc arguments in various ways: - // - // gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed - // g++ <none>: -lgcc_s -lgcc - // gcc shared: -lgcc_s -lgcc - // g++ shared: -lgcc_s -lgcc - // gcc static: -lgcc -lgcc_eh - // g++ static: -lgcc -lgcc_eh - // - // Also, certain targets need additional adjustments. +static LibGccType getLibGccType(const Driver &D, const ArgList &Args) { + if (Args.hasArg(options::OPT_static_libgcc) || + Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie)) + return LibGccType::StaticLibGcc; + if (Args.hasArg(options::OPT_shared_libgcc) || D.CCCIsCXX()) + return LibGccType::SharedLibGcc; + return LibGccType::UnspecifiedLibGcc; +} - bool LibGccFirst = (D.CCCIsCC() && UnspecifiedLibgcc) || StaticLibgcc; - if (LibGccFirst) - CmdArgs.push_back("-lgcc"); +// Gcc adds libgcc arguments in various ways: +// +// gcc <none>: -lgcc --as-needed -lgcc_s --no-as-needed +// g++ <none>: -lgcc_s -lgcc +// gcc shared: -lgcc_s -lgcc +// g++ shared: -lgcc_s -lgcc +// gcc static: -lgcc -lgcc_eh +// g++ static: -lgcc -lgcc_eh +// gcc static-pie: -lgcc -lgcc_eh +// g++ static-pie: -lgcc -lgcc_eh +// +// Also, certain targets need additional adjustments. + +static void AddUnwindLibrary(const ToolChain &TC, const Driver &D, + ArgStringList &CmdArgs, const ArgList &Args) { + ToolChain::UnwindLibType UNW = TC.GetUnwindLibType(Args); + // Targets that don't use unwind libraries. + if (TC.getTriple().isAndroid() || TC.getTriple().isOSIAMCU() || + TC.getTriple().isOSBinFormatWasm() || + UNW == ToolChain::UNW_None) + return; - bool AsNeeded = D.CCCIsCC() && UnspecifiedLibgcc && !isAndroid && !isCygMing; + LibGccType LGT = getLibGccType(D, Args); + bool AsNeeded = LGT == LibGccType::UnspecifiedLibGcc && + !TC.getTriple().isAndroid() && !TC.getTriple().isOSCygMing(); if (AsNeeded) CmdArgs.push_back("--as-needed"); - if ((UnspecifiedLibgcc || SharedLibgcc) && !isAndroid) - CmdArgs.push_back("-lgcc_s"); - - else if (StaticLibgcc && !isAndroid && !IsIAMCU) - CmdArgs.push_back("-lgcc_eh"); + switch (UNW) { + case ToolChain::UNW_None: + return; + case ToolChain::UNW_Libgcc: { + LibGccType LGT = getLibGccType(D, Args); + if (LGT == LibGccType::StaticLibGcc) + CmdArgs.push_back("-lgcc_eh"); + else + CmdArgs.push_back("-lgcc_s"); + break; + } + case ToolChain::UNW_CompilerRT: + CmdArgs.push_back("-lunwind"); + break; + } if (AsNeeded) CmdArgs.push_back("--no-as-needed"); +} - if (!LibGccFirst) +static void AddLibgcc(const ToolChain &TC, const Driver &D, + ArgStringList &CmdArgs, const ArgList &Args) { + LibGccType LGT = getLibGccType(D, Args); + if (LGT != LibGccType::SharedLibGcc) + CmdArgs.push_back("-lgcc"); + AddUnwindLibrary(TC, D, CmdArgs, Args); + if (LGT == LibGccType::SharedLibGcc) CmdArgs.push_back("-lgcc"); // According to Android ABI, we have to link with libdl if we are @@ -1179,7 +1206,7 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D, // // NOTE: This fixes a link error on Android MIPS as well. The non-static // libgcc for MIPS relies on _Unwind_Find_FDE and dl_iterate_phdr from libdl. - if (isAndroid && !StaticLibgcc) + if (TC.getTriple().isAndroid() && LGT != LibGccType::StaticLibGcc) CmdArgs.push_back("-ldl"); } @@ -1191,6 +1218,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D, switch (RLT) { case ToolChain::RLT_CompilerRT: CmdArgs.push_back(TC.getCompilerRTArgString(Args, "builtins")); + AddUnwindLibrary(TC, D, CmdArgs, Args); break; case ToolChain::RLT_Libgcc: // Make sure libgcc is not used under MSVC environment by default @@ -1202,7 +1230,7 @@ void tools::AddRunTimeLibs(const ToolChain &TC, const Driver &D, << Args.getLastArg(options::OPT_rtlib_EQ)->getValue() << "MSVC"; } } else - AddLibgcc(TC.getTriple(), D, CmdArgs, Args); + AddLibgcc(TC, D, CmdArgs, Args); break; } } @@ -1463,3 +1491,8 @@ SmallString<128> tools::getStatsFileName(const llvm::opt::ArgList &Args, llvm::sys::path::replace_extension(StatsFile, "stats"); return StatsFile; } + +void tools::addMultilibFlag(bool Enabled, const char *const Flag, + Multilib::flags_list &Flags) { + Flags.push_back(std::string(Enabled ? "+" : "-") + Flag); +} diff --git a/lib/Driver/ToolChains/CommonArgs.h b/lib/Driver/ToolChains/CommonArgs.h index 3704b2e01b54..9a311708f3ae 100644 --- a/lib/Driver/ToolChains/CommonArgs.h +++ b/lib/Driver/ToolChains/CommonArgs.h @@ -1,9 +1,8 @@ //===--- CommonArgs.h - Args handling for multiple toolchains ---*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -12,6 +11,7 @@ #include "InputInfo.h" #include "clang/Driver/Driver.h" +#include "clang/Driver/Multilib.h" #include "clang/Driver/Tool.h" #include "clang/Driver/ToolChain.h" #include "llvm/Support/CodeGen.h" @@ -32,10 +32,6 @@ void claimNoWarnArgs(const llvm::opt::ArgList &Args); bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs); -void addSanitizerPathLibArgs(const ToolChain &TC, - const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs); - void linkSanitizerRuntimeDeps(const ToolChain &TC, llvm::opt::ArgStringList &CmdArgs); @@ -63,7 +59,7 @@ void AddHIPLinkerScript(const ToolChain &TC, Compilation &C, const Tool &T); const char *SplitDebugName(const llvm::opt::ArgList &Args, - const InputInfo &Output); + const InputInfo &Input, const InputInfo &Output); void SplitDebugInfo(const ToolChain &TC, Compilation &C, const Tool &T, const JobAction &JA, const llvm::opt::ArgList &Args, @@ -122,6 +118,12 @@ void handleTargetFeaturesGroup(const llvm::opt::ArgList &Args, SmallString<128> getStatsFileName(const llvm::opt::ArgList &Args, const InputInfo &Output, const InputInfo &Input, const Driver &D); + +/// \p Flag must be a flag accepted by the driver with its leading '-' removed, +// otherwise '-print-multi-lib' will not emit them correctly. +void addMultilibFlag(bool Enabled, const char *const Flag, + Multilib::flags_list &Flags); + } // end namespace tools } // end namespace driver } // end namespace clang diff --git a/lib/Driver/ToolChains/Contiki.cpp b/lib/Driver/ToolChains/Contiki.cpp index 7f74bfcb4b01..5dda1b1b09fb 100644 --- a/lib/Driver/ToolChains/Contiki.cpp +++ b/lib/Driver/ToolChains/Contiki.cpp @@ -1,9 +1,8 @@ //===--- Contiki.cpp - Contiki ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Contiki.h b/lib/Driver/ToolChains/Contiki.h index 86d59ac92b16..627d80bdda09 100644 --- a/lib/Driver/ToolChains/Contiki.h +++ b/lib/Driver/ToolChains/Contiki.h @@ -1,9 +1,8 @@ //===--- Contiki.h - Contiki ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/CrossWindows.cpp b/lib/Driver/ToolChains/CrossWindows.cpp index 795356026fbe..bd3a6e11c928 100644 --- a/lib/Driver/ToolChains/CrossWindows.cpp +++ b/lib/Driver/ToolChains/CrossWindows.cpp @@ -1,9 +1,8 @@ -//===--- CrossWindowsToolChain.cpp - Cross Windows Tool Chain -------------===// +//===-- CrossWindows.cpp - Cross Windows Tool Chain -----------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -278,6 +277,8 @@ AddCXXStdlibLibArgs(const llvm::opt::ArgList &DriverArgs, clang::SanitizerMask CrossWindowsToolChain::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; return Res; } diff --git a/lib/Driver/ToolChains/CrossWindows.h b/lib/Driver/ToolChains/CrossWindows.h index 2f66446ec732..7267a35d48b9 100644 --- a/lib/Driver/ToolChains/CrossWindows.h +++ b/lib/Driver/ToolChains/CrossWindows.h @@ -1,9 +1,8 @@ //===--- CrossWindows.h - CrossWindows ToolChain Implementation -*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Cuda.cpp b/lib/Driver/ToolChains/Cuda.cpp index 57b8d4340e3b..96f8c513bb56 100644 --- a/lib/Driver/ToolChains/Cuda.cpp +++ b/lib/Driver/ToolChains/Cuda.cpp @@ -1,9 +1,8 @@ //===--- Cuda.cpp - Cuda Tool and ToolChain Implementations -----*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -61,6 +60,8 @@ static CudaVersion ParseCudaVersionFile(llvm::StringRef V) { return CudaVersion::CUDA_92; if (Major == 10 && Minor == 0) return CudaVersion::CUDA_100; + if (Major == 10 && Minor == 1) + return CudaVersion::CUDA_101; return CudaVersion::UNKNOWN; } @@ -453,7 +454,8 @@ void NVPTX::Linker::ConstructJob(Compilation &C, const JobAction &JA, assert(TC.getTriple().isNVPTX() && "Wrong platform"); ArgStringList CmdArgs; - CmdArgs.push_back("--cuda"); + if (TC.CudaInstallation.version() <= CudaVersion::CUDA_100) + CmdArgs.push_back("--cuda"); CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-64" : "-32"); CmdArgs.push_back(Args.MakeArgString("--create")); CmdArgs.push_back(Args.MakeArgString(Output.getFilename())); @@ -643,28 +645,41 @@ void CudaToolChain::addClangTargetOptions( CC1Args.push_back("-mlink-builtin-bitcode"); CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile)); - // Libdevice in CUDA-7.0 requires PTX version that's more recent than LLVM - // defaults to. Use PTX4.2 by default, which is the PTX version that came with - // CUDA-7.0. - const char *PtxFeature = "+ptx42"; - // TODO(tra): CUDA-10+ needs PTX 6.3 to support new features. However that - // requires fair amount of work on LLVM side. We'll keep using PTX 6.1 until - // all prerequisites are in place. - if (CudaInstallation.version() >= CudaVersion::CUDA_91) { - // CUDA-9.1 uses new instructions that are only available in PTX6.1+ - PtxFeature = "+ptx61"; - } else if (CudaInstallation.version() >= CudaVersion::CUDA_90) { - // CUDA-9.0 uses new instructions that are only available in PTX6.0+ - PtxFeature = "+ptx60"; + // New CUDA versions often introduce new instructions that are only supported + // by new PTX version, so we need to raise PTX level to enable them in NVPTX + // back-end. + const char *PtxFeature = nullptr; + switch(CudaInstallation.version()) { + case CudaVersion::CUDA_101: + PtxFeature = "+ptx64"; + break; + case CudaVersion::CUDA_100: + PtxFeature = "+ptx63"; + break; + case CudaVersion::CUDA_92: + PtxFeature = "+ptx61"; + break; + case CudaVersion::CUDA_91: + PtxFeature = "+ptx61"; + break; + case CudaVersion::CUDA_90: + PtxFeature = "+ptx60"; + break; + default: + PtxFeature = "+ptx42"; } CC1Args.append({"-target-feature", PtxFeature}); if (DriverArgs.hasFlag(options::OPT_fcuda_short_ptr, options::OPT_fno_cuda_short_ptr, false)) CC1Args.append({"-mllvm", "--nvptx-short-ptr"}); + if (CudaInstallation.version() >= CudaVersion::UNKNOWN) + CC1Args.push_back(DriverArgs.MakeArgString( + Twine("-target-sdk-version=") + + CudaVersionToString(CudaInstallation.version()))); + if (DeviceOffloadingKind == Action::OFK_OpenMP) { SmallVector<StringRef, 8> LibraryPaths; - if (const Arg *A = DriverArgs.getLastArg(options::OPT_libomptarget_nvptx_path_EQ)) LibraryPaths.push_back(A->getValue()); diff --git a/lib/Driver/ToolChains/Cuda.h b/lib/Driver/ToolChains/Cuda.h index 1d63ede41155..4ee8b6f1fea9 100644 --- a/lib/Driver/ToolChains/Cuda.h +++ b/lib/Driver/ToolChains/Cuda.h @@ -1,9 +1,8 @@ //===--- Cuda.h - Cuda ToolChain Implementations ----------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp index c395c9a4430e..5de7d7132df8 100644 --- a/lib/Driver/ToolChains/Darwin.cpp +++ b/lib/Driver/ToolChains/Darwin.cpp @@ -1,9 +1,8 @@ //===--- Darwin.cpp - Darwin Tool and ToolChain Implementations -*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -12,6 +11,7 @@ #include "CommonArgs.h" #include "clang/Basic/AlignedAllocation.h" #include "clang/Basic/ObjCRuntime.h" +#include "clang/Config/config.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" @@ -462,6 +462,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, // For LTO, pass the name of the optimization record file and other // opt-remarks flags. if (Args.hasFlag(options::OPT_fsave_optimization_record, + options::OPT_fsave_optimization_record_EQ, options::OPT_fno_save_optimization_record, false)) { CmdArgs.push_back("-mllvm"); CmdArgs.push_back("-lto-pass-remarks-output"); @@ -469,7 +470,13 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, SmallString<128> F; F = Output.getFilename(); - F += ".opt.yaml"; + F += ".opt."; + if (const Arg *A = + Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) + F += A->getValue(); + else + F += "yaml"; + CmdArgs.push_back(Args.MakeArgString(F)); if (getLastProfileUseArg(Args)) { @@ -484,20 +491,53 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(Opt)); } } + + if (const Arg *A = + Args.getLastArg(options::OPT_foptimization_record_passes_EQ)) { + CmdArgs.push_back("-mllvm"); + std::string Passes = + std::string("-lto-pass-remarks-filter=") + A->getValue(); + CmdArgs.push_back(Args.MakeArgString(Passes)); + } + + if (const Arg *A = + Args.getLastArg(options::OPT_fsave_optimization_record_EQ)) { + CmdArgs.push_back("-mllvm"); + std::string Format = + std::string("-lto-pass-remarks-format=") + A->getValue(); + CmdArgs.push_back(Args.MakeArgString(Format)); + } } // Propagate the -moutline flag to the linker in LTO. - if (Args.hasFlag(options::OPT_moutline, options::OPT_mno_outline, false)) { - if (getMachOToolChain().getMachOArchName(Args) == "arm64") { - CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-enable-machine-outliner"); + if (Arg *A = + Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) { + if (A->getOption().matches(options::OPT_moutline)) { + if (getMachOToolChain().getMachOArchName(Args) == "arm64") { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-enable-machine-outliner"); - // Outline from linkonceodr functions by default in LTO. + // Outline from linkonceodr functions by default in LTO. + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-enable-linkonceodr-outlining"); + } + } else { + // Disable all outlining behaviour if we have mno-outline. We need to do + // this explicitly, because targets which support default outlining will + // try to do work if we don't. CmdArgs.push_back("-mllvm"); - CmdArgs.push_back("-enable-linkonceodr-outlining"); + CmdArgs.push_back("-enable-machine-outliner=never"); } } + // Setup statistics file output. + SmallString<128> StatsFile = + getStatsFileName(Args, Output, Inputs[0], getToolChain().getDriver()); + if (!StatsFile.empty()) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back(Args.MakeArgString("-lto-stats-file=" + StatsFile.str())); + } + // It seems that the 'e' option is completely ignored for dynamic executables // (the default), and with static executables, the last one wins, as expected. Args.AddAllArgs(CmdArgs, {options::OPT_d_Flag, options::OPT_s, options::OPT_t, @@ -569,15 +609,26 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().ShouldLinkCXXStdlib(Args)) getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + + bool NoStdOrDefaultLibs = + Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs); + bool ForceLinkBuiltins = Args.hasArg(options::OPT_fapple_link_rtlib); + if (!NoStdOrDefaultLibs || ForceLinkBuiltins) { // link_ssp spec is empty. - // Let the tool chain choose which runtime library to link. - getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs); + // If we have both -nostdlib/nodefaultlibs and -fapple-link-rtlib then + // we just want to link the builtins, not the other libs like libSystem. + if (NoStdOrDefaultLibs && ForceLinkBuiltins) { + getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "builtins"); + } else { + // Let the tool chain choose which runtime library to link. + getMachOToolChain().AddLinkRuntimeLibArgs(Args, CmdArgs, + ForceLinkBuiltins); - // No need to do anything for pthreads. Claim argument to avoid warning. - Args.ClaimAllArgs(options::OPT_pthread); - Args.ClaimAllArgs(options::OPT_pthreads); + // No need to do anything for pthreads. Claim argument to avoid warning. + Args.ClaimAllArgs(options::OPT_pthread); + Args.ClaimAllArgs(options::OPT_pthreads); + } } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { @@ -869,6 +920,18 @@ void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { } } +/// Take a path that speculatively points into Xcode and return the +/// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path +/// otherwise. +static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) { + static constexpr llvm::StringLiteral XcodeAppSuffix( + ".app/Contents/Developer"); + size_t Index = PathIntoXcode.find(XcodeAppSuffix); + if (Index == StringRef::npos) + return ""; + return PathIntoXcode.take_front(Index + XcodeAppSuffix.size()); +} + void DarwinClang::AddLinkARCArgs(const ArgList &Args, ArgStringList &CmdArgs) const { // Avoid linking compatibility stubs on i386 mac. @@ -881,10 +944,27 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args, runtime.hasSubscripting()) return; - CmdArgs.push_back("-force_load"); SmallString<128> P(getDriver().ClangExecutable); llvm::sys::path::remove_filename(P); // 'clang' llvm::sys::path::remove_filename(P); // 'bin' + + // 'libarclite' usually lives in the same toolchain as 'clang'. However, the + // Swift open source toolchains for macOS distribute Clang without libarclite. + // In that case, to allow the linker to find 'libarclite', we point to the + // 'libarclite' in the XcodeDefault toolchain instead. + if (getXcodeDeveloperPath(P).empty()) { + if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { + // Try to infer the path to 'libarclite' in the toolchain from the + // specified SDK path. + StringRef XcodePathForSDK = getXcodeDeveloperPath(A->getValue()); + if (!XcodePathForSDK.empty()) { + P = XcodePathForSDK; + llvm::sys::path::append(P, "Toolchains/XcodeDefault.xctoolchain/usr"); + } + } + } + + CmdArgs.push_back("-force_load"); llvm::sys::path::append(P, "lib", "arc", "libarclite_"); // Mash in the platform. if (isTargetWatchOSSimulator()) @@ -1049,7 +1129,6 @@ void Darwin::addProfileRTLibs(const ArgList &Args, addExportedSymbol(CmdArgs, "___llvm_profile_filename"); addExportedSymbol(CmdArgs, "___llvm_profile_raw_version"); addExportedSymbol(CmdArgs, "_lprofCurFilename"); - addExportedSymbol(CmdArgs, "_lprofMergeValueProfData"); } addExportedSymbol(CmdArgs, "_lprofDirMode"); } @@ -1076,7 +1155,8 @@ ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType( } void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { + ArgStringList &CmdArgs, + bool ForceLinkBuiltinRT) const { // Call once to ensure diagnostic is printed if wrong value was specified GetRuntimeLibType(Args); @@ -1084,8 +1164,11 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, // libraries with -static. if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_fapple_kext) || - Args.hasArg(options::OPT_mkernel)) + Args.hasArg(options::OPT_mkernel)) { + if (ForceLinkBuiltinRT) + AddLinkRuntimeLib(Args, CmdArgs, "builtins"); return; + } // Reject -static-libgcc for now, we can deal with this when and if someone // cares. This is useful in situations where someone wants to statically link @@ -1117,8 +1200,6 @@ void DarwinClang::AddLinkRuntimeLibArgs(const ArgList &Args, AddLinkRuntimeLib(Args, CmdArgs, "stats_client", RLO_AlwaysLink); AddLinkSanitizerLibArgs(Args, CmdArgs, "stats"); } - if (Sanitize.needsEsanRt()) - AddLinkSanitizerLibArgs(Args, CmdArgs, "esan"); const XRayArgs &XRay = getXRayArgs(); if (XRay.needsXRayRt()) { @@ -1739,6 +1820,92 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { } } +// Returns the effective header sysroot path to use. This comes either from +// -isysroot or --sysroot. +llvm::StringRef DarwinClang::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const { + if(DriverArgs.hasArg(options::OPT_isysroot)) + return DriverArgs.getLastArgValue(options::OPT_isysroot); + if (!getDriver().SysRoot.empty()) + return getDriver().SysRoot; + return "/"; +} + +void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + const Driver &D = getDriver(); + + llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); + + bool NoStdInc = DriverArgs.hasArg(options::OPT_nostdinc); + bool NoStdlibInc = DriverArgs.hasArg(options::OPT_nostdlibinc); + bool NoBuiltinInc = DriverArgs.hasArg(options::OPT_nobuiltininc); + + // Add <sysroot>/usr/local/include + if (!NoStdInc && !NoStdlibInc) { + SmallString<128> P(Sysroot); + llvm::sys::path::append(P, "usr", "local", "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + // Add the Clang builtin headers (<resource>/include) + if (!NoStdInc && !NoBuiltinInc) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (NoStdInc || NoStdlibInc) + return; + + // Check for configure-time C include directories. + llvm::StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (!CIncludeDirs.empty()) { + llvm::SmallVector<llvm::StringRef, 5> dirs; + CIncludeDirs.split(dirs, ":"); + for (llvm::StringRef dir : dirs) { + llvm::StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? llvm::StringRef(Sysroot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); + } + } else { + // Otherwise, add <sysroot>/usr/include. + SmallString<128> P(Sysroot); + llvm::sys::path::append(P, "usr", "include"); + addExternCSystemInclude(DriverArgs, CC1Args, P.str()); + } +} + +bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + llvm::SmallString<128> Base, + llvm::StringRef Version, + llvm::StringRef ArchDir, + llvm::StringRef BitDir) const { + llvm::sys::path::append(Base, Version); + + // Add the base dir + addSystemInclude(DriverArgs, CC1Args, Base); + + // Add the multilib dirs + { + llvm::SmallString<128> P = Base; + if (!ArchDir.empty()) + llvm::sys::path::append(P, ArchDir); + if (!BitDir.empty()) + llvm::sys::path::append(P, BitDir); + addSystemInclude(DriverArgs, CC1Args, P); + } + + // Add the backward dir + { + llvm::SmallString<128> P = Base; + llvm::sys::path::append(P, "backward"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + return getVFS().exists(Base); +} + void DarwinClang::AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { @@ -1746,29 +1913,90 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs( // CC1Args. // FIXME: this should not be necessary, remove usages in the frontend // (e.g. HeaderSearchOptions::UseLibcxx) and don't pipe -stdlib. + // Also check whether this is used for setting library search paths. ToolChain::AddClangCXXStdlibIncludeArgs(DriverArgs, CC1Args); if (DriverArgs.hasArg(options::OPT_nostdlibinc) || DriverArgs.hasArg(options::OPT_nostdincxx)) return; + llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); + switch (GetCXXStdlibType(DriverArgs)) { case ToolChain::CST_Libcxx: { - llvm::StringRef InstallDir = getDriver().getInstalledDir(); - if (InstallDir.empty()) - break; - // On Darwin, libc++ may be installed alongside the compiler in - // include/c++/v1. - // Get from 'foo/bin' to 'foo/include/c++/v1'. - SmallString<128> P = InstallDir; - // Note that InstallDir can be relative, so we have to '..' and not - // parent_path. - llvm::sys::path::append(P, "..", "include", "c++", "v1"); - addSystemInclude(DriverArgs, CC1Args, P); + // On Darwin, libc++ is installed alongside the compiler in + // include/c++/v1, so get from '<install>/bin' to '<install>/include/c++/v1'. + { + llvm::SmallString<128> P = llvm::StringRef(getDriver().getInstalledDir()); + // Note that P can be relative, so we have to '..' and not parent_path. + llvm::sys::path::append(P, "..", "include", "c++", "v1"); + addSystemInclude(DriverArgs, CC1Args, P); + } + // Also add <sysroot>/usr/include/c++/v1 unless -nostdinc is used, + // to match the legacy behavior in CC1. + if (!DriverArgs.hasArg(options::OPT_nostdinc)) { + llvm::SmallString<128> P = Sysroot; + llvm::sys::path::append(P, "usr", "include", "c++", "v1"); + addSystemInclude(DriverArgs, CC1Args, P); + } break; } + case ToolChain::CST_Libstdcxx: - // FIXME: should we do something about it? + llvm::SmallString<128> UsrIncludeCxx = Sysroot; + llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++"); + + llvm::Triple::ArchType arch = getTriple().getArch(); + bool IsBaseFound = true; + switch (arch) { + default: break; + + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, + "4.2.1", + "powerpc-apple-darwin10", + arch == llvm::Triple::ppc64 ? "ppc64" : ""); + IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, + "4.0.0", "powerpc-apple-darwin10", + arch == llvm::Triple::ppc64 ? "ppc64" : ""); + break; + + case llvm::Triple::x86: + case llvm::Triple::x86_64: + IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, + "4.2.1", + "i686-apple-darwin10", + arch == llvm::Triple::x86_64 ? "x86_64" : ""); + IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, + "4.0.0", "i686-apple-darwin8", + ""); + break; + + case llvm::Triple::arm: + case llvm::Triple::thumb: + IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, + "4.2.1", + "arm-apple-darwin10", + "v7"); + IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, + "4.2.1", + "arm-apple-darwin10", + "v6"); + break; + + case llvm::Triple::aarch64: + IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, + "4.2.1", + "arm64-apple-darwin10", + ""); + break; + } + + if (!IsBaseFound) { + getDriver().Diag(diag::warn_drv_libstdcxx_not_found); + } + break; } } @@ -2056,7 +2284,8 @@ DerivedArgList *MachO::TranslateArgs(const DerivedArgList &Args, } void MachO::AddLinkRuntimeLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { + ArgStringList &CmdArgs, + bool ForceLinkBuiltinRT) const { // Embedded targets are simple at the moment, not supporting sanitizers and // with different libraries for each member of the product { static, PIC } x // { hard-float, soft-float } @@ -2290,22 +2519,27 @@ void Darwin::addStartObjectFileArgs(const ArgList &Args, } } else { if (Args.hasArg(options::OPT_pg) && SupportsProfiling()) { - if (Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_object) || - Args.hasArg(options::OPT_preload)) { - CmdArgs.push_back("-lgcrt0.o"); - } else { - CmdArgs.push_back("-lgcrt1.o"); + if (isTargetMacOS() && isMacosxVersionLT(10, 9)) { + if (Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_object) || + Args.hasArg(options::OPT_preload)) { + CmdArgs.push_back("-lgcrt0.o"); + } else { + CmdArgs.push_back("-lgcrt1.o"); - // darwin_crt2 spec is empty. + // darwin_crt2 spec is empty. + } + // By default on OS X 10.8 and later, we don't link with a crt1.o + // file and the linker knows to use _main as the entry point. But, + // when compiling with -pg, we need to link with the gcrt1.o file, + // so pass the -no_new_main option to tell the linker to use the + // "start" symbol as the entry point. + if (isTargetMacOS() && !isMacosxVersionLT(10, 8)) + CmdArgs.push_back("-no_new_main"); + } else { + getDriver().Diag(diag::err_drv_clang_unsupported_opt_pg_darwin) + << isTargetMacOS(); } - // By default on OS X 10.8 and later, we don't link with a crt1.o - // file and the linker knows to use _main as the entry point. But, - // when compiling with -pg, we need to link with the gcrt1.o file, - // so pass the -no_new_main option to tell the linker to use the - // "start" symbol as the entry point. - if (isTargetMacOS() && !isMacosxVersionLT(10, 8)) - CmdArgs.push_back("-no_new_main"); } else { if (Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_object) || @@ -2357,6 +2591,8 @@ SanitizerMask Darwin::getSupportedSanitizers() const { const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Leak; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; diff --git a/lib/Driver/ToolChains/Darwin.h b/lib/Driver/ToolChains/Darwin.h index d753f8967a61..2dc7c85880f7 100644 --- a/lib/Driver/ToolChains/Darwin.h +++ b/lib/Driver/ToolChains/Darwin.h @@ -1,9 +1,8 @@ //===--- Darwin.h - Darwin ToolChain Implementations ------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -158,7 +157,8 @@ public: /// FIXME: This API is intended for use with embedded libraries only, and is /// misleadingly named. virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; + llvm::opt::ArgStringList &CmdArgs, + bool ForceLinkBuiltinRT = false) const; virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const { @@ -496,12 +496,16 @@ public: RuntimeLibType GetRuntimeLibType(const llvm::opt::ArgList &Args) const override; void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; + llvm::opt::ArgStringList &CmdArgs, + bool ForceLinkBuiltinRT = false) const override; void AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; @@ -528,6 +532,15 @@ private: llvm::opt::ArgStringList &CmdArgs, StringRef Sanitizer, bool shared = true) const; + + bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + llvm::SmallString<128> Base, + llvm::StringRef Version, + llvm::StringRef ArchDir, + llvm::StringRef BitDir) const; + + llvm::StringRef GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const; }; } // end namespace toolchains diff --git a/lib/Driver/ToolChains/DragonFly.cpp b/lib/Driver/ToolChains/DragonFly.cpp index 648469e4cec5..0a7c8b1615e7 100644 --- a/lib/Driver/ToolChains/DragonFly.cpp +++ b/lib/Driver/ToolChains/DragonFly.cpp @@ -1,9 +1,8 @@ //===--- DragonFly.cpp - DragonFly ToolChain Implementations ----*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/DragonFly.h b/lib/Driver/ToolChains/DragonFly.h index 9a06fbd0d3c2..7e76904f1055 100644 --- a/lib/Driver/ToolChains/DragonFly.h +++ b/lib/Driver/ToolChains/DragonFly.h @@ -1,9 +1,8 @@ //===--- DragonFly.h - DragonFly ToolChain Implementations ------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/FreeBSD.cpp b/lib/Driver/ToolChains/FreeBSD.cpp index 7a176d260aee..3a0bab8d07f5 100644 --- a/lib/Driver/ToolChains/FreeBSD.cpp +++ b/lib/Driver/ToolChains/FreeBSD.cpp @@ -1,9 +1,8 @@ //===--- FreeBSD.cpp - FreeBSD ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -411,6 +410,8 @@ SanitizerMask FreeBSD::getSupportedSanitizers() const { const bool IsMIPS64 = getTriple().isMIPS64(); SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Vptr; if (IsX86_64 || IsMIPS64) { Res |= SanitizerKind::Leak; diff --git a/lib/Driver/ToolChains/FreeBSD.h b/lib/Driver/ToolChains/FreeBSD.h index 2943e1cacfbb..adfe21da372f 100644 --- a/lib/Driver/ToolChains/FreeBSD.h +++ b/lib/Driver/ToolChains/FreeBSD.h @@ -1,9 +1,8 @@ //===--- FreeBSD.h - FreeBSD ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Fuchsia.cpp b/lib/Driver/ToolChains/Fuchsia.cpp index de2c7411c5e4..1f5ec9ebb16d 100644 --- a/lib/Driver/ToolChains/Fuchsia.cpp +++ b/lib/Driver/ToolChains/Fuchsia.cpp @@ -1,9 +1,8 @@ //===--- Fuchsia.cpp - Fuchsia ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -16,7 +15,9 @@ #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" using namespace clang::driver; using namespace clang::driver::toolchains; @@ -24,6 +25,8 @@ using namespace clang::driver::tools; using namespace clang; using namespace llvm::opt; +using tools::addMultilibFlag; + void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -99,8 +102,6 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); Args.AddAllArgs(CmdArgs, options::OPT_u); - addSanitizerPathLibArgs(ToolChain, Args, CmdArgs); - ToolChain.AddFilePathLibArgs(Args, CmdArgs); if (D.isUsingLTO()) { @@ -149,7 +150,8 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fsplit_stack)) CmdArgs.push_back("--wrap=pthread_create"); - CmdArgs.push_back("-lc"); + if (!Args.hasArg(options::OPT_nolibc)) + CmdArgs.push_back("-lc"); } C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); @@ -169,6 +171,52 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, llvm::sys::path::append(P, "lib"); getFilePaths().push_back(P.str()); } + + auto FilePaths = [&](const Multilib &M) -> std::vector<std::string> { + std::vector<std::string> FP; + if (D.CCCIsCXX()) { + if (auto CXXStdlibPath = getCXXStdlibPath()) { + SmallString<128> P(*CXXStdlibPath); + llvm::sys::path::append(P, M.gccSuffix()); + FP.push_back(P.str()); + } + } + return FP; + }; + + Multilibs.push_back(Multilib()); + // Use the noexcept variant with -fno-exceptions to avoid the extra overhead. + Multilibs.push_back(Multilib("noexcept", {}, {}, 1) + .flag("-fexceptions") + .flag("+fno-exceptions")); + // ASan has higher priority because we always want the instrumentated version. + Multilibs.push_back(Multilib("asan", {}, {}, 2) + .flag("+fsanitize=address")); + // Use the asan+noexcept variant with ASan and -fno-exceptions. + Multilibs.push_back(Multilib("asan+noexcept", {}, {}, 3) + .flag("+fsanitize=address") + .flag("-fexceptions") + .flag("+fno-exceptions")); + Multilibs.FilterOut([&](const Multilib &M) { + std::vector<std::string> RD = FilePaths(M); + return std::all_of(RD.begin(), RD.end(), [&](std::string P) { + return !getVFS().exists(P); + }); + }); + + Multilib::flags_list Flags; + addMultilibFlag( + Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true), + "fexceptions", Flags); + addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags); + Multilibs.setFilePathsCallback(FilePaths); + + if (Multilibs.select(Flags, SelectedMultilib)) + if (!SelectedMultilib.isDefault()) + if (const auto &PathsCallback = Multilibs.filePathsCallback()) + for (const auto &Path : PathsCallback(SelectedMultilib)) + // Prepend the multilib path to ensure it takes the precedence. + getFilePaths().insert(getFilePaths().begin(), Path); } std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args, @@ -257,8 +305,8 @@ void Fuchsia::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, switch (GetCXXStdlibType(DriverArgs)) { case ToolChain::CST_Libcxx: { - SmallString<128> P(getDriver().ResourceDir); - llvm::sys::path::append(P, "include", "c++", "v1"); + SmallString<128> P(getDriver().Dir); + llvm::sys::path::append(P, "..", "include", "c++", "v1"); addSystemInclude(DriverArgs, CC1Args, P.str()); break; } @@ -283,6 +331,8 @@ void Fuchsia::AddCXXStdlibLibArgs(const ArgList &Args, SanitizerMask Fuchsia::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::SafeStack; diff --git a/lib/Driver/ToolChains/Fuchsia.h b/lib/Driver/ToolChains/Fuchsia.h index e61eddc2aad1..dd7c5c650352 100644 --- a/lib/Driver/ToolChains/Fuchsia.h +++ b/lib/Driver/ToolChains/Fuchsia.h @@ -1,9 +1,8 @@ //===--- Fuchsia.h - Fuchsia ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp index 2ad45097dce8..33cdd3585c29 100644 --- a/lib/Driver/ToolChains/Gnu.cpp +++ b/lib/Driver/ToolChains/Gnu.cpp @@ -1,9 +1,8 @@ //===--- Gnu.cpp - Gnu Tool and ToolChain Implementations -------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -22,6 +21,7 @@ #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" #include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Path.h" @@ -34,6 +34,8 @@ using namespace clang::driver::toolchains; using namespace clang; using namespace llvm::opt; +using tools::addMultilibFlag; + void tools::GnuTool::anchor() {} static bool forwardToGCC(const Option &O) { @@ -309,7 +311,7 @@ static const char *getLDMOption(const llvm::Triple &T, const ArgList &Args) { static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_r)) + Args.hasArg(options::OPT_r) || Args.hasArg(options::OPT_static_pie)) return false; Arg *A = Args.getLastArg(options::OPT_pie, options::OPT_no_pie, @@ -319,6 +321,26 @@ static bool getPIE(const ArgList &Args, const toolchains::Linux &ToolChain) { return A->getOption().matches(options::OPT_pie); } +static bool getStaticPIE(const ArgList &Args, + const toolchains::Linux &ToolChain) { + bool HasStaticPIE = Args.hasArg(options::OPT_static_pie); + // -no-pie is an alias for -nopie. So, handling -nopie takes care of + // -no-pie as well. + if (HasStaticPIE && Args.hasArg(options::OPT_nopie)) { + const Driver &D = ToolChain.getDriver(); + const llvm::opt::OptTable &Opts = D.getOpts(); + const char *StaticPIEName = Opts.getOptionName(options::OPT_static_pie); + const char *NoPIEName = Opts.getOptionName(options::OPT_nopie); + D.Diag(diag::err_drv_cannot_mix_options) << StaticPIEName << NoPIEName; + } + return HasStaticPIE; +} + +static bool getStatic(const ArgList &Args) { + return Args.hasArg(options::OPT_static) && + !Args.hasArg(options::OPT_static_pie); +} + void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -334,6 +356,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, const bool isAndroid = ToolChain.getTriple().isAndroid(); const bool IsIAMCU = ToolChain.getTriple().isOSIAMCU(); const bool IsPIE = getPIE(Args, ToolChain); + const bool IsStaticPIE = getStaticPIE(Args, ToolChain); + const bool IsStatic = getStatic(Args); const bool HasCRTBeginEndFiles = ToolChain.getTriple().hasEnvironment() || (ToolChain.getTriple().getVendor() != llvm::Triple::MipsTechnologies); @@ -354,6 +378,19 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (IsPIE) CmdArgs.push_back("-pie"); + if (IsStaticPIE) { + CmdArgs.push_back("-static"); + CmdArgs.push_back("-pie"); + CmdArgs.push_back("--no-dynamic-linker"); + CmdArgs.push_back("-z"); + CmdArgs.push_back("text"); + } + + if (ToolChain.isNoExecStackDefault()) { + CmdArgs.push_back("-z"); + CmdArgs.push_back("noexecstack"); + } + if (Args.hasArg(options::OPT_rdynamic)) CmdArgs.push_back("-export-dynamic"); @@ -376,6 +413,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--fix-cortex-a53-843419"); } + // Android does not allow shared text relocations. Emit a warning if the + // user's code contains any. + if (isAndroid) + CmdArgs.push_back("--warn-shared-textrel"); + for (const auto &Opt : ToolChain.ExtraOpts) CmdArgs.push_back(Opt.c_str()); @@ -389,7 +431,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, return; } - if (Args.hasArg(options::OPT_static)) { + if (IsStatic) { if (Arch == llvm::Triple::arm || Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumb || Arch == llvm::Triple::thumbeb) CmdArgs.push_back("-Bstatic"); @@ -399,11 +441,11 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-shared"); } - if (!Args.hasArg(options::OPT_static)) { + if (!IsStatic) { if (Args.hasArg(options::OPT_rdynamic)) CmdArgs.push_back("-export-dynamic"); - if (!Args.hasArg(options::OPT_shared)) { + if (!Args.hasArg(options::OPT_shared) && !IsStaticPIE) { const std::string Loader = D.DyldPrefix + ToolChain.getDynamicLinker(Args); CmdArgs.push_back("-dynamic-linker"); @@ -422,6 +464,8 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, crt1 = "gcrt1.o"; else if (IsPIE) crt1 = "Scrt1.o"; + else if (IsStaticPIE) + crt1 = "rcrt1.o"; else crt1 = "crt1.o"; } @@ -433,20 +477,29 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (IsIAMCU) CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); - else { - const char *crtbegin; - if (Args.hasArg(options::OPT_static)) - crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; - else if (Args.hasArg(options::OPT_shared)) - crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; - else if (IsPIE) - crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; - else - crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; - - if (HasCRTBeginEndFiles) - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); - } + else if (HasCRTBeginEndFiles) { + std::string P; + if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT && + !isAndroid) { + std::string crtbegin = ToolChain.getCompilerRT(Args, "crtbegin", + ToolChain::FT_Object); + if (ToolChain.getVFS().exists(crtbegin)) + P = crtbegin; + } + if (P.empty()) { + const char *crtbegin; + if (IsStatic) + crtbegin = isAndroid ? "crtbegin_static.o" : "crtbeginT.o"; + else if (Args.hasArg(options::OPT_shared)) + crtbegin = isAndroid ? "crtbegin_so.o" : "crtbeginS.o"; + else if (IsPIE || IsStaticPIE) + crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbeginS.o"; + else + crtbegin = isAndroid ? "crtbegin_dynamic.o" : "crtbegin.o"; + P = ToolChain.GetFilePath(crtbegin); + } + CmdArgs.push_back(Args.MakeArgString(P)); + } // Add crtfastmath.o if available and fast math is enabled. ToolChain.AddFastMathRuntimeIfAvailable(Args, CmdArgs); @@ -490,7 +543,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_nostdlib)) { if (!Args.hasArg(options::OPT_nodefaultlibs)) { - if (Args.hasArg(options::OPT_static)) + if (IsStatic || IsStaticPIE) CmdArgs.push_back("--start-group"); if (NeedsSanitizerDeps) @@ -519,13 +572,14 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_fsplit_stack)) CmdArgs.push_back("--wrap=pthread_create"); - CmdArgs.push_back("-lc"); + if (!Args.hasArg(options::OPT_nolibc)) + CmdArgs.push_back("-lc"); // Add IAMCU specific libs, if needed. if (IsIAMCU) CmdArgs.push_back("-lgloss"); - if (Args.hasArg(options::OPT_static)) + if (IsStatic || IsStaticPIE) CmdArgs.push_back("--end-group"); else AddRunTimeLibs(ToolChain, D, CmdArgs, Args); @@ -539,16 +593,27 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA, } if (!Args.hasArg(options::OPT_nostartfiles) && !IsIAMCU) { - const char *crtend; - if (Args.hasArg(options::OPT_shared)) - crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; - else if (IsPIE) - crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; - else - crtend = isAndroid ? "crtend_android.o" : "crtend.o"; - - if (HasCRTBeginEndFiles) - CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); + if (HasCRTBeginEndFiles) { + std::string P; + if (ToolChain.GetRuntimeLibType(Args) == ToolChain::RLT_CompilerRT && + !isAndroid) { + std::string crtend = ToolChain.getCompilerRT(Args, "crtend", + ToolChain::FT_Object); + if (ToolChain.getVFS().exists(crtend)) + P = crtend; + } + if (P.empty()) { + const char *crtend; + if (Args.hasArg(options::OPT_shared)) + crtend = isAndroid ? "crtend_so.o" : "crtendS.o"; + else if (IsPIE || IsStaticPIE) + crtend = isAndroid ? "crtend_android.o" : "crtendS.o"; + else + crtend = isAndroid ? "crtend_android.o" : "crtend.o"; + P = ToolChain.GetFilePath(crtend); + } + CmdArgs.push_back(Args.MakeArgString(P)); + } if (!isAndroid) CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); } @@ -585,14 +650,12 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, if (const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ)) { if (A->getOption().getID() == options::OPT_gz) { - CmdArgs.push_back("-compress-debug-sections"); + CmdArgs.push_back("--compress-debug-sections"); } else { StringRef Value = A->getValue(); - if (Value == "none") { - CmdArgs.push_back("-compress-debug-sections=none"); - } else if (Value == "zlib" || Value == "zlib-gnu") { + if (Value == "none" || Value == "zlib" || Value == "zlib-gnu") { CmdArgs.push_back( - Args.MakeArgString("-compress-debug-sections=" + Twine(Value))); + Args.MakeArgString("--compress-debug-sections=" + Twine(Value))); } else { D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; @@ -600,6 +663,10 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, } } + if (getToolChain().isNoExecStackDefault()) { + CmdArgs.push_back("--noexecstack"); + } + switch (getToolChain().getArch()) { default: break; @@ -652,14 +719,16 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, case llvm::Triple::sparcel: { CmdArgs.push_back("-32"); std::string CPU = getCPUName(Args, getToolChain().getTriple()); - CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); + CmdArgs.push_back( + sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); break; } case llvm::Triple::sparcv9: { CmdArgs.push_back("-64"); std::string CPU = getCPUName(Args, getToolChain().getTriple()); - CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); + CmdArgs.push_back( + sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple())); AddAssemblerKPIC(getToolChain(), Args, CmdArgs); break; } @@ -817,7 +886,7 @@ void tools::gnutools::Assembler::ConstructJob(Compilation &C, if (Args.hasArg(options::OPT_gsplit_dwarf) && getToolChain().getTriple().isOSLinux()) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, - SplitDebugName(Args, Output)); + SplitDebugName(Args, Inputs[0], Output)); } namespace { @@ -846,16 +915,6 @@ static bool isSoftFloatABI(const ArgList &Args) { A->getValue() == StringRef("soft")); } -/// \p Flag must be a flag accepted by the driver with its leading '-' removed, -// otherwise '-print-multi-lib' will not emit them correctly. -static void addMultilibFlag(bool Enabled, const char *const Flag, - std::vector<std::string> &Flags) { - if (Enabled) - Flags.push_back(std::string("+") + Flag); - else - Flags.push_back(std::string("-") + Flag); -} - static bool isArmOrThumbArch(llvm::Triple::ArchType Arch) { return Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb; } @@ -874,10 +933,6 @@ static bool isMicroMips(const ArgList &Args) { return A && A->getOption().matches(options::OPT_mmicromips); } -static bool isRISCV(llvm::Triple::ArchType Arch) { - return Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; -} - static bool isMSP430(llvm::Triple::ArchType Arch) { return Arch == llvm::Triple::msp430; } @@ -1850,6 +1905,7 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( // Non-Solaris is much simpler - most systems just go with "/usr". if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux) { // Yet, still look for RHEL devtoolsets. + Prefixes.push_back("/opt/rh/devtoolset-8/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-7/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-6/root/usr"); Prefixes.push_back("/opt/rh/devtoolset-4/root/usr"); @@ -1889,6 +1945,9 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( static const char *const ARMebHFTriples[] = { "armeb-linux-gnueabihf", "armebv7hl-redhat-linux-gnueabi"}; + static const char *const AVRLibDirs[] = {"/lib"}; + static const char *const AVRTriples[] = {"avr"}; + static const char *const X86_64LibDirs[] = {"/lib64", "/lib"}; static const char *const X86_64Triples[] = { "x86_64-linux-gnu", "x86_64-unknown-linux-gnu", @@ -1951,10 +2010,14 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( "powerpc64le-linux-gnu", "powerpc64le-unknown-linux-gnu", "powerpc64le-suse-linux", "ppc64le-redhat-linux"}; - static const char *const RISCV32LibDirs[] = {"/lib", "/lib32"}; - static const char *const RISCVTriples[] = {"riscv32-unknown-linux-gnu", - "riscv64-unknown-linux-gnu", - "riscv32-unknown-elf"}; + static const char *const RISCV32LibDirs[] = {"/lib32", "/lib"}; + static const char *const RISCV32Triples[] = {"riscv32-unknown-linux-gnu", + "riscv32-linux-gnu", + "riscv32-unknown-elf"}; + static const char *const RISCV64LibDirs[] = {"/lib64", "/lib"}; + static const char *const RISCV64Triples[] = {"riscv64-unknown-linux-gnu", + "riscv64-linux-gnu", + "riscv64-unknown-elf"}; static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"}; static const char *const SPARCv8Triples[] = {"sparc-linux-gnu", @@ -2105,6 +2168,10 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( TripleAliases.append(begin(ARMebTriples), end(ARMebTriples)); } break; + case llvm::Triple::avr: + LibDirs.append(begin(AVRLibDirs), end(AVRLibDirs)); + TripleAliases.append(begin(AVRTriples), end(AVRTriples)); + break; case llvm::Triple::x86_64: LibDirs.append(begin(X86_64LibDirs), end(X86_64LibDirs)); TripleAliases.append(begin(X86_64Triples), end(X86_64Triples)); @@ -2184,9 +2251,15 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes( break; case llvm::Triple::riscv32: LibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs)); + TripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples)); + BiarchLibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs)); + BiarchTripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples)); + break; + case llvm::Triple::riscv64: + LibDirs.append(begin(RISCV64LibDirs), end(RISCV64LibDirs)); + TripleAliases.append(begin(RISCV64Triples), end(RISCV64Triples)); BiarchLibDirs.append(begin(RISCV32LibDirs), end(RISCV32LibDirs)); - TripleAliases.append(begin(RISCVTriples), end(RISCVTriples)); - BiarchTripleAliases.append(begin(RISCVTriples), end(RISCVTriples)); + BiarchTripleAliases.append(begin(RISCV32Triples), end(RISCV32Triples)); break; case llvm::Triple::sparc: case llvm::Triple::sparcel: @@ -2235,10 +2308,12 @@ bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs( } else if (TargetTriple.isMIPS()) { if (!findMIPSMultilibs(D, TargetTriple, Path, Args, Detected)) return false; - } else if (isRISCV(TargetArch)) { + } else if (TargetTriple.isRISCV()) { findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); } else if (isMSP430(TargetArch)) { findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); + } else if (TargetArch == llvm::Triple::avr) { + // AVR has no multilibs. } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args, NeedsBiarchSuffix, Detected)) { return false; @@ -2512,7 +2587,8 @@ bool Generic_GCC::IsIntegratedAssemblerDefault() const { case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::sparcv9: - if (getTriple().isOSSolaris() || getTriple().isOSOpenBSD()) + if (getTriple().isOSFreeBSD() || getTriple().isOSOpenBSD() || + getTriple().isOSSolaris()) return true; return false; default: diff --git a/lib/Driver/ToolChains/Gnu.h b/lib/Driver/ToolChains/Gnu.h index e8e74e4d80fd..3bb38c498b35 100644 --- a/lib/Driver/ToolChains/Gnu.h +++ b/lib/Driver/ToolChains/Gnu.h @@ -1,9 +1,8 @@ //===--- Gnu.h - Gnu Tool and ToolChain Implementations ---------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/HIP.cpp b/lib/Driver/ToolChains/HIP.cpp index 868765cf88e5..2ec97e798fd0 100644 --- a/lib/Driver/ToolChains/HIP.cpp +++ b/lib/Driver/ToolChains/HIP.cpp @@ -1,9 +1,8 @@ //===--- HIP.cpp - HIP Tool and ToolChain Implementations -------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -32,7 +31,7 @@ using namespace llvm::opt; namespace { -static void addBCLib(Compilation &C, const ArgList &Args, +static void addBCLib(const Driver &D, const ArgList &Args, ArgStringList &CmdArgs, ArgStringList LibraryPaths, StringRef BCName) { StringRef FullName; @@ -41,11 +40,12 @@ static void addBCLib(Compilation &C, const ArgList &Args, llvm::sys::path::append(Path, BCName); FullName = Path; if (llvm::sys::fs::exists(FullName)) { + CmdArgs.push_back("-mlink-builtin-bitcode"); CmdArgs.push_back(Args.MakeArgString(FullName)); return; } } - C.getDriver().Diag(diag::err_drv_no_such_file) << BCName; + D.Diag(diag::err_drv_no_such_file) << BCName; } } // namespace @@ -59,44 +59,6 @@ const char *AMDGCN::Linker::constructLLVMLinkCommand( for (const auto &II : Inputs) CmdArgs.push_back(II.getFilename()); - ArgStringList LibraryPaths; - - // Find in --hip-device-lib-path and HIP_LIBRARY_PATH. - for (auto Path : Args.getAllArgValues(options::OPT_hip_device_lib_path_EQ)) - LibraryPaths.push_back(Args.MakeArgString(Path)); - - addDirectoryList(Args, LibraryPaths, "-L", "HIP_DEVICE_LIB_PATH"); - - llvm::SmallVector<std::string, 10> BCLibs; - - // Add bitcode library in --hip-device-lib. - for (auto Lib : Args.getAllArgValues(options::OPT_hip_device_lib_EQ)) { - BCLibs.push_back(Args.MakeArgString(Lib)); - } - - // If --hip-device-lib is not set, add the default bitcode libraries. - if (BCLibs.empty()) { - // Get the bc lib file name for ISA version. For example, - // gfx803 => oclc_isa_version_803.amdgcn.bc. - std::string ISAVerBC = - "oclc_isa_version_" + SubArchName.drop_front(3).str() + ".amdgcn.bc"; - - llvm::StringRef FlushDenormalControlBC; - if (Args.hasArg(options::OPT_fcuda_flush_denormals_to_zero)) - FlushDenormalControlBC = "oclc_daz_opt_on.amdgcn.bc"; - else - FlushDenormalControlBC = "oclc_daz_opt_off.amdgcn.bc"; - - BCLibs.append({"hip.amdgcn.bc", "opencl.amdgcn.bc", - "ocml.amdgcn.bc", "ockl.amdgcn.bc", - "oclc_finite_only_off.amdgcn.bc", - FlushDenormalControlBC, - "oclc_correctly_rounded_sqrt_on.amdgcn.bc", - "oclc_unsafe_math_off.amdgcn.bc", ISAVerBC}); - } - for (auto Lib : BCLibs) - addBCLib(C, Args, CmdArgs, LibraryPaths, Lib); - // Add an intermediate output file. CmdArgs.push_back("-o"); std::string TmpName = @@ -141,6 +103,11 @@ const char *AMDGCN::Linker::constructOptCommand( } OptArgs.push_back("-mtriple=amdgcn-amd-amdhsa"); OptArgs.push_back(Args.MakeArgString("-mcpu=" + SubArchName)); + + for (const Arg *A : Args.filtered(options::OPT_mllvm)) { + OptArgs.push_back(A->getValue(0)); + } + OptArgs.push_back("-o"); std::string TmpFileName = C.getDriver().GetTemporaryPath( OutputFilePrefix.str() + "-optimized", "bc"); @@ -160,8 +127,30 @@ const char *AMDGCN::Linker::constructLlcCommand( llvm::StringRef OutputFilePrefix, const char *InputFileName) const { // Construct llc command. ArgStringList LlcArgs{InputFileName, "-mtriple=amdgcn-amd-amdhsa", - "-filetype=obj", "-mattr=-code-object-v3", - Args.MakeArgString("-mcpu=" + SubArchName), "-o"}; + "-filetype=obj", + Args.MakeArgString("-mcpu=" + SubArchName)}; + + // Extract all the -m options + std::vector<llvm::StringRef> Features; + handleTargetFeaturesGroup( + Args, Features, options::OPT_m_amdgpu_Features_Group); + + // Add features to mattr such as xnack + std::string MAttrString = "-mattr="; + for(auto OneFeature : Features) { + MAttrString.append(Args.MakeArgString(OneFeature)); + if (OneFeature != Features.back()) + MAttrString.append(","); + } + if(!Features.empty()) + LlcArgs.push_back(Args.MakeArgString(MAttrString)); + + for (const Arg *A : Args.filtered(options::OPT_mllvm)) { + LlcArgs.push_back(A->getValue(0)); + } + + // Add output filename + LlcArgs.push_back("-o"); std::string LlcOutputFileName = C.getDriver().GetTemporaryPath(OutputFilePrefix, "o"); const char *LlcOutputFile = @@ -181,9 +170,8 @@ void AMDGCN::Linker::constructLldCommand(Compilation &C, const JobAction &JA, const char *InputFileName) const { // Construct lld command. // The output from ld.lld is an HSA code object file. - ArgStringList LldArgs{"-flavor", "gnu", "--no-undefined", - "-shared", "-o", Output.getFilename(), - InputFileName}; + ArgStringList LldArgs{ + "-flavor", "gnu", "-shared", "-o", Output.getFilename(), InputFileName}; SmallString<128> LldPath(C.getDriver().Dir); llvm::sys::path::append(LldPath, "lld"); const char *Lld = Args.MakeArgString(LldPath); @@ -294,8 +282,54 @@ void HIPToolChain::addClangTargetOptions( // Default to "hidden" visibility, as object level linking will not be // supported for the foreseeable future. if (!DriverArgs.hasArg(options::OPT_fvisibility_EQ, - options::OPT_fvisibility_ms_compat)) + options::OPT_fvisibility_ms_compat)) { CC1Args.append({"-fvisibility", "hidden"}); + CC1Args.push_back("-fapply-global-visibility-to-externs"); + } + ArgStringList LibraryPaths; + + // Find in --hip-device-lib-path and HIP_LIBRARY_PATH. + for (auto Path : + DriverArgs.getAllArgValues(options::OPT_hip_device_lib_path_EQ)) + LibraryPaths.push_back(DriverArgs.MakeArgString(Path)); + + addDirectoryList(DriverArgs, LibraryPaths, "-L", "HIP_DEVICE_LIB_PATH"); + + llvm::SmallVector<std::string, 10> BCLibs; + + // Add bitcode library in --hip-device-lib. + for (auto Lib : DriverArgs.getAllArgValues(options::OPT_hip_device_lib_EQ)) { + BCLibs.push_back(DriverArgs.MakeArgString(Lib)); + } + + // If --hip-device-lib is not set, add the default bitcode libraries. + if (BCLibs.empty()) { + // Get the bc lib file name for ISA version. For example, + // gfx803 => oclc_isa_version_803.amdgcn.bc. + std::string GFXVersion = GpuArch.drop_front(3).str(); + std::string ISAVerBC = "oclc_isa_version_" + GFXVersion + ".amdgcn.bc"; + + llvm::StringRef FlushDenormalControlBC; + if (DriverArgs.hasArg(options::OPT_fcuda_flush_denormals_to_zero)) + FlushDenormalControlBC = "oclc_daz_opt_on.amdgcn.bc"; + else + FlushDenormalControlBC = "oclc_daz_opt_off.amdgcn.bc"; + + llvm::StringRef WaveFrontSizeBC; + if (stoi(GFXVersion) < 1000) + WaveFrontSizeBC = "oclc_wavefrontsize64_on.amdgcn.bc"; + else + WaveFrontSizeBC = "oclc_wavefrontsize64_off.amdgcn.bc"; + + BCLibs.append({"hip.amdgcn.bc", "opencl.amdgcn.bc", "ocml.amdgcn.bc", + "ockl.amdgcn.bc", "oclc_finite_only_off.amdgcn.bc", + FlushDenormalControlBC, + "oclc_correctly_rounded_sqrt_on.amdgcn.bc", + "oclc_unsafe_math_off.amdgcn.bc", ISAVerBC, + WaveFrontSizeBC}); + } + for (auto Lib : BCLibs) + addBCLib(getDriver(), DriverArgs, CC1Args, LibraryPaths, Lib); } llvm::opt::DerivedArgList * diff --git a/lib/Driver/ToolChains/HIP.h b/lib/Driver/ToolChains/HIP.h index 3af19d44dae0..a650095d054d 100644 --- a/lib/Driver/ToolChains/HIP.h +++ b/lib/Driver/ToolChains/HIP.h @@ -1,9 +1,8 @@ //===--- HIP.h - HIP ToolChain Implementations ------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Haiku.cpp b/lib/Driver/ToolChains/Haiku.cpp index 12461ec9c4bd..18f550c9ceca 100644 --- a/lib/Driver/ToolChains/Haiku.cpp +++ b/lib/Driver/ToolChains/Haiku.cpp @@ -1,9 +1,8 @@ //===--- Haiku.cpp - Haiku ToolChain Implementations ------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Haiku.h b/lib/Driver/ToolChains/Haiku.h index a12a48e00976..2bc98322bebf 100644 --- a/lib/Driver/ToolChains/Haiku.h +++ b/lib/Driver/ToolChains/Haiku.h @@ -1,9 +1,8 @@ //===--- Haiku.h - Haiku ToolChain Implementations --------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Hexagon.cpp b/lib/Driver/ToolChains/Hexagon.cpp index d302a3e24d8b..f2c3ea11a9f3 100644 --- a/lib/Driver/ToolChains/Hexagon.cpp +++ b/lib/Driver/ToolChains/Hexagon.cpp @@ -1,9 +1,8 @@ //===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -131,11 +130,11 @@ void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const Driver &D = HTC.getDriver(); ArgStringList CmdArgs; - CmdArgs.push_back("-march=hexagon"); + CmdArgs.push_back("--arch=hexagon"); RenderExtraToolArgs(JA, CmdArgs); - const char *AsName = "hexagon-llvm-mc"; + const char *AsName = "llvm-mc"; CmdArgs.push_back("-filetype=obj"); CmdArgs.push_back(Args.MakeArgString( "-mcpu=hexagon" + @@ -431,7 +430,7 @@ void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args, std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(), D.PrefixDirs); - if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end()) + if (llvm::find(RootDirs, TargetDir) == RootDirs.end()) RootDirs.push_back(TargetDir); bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC); diff --git a/lib/Driver/ToolChains/Hexagon.h b/lib/Driver/ToolChains/Hexagon.h index a9e599de7ae5..d7b4a13d3a4f 100644 --- a/lib/Driver/ToolChains/Hexagon.h +++ b/lib/Driver/ToolChains/Hexagon.h @@ -1,9 +1,8 @@ //===--- Hexagon.h - Hexagon ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Hurd.cpp b/lib/Driver/ToolChains/Hurd.cpp index ff7b685dae3f..92b0a7f2483f 100644 --- a/lib/Driver/ToolChains/Hurd.cpp +++ b/lib/Driver/ToolChains/Hurd.cpp @@ -1,9 +1,8 @@ //===--- Hurd.cpp - Hurd ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Hurd.h b/lib/Driver/ToolChains/Hurd.h index d14619f0e2ce..a2c3d074e9f9 100644 --- a/lib/Driver/ToolChains/Hurd.h +++ b/lib/Driver/ToolChains/Hurd.h @@ -1,9 +1,8 @@ //===--- Hurd.h - Hurd ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Lanai.h b/lib/Driver/ToolChains/Lanai.h index bb92bfaea7e2..dc04b0cfe2ee 100644 --- a/lib/Driver/ToolChains/Lanai.h +++ b/lib/Driver/ToolChains/Lanai.h @@ -1,9 +1,8 @@ //===--- Lanai.h - Lanai ToolChain Implementations --------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp index 65ab9b2daf54..d900508ad938 100644 --- a/lib/Driver/ToolChains/Linux.cpp +++ b/lib/Driver/ToolChains/Linux.cpp @@ -1,9 +1,8 @@ //===--- Linux.h - Linux ToolChain Implementations --------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -45,6 +44,7 @@ static std::string getMultiarchTriple(const Driver &D, TargetTriple.getEnvironment(); bool IsAndroid = TargetTriple.isAndroid(); bool IsMipsR6 = TargetTriple.getSubArch() == llvm::Triple::MipsSubArch_r6; + bool IsMipsN32Abi = TargetTriple.getEnvironment() == llvm::Triple::GNUABIN32; // For most architectures, just use whatever we have rather than trying to be // clever. @@ -103,33 +103,37 @@ static std::string getMultiarchTriple(const Driver &D, return "aarch64_be-linux-gnu"; break; case llvm::Triple::mips: { - std::string Arch = IsMipsR6 ? "mipsisa32r6" : "mips"; - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) - return Arch + "-linux-gnu"; + std::string MT = IsMipsR6 ? "mipsisa32r6-linux-gnu" : "mips-linux-gnu"; + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; break; } case llvm::Triple::mipsel: { if (IsAndroid) return "mipsel-linux-android"; - std::string Arch = IsMipsR6 ? "mipsisa32r6el" : "mipsel"; - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-gnu")) - return Arch + "-linux-gnu"; + std::string MT = IsMipsR6 ? "mipsisa32r6el-linux-gnu" : "mipsel-linux-gnu"; + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; break; } case llvm::Triple::mips64: { - std::string Arch = IsMipsR6 ? "mipsisa64r6" : "mips64"; - std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) - return Arch + "-linux-" + ABI; + std::string MT = std::string(IsMipsR6 ? "mipsisa64r6" : "mips64") + + "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64"); + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; + if (D.getVFS().exists(SysRoot + "/lib/mips64-linux-gnu")) + return "mips64-linux-gnu"; break; } case llvm::Triple::mips64el: { if (IsAndroid) return "mips64el-linux-android"; - std::string Arch = IsMipsR6 ? "mipsisa64r6el" : "mips64el"; - std::string ABI = llvm::Triple::getEnvironmentTypeName(TargetEnvironment); - if (D.getVFS().exists(SysRoot + "/lib/" + Arch + "-linux-" + ABI)) - return Arch + "-linux-" + ABI; + std::string MT = std::string(IsMipsR6 ? "mipsisa64r6el" : "mips64el") + + "-linux-" + (IsMipsN32Abi ? "gnuabin32" : "gnuabi64"); + if (D.getVFS().exists(SysRoot + "/lib/" + MT)) + return MT; + if (D.getVFS().exists(SysRoot + "/lib/mips64el-linux-gnu")) + return "mips64el-linux-gnu"; break; } case llvm::Triple::ppc: @@ -230,9 +234,11 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // used to target i386. // FIXME: This seems unlikely to be Linux-specific. ToolChain::path_list &PPaths = getProgramPaths(); - PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + - GCCInstallation.getTriple().str() + "/bin") - .str()); + if (GCCInstallation.isValid()) { + PPaths.push_back(Twine(GCCInstallation.getParentLibPath() + "/../" + + GCCInstallation.getTriple().str() + "/bin") + .str()); + } Distro Distro(D.getVFS()); @@ -270,8 +276,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) const bool IsAndroid = Triple.isAndroid(); const bool IsMips = Triple.isMIPS(); const bool IsHexagon = Arch == llvm::Triple::hexagon; - const bool IsRISCV = - Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; + const bool IsRISCV = Triple.isRISCV(); if (IsMips && !SysRoot.empty()) ExtraOpts.push_back("--sysroot=" + SysRoot); @@ -295,9 +300,6 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) ExtraOpts.push_back("--hash-style=both"); } - if (Distro.IsRedhat() && Distro != Distro::RHEL5 && Distro != Distro::RHEL6) - ExtraOpts.push_back("--no-add-needed"); - #ifdef ENABLE_LINKER_BUILD_ID ExtraOpts.push_back("--build-id"); #endif @@ -326,8 +328,9 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) // Sourcery CodeBench MIPS toolchain holds some libraries under // a biarch-like suffix of the GCC installation. - addPathIfExists(D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(), - Paths); + addPathIfExists( + D, GCCInstallation.getInstallPath() + SelectedMultilib.gccSuffix(), + Paths); // GCC cross compiling toolchains will install target libraries which ship // as part of the toolchain under <prefix>/<triple>/<libdir> rather than as @@ -637,8 +640,9 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const { } } - if (Distro == Distro::Exherbo && (Triple.getVendor() == llvm::Triple::UnknownVendor || - Triple.getVendor() == llvm::Triple::PC)) + if (Distro == Distro::Exherbo && + (Triple.getVendor() == llvm::Triple::UnknownVendor || + Triple.getVendor() == llvm::Triple::PC)) return "/usr/" + Triple.str() + "/lib/" + Loader; return "/" + LibDir + "/" + Loader; } @@ -858,12 +862,13 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); } -static std::string DetectLibcxxIncludePath(StringRef base) { +static std::string DetectLibcxxIncludePath(llvm::vfs::FileSystem &vfs, + StringRef base) { std::error_code EC; int MaxVersion = 0; std::string MaxVersionString = ""; - for (llvm::sys::fs::directory_iterator LI(base, EC), LE; !EC && LI != LE; - LI = LI.increment(EC)) { + for (llvm::vfs::directory_iterator LI = vfs.dir_begin(base, EC), LE; + !EC && LI != LE; LI = LI.increment(EC)) { StringRef VersionText = llvm::sys::path::filename(LI->path()); int Version; if (VersionText[0] == 'v' && @@ -881,13 +886,12 @@ void Linux::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { const std::string& SysRoot = computeSysRoot(); const std::string LibCXXIncludePathCandidates[] = { - DetectLibcxxIncludePath(getDriver().ResourceDir + "/include/c++"), - DetectLibcxxIncludePath(getDriver().Dir + "/../include/c++"), + DetectLibcxxIncludePath(getVFS(), getDriver().Dir + "/../include/c++"), // If this is a development, non-installed, clang, libcxx will // not be found at ../include/c++ but it likely to be found at // one of the following two locations: - DetectLibcxxIncludePath(SysRoot + "/usr/local/include/c++"), - DetectLibcxxIncludePath(SysRoot + "/usr/include/c++") }; + DetectLibcxxIncludePath(getVFS(), SysRoot + "/usr/local/include/c++"), + DetectLibcxxIncludePath(getVFS(), SysRoot + "/usr/include/c++") }; for (const auto &IncludePath : LibCXXIncludePathCandidates) { if (IncludePath.empty() || !getVFS().exists(IncludePath)) continue; @@ -972,6 +976,10 @@ bool Linux::isPIEDefault() const { getTriple().isMusl() || getSanitizerArgs().requiresPIE(); } +bool Linux::isNoExecStackDefault() const { + return getTriple().isAndroid(); +} + bool Linux::IsMathErrnoDefault() const { if (getTriple().isAndroid()) return false; @@ -993,6 +1001,8 @@ SanitizerMask Linux::getSupportedSanitizers() const { getTriple().getArch() == llvm::Triple::thumbeb; SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::KernelAddress; @@ -1007,8 +1017,6 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::Thread; if (IsX86_64) Res |= SanitizerKind::KernelMemory; - if (IsX86_64 || IsMIPS64) - Res |= SanitizerKind::Efficiency; if (IsX86 || IsX86_64) Res |= SanitizerKind::Function; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch || @@ -1018,6 +1026,8 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::HWAddress; Res |= SanitizerKind::KernelHWAddress; } + if (IsAArch64) + Res |= SanitizerKind::MemTag; return Res; } @@ -1027,7 +1037,8 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, // Add linker option -u__llvm_runtime_variable to cause runtime // initialization module to be linked in. - if ((!Args.hasArg(options::OPT_coverage)) && (!Args.hasArg(options::OPT_ftest_coverage))) + if ((!Args.hasArg(options::OPT_coverage)) && + (!Args.hasArg(options::OPT_ftest_coverage))) CmdArgs.push_back(Args.MakeArgString( Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); ToolChain::addProfileRTLibs(Args, CmdArgs); diff --git a/lib/Driver/ToolChains/Linux.h b/lib/Driver/ToolChains/Linux.h index 4a662cb4b427..4c61994691c7 100644 --- a/lib/Driver/ToolChains/Linux.h +++ b/lib/Driver/ToolChains/Linux.h @@ -1,9 +1,8 @@ //===--- Linux.h - Linux ToolChain Implementations --------------*- C++ -*-===// // -// 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 @@ public: llvm::opt::ArgStringList &CC1Args) const override; CXXStdlibType GetDefaultCXXStdlibType() const override; bool isPIEDefault() const override; + bool isNoExecStackDefault() const override; bool IsMathErrnoDefault() const override; SanitizerMask getSupportedSanitizers() const override; void addProfileRTLibs(const llvm::opt::ArgList &Args, diff --git a/lib/Driver/ToolChains/MSP430.cpp b/lib/Driver/ToolChains/MSP430.cpp index b2ff88dbd021..fc6048f17d78 100644 --- a/lib/Driver/ToolChains/MSP430.cpp +++ b/lib/Driver/ToolChains/MSP430.cpp @@ -1,9 +1,8 @@ //===--- MSP430.cpp - MSP430 Helpers for Tools ------------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/MSP430.h b/lib/Driver/ToolChains/MSP430.h index 0fdceb75b963..b5308a8dd687 100644 --- a/lib/Driver/ToolChains/MSP430.h +++ b/lib/Driver/ToolChains/MSP430.h @@ -1,9 +1,8 @@ //===--- MSP430.h - MSP430-specific Tool Helpers ----------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -37,6 +36,10 @@ public: llvm::opt::ArgStringList &CC1Args, Action::OffloadKind) const override; + bool isPICDefault() const override { return false; } + bool isPIEDefault() const override { return false; } + bool isPICDefaultForced() const override { return true; } + protected: Tool *buildLinker() const override; diff --git a/lib/Driver/ToolChains/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp index 7e34b0df5c8c..6ed80a8f4752 100644 --- a/lib/Driver/ToolChains/MSVC.cpp +++ b/lib/Driver/ToolChains/MSVC.cpp @@ -1,9 +1,8 @@ -//===--- ToolChains.cpp - ToolChain Implementations -----------------------===// +//===-- MSVC.cpp - MSVC ToolChain Implementations -------------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -378,7 +377,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasArg(options::OPT_shared)) CmdArgs.push_back( Args.MakeArgString(std::string("-wholearchive:") + - TC.getCompilerRTArgString(Args, "fuzzer", false))); + TC.getCompilerRTArgString(Args, "fuzzer"))); CmdArgs.push_back(Args.MakeArgString("-debug")); // Prevent the linker from padding sections we use for instrumentation // arrays. @@ -489,15 +488,25 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, // their own link.exe which may come first. linkPath = FindVisualStudioExecutable(TC, "link.exe"); - if (!TC.FoundMSVCInstall() && !llvm::sys::fs::can_execute(linkPath)) - C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found); + if (!TC.FoundMSVCInstall() && !llvm::sys::fs::can_execute(linkPath)) { + llvm::SmallString<128> ClPath; + ClPath = TC.GetProgramPath("cl.exe"); + if (llvm::sys::fs::can_execute(ClPath)) { + linkPath = llvm::sys::path::parent_path(ClPath); + llvm::sys::path::append(linkPath, "link.exe"); + if (!llvm::sys::fs::can_execute(linkPath)) + C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found); + } else { + C.getDriver().Diag(clang::diag::warn_drv_msvc_not_found); + } + } #ifdef _WIN32 // When cross-compiling with VS2017 or newer, link.exe expects to have // its containing bin directory at the top of PATH, followed by the // native target bin directory. // e.g. when compiling for x86 on an x64 host, PATH should start with: - // /bin/HostX64/x86;/bin/HostX64/x64 + // /bin/Hostx64/x86;/bin/Hostx64/x64 // This doesn't attempt to handle ToolsetLayout::DevDivInternal. if (TC.getIsVS2017OrNewer() && llvm::Triple(llvm::sys::getProcessTriple()).getArch() != TC.getArch()) { @@ -617,11 +626,11 @@ std::unique_ptr<Command> visualstudio::Compiler::GetCommand( // FIXME: How can we ensure this stays in sync with relevant clang-cl options? if (Args.hasFlag(options::OPT__SLASH_GR_, options::OPT__SLASH_GR, - /*default=*/false)) + /*Default=*/false)) CmdArgs.push_back("/GR-"); if (Args.hasFlag(options::OPT__SLASH_GS_, options::OPT__SLASH_GS, - /*default=*/false)) + /*Default=*/false)) CmdArgs.push_back("/GS-"); if (Arg *A = Args.getLastArg(options::OPT_ffunction_sections, @@ -839,7 +848,7 @@ MSVCToolChain::getSubDirectoryPath(SubDirectoryType Type, if (VSLayout == ToolsetLayout::VS2017OrNewer) { const bool HostIsX64 = llvm::Triple(llvm::sys::getProcessTriple()).isArch64Bit(); - const char *const HostName = HostIsX64 ? "HostX64" : "HostX86"; + const char *const HostName = HostIsX64 ? "Hostx64" : "Hostx86"; llvm::sys::path::append(Path, "bin", HostName, SubdirName); } else { // OlderVS or DevDivInternal llvm::sys::path::append(Path, "bin", SubdirName); @@ -1318,6 +1327,8 @@ MSVCToolChain::ComputeEffectiveClangTriple(const ArgList &Args, SanitizerMask MSVCToolChain::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res &= ~SanitizerKind::CFIMFCall; @@ -1408,10 +1419,10 @@ static void TranslateOptArg(Arg *A, llvm::opt::DerivedArgList &DAL, DAL.AddFlagArg( A, Opts.getOption(options::OPT_fno_omit_frame_pointer)); } else { - // Don't warn about /Oy- in 64-bit builds (where + // Don't warn about /Oy- in x86-64 builds (where // SupportsForcingFramePointer is false). The flag having no effect // there is a compiler-internal optimization, and people shouldn't have - // to special-case their build files for 64-bit clang-cl. + // to special-case their build files for x86-64 clang-cl. A->claim(); } break; @@ -1442,8 +1453,8 @@ MSVCToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args, DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); const OptTable &Opts = getDriver().getOpts(); - // /Oy and /Oy- only has an effect under X86-32. - bool SupportsForcingFramePointer = getArch() == llvm::Triple::x86; + // /Oy and /Oy- don't have an effect on X86-64 + bool SupportsForcingFramePointer = getArch() != llvm::Triple::x86_64; // The -O[12xd] flag actually expands to several flags. We must desugar the // flags so that options embedded can be negated. For example, the '-O2' flag diff --git a/lib/Driver/ToolChains/MSVC.h b/lib/Driver/ToolChains/MSVC.h index ebca0018bb85..aba9417c9727 100644 --- a/lib/Driver/ToolChains/MSVC.h +++ b/lib/Driver/ToolChains/MSVC.h @@ -1,9 +1,8 @@ //===--- MSVC.h - MSVC ToolChain Implementations ----------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp index 2d5217d03d3a..0e1873cce25b 100644 --- a/lib/Driver/ToolChains/MinGW.cpp +++ b/lib/Driver/ToolChains/MinGW.cpp @@ -1,9 +1,8 @@ //===--- MinGW.cpp - MinGWToolChain Implementation ------------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -54,7 +53,7 @@ void tools::MinGW::Assembler::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_gsplit_dwarf)) SplitDebugInfo(getToolChain(), C, *this, JA, Args, Output, - SplitDebugName(Args, Output)); + SplitDebugName(Args, Inputs[0], Output)); } void tools::MinGW::Linker::AddLibGCC(const ArgList &Args, @@ -249,22 +248,24 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Sanitize.needsAsanRt()) { // MinGW always links against a shared MSVCRT. - CmdArgs.push_back( - TC.getCompilerRTArgString(Args, "asan_dynamic", true)); + CmdArgs.push_back(TC.getCompilerRTArgString(Args, "asan_dynamic", + ToolChain::FT_Shared)); CmdArgs.push_back( TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); - CmdArgs.push_back(Args.MakeArgString("--require-defined")); - CmdArgs.push_back(Args.MakeArgString(TC.getArch() == llvm::Triple::x86 - ? "___asan_seh_interceptor" - : "__asan_seh_interceptor")); + CmdArgs.push_back("--require-defined"); + CmdArgs.push_back(TC.getArch() == llvm::Triple::x86 + ? "___asan_seh_interceptor" + : "__asan_seh_interceptor"); // Make sure the linker consider all object files from the dynamic // runtime thunk. - CmdArgs.push_back(Args.MakeArgString("--whole-archive")); - CmdArgs.push_back(Args.MakeArgString( - TC.getCompilerRT(Args, "asan_dynamic_runtime_thunk"))); - CmdArgs.push_back(Args.MakeArgString("--no-whole-archive")); + CmdArgs.push_back("--whole-archive"); + CmdArgs.push_back( + TC.getCompilerRTArgString(Args, "asan_dynamic_runtime_thunk")); + CmdArgs.push_back("--no-whole-archive"); } + TC.addProfileRTLibs(Args, CmdArgs); + if (!HasWindowsApp) { // Add system libraries. If linking to libwindowsapp.a, that import // library replaces all these and we shouldn't accidentally try to @@ -435,7 +436,8 @@ bool toolchains::MinGW::IsUnwindTablesDefault(const ArgList &Args) const { if (ExceptionArg && ExceptionArg->getOption().matches(options::OPT_fseh_exceptions)) return true; - return getArch() == llvm::Triple::x86_64; + return getArch() == llvm::Triple::x86_64 || + getArch() == llvm::Triple::aarch64; } bool toolchains::MinGW::isPICDefault() const { @@ -450,7 +452,7 @@ bool toolchains::MinGW::isPICDefaultForced() const { llvm::ExceptionHandling toolchains::MinGW::GetExceptionModel(const ArgList &Args) const { - if (getArch() == llvm::Triple::x86_64) + if (getArch() == llvm::Triple::x86_64 || getArch() == llvm::Triple::aarch64) return llvm::ExceptionHandling::WinEH; return llvm::ExceptionHandling::DwarfCFI; } @@ -458,6 +460,8 @@ toolchains::MinGW::GetExceptionModel(const ArgList &Args) const { SanitizerMask toolchains::MinGW::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; return Res; } diff --git a/lib/Driver/ToolChains/MinGW.h b/lib/Driver/ToolChains/MinGW.h index 04d23006ee75..08298e910ebb 100644 --- a/lib/Driver/ToolChains/MinGW.h +++ b/lib/Driver/ToolChains/MinGW.h @@ -1,9 +1,8 @@ //===--- MinGW.h - MinGW ToolChain Implementations --------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Minix.cpp b/lib/Driver/ToolChains/Minix.cpp index 7fadcb129d46..dbcc1f8908c4 100644 --- a/lib/Driver/ToolChains/Minix.cpp +++ b/lib/Driver/ToolChains/Minix.cpp @@ -1,9 +1,8 @@ //===--- Minix.cpp - Minix ToolChain Implementations ------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Minix.h b/lib/Driver/ToolChains/Minix.h index 6fd71850ad06..1ed6acebab9c 100644 --- a/lib/Driver/ToolChains/Minix.h +++ b/lib/Driver/ToolChains/Minix.h @@ -1,9 +1,8 @@ //===--- Minix.h - Minix ToolChain Implementations --------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/MipsLinux.cpp b/lib/Driver/ToolChains/MipsLinux.cpp index 9f23996b764a..cfda7f4bb4df 100644 --- a/lib/Driver/ToolChains/MipsLinux.cpp +++ b/lib/Driver/ToolChains/MipsLinux.cpp @@ -1,9 +1,8 @@ -//===--- Mips.cpp - Mips ToolChain Implementations --------------*- C++ -*-===// +//===-- MipsLinux.cpp - Mips ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -119,11 +118,23 @@ void MipsLLVMToolChain::AddCXXStdlibLibArgs(const ArgList &Args, std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, StringRef Component, - bool Shared) const { + FileType Type) const { SmallString<128> Path(getDriver().ResourceDir); llvm::sys::path::append(Path, SelectedMultilib.osSuffix(), "lib" + LibSuffix, getOS()); - llvm::sys::path::append(Path, Twine("libclang_rt." + Component + "-" + - "mips" + (Shared ? ".so" : ".a"))); + const char *Suffix; + switch (Type) { + case ToolChain::FT_Object: + Suffix = ".o"; + break; + case ToolChain::FT_Static: + Suffix = ".a"; + break; + case ToolChain::FT_Shared: + Suffix = ".so"; + break; + } + llvm::sys::path::append( + Path, Twine("libclang_rt." + Component + "-" + "mips" + Suffix)); return Path.str(); } diff --git a/lib/Driver/ToolChains/MipsLinux.h b/lib/Driver/ToolChains/MipsLinux.h index edf58a62b95c..31b547c0063c 100644 --- a/lib/Driver/ToolChains/MipsLinux.h +++ b/lib/Driver/ToolChains/MipsLinux.h @@ -1,9 +1,8 @@ //===--- Mips.h - Mips ToolChain Implementations ----------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -38,8 +37,9 @@ public: void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; - std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, - bool Shared = false) const override; + std::string + getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, + FileType Type = ToolChain::FT_Static) const override; std::string computeSysRoot() const override; diff --git a/lib/Driver/ToolChains/Myriad.cpp b/lib/Driver/ToolChains/Myriad.cpp index 2b4c1d165576..16eea1f13b14 100644 --- a/lib/Driver/ToolChains/Myriad.cpp +++ b/lib/Driver/ToolChains/Myriad.cpp @@ -1,9 +1,8 @@ //===--- Myriad.cpp - Myriad ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Myriad.h b/lib/Driver/ToolChains/Myriad.h index 33307c3f871a..9f5225fbc62c 100644 --- a/lib/Driver/ToolChains/Myriad.h +++ b/lib/Driver/ToolChains/Myriad.h @@ -1,9 +1,8 @@ //===--- Myriad.h - Myriad ToolChain Implementations ------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/NaCl.cpp b/lib/Driver/ToolChains/NaCl.cpp index 89a18944c319..984afc1758b1 100644 --- a/lib/Driver/ToolChains/NaCl.cpp +++ b/lib/Driver/ToolChains/NaCl.cpp @@ -1,9 +1,8 @@ //===--- NaCl.cpp - Native Client ToolChain Implementations -----*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/NaCl.h b/lib/Driver/ToolChains/NaCl.h index e0885b526d70..ab243f8087bb 100644 --- a/lib/Driver/ToolChains/NaCl.h +++ b/lib/Driver/ToolChains/NaCl.h @@ -1,9 +1,8 @@ //===--- NaCl.h - Native Client ToolChain Implementations -------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp index b1321cacaf7a..3219a5d1e4f4 100644 --- a/lib/Driver/ToolChains/NetBSD.cpp +++ b/lib/Driver/ToolChains/NetBSD.cpp @@ -1,9 +1,8 @@ //===--- NetBSD.cpp - NetBSD ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -17,6 +16,7 @@ #include "clang/Driver/Options.h" #include "clang/Driver/SanitizerArgs.h" #include "llvm/Option/ArgList.h" +#include "llvm/Support/VirtualFileSystem.h" using namespace clang::driver; using namespace clang::driver::tools; @@ -256,6 +256,13 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs); AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + const SanitizerArgs &SanArgs = ToolChain.getSanitizerArgs(); + if (SanArgs.needsSharedRt()) { + CmdArgs.push_back("-rpath"); + CmdArgs.push_back(Args.MakeArgString( + ToolChain.getCompilerRTPath().c_str())); + } + unsigned Major, Minor, Micro; ToolChain.getTriple().getOSVersion(Major, Minor, Micro); bool useLibgcc = true; @@ -416,8 +423,23 @@ ToolChain::CXXStdlibType NetBSD::GetDefaultCXXStdlibType() const { void NetBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { - addSystemInclude(DriverArgs, CC1Args, - getDriver().SysRoot + "/usr/include/c++/"); + const std::string Candidates[] = { + // directory relative to build tree + getDriver().Dir + "/../include/c++/v1", + // system install with full upstream path + getDriver().SysRoot + "/usr/include/c++/v1", + // system install from src + getDriver().SysRoot + "/usr/include/c++", + }; + + for (const auto &IncludePath : Candidates) { + if (!getVFS().exists(IncludePath + "/__config")) + continue; + + // Use the first candidate that looks valid. + addSystemInclude(DriverArgs, CC1Args, IncludePath); + return; + } } void NetBSD::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, @@ -441,6 +463,8 @@ SanitizerMask NetBSD::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); if (IsX86 || IsX86_64) { Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Function; Res |= SanitizerKind::Leak; Res |= SanitizerKind::SafeStack; @@ -449,7 +473,6 @@ SanitizerMask NetBSD::getSupportedSanitizers() const { } if (IsX86_64) { Res |= SanitizerKind::DataFlow; - Res |= SanitizerKind::Efficiency; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; Res |= SanitizerKind::HWAddress; diff --git a/lib/Driver/ToolChains/NetBSD.h b/lib/Driver/ToolChains/NetBSD.h index ae0865fd6573..6d404263f625 100644 --- a/lib/Driver/ToolChains/NetBSD.h +++ b/lib/Driver/ToolChains/NetBSD.h @@ -1,9 +1,8 @@ //===--- NetBSD.h - NetBSD ToolChain Implementations ------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/OpenBSD.cpp b/lib/Driver/ToolChains/OpenBSD.cpp index 3d35d37b7db3..8441b83c29a9 100644 --- a/lib/Driver/ToolChains/OpenBSD.cpp +++ b/lib/Driver/ToolChains/OpenBSD.cpp @@ -1,9 +1,8 @@ //===--- OpenBSD.cpp - OpenBSD ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -189,11 +188,11 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-lm"); } if (NeedsSanitizerDeps) { - CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false)); + CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins")); linkSanitizerRuntimeDeps(ToolChain, CmdArgs); } if (NeedsXRayDeps) { - CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins", false)); + CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins")); linkXRayRuntimeDeps(ToolChain, CmdArgs); } // FIXME: For some reason GCC passes -lgcc before adding @@ -227,9 +226,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); } - const char *Exec = Args.MakeArgString( - !NeedsSanitizerDeps ? ToolChain.GetLinkerPath() - : ToolChain.GetProgramPath("ld.lld")); + const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); } diff --git a/lib/Driver/ToolChains/OpenBSD.h b/lib/Driver/ToolChains/OpenBSD.h index 1912abdb95bc..c92d109b7c16 100644 --- a/lib/Driver/ToolChains/OpenBSD.h +++ b/lib/Driver/ToolChains/OpenBSD.h @@ -1,9 +1,8 @@ //===--- OpenBSD.h - OpenBSD ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/PPCLinux.cpp b/lib/Driver/ToolChains/PPCLinux.cpp new file mode 100644 index 000000000000..5221e5d0e22c --- /dev/null +++ b/lib/Driver/ToolChains/PPCLinux.cpp @@ -0,0 +1,31 @@ +//===-- PPCLinux.cpp - PowerPC ToolChain Implementations --------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "PPCLinux.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/Options.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver::toolchains; +using namespace llvm::opt; + +void PPCLinuxToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + // PPC wrapper headers are implementation of x86 intrinsics on PowerPC, which + // is not supported on PPC32 platform. + if (getArch() != llvm::Triple::ppc && + !DriverArgs.hasArg(clang::driver::options::OPT_nostdinc) && + !DriverArgs.hasArg(options::OPT_nobuiltininc)) { + const Driver &D = getDriver(); + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include", "ppc_wrappers"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + Linux::AddClangSystemIncludeArgs(DriverArgs, CC1Args); +} diff --git a/lib/Driver/ToolChains/PPCLinux.h b/lib/Driver/ToolChains/PPCLinux.h new file mode 100644 index 000000000000..b3ef7b61dc3a --- /dev/null +++ b/lib/Driver/ToolChains/PPCLinux.h @@ -0,0 +1,33 @@ +//===--- PPCLinux.h - PowerPC ToolChain Implementations ---------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_LINUX_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_LINUX_H + +#include "Linux.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY PPCLinuxToolChain : public Linux { +public: + PPCLinuxToolChain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args) + : Linux(D, Triple, Args) {} + + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; +}; + +} // end namespace toolchains +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_PPC_LINUX_H diff --git a/lib/Driver/ToolChains/PS4CPU.cpp b/lib/Driver/ToolChains/PS4CPU.cpp index 0708d25fe45c..7be471365668 100644 --- a/lib/Driver/ToolChains/PS4CPU.cpp +++ b/lib/Driver/ToolChains/PS4CPU.cpp @@ -1,9 +1,8 @@ //===--- PS4CPU.cpp - PS4CPU ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -426,6 +425,8 @@ bool toolchains::PS4CPU::HasNativeLLVMSupport() const { return true; } SanitizerMask toolchains::PS4CPU::getSupportedSanitizers() const { SanitizerMask Res = ToolChain::getSupportedSanitizers(); Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Vptr; return Res; } diff --git a/lib/Driver/ToolChains/PS4CPU.h b/lib/Driver/ToolChains/PS4CPU.h index bd0a44352f4d..e9f0891c1194 100644 --- a/lib/Driver/ToolChains/PS4CPU.h +++ b/lib/Driver/ToolChains/PS4CPU.h @@ -1,9 +1,8 @@ //===--- PS4CPU.h - PS4CPU ToolChain Implementations ------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/RISCVToolchain.cpp b/lib/Driver/ToolChains/RISCVToolchain.cpp index e787c82b28a8..c5fdd129c3a8 100644 --- a/lib/Driver/ToolChains/RISCVToolchain.cpp +++ b/lib/Driver/ToolChains/RISCVToolchain.cpp @@ -1,9 +1,8 @@ //===--- RISCVToolchain.cpp - RISCV ToolChain Implementations ---*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/RISCVToolchain.h b/lib/Driver/ToolChains/RISCVToolchain.h index 4b38690b1b61..b2b56b066efd 100644 --- a/lib/Driver/ToolChains/RISCVToolchain.h +++ b/lib/Driver/ToolChains/RISCVToolchain.h @@ -1,9 +1,8 @@ //===--- RISCVToolchain.h - RISCV ToolChain Implementations -----*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/Solaris.cpp b/lib/Driver/ToolChains/Solaris.cpp index b48edbb08ee6..38f24d4cf7e7 100644 --- a/lib/Driver/ToolChains/Solaris.cpp +++ b/lib/Driver/ToolChains/Solaris.cpp @@ -1,9 +1,8 @@ //===--- Solaris.cpp - Solaris ToolChain Implementations --------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -66,10 +65,6 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-Bdynamic"); if (Args.hasArg(options::OPT_shared)) { CmdArgs.push_back("-shared"); - } else { - CmdArgs.push_back("--dynamic-linker"); - CmdArgs.push_back( - Args.MakeArgString(getToolChain().GetFilePath("ld.so.1"))); } // libpthread has been folded into libc since Solaris 10, no need to do @@ -97,13 +92,6 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); } - // Provide __start___sancov_guards. Solaris ld doesn't automatically create - // __start_SECNAME labels. - CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back( - getToolChain().getCompilerRTArgString(Args, "sancov_begin", false)); - CmdArgs.push_back("--no-whole-archive"); - getToolChain().AddFilePathLibArgs(Args, CmdArgs); Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, @@ -132,13 +120,6 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA, linkSanitizerRuntimeDeps(getToolChain(), CmdArgs); } - // Provide __stop___sancov_guards. Solaris ld doesn't automatically create - // __stop_SECNAME labels. - CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back( - getToolChain().getCompilerRTArgString(Args, "sancov_end", false)); - CmdArgs.push_back("--no-whole-archive"); - if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { CmdArgs.push_back( Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); @@ -200,6 +181,8 @@ SanitizerMask Solaris::getSupportedSanitizers() const { // FIXME: Omit X86_64 until 64-bit support is figured out. if (IsX86) { Res |= SanitizerKind::Address; + Res |= SanitizerKind::PointerCompare; + Res |= SanitizerKind::PointerSubtract; } Res |= SanitizerKind::Vptr; return Res; diff --git a/lib/Driver/ToolChains/Solaris.h b/lib/Driver/ToolChains/Solaris.h index 4d9c828b5c6b..b79e626ef38d 100644 --- a/lib/Driver/ToolChains/Solaris.h +++ b/lib/Driver/ToolChains/Solaris.h @@ -1,9 +1,8 @@ //===--- Solaris.h - Solaris ToolChain Implementations ----------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/TCE.cpp b/lib/Driver/ToolChains/TCE.cpp index ae8a1c806485..33a81c54bd42 100644 --- a/lib/Driver/ToolChains/TCE.cpp +++ b/lib/Driver/ToolChains/TCE.cpp @@ -1,9 +1,8 @@ //===--- TCE.cpp - TCE ToolChain Implementations ----------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/TCE.h b/lib/Driver/ToolChains/TCE.h index 4644f4eedb0e..72933dae965e 100644 --- a/lib/Driver/ToolChains/TCE.h +++ b/lib/Driver/ToolChains/TCE.h @@ -1,9 +1,8 @@ //===--- TCE.h - TCE Tool and ToolChain Implementations ---------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp index 6310d5fabaec..7a40c13c065a 100644 --- a/lib/Driver/ToolChains/WebAssembly.cpp +++ b/lib/Driver/ToolChains/WebAssembly.cpp @@ -1,18 +1,20 @@ //===--- WebAssembly.cpp - WebAssembly ToolChain Implementation -*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// #include "WebAssembly.h" #include "CommonArgs.h" +#include "clang/Config/config.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Option/ArgList.h" using namespace clang::driver; @@ -21,9 +23,6 @@ using namespace clang::driver::toolchains; using namespace clang; using namespace llvm::opt; -wasm::Linker::Linker(const ToolChain &TC) - : GnuTool("wasm::Linker", "lld", TC) {} - /// Following the conventions in https://wiki.debian.org/Multiarch/Tuples, /// we remove the vendor field to form the multiarch triple. static std::string getMultiarchTriple(const Driver &D, @@ -33,9 +32,24 @@ static std::string getMultiarchTriple(const Driver &D, TargetTriple.getOSAndEnvironmentName()).str(); } -bool wasm::Linker::isLinkJob() const { return true; } +std::string wasm::Linker::getLinkerPath(const ArgList &Args) const { + const ToolChain &ToolChain = getToolChain(); + if (const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ)) { + StringRef UseLinker = A->getValue(); + if (!UseLinker.empty()) { + if (llvm::sys::path::is_absolute(UseLinker) && + llvm::sys::fs::can_execute(UseLinker)) + return UseLinker; + + // Accept 'lld', and 'ld' as aliases for the default linker + if (UseLinker != "lld" && UseLinker != "ld") + ToolChain.getDriver().Diag(diag::err_drv_invalid_linker_name) + << A->getAsString(Args); + } + } -bool wasm::Linker::hasIntegratedCPP() const { return false; } + return ToolChain.GetProgramPath(ToolChain.getDefaultLinker()); +} void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, @@ -44,7 +58,7 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, const char *LinkingOutput) const { const ToolChain &ToolChain = getToolChain(); - const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath()); + const char *Linker = Args.MakeArgString(getLinkerPath(Args)); ArgStringList CmdArgs; if (Args.hasArg(options::OPT_s)) @@ -63,8 +77,10 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (ToolChain.ShouldLinkCXXStdlib(Args)) ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); - if (Args.hasArg(options::OPT_pthread)) + if (Args.hasArg(options::OPT_pthread)) { CmdArgs.push_back("-lpthread"); + CmdArgs.push_back("--shared-memory"); + } CmdArgs.push_back("-lc"); AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args); @@ -124,6 +140,32 @@ void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, if (DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array, options::OPT_fno_use_init_array, true)) CC1Args.push_back("-fuse-init-array"); + + // '-pthread' implies atomics, bulk-memory, and mutable-globals + if (DriverArgs.hasFlag(options::OPT_pthread, options::OPT_no_pthread, + false)) { + if (DriverArgs.hasFlag(options::OPT_mno_atomics, options::OPT_matomics, + false)) + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-pthread" + << "-mno-atomics"; + if (DriverArgs.hasFlag(options::OPT_mno_bulk_memory, + options::OPT_mbulk_memory, false)) + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-pthread" + << "-mno-bulk-memory"; + if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals, + options::OPT_mmutable_globals, false)) + getDriver().Diag(diag::err_drv_argument_not_allowed_with) + << "-pthread" + << "-mno-mutable-globals"; + CC1Args.push_back("-target-feature"); + CC1Args.push_back("+atomics"); + CC1Args.push_back("-target-feature"); + CC1Args.push_back("+bulk-memory"); + CC1Args.push_back("-target-feature"); + CC1Args.push_back("+mutable-globals"); + } } ToolChain::RuntimeLibType WebAssembly::GetDefaultRuntimeLibType() const { @@ -143,14 +185,39 @@ WebAssembly::GetCXXStdlibType(const ArgList &Args) const { void WebAssembly::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - if (!DriverArgs.hasArg(options::OPT_nostdinc)) { - if (getTriple().getOS() != llvm::Triple::UnknownOS) { - const std::string MultiarchTriple = - getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot); - addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include/" + MultiarchTriple); + if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) + return; + + const Driver &D = getDriver(); + + if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + addSystemInclude(DriverArgs, CC1Args, P); + } + + if (DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + // Check for configure-time C include directories. + StringRef CIncludeDirs(C_INCLUDE_DIRS); + if (CIncludeDirs != "") { + SmallVector<StringRef, 5> dirs; + CIncludeDirs.split(dirs, ":"); + for (StringRef dir : dirs) { + StringRef Prefix = + llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : ""; + addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); } - addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include"); + return; } + + if (getTriple().getOS() != llvm::Triple::UnknownOS) { + const std::string MultiarchTriple = + getMultiarchTriple(D, getTriple(), D.SysRoot); + addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include/" + MultiarchTriple); + } + addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/include"); } void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, @@ -161,7 +228,8 @@ void WebAssembly::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, const std::string MultiarchTriple = getMultiarchTriple(getDriver(), getTriple(), getDriver().SysRoot); addSystemInclude(DriverArgs, CC1Args, - getDriver().SysRoot + "/include/" + MultiarchTriple + "/c++/v1"); + getDriver().SysRoot + "/include/" + MultiarchTriple + + "/c++/v1"); } addSystemInclude(DriverArgs, CC1Args, getDriver().SysRoot + "/include/c++/v1"); @@ -181,12 +249,12 @@ void WebAssembly::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, } } -std::string WebAssembly::getThreadModel() const { - // The WebAssembly MVP does not yet support threads; for now, use the - // "single" threading model, which lowers atomics to non-atomic operations. - // When threading support is standardized and implemented in popular engines, - // this override should be removed. - return "single"; +SanitizerMask WebAssembly::getSupportedSanitizers() const { + SanitizerMask Res = ToolChain::getSupportedSanitizers(); + if (getTriple().isOSEmscripten()) { + Res |= SanitizerKind::Vptr | SanitizerKind::Leak | SanitizerKind::Address; + } + return Res; } Tool *WebAssembly::buildLinker() const { diff --git a/lib/Driver/ToolChains/WebAssembly.h b/lib/Driver/ToolChains/WebAssembly.h index d795bad90020..67d5fce84576 100644 --- a/lib/Driver/ToolChains/WebAssembly.h +++ b/lib/Driver/ToolChains/WebAssembly.h @@ -1,9 +1,8 @@ //===--- WebAssembly.h - WebAssembly ToolChain Implementations --*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// @@ -21,9 +20,11 @@ namespace wasm { class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { public: - explicit Linker(const ToolChain &TC); - bool isLinkJob() const override; - bool hasIntegratedCPP() const override; + explicit Linker(const ToolChain &TC) + : GnuTool("wasm::Linker", "linker", TC) {} + bool isLinkJob() const override { return true; } + bool hasIntegratedCPP() const override { return false; } + std::string getLinkerPath(const llvm::opt::ArgList &Args) const; void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, @@ -65,7 +66,7 @@ private: llvm::opt::ArgStringList &CC1Args) const override; void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; - std::string getThreadModel() const override; + SanitizerMask getSupportedSanitizers() const override; const char *getDefaultLinker() const override { return "wasm-ld"; } diff --git a/lib/Driver/ToolChains/XCore.cpp b/lib/Driver/ToolChains/XCore.cpp index 43175ad7d632..477cdb760914 100644 --- a/lib/Driver/ToolChains/XCore.cpp +++ b/lib/Driver/ToolChains/XCore.cpp @@ -1,9 +1,8 @@ //===--- XCore.cpp - XCore ToolChain Implementations ------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/ToolChains/XCore.h b/lib/Driver/ToolChains/XCore.h index 00c89bd15f78..41dce08454c0 100644 --- a/lib/Driver/ToolChains/XCore.h +++ b/lib/Driver/ToolChains/XCore.h @@ -1,9 +1,8 @@ //===--- XCore.h - XCore ToolChain Implementations --------------*- C++ -*-===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/Types.cpp b/lib/Driver/Types.cpp index 9d2737bbc719..96937678ac6b 100644 --- a/lib/Driver/Types.cpp +++ b/lib/Driver/Types.cpp @@ -1,9 +1,8 @@ //===--- Types.cpp - Driver input & temporary type information ------------===// // -// 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 // //===----------------------------------------------------------------------===// diff --git a/lib/Driver/XRayArgs.cpp b/lib/Driver/XRayArgs.cpp index 1a48493d7dc7..45ef96e12b3b 100644 --- a/lib/Driver/XRayArgs.cpp +++ b/lib/Driver/XRayArgs.cpp @@ -1,9 +1,8 @@ //===--- XRayArgs.cpp - Arguments for XRay --------------------------------===// // -// 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 // //===----------------------------------------------------------------------===// #include "clang/Driver/XRayArgs.h" |