14#include "llvm/ADT/StringExtras.h"
15#include "llvm/Option/ArgList.h"
16#include "llvm/ProfileData/InstrProf.h"
17#include "llvm/Support/Path.h"
27using namespace llvm::sys;
33 const char *LinkingOutput)
const {
35 ArgStringList CmdArgs;
40 if (!IsArch32Bit && !IsArch64Bit)
41 llvm_unreachable(
"Unsupported bit width value.");
43 if (Arg *A =
C.getArgs().getLastArg(options::OPT_G)) {
44 D.Diag(diag::err_drv_unsupported_opt_for_target)
45 << A->getSpelling() <<
D.getTargetTriple();
50 CmdArgs.push_back(
"-a32");
53 CmdArgs.push_back(
"-a64");
60 CmdArgs.push_back(
"-many");
62 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
67 CmdArgs.push_back(
"-o");
74 if (Inputs.size() != 1)
75 llvm_unreachable(
"Invalid number of input files.");
81 const char *Exec = Args.MakeArgString(
getToolChain().GetProgramPath(
"as"));
83 Exec, CmdArgs, Inputs, Output));
89 for (
size_t i = 0, Size = CmdArgs.size(); i < Size; ++i) {
90 llvm::StringRef ArgString(CmdArgs[i]);
92 if (ArgString.starts_with(
"-bE:") || ArgString.starts_with(
"-bexport:") ||
93 ArgString ==
"-bexpall" || ArgString ==
"-bexpfull")
97 if (ArgString ==
"-b" && i + 1 < Size) {
99 llvm::StringRef ArgNextString(CmdArgs[i]);
100 if (ArgNextString.starts_with(
"E:") ||
101 ArgNextString.starts_with(
"export:") || ArgNextString ==
"expall" ||
102 ArgNextString ==
"expfull")
112 const char *LinkingOutput)
const {
115 ArgStringList CmdArgs;
120 if (!(IsArch32Bit || IsArch64Bit))
121 llvm_unreachable(
"Unsupported bit width value.");
123 if (Arg *A =
C.getArgs().getLastArg(options::OPT_G)) {
124 D.Diag(diag::err_drv_unsupported_opt_for_target)
125 << A->getSpelling() <<
D.getTargetTriple();
129 if (Args.hasArg(options::OPT_static))
130 CmdArgs.push_back(
"-bnso");
133 if (Args.hasArg(options::OPT_shared)) {
134 CmdArgs.push_back(
"-bM:SRE");
135 CmdArgs.push_back(
"-bnoentry");
138 if (Args.hasFlag(options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr,
140 if (Args.hasArg(options::OPT_shared))
141 D.Diag(diag::err_roptr_cannot_build_shared);
146 CmdArgs.push_back(
"-bforceimprw");
152 if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
154 Args.hasFlag(options::OPT_fprofile_generate,
155 options::OPT_fno_profile_generate,
false) ||
156 Args.hasFlag(options::OPT_fprofile_generate_EQ,
157 options::OPT_fno_profile_generate,
false) ||
158 Args.hasFlag(options::OPT_fprofile_instr_generate,
159 options::OPT_fno_profile_instr_generate,
false) ||
160 Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,
161 options::OPT_fno_profile_instr_generate,
false) ||
162 Args.hasFlag(options::OPT_fcs_profile_generate,
163 options::OPT_fno_profile_generate,
false) ||
164 Args.hasFlag(options::OPT_fcs_profile_generate_EQ,
165 options::OPT_fno_profile_generate,
false) ||
166 Args.hasArg(options::OPT_fcreate_profile) ||
167 Args.hasArg(options::OPT_coverage))
168 CmdArgs.push_back(
"-bdbg:namedsects:ss");
171 Args.getLastArg(clang::driver::options::OPT_mxcoff_build_id_EQ)) {
172 StringRef BuildId = A->getValue();
173 if (BuildId[0] !=
'0' || BuildId[1] !=
'x' ||
174 BuildId.find_if_not(llvm::isHexDigit, 2) != StringRef::npos)
176 << A->getSpelling() << BuildId;
178 std::string LinkerFlag =
"-bdbg:ldrinfo:xcoff_binary_id:0x";
179 if (BuildId.size() % 2)
181 LinkerFlag += BuildId.drop_front(2).lower();
182 CmdArgs.push_back(Args.MakeArgString(LinkerFlag));
189 CmdArgs.push_back(
"-o");
196 CmdArgs.push_back(
"-b32");
197 CmdArgs.push_back(
"-bpT:0x10000000");
198 CmdArgs.push_back(
"-bpD:0x20000000");
201 CmdArgs.push_back(
"-b64");
202 CmdArgs.push_back(
"-bpT:0x100000000");
203 CmdArgs.push_back(
"-bpD:0x110000000");
206 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
207 options::OPT_shared, options::OPT_r)) {
208 auto getCrt0Basename = [&Args, IsArch32Bit] {
209 if (Arg *A = Args.getLastArgNoClaim(options::OPT_p, options::OPT_pg)) {
211 if (A->getOption().matches(options::OPT_pg))
212 return IsArch32Bit ?
"gcrt0.o" :
"gcrt0_64.o";
214 return IsArch32Bit ?
"mcrt0.o" :
"mcrt0_64.o";
216 return IsArch32Bit ?
"crt0.o" :
"crt0_64.o";
222 CmdArgs.push_back(Args.MakeArgString(
230 CmdArgs.push_back(
"-bcdtors:all:0:s");
232 if (Args.hasArg(options::OPT_rpath)) {
233 for (
const auto &bopt : Args.getAllArgValues(options::OPT_b))
235 if (!bopt.rfind(
"libpath:", 0) || bopt ==
"nolibpath")
236 D.Diag(diag::err_drv_cannot_mix_options) <<
"-rpath" <<
"-b" + bopt;
238 for (
const auto &wlopt : Args.getAllArgValues(options::OPT_Wl_COMMA))
241 if (!wlopt.rfind(
"-blibpath:", 0) || wlopt ==
"-bnolibpath")
242 D.Diag(diag::err_drv_cannot_mix_options) <<
"-rpath" <<
"-Wl," + wlopt;
244 for (
const auto &xopt : Args.getAllArgValues(options::OPT_Xlinker))
247 if (!xopt.rfind(
"-blibpath:", 0) || xopt ==
"-bnolibpath")
248 D.Diag(diag::err_drv_cannot_mix_options)
249 <<
"-rpath" <<
"-Xlinker " + xopt;
251 std::string BlibPathStr =
"";
252 for (
const auto &dir : Args.getAllArgValues(options::OPT_rpath))
253 BlibPathStr += dir +
":";
254 BlibPathStr +=
"/usr/lib:/lib";
255 CmdArgs.push_back(Args.MakeArgString(Twine(
"-blibpath:") + BlibPathStr));
267 const char *CreateExportListExec = Args.MakeArgString(
270 ArgStringList CreateExportCmdArgs;
272 std::string CreateExportListPath =
273 C.getDriver().GetTemporaryPath(
"CreateExportList",
"exp");
274 const char *ExportList =
275 C.addTempFile(
C.getArgs().MakeArgString(CreateExportListPath));
277 for (
const auto &II : Inputs)
279 CreateExportCmdArgs.push_back(II.getFilename());
281 CreateExportCmdArgs.push_back(
"--export-symbols");
282 CreateExportCmdArgs.push_back(
"-X");
284 CreateExportCmdArgs.push_back(
"32");
287 CreateExportCmdArgs.push_back(
"64");
290 auto ExpCommand = std::make_unique<Command>(
292 CreateExportCmdArgs, Inputs, Output);
293 ExpCommand->setRedirectFiles(
294 {std::nullopt, std::string(ExportList), std::nullopt});
295 C.addCommand(std::move(ExpCommand));
296 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-bE:") + ExportList));
300 Args.AddAllArgs(CmdArgs, options::OPT_L);
301 if (!Args.hasArg(options::OPT_r)) {
305 if (getToolChain().ShouldLinkCXXStdlib(Args))
306 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
308 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
312 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
313 options::OPT_fno_openmp,
false)) {
316 CmdArgs.push_back(
"-lomp");
319 CmdArgs.push_back(
"-liomp5");
322 CmdArgs.push_back(
"-lgomp");
331 if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread))
332 CmdArgs.push_back(
"-lpthreads");
335 CmdArgs.push_back(
"-lm");
337 CmdArgs.push_back(
"-lc");
339 if (Args.hasArgNoClaim(options::OPT_p, options::OPT_pg)) {
340 CmdArgs.push_back(Args.MakeArgString((llvm::Twine(
"-L") +
D.SysRoot) +
342 CmdArgs.push_back(Args.MakeArgString((llvm::Twine(
"-L") +
D.SysRoot) +
343 "/usr/lib/profiled"));
348 if (
D.IsFlangMode() &&
349 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
352 CmdArgs.push_back(
"-lm");
353 CmdArgs.push_back(
"-lpthread");
357 Exec, CmdArgs, Inputs, Output));
365 ParseInlineAsmUsingAsmParser = Args.hasFlag(
366 options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
true);
373AIX::GetHeaderSysroot(
const llvm::opt::ArgList &DriverArgs)
const {
374 if (DriverArgs.hasArg(options::OPT_isysroot))
375 return DriverArgs.getLastArgValue(options::OPT_isysroot);
381void AIX::AddOpenMPIncludeArgs(
const ArgList &DriverArgs,
382 ArgStringList &CC1Args)
const {
384 if (DriverArgs.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
385 options::OPT_fno_openmp,
false)) {
387 switch (
getDriver().getOpenMPRuntime(DriverArgs)) {
389 PathOpenMP = GetHeaderSysroot(DriverArgs);
390 llvm::sys::path::append(PathOpenMP,
"opt/IBM/openxlCSDK",
"include",
404 ArgStringList &CC1Args)
const {
406 if (DriverArgs.hasArg(options::OPT_nostdinc))
409 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
412 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
415 path::append(
P,
"include",
"ppc_wrappers");
424 AddOpenMPIncludeArgs(DriverArgs, CC1Args);
427 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
432 path::append(UP,
"/usr/include");
437 const llvm::opt::ArgList &DriverArgs,
438 llvm::opt::ArgStringList &CC1Args)
const {
440 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
441 DriverArgs.hasArg(options::OPT_nostdincxx) ||
442 DriverArgs.hasArg(options::OPT_nostdlibinc))
447 llvm::report_fatal_error(
448 "picking up libstdc++ headers is unimplemented on AIX");
450 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
452 llvm::sys::path::append(PathCPP,
"opt/IBM/openxlCSDK",
"include",
"c++",
457 CC1Args.push_back(
"-D__LIBC_NO_CPP_MATH_OVERLOADS__");
462 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
466 llvm::opt::ArgStringList &CmdArgs)
const {
469 llvm::report_fatal_error(
"linking libstdc++ unimplemented on AIX");
471 CmdArgs.push_back(
"-lc++");
472 if (Args.hasArg(options::OPT_fexperimental_library))
473 CmdArgs.push_back(
"-lc++experimental");
474 CmdArgs.push_back(
"-lc++abi");
478 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
484 llvm::opt::ArgStringList &CC1Args,
490 const bool TOCDataGloballyinEffect = [&Args]() {
491 if (
const Arg *LastArg =
492 Args.getLastArg(options::OPT_mtocdata, options::OPT_mno_tocdata))
493 return LastArg->getOption().matches(options::OPT_mtocdata);
498 enum TOCDataSetting {
503 const TOCDataSetting DefaultTocDataSetting =
504 TOCDataGloballyinEffect ? DataInTOC : AddressInTOC;
511 std::set<llvm::StringRef> ExplicitlySpecifiedGlobals;
512 for (
const auto Arg :
513 Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) {
514 TOCDataSetting ArgTocDataSetting =
515 Arg->getOption().matches(options::OPT_mtocdata_EQ) ? DataInTOC
518 if (ArgTocDataSetting != DefaultTocDataSetting)
519 for (
const char *Val : Arg->getValues())
520 ExplicitlySpecifiedGlobals.insert(Val);
522 for (
const char *Val : Arg->getValues())
523 ExplicitlySpecifiedGlobals.erase(Val);
526 auto buildExceptionList = [](
const std::set<llvm::StringRef> &ExplicitValues,
527 const char *OptionSpelling) {
528 std::string Option(OptionSpelling);
530 for (
const auto &
E : ExplicitValues) {
544 const char *TocDataGlobalOption =
545 TOCDataGloballyinEffect ?
"-mtocdata" :
"-mno-tocdata";
546 CC1Args.push_back(TocDataGlobalOption);
548 const char *TocDataListOption =
549 TOCDataGloballyinEffect ?
"-mno-tocdata=" :
"-mtocdata=";
550 if (!ExplicitlySpecifiedGlobals.empty())
551 CC1Args.push_back(Args.MakeArgString(llvm::Twine(
552 buildExceptionList(ExplicitlySpecifiedGlobals, TocDataListOption))));
556 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args,
558 Args.AddLastArg(CC1Args, options::OPT_mignore_xcoff_visibility);
559 Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ);
560 Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr);
563 if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ,
564 options::OPT_mtocdata))
567 if (Args.hasArg(options::OPT_msave_reg_params))
568 CC1Args.push_back(
"-msave-reg-params");
570 if (Args.hasFlag(options::OPT_fxl_pragma_pack,
571 options::OPT_fno_xl_pragma_pack,
true))
572 CC1Args.push_back(
"-fxl-pragma-pack");
576 if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
577 options::OPT_fno_sized_deallocation))
578 CC1Args.push_back(
"-fno-sized-deallocation");
582 llvm::opt::ArgStringList &CmdArgs)
const {
586 CmdArgs.push_back(Args.MakeArgString(
587 Twine(
"-u", llvm::getInstrProfRuntimeHookVarName())));
590 Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) {
591 StringRef Val = A->getValue();
592 if (Val ==
"atomic" || Val ==
"prefer-atomic")
593 CmdArgs.push_back(
"-latomic");
static void addTocDataOptions(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args, const Driver &D)
static bool hasExportListLinkerOpts(const ArgStringList &CmdArgs)
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...
std::string SysRoot
sysroot, if present
OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const
Compute the desired OpenMP runtime from the flags provided.
DiagnosticBuilder Diag(unsigned DiagID) const
std::string ClangExecutable
The original path to the clang executable.
@ OMPRT_IOMP5
The legacy name for the LLVM OpenMP runtime from when it was the Intel OpenMP runtime.
@ OMPRT_OMP
The LLVM OpenMP runtime.
@ OMPRT_Unknown
An unknown OpenMP runtime.
@ OMPRT_GOMP
The GNU OpenMP runtime.
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.