aboutsummaryrefslogtreecommitdiff
path: root/lib/Driver
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Driver')
-rw-r--r--lib/Driver/Action.cpp7
-rw-r--r--lib/Driver/Compilation.cpp19
-rw-r--r--lib/Driver/DarwinSDKInfo.cpp7
-rw-r--r--lib/Driver/Distro.cpp12
-rw-r--r--lib/Driver/Driver.cpp215
-rw-r--r--lib/Driver/DriverOptions.cpp7
-rw-r--r--lib/Driver/InputInfo.h7
-rw-r--r--lib/Driver/Job.cpp13
-rw-r--r--lib/Driver/Multilib.cpp27
-rw-r--r--lib/Driver/Phases.cpp7
-rw-r--r--lib/Driver/SanitizerArgs.cpp291
-rw-r--r--lib/Driver/Tool.cpp7
-rw-r--r--lib/Driver/ToolChain.cpp147
-rw-r--r--lib/Driver/ToolChains/AMDGPU.cpp28
-rw-r--r--lib/Driver/ToolChains/AMDGPU.h11
-rw-r--r--lib/Driver/ToolChains/AVR.cpp129
-rw-r--r--lib/Driver/ToolChains/AVR.h30
-rw-r--r--lib/Driver/ToolChains/Ananas.cpp7
-rw-r--r--lib/Driver/ToolChains/Ananas.h7
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp69
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.h7
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.cpp132
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.h10
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp8
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.h7
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.cpp9
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.h7
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.cpp55
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.h7
-rw-r--r--lib/Driver/ToolChains/Arch/Sparc.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/Sparc.h7
-rw-r--r--lib/Driver/ToolChains/Arch/SystemZ.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/SystemZ.h7
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp8
-rw-r--r--lib/Driver/ToolChains/Arch/X86.h7
-rw-r--r--lib/Driver/ToolChains/BareMetal.cpp9
-rw-r--r--lib/Driver/ToolChains/BareMetal.h7
-rw-r--r--lib/Driver/ToolChains/Clang.cpp559
-rw-r--r--lib/Driver/ToolChains/Clang.h9
-rw-r--r--lib/Driver/ToolChains/CloudABI.cpp7
-rw-r--r--lib/Driver/ToolChains/CloudABI.h7
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp199
-rw-r--r--lib/Driver/ToolChains/CommonArgs.h20
-rw-r--r--lib/Driver/ToolChains/Contiki.cpp7
-rw-r--r--lib/Driver/ToolChains/Contiki.h7
-rw-r--r--lib/Driver/ToolChains/CrossWindows.cpp11
-rw-r--r--lib/Driver/ToolChains/CrossWindows.h7
-rw-r--r--lib/Driver/ToolChains/Cuda.cpp53
-rw-r--r--lib/Driver/ToolChains/Cuda.h7
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp336
-rw-r--r--lib/Driver/ToolChains/Darwin.h25
-rw-r--r--lib/Driver/ToolChains/DragonFly.cpp7
-rw-r--r--lib/Driver/ToolChains/DragonFly.h7
-rw-r--r--lib/Driver/ToolChains/FreeBSD.cpp9
-rw-r--r--lib/Driver/ToolChains/FreeBSD.h7
-rw-r--r--lib/Driver/ToolChains/Fuchsia.cpp68
-rw-r--r--lib/Driver/ToolChains/Fuchsia.h7
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp206
-rw-r--r--lib/Driver/ToolChains/Gnu.h7
-rw-r--r--lib/Driver/ToolChains/HIP.cpp134
-rw-r--r--lib/Driver/ToolChains/HIP.h7
-rw-r--r--lib/Driver/ToolChains/Haiku.cpp7
-rw-r--r--lib/Driver/ToolChains/Haiku.h7
-rw-r--r--lib/Driver/ToolChains/Hexagon.cpp13
-rw-r--r--lib/Driver/ToolChains/Hexagon.h7
-rw-r--r--lib/Driver/ToolChains/Hurd.cpp7
-rw-r--r--lib/Driver/ToolChains/Hurd.h7
-rw-r--r--lib/Driver/ToolChains/Lanai.h7
-rw-r--r--lib/Driver/ToolChains/Linux.cpp91
-rw-r--r--lib/Driver/ToolChains/Linux.h8
-rw-r--r--lib/Driver/ToolChains/MSP430.cpp7
-rw-r--r--lib/Driver/ToolChains/MSP430.h11
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp43
-rw-r--r--lib/Driver/ToolChains/MSVC.h7
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp38
-rw-r--r--lib/Driver/ToolChains/MinGW.h7
-rw-r--r--lib/Driver/ToolChains/Minix.cpp7
-rw-r--r--lib/Driver/ToolChains/Minix.h7
-rw-r--r--lib/Driver/ToolChains/MipsLinux.cpp27
-rw-r--r--lib/Driver/ToolChains/MipsLinux.h12
-rw-r--r--lib/Driver/ToolChains/Myriad.cpp7
-rw-r--r--lib/Driver/ToolChains/Myriad.h7
-rw-r--r--lib/Driver/ToolChains/NaCl.cpp7
-rw-r--r--lib/Driver/ToolChains/NaCl.h7
-rw-r--r--lib/Driver/ToolChains/NetBSD.cpp37
-rw-r--r--lib/Driver/ToolChains/NetBSD.h7
-rw-r--r--lib/Driver/ToolChains/OpenBSD.cpp15
-rw-r--r--lib/Driver/ToolChains/OpenBSD.h7
-rw-r--r--lib/Driver/ToolChains/PPCLinux.cpp31
-rw-r--r--lib/Driver/ToolChains/PPCLinux.h33
-rw-r--r--lib/Driver/ToolChains/PS4CPU.cpp9
-rw-r--r--lib/Driver/ToolChains/PS4CPU.h7
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.cpp7
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.h7
-rw-r--r--lib/Driver/ToolChains/Solaris.cpp27
-rw-r--r--lib/Driver/ToolChains/Solaris.h7
-rw-r--r--lib/Driver/ToolChains/TCE.cpp7
-rw-r--r--lib/Driver/ToolChains/TCE.h7
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp116
-rw-r--r--lib/Driver/ToolChains/WebAssembly.h17
-rw-r--r--lib/Driver/ToolChains/XCore.cpp7
-rw-r--r--lib/Driver/ToolChains/XCore.h7
-rw-r--r--lib/Driver/Types.cpp7
-rw-r--r--lib/Driver/XRayArgs.cpp7
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"