14#include "llvm/ADT/StringExtras.h"
15#include "llvm/Option/ArgList.h"
16#include "llvm/ProfileData/InstrProf.h"
17#include "llvm/Support/Path.h"
28using namespace llvm::sys;
34 const char *LinkingOutput)
const {
36 ArgStringList CmdArgs;
41 if (!IsArch32Bit && !IsArch64Bit)
42 llvm_unreachable(
"Unsupported bit width value.");
44 if (Arg *A =
C.getArgs().getLastArg(options::OPT_G)) {
45 D.
Diag(diag::err_drv_unsupported_opt_for_target)
51 CmdArgs.push_back(
"-a32");
54 CmdArgs.push_back(
"-a64");
61 CmdArgs.push_back(
"-many");
63 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
68 CmdArgs.push_back(
"-o");
75 if (Inputs.size() != 1)
76 llvm_unreachable(
"Invalid number of input files.");
82 const char *Exec = Args.MakeArgString(
getToolChain().GetProgramPath(
"as"));
84 Exec, CmdArgs, Inputs, Output));
90 for (
size_t i = 0, Size = CmdArgs.size(); i < Size; ++i) {
91 llvm::StringRef ArgString(CmdArgs[i]);
93 if (ArgString.starts_with(
"-bE:") || ArgString.starts_with(
"-bexport:") ||
94 ArgString ==
"-bexpall" || ArgString ==
"-bexpfull")
98 if (ArgString ==
"-b" && i + 1 < Size) {
100 llvm::StringRef ArgNextString(CmdArgs[i]);
101 if (ArgNextString.starts_with(
"E:") ||
102 ArgNextString.starts_with(
"export:") || ArgNextString ==
"expall" ||
103 ArgNextString ==
"expfull")
113 const char *LinkingOutput)
const {
116 ArgStringList CmdArgs;
121 if (!(IsArch32Bit || IsArch64Bit))
122 llvm_unreachable(
"Unsupported bit width value.");
124 if (Arg *A =
C.getArgs().getLastArg(options::OPT_G)) {
125 D.
Diag(diag::err_drv_unsupported_opt_for_target)
130 if (Args.hasArg(options::OPT_static))
131 CmdArgs.push_back(
"-bnso");
134 if (Args.hasArg(options::OPT_shared)) {
135 CmdArgs.push_back(
"-bM:SRE");
136 CmdArgs.push_back(
"-bnoentry");
139 if (Args.hasFlag(options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr,
141 if (Args.hasArg(options::OPT_shared))
142 D.
Diag(diag::err_roptr_cannot_build_shared);
147 CmdArgs.push_back(
"-bforceimprw");
154 CmdArgs.push_back(
"-bdbg:namedsects:ss");
156 if (Arg *A = Args.getLastArg(options::OPT_mxcoff_build_id_EQ)) {
157 StringRef BuildId = A->getValue();
158 if (BuildId[0] !=
'0' || BuildId[1] !=
'x' ||
159 BuildId.find_if_not(llvm::isHexDigit, 2) != StringRef::npos)
161 << A->getSpelling() << BuildId;
163 std::string LinkerFlag =
"-bdbg:ldrinfo:xcoff_binary_id:0x";
164 if (BuildId.size() % 2)
166 LinkerFlag += BuildId.drop_front(2).lower();
167 CmdArgs.push_back(Args.MakeArgString(LinkerFlag));
174 CmdArgs.push_back(
"-o");
181 CmdArgs.push_back(
"-b32");
182 CmdArgs.push_back(
"-bpT:0x10000000");
183 CmdArgs.push_back(
"-bpD:0x20000000");
186 CmdArgs.push_back(
"-b64");
187 CmdArgs.push_back(
"-bpT:0x100000000");
188 CmdArgs.push_back(
"-bpD:0x110000000");
191 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
192 options::OPT_shared, options::OPT_r)) {
193 auto getCrt0Basename = [&Args, IsArch32Bit] {
194 if (Arg *A = Args.getLastArgNoClaim(options::OPT_p, options::OPT_pg)) {
196 if (A->getOption().matches(options::OPT_pg))
197 return IsArch32Bit ?
"gcrt0.o" :
"gcrt0_64.o";
199 return IsArch32Bit ?
"mcrt0.o" :
"mcrt0_64.o";
201 return IsArch32Bit ?
"crt0.o" :
"crt0_64.o";
207 CmdArgs.push_back(Args.MakeArgString(
215 CmdArgs.push_back(
"-bcdtors:mbr:0:s");
217 if (Args.hasArg(options::OPT_rpath)) {
218 for (
const auto &bopt : Args.getAllArgValues(options::OPT_b))
220 if (!bopt.rfind(
"libpath:", 0) || bopt ==
"nolibpath")
221 D.
Diag(diag::err_drv_cannot_mix_options) <<
"-rpath" <<
"-b" + bopt;
223 for (
const auto &wlopt : Args.getAllArgValues(options::OPT_Wl_COMMA))
226 if (!wlopt.rfind(
"-blibpath:", 0) || wlopt ==
"-bnolibpath")
227 D.
Diag(diag::err_drv_cannot_mix_options) <<
"-rpath" <<
"-Wl," + wlopt;
229 for (
const auto &xopt : Args.getAllArgValues(options::OPT_Xlinker))
232 if (!xopt.rfind(
"-blibpath:", 0) || xopt ==
"-bnolibpath")
233 D.
Diag(diag::err_drv_cannot_mix_options)
234 <<
"-rpath" <<
"-Xlinker " + xopt;
236 std::string BlibPathStr =
"";
237 for (
const auto &dir : Args.getAllArgValues(options::OPT_rpath))
238 BlibPathStr += dir +
":";
239 BlibPathStr +=
"/usr/lib:/lib";
240 CmdArgs.push_back(Args.MakeArgString(Twine(
"-blibpath:") + BlibPathStr));
251 const char *CreateExportListExec = Args.MakeArgString(
253 ArgStringList CreateExportCmdArgs;
255 std::string CreateExportListPath =
256 C.getDriver().GetTemporaryPath(
"CreateExportList",
"exp");
257 const char *ExportList =
258 C.addTempFile(
C.getArgs().MakeArgString(CreateExportListPath));
260 for (
const auto &II : Inputs)
262 CreateExportCmdArgs.push_back(II.getFilename());
264 CreateExportCmdArgs.push_back(
"--export-symbols");
265 CreateExportCmdArgs.push_back(
"-X");
267 CreateExportCmdArgs.push_back(
"32");
270 CreateExportCmdArgs.push_back(
"64");
273 auto ExpCommand = std::make_unique<Command>(
275 CreateExportCmdArgs, Inputs, Output);
276 ExpCommand->setRedirectFiles(
277 {std::nullopt, std::string(ExportList), std::nullopt});
278 C.addCommand(std::move(ExpCommand));
279 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-bE:") + ExportList));
283 Args.AddAllArgs(CmdArgs, options::OPT_L);
284 if (!Args.hasArg(options::OPT_r)) {
291 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
295 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
296 options::OPT_fno_openmp,
false)) {
299 CmdArgs.push_back(
"-lomp");
302 CmdArgs.push_back(
"-liomp5");
305 CmdArgs.push_back(
"-lgomp");
312 CmdArgs.push_back(
"-lpthreads");
316 if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread))
317 CmdArgs.push_back(
"-lpthreads");
320 CmdArgs.push_back(
"-lm");
322 CmdArgs.push_back(
"-lc");
324 if (Args.hasArgNoClaim(options::OPT_p, options::OPT_pg)) {
325 CmdArgs.push_back(Args.MakeArgString((llvm::Twine(
"-L") + D.
SysRoot) +
327 CmdArgs.push_back(Args.MakeArgString((llvm::Twine(
"-L") + D.
SysRoot) +
328 "/usr/lib/profiled"));
334 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
337 CmdArgs.push_back(
"-lm");
338 CmdArgs.push_back(
"-lpthread");
342 Exec, CmdArgs, Inputs, Output));
350 ParseInlineAsmUsingAsmParser = Args.hasFlag(
351 options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
true);
362AIX::GetHeaderSysroot(
const llvm::opt::ArgList &DriverArgs)
const {
363 if (DriverArgs.hasArg(options::OPT_isysroot))
364 return DriverArgs.getLastArgValue(options::OPT_isysroot);
370void AIX::AddOpenMPIncludeArgs(
const ArgList &DriverArgs,
371 ArgStringList &CC1Args)
const {
373 if (DriverArgs.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
374 options::OPT_fno_openmp,
false)) {
376 switch (
getDriver().getOpenMPRuntime(DriverArgs)) {
378 PathOpenMP = GetHeaderSysroot(DriverArgs);
379 llvm::sys::path::append(PathOpenMP,
"opt/IBM/openxlCSDK",
"include",
393 ArgStringList &CC1Args)
const {
395 if (DriverArgs.hasArg(options::OPT_nostdinc))
398 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
401 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
404 path::append(P,
"include",
"ppc_wrappers");
413 AddOpenMPIncludeArgs(DriverArgs, CC1Args);
416 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
421 path::append(UP,
"/usr/include");
426 const llvm::opt::ArgList &DriverArgs,
427 llvm::opt::ArgStringList &CC1Args)
const {
429 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
430 DriverArgs.hasArg(options::OPT_nostdincxx) ||
431 DriverArgs.hasArg(options::OPT_nostdlibinc))
436 llvm::report_fatal_error(
437 "picking up libstdc++ headers is unimplemented on AIX");
439 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
441 llvm::sys::path::append(PathCPP,
"opt/IBM/openxlCSDK",
"include",
"c++",
446 CC1Args.push_back(
"-D__LIBC_NO_CPP_MATH_OVERLOADS__");
451 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
455 llvm::opt::ArgStringList &CmdArgs)
const {
460 if (LibPath.length() > 0 && LibPath !=
getDriver().SysRoot +
"/usr/lib" &&
461 LibPath !=
getDriver().SysRoot +
"/lib") {
462 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
468 llvm::opt::ArgStringList &CmdArgs)
const {
471 llvm::report_fatal_error(
"linking libstdc++ unimplemented on AIX");
473 CmdArgs.push_back(
"-lc++");
474 if (Args.hasArg(options::OPT_fexperimental_library))
475 CmdArgs.push_back(
"-lc++experimental");
476 CmdArgs.push_back(
"-lc++abi");
480 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
486 llvm::opt::ArgStringList &CC1Args,
492 const bool TOCDataGloballyinEffect = [&Args]() {
493 if (
const Arg *LastArg =
494 Args.getLastArg(options::OPT_mtocdata, options::OPT_mno_tocdata))
495 return LastArg->getOption().matches(options::OPT_mtocdata);
500 enum TOCDataSetting {
505 const TOCDataSetting DefaultTocDataSetting =
506 TOCDataGloballyinEffect ? DataInTOC : AddressInTOC;
513 std::set<llvm::StringRef> ExplicitlySpecifiedGlobals;
514 for (
const auto Arg :
515 Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) {
516 TOCDataSetting ArgTocDataSetting =
517 Arg->getOption().matches(options::OPT_mtocdata_EQ) ? DataInTOC
520 if (ArgTocDataSetting != DefaultTocDataSetting)
521 for (
const char *Val : Arg->getValues())
522 ExplicitlySpecifiedGlobals.insert(Val);
524 for (
const char *Val : Arg->getValues())
525 ExplicitlySpecifiedGlobals.erase(Val);
528 auto buildExceptionList = [](
const std::set<llvm::StringRef> &ExplicitValues,
529 const char *OptionSpelling) {
530 std::string Option(OptionSpelling);
532 for (
const auto &E : ExplicitValues) {
546 const char *TocDataGlobalOption =
547 TOCDataGloballyinEffect ?
"-mtocdata" :
"-mno-tocdata";
548 CC1Args.push_back(TocDataGlobalOption);
550 const char *TocDataListOption =
551 TOCDataGloballyinEffect ?
"-mno-tocdata=" :
"-mtocdata=";
552 if (!ExplicitlySpecifiedGlobals.empty())
553 CC1Args.push_back(Args.MakeArgString(llvm::Twine(
554 buildExceptionList(ExplicitlySpecifiedGlobals, TocDataListOption))));
558 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args,
560 Args.AddLastArg(CC1Args, options::OPT_mignore_xcoff_visibility);
561 Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ);
562 Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr);
565 if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ,
566 options::OPT_mtocdata))
569 if (Args.hasArg(options::OPT_msave_reg_params))
570 CC1Args.push_back(
"-msave-reg-params");
572 if (Args.hasFlag(options::OPT_fxl_pragma_pack,
573 options::OPT_fno_xl_pragma_pack,
true))
574 CC1Args.push_back(
"-fxl-pragma-pack");
578 if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
579 options::OPT_fno_sized_deallocation))
580 CC1Args.push_back(
"-fno-sized-deallocation");
584 llvm::opt::ArgStringList &CmdArgs)
const {
588 CmdArgs.push_back(Args.MakeArgString(
589 Twine(
"-u", llvm::getInstrProfRuntimeHookVarName())));
592 Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) {
593 StringRef Val = A->getValue();
594 if (Val ==
"atomic" || Val ==
"prefer-atomic")
595 CmdArgs.push_back(
"-lcompiler_rt");
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
@ 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.
std::string getTargetTriple() const
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
std::string DriverExecutable
The original path to the driver executable.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
SmallVector< InputInfo, 4 > InputInfoList
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.