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()) {
336 CmdArgs.push_back(
"-lm");
337 CmdArgs.push_back(
"-lpthread");
341 Exec, CmdArgs, Inputs, Output));
349 ParseInlineAsmUsingAsmParser = Args.hasFlag(
350 options::OPT_fintegrated_as, options::OPT_fno_integrated_as,
true);
357AIX::GetHeaderSysroot(
const llvm::opt::ArgList &DriverArgs)
const {
358 if (DriverArgs.hasArg(options::OPT_isysroot))
359 return DriverArgs.getLastArgValue(options::OPT_isysroot);
365void AIX::AddOpenMPIncludeArgs(
const ArgList &DriverArgs,
366 ArgStringList &CC1Args)
const {
368 if (DriverArgs.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
369 options::OPT_fno_openmp,
false)) {
371 switch (
getDriver().getOpenMPRuntime(DriverArgs)) {
373 PathOpenMP = GetHeaderSysroot(DriverArgs);
374 llvm::sys::path::append(PathOpenMP,
"opt/IBM/openxlCSDK",
"include",
388 ArgStringList &CC1Args)
const {
390 if (DriverArgs.hasArg(options::OPT_nostdinc))
393 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
396 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
399 path::append(
P,
"include",
"ppc_wrappers");
408 AddOpenMPIncludeArgs(DriverArgs, CC1Args);
411 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
416 path::append(UP,
"/usr/include");
421 const llvm::opt::ArgList &DriverArgs,
422 llvm::opt::ArgStringList &CC1Args)
const {
424 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
425 DriverArgs.hasArg(options::OPT_nostdincxx) ||
426 DriverArgs.hasArg(options::OPT_nostdlibinc))
431 llvm::report_fatal_error(
432 "picking up libstdc++ headers is unimplemented on AIX");
434 llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
436 llvm::sys::path::append(PathCPP,
"opt/IBM/openxlCSDK",
"include",
"c++",
441 CC1Args.push_back(
"-D__LIBC_NO_CPP_MATH_OVERLOADS__");
446 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
450 llvm::opt::ArgStringList &CmdArgs)
const {
453 llvm::report_fatal_error(
"linking libstdc++ unimplemented on AIX");
455 CmdArgs.push_back(
"-lc++");
456 if (Args.hasArg(options::OPT_fexperimental_library))
457 CmdArgs.push_back(
"-lc++experimental");
458 CmdArgs.push_back(
"-lc++abi");
462 llvm_unreachable(
"Unexpected C++ library type; only libc++ is supported.");
468 llvm::opt::ArgStringList &CC1Args,
474 const bool TOCDataGloballyinEffect = [&Args]() {
475 if (
const Arg *LastArg =
476 Args.getLastArg(options::OPT_mtocdata, options::OPT_mno_tocdata))
477 return LastArg->getOption().matches(options::OPT_mtocdata);
482 enum TOCDataSetting {
487 const TOCDataSetting DefaultTocDataSetting =
488 TOCDataGloballyinEffect ? DataInTOC : AddressInTOC;
495 std::set<llvm::StringRef> ExplicitlySpecifiedGlobals;
496 for (
const auto Arg :
497 Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) {
498 TOCDataSetting ArgTocDataSetting =
499 Arg->getOption().matches(options::OPT_mtocdata_EQ) ? DataInTOC
502 if (ArgTocDataSetting != DefaultTocDataSetting)
503 for (
const char *Val : Arg->getValues())
504 ExplicitlySpecifiedGlobals.insert(Val);
506 for (
const char *Val : Arg->getValues())
507 ExplicitlySpecifiedGlobals.erase(Val);
510 auto buildExceptionList = [](
const std::set<llvm::StringRef> &ExplicitValues,
511 const char *OptionSpelling) {
512 std::string Option(OptionSpelling);
514 for (
const auto &
E : ExplicitValues) {
528 const char *TocDataGlobalOption =
529 TOCDataGloballyinEffect ?
"-mtocdata" :
"-mno-tocdata";
530 CC1Args.push_back(TocDataGlobalOption);
532 const char *TocDataListOption =
533 TOCDataGloballyinEffect ?
"-mno-tocdata=" :
"-mtocdata=";
534 if (!ExplicitlySpecifiedGlobals.empty())
535 CC1Args.push_back(Args.MakeArgString(llvm::Twine(
536 buildExceptionList(ExplicitlySpecifiedGlobals, TocDataListOption))));
540 const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args,
542 Args.AddLastArg(CC1Args, options::OPT_mignore_xcoff_visibility);
543 Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ);
544 Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr);
547 if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ,
548 options::OPT_mtocdata))
551 if (Args.hasArg(options::OPT_msave_reg_params))
552 CC1Args.push_back(
"-msave-reg-params");
554 if (Args.hasFlag(options::OPT_fxl_pragma_pack,
555 options::OPT_fno_xl_pragma_pack,
true))
556 CC1Args.push_back(
"-fxl-pragma-pack");
560 if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
561 options::OPT_fno_sized_deallocation))
562 CC1Args.push_back(
"-fno-sized-deallocation");
566 llvm::opt::ArgStringList &CmdArgs)
const {
570 CmdArgs.push_back(Args.MakeArgString(
571 Twine(
"-u", llvm::getInstrProfRuntimeHookVarName())));
574 Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) {
575 StringRef Val = A->getValue();
576 if (Val ==
"atomic" || Val ==
"prefer-atomic")
577 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.