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:all: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));
252 const char *CreateExportListExec = Args.MakeArgString(
255 ArgStringList CreateExportCmdArgs;
257 std::string CreateExportListPath =
258 C.getDriver().GetTemporaryPath(
"CreateExportList",
"exp");
259 const char *ExportList =
260 C.addTempFile(
C.getArgs().MakeArgString(CreateExportListPath));
262 for (
const auto &II : Inputs)
264 CreateExportCmdArgs.push_back(II.getFilename());
266 CreateExportCmdArgs.push_back(
"--export-symbols");
267 CreateExportCmdArgs.push_back(
"-X");
269 CreateExportCmdArgs.push_back(
"32");
272 CreateExportCmdArgs.push_back(
"64");
275 auto ExpCommand = std::make_unique<Command>(
277 CreateExportCmdArgs, Inputs, Output);
278 ExpCommand->setRedirectFiles(
279 {std::nullopt, std::string(ExportList), std::nullopt});
280 C.addCommand(std::move(ExpCommand));
281 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-bE:") + ExportList));
285 Args.AddAllArgs(CmdArgs, options::OPT_L);
286 if (!Args.hasArg(options::OPT_r)) {
293 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
297 if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
298 options::OPT_fno_openmp,
false)) {
301 CmdArgs.push_back(
"-lomp");
304 CmdArgs.push_back(
"-liomp5");
307 CmdArgs.push_back(
"-lgomp");
314 CmdArgs.push_back(
"-lpthreads");
318 if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread))
319 CmdArgs.push_back(
"-lpthreads");
322 CmdArgs.push_back(
"-lm");
324 CmdArgs.push_back(
"-lc");
326 if (Args.hasArgNoClaim(options::OPT_p, options::OPT_pg)) {
327 CmdArgs.push_back(Args.MakeArgString((llvm::Twine(
"-L") + D.
SysRoot) +
329 CmdArgs.push_back(Args.MakeArgString((llvm::Twine(
"-L") + D.
SysRoot) +
330 "/usr/lib/profiled"));
336 !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
339 CmdArgs.push_back(
"-lm");
340 CmdArgs.push_back(
"-lpthread");
344 Exec, CmdArgs, Inputs, Output));
352 ParseInlineAsmUsingAsmParser = Args.hasFlag(
353 options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
true);
364AIX::GetHeaderSysroot(
const llvm::opt::ArgList &DriverArgs)
const {
365 if (DriverArgs.hasArg(options::OPT_isysroot))
366 return DriverArgs.getLastArgValue(options::OPT_isysroot);
372void AIX::AddOpenMPIncludeArgs(
const ArgList &DriverArgs,
373 ArgStringList &CC1Args)
const {
375 if (DriverArgs.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
376 options::OPT_fno_openmp,
false)) {
378 switch (
getDriver().getOpenMPRuntime(DriverArgs)) {
380 PathOpenMP = GetHeaderSysroot(DriverArgs);
381 llvm::sys::path::append(PathOpenMP,
"opt/IBM/openxlCSDK",
"include",
395 ArgStringList &CC1Args)
const {
397 if (DriverArgs.hasArg(options::OPT_nostdinc))
400 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
403 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
406 path::append(P,
"include",
"ppc_wrappers");
415 AddOpenMPIncludeArgs(DriverArgs, CC1Args);
418 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
423 path::append(UP,
"/usr/include");
428 const llvm::opt::ArgList &DriverArgs,
429 llvm::opt::ArgStringList &CC1Args)
const {
431 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
432 DriverArgs.hasArg(options::OPT_nostdincxx) ||
433 DriverArgs.hasArg(options::OPT_nostdlibinc))
438 llvm::report_fatal_error(
439 "picking up libstdc++ headers is unimplemented on AIX");
441 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
443 llvm::sys::path::append(PathCPP,
"opt/IBM/openxlCSDK",
"include",
"c++",
448 CC1Args.push_back(
"-D__LIBC_NO_CPP_MATH_OVERLOADS__");
453 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
457 llvm::opt::ArgStringList &CmdArgs)
const {
462 if (LibPath.length() > 0 && LibPath !=
getDriver().SysRoot +
"/usr/lib" &&
463 LibPath !=
getDriver().SysRoot +
"/lib") {
464 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
470 llvm::opt::ArgStringList &CmdArgs)
const {
473 llvm::report_fatal_error(
"linking libstdc++ unimplemented on AIX");
475 CmdArgs.push_back(
"-lc++");
476 if (Args.hasArg(options::OPT_fexperimental_library))
477 CmdArgs.push_back(
"-lc++experimental");
478 CmdArgs.push_back(
"-lc++abi");
482 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
488 llvm::opt::ArgStringList &CC1Args,
494 const bool TOCDataGloballyinEffect = [&Args]() {
495 if (
const Arg *LastArg =
496 Args.getLastArg(options::OPT_mtocdata, options::OPT_mno_tocdata))
497 return LastArg->getOption().matches(options::OPT_mtocdata);
502 enum TOCDataSetting {
507 const TOCDataSetting DefaultTocDataSetting =
508 TOCDataGloballyinEffect ? DataInTOC : AddressInTOC;
515 std::set<llvm::StringRef> ExplicitlySpecifiedGlobals;
516 for (
const auto Arg :
517 Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) {
518 TOCDataSetting ArgTocDataSetting =
519 Arg->getOption().matches(options::OPT_mtocdata_EQ) ? DataInTOC
522 if (ArgTocDataSetting != DefaultTocDataSetting)
523 for (
const char *Val : Arg->getValues())
524 ExplicitlySpecifiedGlobals.insert(Val);
526 for (
const char *Val : Arg->getValues())
527 ExplicitlySpecifiedGlobals.erase(Val);
530 auto buildExceptionList = [](
const std::set<llvm::StringRef> &ExplicitValues,
531 const char *OptionSpelling) {
532 std::string Option(OptionSpelling);
534 for (
const auto &E : ExplicitValues) {
548 const char *TocDataGlobalOption =
549 TOCDataGloballyinEffect ?
"-mtocdata" :
"-mno-tocdata";
550 CC1Args.push_back(TocDataGlobalOption);
552 const char *TocDataListOption =
553 TOCDataGloballyinEffect ?
"-mno-tocdata=" :
"-mtocdata=";
554 if (!ExplicitlySpecifiedGlobals.empty())
555 CC1Args.push_back(Args.MakeArgString(llvm::Twine(
556 buildExceptionList(ExplicitlySpecifiedGlobals, TocDataListOption))));
560 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args,
562 Args.AddLastArg(CC1Args, options::OPT_mignore_xcoff_visibility);
563 Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ);
564 Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr);
567 if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ,
568 options::OPT_mtocdata))
571 if (Args.hasArg(options::OPT_msave_reg_params))
572 CC1Args.push_back(
"-msave-reg-params");
574 if (Args.hasFlag(options::OPT_fxl_pragma_pack,
575 options::OPT_fno_xl_pragma_pack,
true))
576 CC1Args.push_back(
"-fxl-pragma-pack");
580 if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
581 options::OPT_fno_sized_deallocation))
582 CC1Args.push_back(
"-fno-sized-deallocation");
586 llvm::opt::ArgStringList &CmdArgs)
const {
590 CmdArgs.push_back(Args.MakeArgString(
591 Twine(
"-u", llvm::getInstrProfRuntimeHookVarName())));
594 Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) {
595 StringRef Val = A->getValue();
596 if (Val ==
"atomic" || Val ==
"prefer-atomic")
597 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.
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
std::string getTargetTriple() const
bool IsFlangMode() const
Whether the driver should invoke flang for fortran inputs.
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
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.