Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
35294 views
1
//===--- AIX.cpp - AIX ToolChain Implementations ----------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "AIX.h"
10
#include "Arch/PPC.h"
11
#include "CommonArgs.h"
12
#include "clang/Driver/Compilation.h"
13
#include "clang/Driver/Options.h"
14
#include "clang/Driver/SanitizerArgs.h"
15
#include "llvm/ADT/StringExtras.h"
16
#include "llvm/Option/ArgList.h"
17
#include "llvm/ProfileData/InstrProf.h"
18
#include "llvm/Support/Path.h"
19
20
#include <set>
21
22
using AIX = clang::driver::toolchains::AIX;
23
using namespace clang::driver;
24
using namespace clang::driver::tools;
25
using namespace clang::driver::toolchains;
26
27
using namespace llvm::opt;
28
using namespace llvm::sys;
29
30
void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
31
const InputInfo &Output,
32
const InputInfoList &Inputs,
33
const ArgList &Args,
34
const char *LinkingOutput) const {
35
const Driver &D = getToolChain().getDriver();
36
ArgStringList CmdArgs;
37
38
const bool IsArch32Bit = getToolChain().getTriple().isArch32Bit();
39
const bool IsArch64Bit = getToolChain().getTriple().isArch64Bit();
40
// Only support 32 and 64 bit.
41
if (!IsArch32Bit && !IsArch64Bit)
42
llvm_unreachable("Unsupported bit width value.");
43
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();
47
}
48
49
// Specify the mode in which the as(1) command operates.
50
if (IsArch32Bit) {
51
CmdArgs.push_back("-a32");
52
} else {
53
// Must be 64-bit, otherwise asserted already.
54
CmdArgs.push_back("-a64");
55
}
56
57
// Accept any mixture of instructions.
58
// On Power for AIX and Linux, this behaviour matches that of GCC for both the
59
// user-provided assembler source case and the compiler-produced assembler
60
// source case. Yet XL with user-provided assembler source would not add this.
61
CmdArgs.push_back("-many");
62
63
Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
64
65
// Specify assembler output file.
66
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
67
if (Output.isFilename()) {
68
CmdArgs.push_back("-o");
69
CmdArgs.push_back(Output.getFilename());
70
}
71
72
// Specify assembler input file.
73
// The system assembler on AIX takes exactly one input file. The driver is
74
// expected to invoke as(1) separately for each assembler source input file.
75
if (Inputs.size() != 1)
76
llvm_unreachable("Invalid number of input files.");
77
const InputInfo &II = Inputs[0];
78
assert((II.isFilename() || II.isNothing()) && "Invalid input.");
79
if (II.isFilename())
80
CmdArgs.push_back(II.getFilename());
81
82
const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
83
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
84
Exec, CmdArgs, Inputs, Output));
85
}
86
87
// Determine whether there are any linker options that supply an export list
88
// (or equivalent information about what to export) being sent to the linker.
89
static bool hasExportListLinkerOpts(const ArgStringList &CmdArgs) {
90
for (size_t i = 0, Size = CmdArgs.size(); i < Size; ++i) {
91
llvm::StringRef ArgString(CmdArgs[i]);
92
93
if (ArgString.starts_with("-bE:") || ArgString.starts_with("-bexport:") ||
94
ArgString == "-bexpall" || ArgString == "-bexpfull")
95
return true;
96
97
// If we split -b option, check the next opt.
98
if (ArgString == "-b" && i + 1 < Size) {
99
++i;
100
llvm::StringRef ArgNextString(CmdArgs[i]);
101
if (ArgNextString.starts_with("E:") ||
102
ArgNextString.starts_with("export:") || ArgNextString == "expall" ||
103
ArgNextString == "expfull")
104
return true;
105
}
106
}
107
return false;
108
}
109
110
void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
111
const InputInfo &Output,
112
const InputInfoList &Inputs, const ArgList &Args,
113
const char *LinkingOutput) const {
114
const AIX &ToolChain = static_cast<const AIX &>(getToolChain());
115
const Driver &D = ToolChain.getDriver();
116
ArgStringList CmdArgs;
117
118
const bool IsArch32Bit = ToolChain.getTriple().isArch32Bit();
119
const bool IsArch64Bit = ToolChain.getTriple().isArch64Bit();
120
// Only support 32 and 64 bit.
121
if (!(IsArch32Bit || IsArch64Bit))
122
llvm_unreachable("Unsupported bit width value.");
123
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();
127
}
128
129
// Force static linking when "-static" is present.
130
if (Args.hasArg(options::OPT_static))
131
CmdArgs.push_back("-bnso");
132
133
// Add options for shared libraries.
134
if (Args.hasArg(options::OPT_shared)) {
135
CmdArgs.push_back("-bM:SRE");
136
CmdArgs.push_back("-bnoentry");
137
}
138
139
if (Args.hasFlag(options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr,
140
false)) {
141
if (Args.hasArg(options::OPT_shared))
142
D.Diag(diag::err_roptr_cannot_build_shared);
143
144
// The `-mxcoff-roptr` option places constants in RO sections as much as
145
// possible. Then `-bforceimprw` changes such sections to RW if they contain
146
// imported symbols that need to be resolved.
147
CmdArgs.push_back("-bforceimprw");
148
}
149
150
// PGO instrumentation generates symbols belonging to special sections, and
151
// the linker needs to place all symbols in a particular section together in
152
// memory; the AIX linker does that under an option.
153
if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs,
154
false) ||
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");
170
171
if (Arg *A =
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)
176
ToolChain.getDriver().Diag(diag::err_drv_unsupported_option_argument)
177
<< A->getSpelling() << BuildId;
178
else {
179
std::string LinkerFlag = "-bdbg:ldrinfo:xcoff_binary_id:0x";
180
if (BuildId.size() % 2) // Prepend a 0 if odd number of digits.
181
LinkerFlag += "0";
182
LinkerFlag += BuildId.drop_front(2).lower();
183
CmdArgs.push_back(Args.MakeArgString(LinkerFlag));
184
}
185
}
186
187
// Specify linker output file.
188
assert((Output.isFilename() || Output.isNothing()) && "Invalid output.");
189
if (Output.isFilename()) {
190
CmdArgs.push_back("-o");
191
CmdArgs.push_back(Output.getFilename());
192
}
193
194
// Set linking mode (i.e., 32/64-bit) and the address of
195
// text and data sections based on arch bit width.
196
if (IsArch32Bit) {
197
CmdArgs.push_back("-b32");
198
CmdArgs.push_back("-bpT:0x10000000");
199
CmdArgs.push_back("-bpD:0x20000000");
200
} else {
201
// Must be 64-bit, otherwise asserted already.
202
CmdArgs.push_back("-b64");
203
CmdArgs.push_back("-bpT:0x100000000");
204
CmdArgs.push_back("-bpD:0x110000000");
205
}
206
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)) {
211
// Enable gprofiling when "-pg" is specified.
212
if (A->getOption().matches(options::OPT_pg))
213
return IsArch32Bit ? "gcrt0.o" : "gcrt0_64.o";
214
// Enable profiling when "-p" is specified.
215
return IsArch32Bit ? "mcrt0.o" : "mcrt0_64.o";
216
}
217
return IsArch32Bit ? "crt0.o" : "crt0_64.o";
218
};
219
220
CmdArgs.push_back(
221
Args.MakeArgString(ToolChain.GetFilePath(getCrt0Basename())));
222
223
CmdArgs.push_back(Args.MakeArgString(
224
ToolChain.GetFilePath(IsArch32Bit ? "crti.o" : "crti_64.o")));
225
}
226
227
// Collect all static constructor and destructor functions in both C and CXX
228
// language link invocations. This has to come before AddLinkerInputs as the
229
// implied option needs to precede any other '-bcdtors' settings or
230
// '-bnocdtors' that '-Wl' might forward.
231
CmdArgs.push_back("-bcdtors:all:0:s");
232
233
// Specify linker input file(s).
234
AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
235
236
if (D.isUsingLTO()) {
237
assert(!Inputs.empty() && "Must have at least one input.");
238
// Find the first filename InputInfo object.
239
auto Input = llvm::find_if(
240
Inputs, [](const InputInfo &II) -> bool { return II.isFilename(); });
241
if (Input == Inputs.end())
242
// For a very rare case, all of the inputs to the linker are
243
// InputArg. If that happens, just use the first InputInfo.
244
Input = Inputs.begin();
245
246
addLTOOptions(ToolChain, Args, CmdArgs, Output, *Input,
247
D.getLTOMode() == LTOK_Thin);
248
}
249
250
if (Args.hasArg(options::OPT_shared) && !hasExportListLinkerOpts(CmdArgs)) {
251
252
const char *CreateExportListExec = Args.MakeArgString(
253
path::parent_path(ToolChain.getDriver().ClangExecutable) +
254
"/llvm-nm");
255
ArgStringList CreateExportCmdArgs;
256
257
std::string CreateExportListPath =
258
C.getDriver().GetTemporaryPath("CreateExportList", "exp");
259
const char *ExportList =
260
C.addTempFile(C.getArgs().MakeArgString(CreateExportListPath));
261
262
for (const auto &II : Inputs)
263
if (II.isFilename())
264
CreateExportCmdArgs.push_back(II.getFilename());
265
266
CreateExportCmdArgs.push_back("--export-symbols");
267
CreateExportCmdArgs.push_back("-X");
268
if (IsArch32Bit) {
269
CreateExportCmdArgs.push_back("32");
270
} else {
271
// Must be 64-bit, otherwise asserted already.
272
CreateExportCmdArgs.push_back("64");
273
}
274
275
auto ExpCommand = std::make_unique<Command>(
276
JA, *this, ResponseFileSupport::None(), CreateExportListExec,
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));
282
}
283
284
// Add directory to library search path.
285
Args.AddAllArgs(CmdArgs, options::OPT_L);
286
if (!Args.hasArg(options::OPT_r)) {
287
ToolChain.AddFilePathLibArgs(Args, CmdArgs);
288
ToolChain.addProfileRTLibs(Args, CmdArgs);
289
290
if (getToolChain().ShouldLinkCXXStdlib(Args))
291
getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
292
293
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
294
AddRunTimeLibs(ToolChain, D, CmdArgs, Args);
295
296
// Add OpenMP runtime if -fopenmp is specified.
297
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
298
options::OPT_fno_openmp, false)) {
299
switch (ToolChain.getDriver().getOpenMPRuntime(Args)) {
300
case Driver::OMPRT_OMP:
301
CmdArgs.push_back("-lomp");
302
break;
303
case Driver::OMPRT_IOMP5:
304
CmdArgs.push_back("-liomp5");
305
break;
306
case Driver::OMPRT_GOMP:
307
CmdArgs.push_back("-lgomp");
308
break;
309
case Driver::OMPRT_Unknown:
310
// Already diagnosed.
311
break;
312
}
313
}
314
315
// Support POSIX threads if "-pthreads" or "-pthread" is present.
316
if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread))
317
CmdArgs.push_back("-lpthreads");
318
319
if (D.CCCIsCXX())
320
CmdArgs.push_back("-lm");
321
322
CmdArgs.push_back("-lc");
323
324
if (Args.hasArgNoClaim(options::OPT_p, options::OPT_pg)) {
325
CmdArgs.push_back(Args.MakeArgString((llvm::Twine("-L") + D.SysRoot) +
326
"/lib/profiled"));
327
CmdArgs.push_back(Args.MakeArgString((llvm::Twine("-L") + D.SysRoot) +
328
"/usr/lib/profiled"));
329
}
330
}
331
}
332
333
if (D.IsFlangMode()) {
334
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
335
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
336
CmdArgs.push_back("-lm");
337
CmdArgs.push_back("-lpthread");
338
}
339
const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
340
C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
341
Exec, CmdArgs, Inputs, Output));
342
}
343
344
/// AIX - AIX tool chain which can call as(1) and ld(1) directly.
345
AIX::AIX(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
346
: ToolChain(D, Triple, Args) {
347
getProgramPaths().push_back(getDriver().Dir);
348
349
ParseInlineAsmUsingAsmParser = Args.hasFlag(
350
options::OPT_fintegrated_as, options::OPT_fno_integrated_as, true);
351
getLibraryPaths().push_back(getDriver().SysRoot + "/usr/lib");
352
}
353
354
// Returns the effective header sysroot path to use.
355
// This comes from either -isysroot or --sysroot.
356
llvm::StringRef
357
AIX::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const {
358
if (DriverArgs.hasArg(options::OPT_isysroot))
359
return DriverArgs.getLastArgValue(options::OPT_isysroot);
360
if (!getDriver().SysRoot.empty())
361
return getDriver().SysRoot;
362
return "/";
363
}
364
365
void AIX::AddOpenMPIncludeArgs(const ArgList &DriverArgs,
366
ArgStringList &CC1Args) const {
367
// Add OpenMP include paths if -fopenmp is specified.
368
if (DriverArgs.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
369
options::OPT_fno_openmp, false)) {
370
SmallString<128> PathOpenMP;
371
switch (getDriver().getOpenMPRuntime(DriverArgs)) {
372
case Driver::OMPRT_OMP:
373
PathOpenMP = GetHeaderSysroot(DriverArgs);
374
llvm::sys::path::append(PathOpenMP, "opt/IBM/openxlCSDK", "include",
375
"openmp");
376
addSystemInclude(DriverArgs, CC1Args, PathOpenMP.str());
377
break;
378
case Driver::OMPRT_IOMP5:
379
case Driver::OMPRT_GOMP:
380
case Driver::OMPRT_Unknown:
381
// Unknown / unsupported include paths.
382
break;
383
}
384
}
385
}
386
387
void AIX::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
388
ArgStringList &CC1Args) const {
389
// Return if -nostdinc is specified as a driver option.
390
if (DriverArgs.hasArg(options::OPT_nostdinc))
391
return;
392
393
llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
394
const Driver &D = getDriver();
395
396
if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
397
SmallString<128> P(D.ResourceDir);
398
// Add the PowerPC intrinsic headers (<resource>/include/ppc_wrappers)
399
path::append(P, "include", "ppc_wrappers");
400
addSystemInclude(DriverArgs, CC1Args, P);
401
// Add the Clang builtin headers (<resource>/include)
402
addSystemInclude(DriverArgs, CC1Args, path::parent_path(P.str()));
403
}
404
405
// Add the include directory containing omp.h. This needs to be before
406
// adding the system include directory because other compilers put their
407
// omp.h in /usr/include.
408
AddOpenMPIncludeArgs(DriverArgs, CC1Args);
409
410
// Return if -nostdlibinc is specified as a driver option.
411
if (DriverArgs.hasArg(options::OPT_nostdlibinc))
412
return;
413
414
// Add <sysroot>/usr/include.
415
SmallString<128> UP(Sysroot);
416
path::append(UP, "/usr/include");
417
addSystemInclude(DriverArgs, CC1Args, UP.str());
418
}
419
420
void AIX::AddClangCXXStdlibIncludeArgs(
421
const llvm::opt::ArgList &DriverArgs,
422
llvm::opt::ArgStringList &CC1Args) const {
423
424
if (DriverArgs.hasArg(options::OPT_nostdinc) ||
425
DriverArgs.hasArg(options::OPT_nostdincxx) ||
426
DriverArgs.hasArg(options::OPT_nostdlibinc))
427
return;
428
429
switch (GetCXXStdlibType(DriverArgs)) {
430
case ToolChain::CST_Libstdcxx:
431
llvm::report_fatal_error(
432
"picking up libstdc++ headers is unimplemented on AIX");
433
case ToolChain::CST_Libcxx: {
434
llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs);
435
SmallString<128> PathCPP(Sysroot);
436
llvm::sys::path::append(PathCPP, "opt/IBM/openxlCSDK", "include", "c++",
437
"v1");
438
addSystemInclude(DriverArgs, CC1Args, PathCPP.str());
439
// Required in order to suppress conflicting C++ overloads in the system
440
// libc headers that were used by XL C++.
441
CC1Args.push_back("-D__LIBC_NO_CPP_MATH_OVERLOADS__");
442
return;
443
}
444
}
445
446
llvm_unreachable("Unexpected C++ library type; only libc++ is supported.");
447
}
448
449
void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
450
llvm::opt::ArgStringList &CmdArgs) const {
451
switch (GetCXXStdlibType(Args)) {
452
case ToolChain::CST_Libstdcxx:
453
llvm::report_fatal_error("linking libstdc++ unimplemented on AIX");
454
case ToolChain::CST_Libcxx:
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");
459
return;
460
}
461
462
llvm_unreachable("Unexpected C++ library type; only libc++ is supported.");
463
}
464
465
// This function processes all the mtocdata options to build the final
466
// simplified toc data options to pass to CC1.
467
static void addTocDataOptions(const llvm::opt::ArgList &Args,
468
llvm::opt::ArgStringList &CC1Args,
469
const Driver &D) {
470
471
// Check the global toc-data setting. The default is -mno-tocdata.
472
// To enable toc-data globally, -mtocdata must be specified.
473
// Additionally, it must be last to take effect.
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);
478
else
479
return false;
480
}();
481
482
enum TOCDataSetting {
483
AddressInTOC = 0, // Address of the symbol stored in the TOC.
484
DataInTOC = 1 // Symbol defined in the TOC.
485
};
486
487
const TOCDataSetting DefaultTocDataSetting =
488
TOCDataGloballyinEffect ? DataInTOC : AddressInTOC;
489
490
// Process the list of variables in the explicitly specified options
491
// -mtocdata= and -mno-tocdata= to see which variables are opposite to
492
// the global setting of tocdata in TOCDataGloballyinEffect.
493
// Those that have the opposite setting to TOCDataGloballyinEffect, are added
494
// to ExplicitlySpecifiedGlobals.
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
500
: AddressInTOC;
501
502
if (ArgTocDataSetting != DefaultTocDataSetting)
503
for (const char *Val : Arg->getValues())
504
ExplicitlySpecifiedGlobals.insert(Val);
505
else
506
for (const char *Val : Arg->getValues())
507
ExplicitlySpecifiedGlobals.erase(Val);
508
}
509
510
auto buildExceptionList = [](const std::set<llvm::StringRef> &ExplicitValues,
511
const char *OptionSpelling) {
512
std::string Option(OptionSpelling);
513
bool IsFirst = true;
514
for (const auto &E : ExplicitValues) {
515
if (!IsFirst)
516
Option += ",";
517
518
IsFirst = false;
519
Option += E.str();
520
}
521
return Option;
522
};
523
524
// Pass the final tocdata options to CC1 consisting of the default
525
// tocdata option (-mtocdata/-mno-tocdata) along with the list
526
// option (-mno-tocdata=/-mtocdata=) if there are any explicitly specified
527
// variables which would be exceptions to the default setting.
528
const char *TocDataGlobalOption =
529
TOCDataGloballyinEffect ? "-mtocdata" : "-mno-tocdata";
530
CC1Args.push_back(TocDataGlobalOption);
531
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))));
537
}
538
539
void AIX::addClangTargetOptions(
540
const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args,
541
Action::OffloadKind DeviceOffloadingKind) const {
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);
545
546
// Forward last mtocdata/mno_tocdata options to -cc1.
547
if (Args.hasArg(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ,
548
options::OPT_mtocdata))
549
addTocDataOptions(Args, CC1Args, getDriver());
550
551
if (Args.hasFlag(options::OPT_fxl_pragma_pack,
552
options::OPT_fno_xl_pragma_pack, true))
553
CC1Args.push_back("-fxl-pragma-pack");
554
555
// Pass "-fno-sized-deallocation" only when the user hasn't manually enabled
556
// or disabled sized deallocations.
557
if (!Args.getLastArgNoClaim(options::OPT_fsized_deallocation,
558
options::OPT_fno_sized_deallocation))
559
CC1Args.push_back("-fno-sized-deallocation");
560
}
561
562
void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args,
563
llvm::opt::ArgStringList &CmdArgs) const {
564
if (needsProfileRT(Args)) {
565
// Add linker option -u__llvm_profile_runtime to cause runtime
566
// initialization to occur.
567
CmdArgs.push_back(Args.MakeArgString(
568
Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
569
570
if (const auto *A =
571
Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) {
572
StringRef Val = A->getValue();
573
if (Val == "atomic" || Val == "prefer-atomic")
574
CmdArgs.push_back("-latomic");
575
}
576
}
577
578
ToolChain::addProfileRTLibs(Args, CmdArgs);
579
}
580
581
ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const {
582
return ToolChain::CST_Libcxx;
583
}
584
585
ToolChain::RuntimeLibType AIX::GetDefaultRuntimeLibType() const {
586
return ToolChain::RLT_CompilerRT;
587
}
588
589
auto AIX::buildAssembler() const -> Tool * { return new aix::Assembler(*this); }
590
591
auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); }
592
593