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");
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(
"-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.