15#include "llvm/ADT/StringExtras.h"
16#include "llvm/Option/ArgList.h"
17#include "llvm/ProfileData/InstrProf.h"
18#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)
46 << A->getSpelling() <<
D.getTargetTriple();
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)
126 << A->getSpelling() <<
D.getTargetTriple();
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");
153 if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
155 Args.hasFlag(options::OPT_fprofile_generate,
156 options::OPT_fno_profile_generate,
false) ||
157 Args.hasFlag(options::OPT_fprofile_generate_EQ,
158 options::OPT_fno_profile_generate,
false) ||
159 Args.hasFlag(options::OPT_fprofile_instr_generate,
160 options::OPT_fno_profile_instr_generate,
false) ||
161 Args.hasFlag(options::OPT_fprofile_instr_generate_EQ,
162 options::OPT_fno_profile_instr_generate,
false) ||
163 Args.hasFlag(options::OPT_fcs_profile_generate,
164 options::OPT_fno_profile_generate,
false) ||
165 Args.hasFlag(options::OPT_fcs_profile_generate_EQ,
166 options::OPT_fno_profile_generate,
false) ||
167 Args.hasArg(options::OPT_fcreate_profile) ||
168 Args.hasArg(options::OPT_coverage))
169 CmdArgs.push_back(
"-bdbg:namedsects:ss");
172 Args.getLastArg(clang::driver::options::OPT_mxcoff_build_id_EQ)) {
173 StringRef BuildId = A->getValue();
174 if (BuildId[0] !=
'0' || BuildId[1] !=
'x' ||
175 BuildId.find_if_not(llvm::isHexDigit, 2) != StringRef::npos)
177 << A->getSpelling() << BuildId;
179 std::string LinkerFlag =
"-bdbg:ldrinfo:xcoff_binary_id:0x";
180 if (BuildId.size() % 2)
182 LinkerFlag += BuildId.drop_front(2).lower();
183 CmdArgs.push_back(Args.MakeArgString(LinkerFlag));
190 CmdArgs.push_back(
"-o");
197 CmdArgs.push_back(
"-b32");
198 CmdArgs.push_back(
"-bpT:0x10000000");
199 CmdArgs.push_back(
"-bpD:0x20000000");
202 CmdArgs.push_back(
"-b64");
203 CmdArgs.push_back(
"-bpT:0x100000000");
204 CmdArgs.push_back(
"-bpD:0x110000000");
207 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles,
208 options::OPT_shared, options::OPT_r)) {
209 auto getCrt0Basename = [&Args, IsArch32Bit] {
210 if (Arg *A = Args.getLastArgNoClaim(options::OPT_p, options::OPT_pg)) {
212 if (A->getOption().matches(options::OPT_pg))
213 return IsArch32Bit ?
"gcrt0.o" :
"gcrt0_64.o";
215 return IsArch32Bit ?
"mcrt0.o" :
"mcrt0_64.o";
217 return IsArch32Bit ?
"crt0.o" :
"crt0_64.o";
223 CmdArgs.push_back(Args.MakeArgString(
231 CmdArgs.push_back(
"-bcdtors:all:0:s");
236 if (
D.isUsingLTO()) {
237 assert(!Inputs.empty() &&
"Must have at least one input.");
239 auto Input = llvm::find_if(
241 if (Input == Inputs.end())
244 Input = Inputs.begin();
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)) {
290 if (getToolChain().ShouldLinkCXXStdlib(Args))
291 getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
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"));
333 if (
D.IsFlangMode() &&
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);
358AIX::GetHeaderSysroot(
const llvm::opt::ArgList &DriverArgs)
const {
359 if (DriverArgs.hasArg(options::OPT_isysroot))
360 return DriverArgs.getLastArgValue(options::OPT_isysroot);
366void AIX::AddOpenMPIncludeArgs(
const ArgList &DriverArgs,
367 ArgStringList &CC1Args)
const {
369 if (DriverArgs.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
370 options::OPT_fno_openmp,
false)) {
372 switch (
getDriver().getOpenMPRuntime(DriverArgs)) {
374 PathOpenMP = GetHeaderSysroot(DriverArgs);
375 llvm::sys::path::append(PathOpenMP,
"opt/IBM/openxlCSDK",
"include",
389 ArgStringList &CC1Args)
const {
391 if (DriverArgs.hasArg(options::OPT_nostdinc))
394 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
397 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
400 path::append(
P,
"include",
"ppc_wrappers");
409 AddOpenMPIncludeArgs(DriverArgs, CC1Args);
412 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
417 path::append(UP,
"/usr/include");
422 const llvm::opt::ArgList &DriverArgs,
423 llvm::opt::ArgStringList &CC1Args)
const {
425 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
426 DriverArgs.hasArg(options::OPT_nostdincxx) ||
427 DriverArgs.hasArg(options::OPT_nostdlibinc))
432 llvm::report_fatal_error(
433 "picking up libstdc++ headers is unimplemented on AIX");
435 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
437 llvm::sys::path::append(PathCPP,
"opt/IBM/openxlCSDK",
"include",
"c++",
442 CC1Args.push_back(
"-D__LIBC_NO_CPP_MATH_OVERLOADS__");
447 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
451 llvm::opt::ArgStringList &CmdArgs)
const {
454 llvm::report_fatal_error(
"linking libstdc++ unimplemented on AIX");
456 CmdArgs.push_back(
"-lc++");
457 if (Args.hasArg(options::OPT_fexperimental_library))
458 CmdArgs.push_back(
"-lc++experimental");
459 CmdArgs.push_back(
"-lc++abi");
463 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
469 llvm::opt::ArgStringList &CC1Args,
475 const bool TOCDataGloballyinEffect = [&Args]() {
476 if (
const Arg *LastArg =
477 Args.getLastArg(options::OPT_mtocdata, options::OPT_mno_tocdata))
478 return LastArg->getOption().matches(options::OPT_mtocdata);
483 enum TOCDataSetting {
488 const TOCDataSetting DefaultTocDataSetting =
489 TOCDataGloballyinEffect ? DataInTOC : AddressInTOC;
496 std::set<llvm::StringRef> ExplicitlySpecifiedGlobals;
497 for (
const auto Arg :
498 Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) {
499 TOCDataSetting ArgTocDataSetting =
500 Arg->getOption().matches(options::OPT_mtocdata_EQ) ? DataInTOC
503 if (ArgTocDataSetting != DefaultTocDataSetting)
504 for (
const char *Val : Arg->getValues())
505 ExplicitlySpecifiedGlobals.insert(Val);
507 for (
const char *Val : Arg->getValues())
508 ExplicitlySpecifiedGlobals.erase(Val);
511 auto buildExceptionList = [](
const std::set<llvm::StringRef> &ExplicitValues,
512 const char *OptionSpelling) {
513 std::string Option(OptionSpelling);
515 for (
const auto &
E : ExplicitValues) {
529 const char *TocDataGlobalOption =
530 TOCDataGloballyinEffect ?
"-mtocdata" :
"-mno-tocdata";
531 CC1Args.push_back(TocDataGlobalOption);
533 const char *TocDataListOption =
534 TOCDataGloballyinEffect ?
"-mno-tocdata=" :
"-mtocdata=";
535 if (!ExplicitlySpecifiedGlobals.empty())
536 CC1Args.push_back(Args.MakeArgString(llvm::Twine(
537 buildExceptionList(ExplicitlySpecifiedGlobals, TocDataListOption))));
541 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args,
543 Args.AddLastArg(CC1Args, options::OPT_mignore_xcoff_visibility);
544 Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ);
545 Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr);
548 if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ,
549 options::OPT_mtocdata))
552 if (Args.hasArg(options::OPT_msave_reg_params))
553 CC1Args.push_back(
"-msave-reg-params");
555 if (Args.hasFlag(options::OPT_fxl_pragma_pack,
556 options::OPT_fno_xl_pragma_pack,
true))
557 CC1Args.push_back(
"-fxl-pragma-pack");
561 if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
562 options::OPT_fno_sized_deallocation))
563 CC1Args.push_back(
"-fno-sized-deallocation");
567 llvm::opt::ArgStringList &CmdArgs)
const {
571 CmdArgs.push_back(Args.MakeArgString(
572 Twine(
"-u", llvm::getInstrProfRuntimeHookVarName())));
575 Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) {
576 StringRef Val = A->getValue();
577 if (Val ==
"atomic" || Val ==
"prefer-atomic")
578 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.