13#include "clang/Config/config.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/Option/ArgList.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/Path.h"
35 const char *LinkingOutput)
const {
42 const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ);
43 StringRef UseLinker = A ? A->getValue() : CLANG_DEFAULT_LINKER;
44 return UseLinker ==
"bfd" || UseLinker ==
"gld";
48 if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_static) ||
49 Args.hasArg(options::OPT_r))
52 return Args.hasFlag(options::OPT_pie, options::OPT_no_pie,
59 if (
const Arg *A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
60 StringRef UseLinker = A->getValue();
61 if (!UseLinker.empty()) {
62 if (llvm::sys::path::is_absolute(UseLinker) &&
63 llvm::sys::fs::can_execute(UseLinker))
64 return std::string(UseLinker);
67 if (UseLinker ==
"bfd" || UseLinker ==
"gld")
69 return "/usr/gnu/bin/ld";
72 if (UseLinker !=
"ld")
74 << A->getAsString(Args);
86 const char *LinkingOutput)
const {
92 ArgStringList CmdArgs;
96 CmdArgs.push_back(
"-C");
98 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared,
100 CmdArgs.push_back(
"-e");
101 CmdArgs.push_back(
"_start");
106 CmdArgs.push_back(
"-pie");
108 CmdArgs.push_back(
"-z");
109 CmdArgs.push_back(
"type=pie");
113 if (Args.hasArg(options::OPT_static)) {
114 CmdArgs.push_back(
"-Bstatic");
115 CmdArgs.push_back(
"-dn");
117 if (!Args.hasArg(options::OPT_r) && Args.hasArg(options::OPT_shared))
118 CmdArgs.push_back(
"-shared");
122 Args.ClaimAllArgs(options::OPT_pthread);
123 Args.ClaimAllArgs(options::OPT_pthreads);
129 case llvm::Triple::x86:
130 CmdArgs.push_back(
"-m");
131 CmdArgs.push_back(
"elf_i386_sol2");
133 case llvm::Triple::x86_64:
134 CmdArgs.push_back(
"-m");
135 CmdArgs.push_back(
"elf_x86_64_sol2");
137 case llvm::Triple::sparc:
138 CmdArgs.push_back(
"-m");
139 CmdArgs.push_back(
"elf32_sparc_sol2");
141 case llvm::Triple::sparcv9:
142 CmdArgs.push_back(
"-m");
143 CmdArgs.push_back(
"elf64_sparc_sol2");
149 if (Args.hasArg(options::OPT_rdynamic))
150 CmdArgs.push_back(
"-export-dynamic");
152 CmdArgs.push_back(
"--eh-frame-hdr");
155 Args.ClaimAllArgs(options::OPT_rdynamic);
160 CmdArgs.push_back(
"-o");
164 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
166 if (!Args.hasArg(options::OPT_shared))
171 const Arg *
Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi);
172 bool HaveAnsi =
false;
175 HaveAnsi =
Std->getOption().matches(options::OPT_ansi);
180 const char *values_X =
"values-Xa.o";
182 if (HaveAnsi || (LangStd && !LangStd->
isGNUMode()))
183 values_X =
"values-Xc.o";
186 const char *values_xpg =
"values-xpg6.o";
189 values_xpg =
"values-xpg4.o";
192 const char *crtbegin =
nullptr;
193 if (Args.hasArg(options::OPT_shared) || IsPIE)
194 crtbegin =
"crtbeginS.o";
196 crtbegin =
"crtbegin.o";
204 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group});
209 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
212 bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
213 !Args.hasArg(options::OPT_static);
219 CmdArgs.push_back(
"-lm");
222 Args.ClaimAllArgs(options::OPT_stdlib_EQ);
226 if (
D.IsFlangMode()) {
229 CmdArgs.push_back(
"-lm");
231 if (Args.hasArg(options::OPT_fstack_protector) ||
232 Args.hasArg(options::OPT_fstack_protector_strong) ||
233 Args.hasArg(options::OPT_fstack_protector_all)) {
235 CmdArgs.push_back(
"-lssp_nonshared");
236 CmdArgs.push_back(
"-lssp");
240 if (Arch == llvm::Triple::sparc) {
242 CmdArgs.push_back(
"-latomic");
246 CmdArgs.push_back(
"-lgcc_s");
248 CmdArgs.push_back(
"-lc");
249 if (!Args.hasArg(options::OPT_shared)) {
250 CmdArgs.push_back(
"-lgcc");
253 if (NeedsSanitizerDeps) {
259 if (Arch == llvm::Triple::x86_64 &&
263 CmdArgs.push_back(
"-z");
264 CmdArgs.push_back(
"relax=transtls");
270 CmdArgs.push_back(
"-z");
271 CmdArgs.push_back(
"now");
275 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
277 const char *crtend =
nullptr;
278 if (Args.hasArg(options::OPT_shared) || IsPIE)
279 crtend =
"crtendS.o";
288 const char *Exec = Args.MakeArgString(getLinkerPath(Args));
290 Exec, CmdArgs, Inputs, Output));
294 switch (Triple.getArch()) {
295 case llvm::Triple::x86:
296 case llvm::Triple::sparc:
299 case llvm::Triple::x86_64:
301 case llvm::Triple::sparcv9:
329 if (StringRef(
D.Dir).starts_with(
D.SysRoot))
336 const bool IsX86 =
getTriple().getArch() == llvm::Triple::x86;
340 Res |= SanitizerKind::Address;
341 Res |= SanitizerKind::PointerCompare;
342 Res |= SanitizerKind::PointerSubtract;
344 Res |= SanitizerKind::SafeStack;
345 Res |= SanitizerKind::Vptr;
351 return llvm::StringSwitch<const char *>(CLANG_DEFAULT_LINKER)
352 .Cases(
"bfd",
"gld",
"/usr/gnu/bin/ld")
353 .Default(
"/usr/bin/ld");
363 ArgStringList &CC1Args)
const {
366 if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
369 if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
372 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
374 llvm::sys::path::append(
P,
"include");
378 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
382 StringRef CIncludeDirs(C_INCLUDE_DIRS);
383 if (CIncludeDirs !=
"") {
385 CIncludeDirs.split(dirs,
":");
386 for (StringRef dir : dirs) {
388 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(
D.SysRoot);
409 const llvm::opt::ArgList &DriverArgs,
410 llvm::opt::ArgStringList &CC1Args)
const {
static StringRef getSolarisLibSuffix(const llvm::Triple &Triple)
static bool getPIE(const ArgList &Args, const ToolChain &TC)
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
const IncludeDirsFunc & includeDirsCallback() const
std::function< std::vector< std::string >(const Multilib &M)> IncludeDirsFunc
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
const std::string & includeSuffix() const
Get the include directory suffix.
bool needsStatsRt() const
bool needsUbsanRt() const
bool requiresMinimalRuntime() const
bool needsSharedRt() const
The JSON file list parser is used to communicate input to InstallAPI.
@ C
Languages that the frontend can parse and compile.
LangStandard - Information about the properties of a particular language standard.
static const LangStandard * getLangStandardForName(StringRef Name)
clang::Language getLanguage() const
Get the language that this standard describes.
bool isGNUMode() const
isGNUMode - Language includes GNU extensions.
bool isC99() const
isC99 - Language is a superset of C99.
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.