/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/AIX.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | using AIX = clang::driver::toolchains::AIX; |
21 | | using namespace clang::driver; |
22 | | using namespace clang::driver::tools; |
23 | | using namespace clang::driver::toolchains; |
24 | | |
25 | | using namespace llvm::opt; |
26 | | using namespace llvm::sys; |
27 | | |
28 | | void aix::Assembler::ConstructJob(Compilation &C, const JobAction &JA, |
29 | | const InputInfo &Output, |
30 | | const InputInfoList &Inputs, |
31 | | const ArgList &Args, |
32 | 15 | const char *LinkingOutput) const { |
33 | 15 | const Driver &D = getToolChain().getDriver(); |
34 | 15 | ArgStringList CmdArgs; |
35 | | |
36 | 15 | const bool IsArch32Bit = getToolChain().getTriple().isArch32Bit(); |
37 | 15 | const bool IsArch64Bit = getToolChain().getTriple().isArch64Bit(); |
38 | | // Only support 32 and 64 bit. |
39 | 15 | if (!IsArch32Bit && !IsArch64Bit6 ) |
40 | 0 | llvm_unreachable("Unsupported bit width value."); |
41 | | |
42 | 15 | if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) { |
43 | 2 | D.Diag(diag::err_drv_unsupported_opt_for_target) |
44 | 2 | << A->getSpelling() << D.getTargetTriple(); |
45 | 2 | } |
46 | | |
47 | | // Specify the mode in which the as(1) command operates. |
48 | 15 | if (IsArch32Bit) { |
49 | 9 | CmdArgs.push_back("-a32"); |
50 | 9 | } else { |
51 | | // Must be 64-bit, otherwise asserted already. |
52 | 6 | CmdArgs.push_back("-a64"); |
53 | 6 | } |
54 | | |
55 | | // Accept any mixture of instructions. |
56 | | // On Power for AIX and Linux, this behaviour matches that of GCC for both the |
57 | | // user-provided assembler source case and the compiler-produced assembler |
58 | | // source case. Yet XL with user-provided assembler source would not add this. |
59 | 15 | CmdArgs.push_back("-many"); |
60 | | |
61 | 15 | Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); |
62 | | |
63 | | // Specify assembler output file. |
64 | 15 | assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); |
65 | 15 | if (Output.isFilename()) { |
66 | 15 | CmdArgs.push_back("-o"); |
67 | 15 | CmdArgs.push_back(Output.getFilename()); |
68 | 15 | } |
69 | | |
70 | | // Specify assembler input file. |
71 | | // The system assembler on AIX takes exactly one input file. The driver is |
72 | | // expected to invoke as(1) separately for each assembler source input file. |
73 | 15 | if (Inputs.size() != 1) |
74 | 0 | llvm_unreachable("Invalid number of input files."); |
75 | 15 | const InputInfo &II = Inputs[0]; |
76 | 15 | assert((II.isFilename() || II.isNothing()) && "Invalid input."); |
77 | 15 | if (II.isFilename()) |
78 | 15 | CmdArgs.push_back(II.getFilename()); |
79 | | |
80 | 15 | const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); |
81 | 15 | C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), |
82 | 15 | Exec, CmdArgs, Inputs, Output)); |
83 | 15 | } |
84 | | |
85 | | // Determine whether there are any linker options that supply an export list |
86 | | // (or equivalent information about what to export) being sent to the linker. |
87 | 19 | static bool hasExportListLinkerOpts(const ArgStringList &CmdArgs) { |
88 | 192 | for (size_t i = 0, Size = CmdArgs.size(); i < Size; ++i173 ) { |
89 | 188 | llvm::StringRef ArgString(CmdArgs[i]); |
90 | | |
91 | 188 | if (ArgString.startswith("-bE:") || ArgString.startswith("-bexport:")184 || |
92 | 188 | ArgString == "-bexpall"182 || ArgString == "-bexpfull"180 ) |
93 | 10 | return true; |
94 | | |
95 | | // If we split -b option, check the next opt. |
96 | 178 | if (ArgString == "-b" && i + 1 < Size5 ) { |
97 | 5 | ++i; |
98 | 5 | llvm::StringRef ArgNextString(CmdArgs[i]); |
99 | 5 | if (ArgNextString.startswith("E:") || |
100 | 5 | ArgNextString.startswith("export:")3 || ArgNextString == "expall"2 || |
101 | 5 | ArgNextString == "expfull"1 ) |
102 | 5 | return true; |
103 | 5 | } |
104 | 178 | } |
105 | 4 | return false; |
106 | 19 | } |
107 | | |
108 | | void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
109 | | const InputInfo &Output, |
110 | | const InputInfoList &Inputs, const ArgList &Args, |
111 | 129 | const char *LinkingOutput) const { |
112 | 129 | const AIX &ToolChain = static_cast<const AIX &>(getToolChain()); |
113 | 129 | const Driver &D = ToolChain.getDriver(); |
114 | 129 | ArgStringList CmdArgs; |
115 | | |
116 | 129 | const bool IsArch32Bit = ToolChain.getTriple().isArch32Bit(); |
117 | 129 | const bool IsArch64Bit = ToolChain.getTriple().isArch64Bit(); |
118 | | // Only support 32 and 64 bit. |
119 | 129 | if (!(IsArch32Bit || IsArch64Bit42 )) |
120 | 0 | llvm_unreachable("Unsupported bit width value."); |
121 | | |
122 | 129 | if (Arg *A = C.getArgs().getLastArg(options::OPT_G)) { |
123 | 2 | D.Diag(diag::err_drv_unsupported_opt_for_target) |
124 | 2 | << A->getSpelling() << D.getTargetTriple(); |
125 | 2 | } |
126 | | |
127 | | // Force static linking when "-static" is present. |
128 | 129 | if (Args.hasArg(options::OPT_static)) |
129 | 3 | CmdArgs.push_back("-bnso"); |
130 | | |
131 | | // Add options for shared libraries. |
132 | 129 | if (Args.hasArg(options::OPT_shared)) { |
133 | 19 | CmdArgs.push_back("-bM:SRE"); |
134 | 19 | CmdArgs.push_back("-bnoentry"); |
135 | 19 | } |
136 | | |
137 | 129 | if (Args.hasFlag(options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr, |
138 | 129 | false)) { |
139 | 6 | if (Args.hasArg(options::OPT_shared)) |
140 | 1 | D.Diag(diag::err_roptr_cannot_build_shared); |
141 | | |
142 | | // The `-mxcoff-roptr` option places constants in RO sections as much as |
143 | | // possible. Then `-bforceimprw` changes such sections to RW if they contain |
144 | | // imported symbols that need to be resolved. |
145 | 6 | CmdArgs.push_back("-bforceimprw"); |
146 | 6 | } |
147 | | |
148 | | // PGO instrumentation generates symbols belonging to special sections, and |
149 | | // the linker needs to place all symbols in a particular section together in |
150 | | // memory; the AIX linker does that under an option. |
151 | 129 | if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, |
152 | 129 | false) || |
153 | 129 | Args.hasFlag(options::OPT_fprofile_generate, |
154 | 129 | options::OPT_fno_profile_generate, false) || |
155 | 129 | Args.hasFlag(options::OPT_fprofile_generate_EQ, |
156 | 123 | options::OPT_fno_profile_generate, false) || |
157 | 129 | Args.hasFlag(options::OPT_fprofile_instr_generate, |
158 | 123 | options::OPT_fno_profile_instr_generate, false) || |
159 | 129 | Args.hasFlag(options::OPT_fprofile_instr_generate_EQ, |
160 | 123 | options::OPT_fno_profile_instr_generate, false) || |
161 | 129 | Args.hasFlag(options::OPT_fcs_profile_generate, |
162 | 123 | options::OPT_fno_profile_generate, false) || |
163 | 129 | Args.hasFlag(options::OPT_fcs_profile_generate_EQ, |
164 | 122 | options::OPT_fno_profile_generate, false) || |
165 | 129 | Args.hasArg(options::OPT_fcreate_profile)122 || |
166 | 129 | Args.hasArg(options::OPT_coverage)122 ) |
167 | 7 | CmdArgs.push_back("-bdbg:namedsects:ss"); |
168 | | |
169 | 129 | if (Arg *A = |
170 | 129 | Args.getLastArg(clang::driver::options::OPT_mxcoff_build_id_EQ)) { |
171 | 4 | StringRef BuildId = A->getValue(); |
172 | 4 | if (BuildId[0] != '0' || BuildId[1] != 'x'3 || |
173 | 4 | BuildId.find_if_not(llvm::isHexDigit, 2) != StringRef::npos3 ) |
174 | 2 | ToolChain.getDriver().Diag(diag::err_drv_unsupported_option_argument) |
175 | 2 | << A->getSpelling() << BuildId; |
176 | 2 | else { |
177 | 2 | std::string LinkerFlag = "-bdbg:ldrinfo:xcoff_binary_id:0x"; |
178 | 2 | if (BuildId.size() % 2) // Prepend a 0 if odd number of digits. |
179 | 1 | LinkerFlag += "0"; |
180 | 2 | LinkerFlag += BuildId.drop_front(2).lower(); |
181 | 2 | CmdArgs.push_back(Args.MakeArgString(LinkerFlag)); |
182 | 2 | } |
183 | 4 | } |
184 | | |
185 | | // Specify linker output file. |
186 | 129 | assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); |
187 | 129 | if (Output.isFilename()) { |
188 | 129 | CmdArgs.push_back("-o"); |
189 | 129 | CmdArgs.push_back(Output.getFilename()); |
190 | 129 | } |
191 | | |
192 | | // Set linking mode (i.e., 32/64-bit) and the address of |
193 | | // text and data sections based on arch bit width. |
194 | 129 | if (IsArch32Bit) { |
195 | 87 | CmdArgs.push_back("-b32"); |
196 | 87 | CmdArgs.push_back("-bpT:0x10000000"); |
197 | 87 | CmdArgs.push_back("-bpD:0x20000000"); |
198 | 87 | } else { |
199 | | // Must be 64-bit, otherwise asserted already. |
200 | 42 | CmdArgs.push_back("-b64"); |
201 | 42 | CmdArgs.push_back("-bpT:0x100000000"); |
202 | 42 | CmdArgs.push_back("-bpD:0x110000000"); |
203 | 42 | } |
204 | | |
205 | 129 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, |
206 | 129 | options::OPT_shared, options::OPT_r)) { |
207 | 104 | auto getCrt0Basename = [&Args, IsArch32Bit] { |
208 | 104 | if (Arg *A = Args.getLastArgNoClaim(options::OPT_p, options::OPT_pg)) { |
209 | | // Enable gprofiling when "-pg" is specified. |
210 | 6 | if (A->getOption().matches(options::OPT_pg)) |
211 | 3 | return IsArch32Bit ? "gcrt0.o"2 : "gcrt0_64.o"1 ; |
212 | | // Enable profiling when "-p" is specified. |
213 | 3 | return IsArch32Bit ? "mcrt0.o"2 : "mcrt0_64.o"1 ; |
214 | 6 | } |
215 | 98 | return IsArch32Bit ? "crt0.o"73 : "crt0_64.o"25 ; |
216 | 104 | }; |
217 | | |
218 | 104 | CmdArgs.push_back( |
219 | 104 | Args.MakeArgString(ToolChain.GetFilePath(getCrt0Basename()))); |
220 | | |
221 | 104 | CmdArgs.push_back(Args.MakeArgString( |
222 | 104 | ToolChain.GetFilePath(IsArch32Bit ? "crti.o"77 : "crti_64.o"27 ))); |
223 | 104 | } |
224 | | |
225 | | // Collect all static constructor and destructor functions in both C and CXX |
226 | | // language link invocations. This has to come before AddLinkerInputs as the |
227 | | // implied option needs to precede any other '-bcdtors' settings or |
228 | | // '-bnocdtors' that '-Wl' might forward. |
229 | 129 | CmdArgs.push_back("-bcdtors:all:0:s"); |
230 | | |
231 | | // Specify linker input file(s). |
232 | 129 | AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); |
233 | | |
234 | 129 | if (D.isUsingLTO()) { |
235 | 31 | assert(!Inputs.empty() && "Must have at least one input."); |
236 | 31 | addLTOOptions(ToolChain, Args, CmdArgs, Output, Inputs[0], |
237 | 31 | D.getLTOMode() == LTOK_Thin); |
238 | 31 | } |
239 | | |
240 | 129 | if (Args.hasArg(options::OPT_shared) && !hasExportListLinkerOpts(CmdArgs)19 ) { |
241 | | |
242 | 4 | const char *CreateExportListExec = Args.MakeArgString( |
243 | 4 | path::parent_path(ToolChain.getDriver().ClangExecutable) + |
244 | 4 | "/llvm-nm"); |
245 | 4 | ArgStringList CreateExportCmdArgs; |
246 | | |
247 | 4 | std::string CreateExportListPath = |
248 | 4 | C.getDriver().GetTemporaryPath("CreateExportList", "exp"); |
249 | 4 | const char *ExportList = |
250 | 4 | C.addTempFile(C.getArgs().MakeArgString(CreateExportListPath)); |
251 | | |
252 | 4 | for (const auto &II : Inputs) |
253 | 5 | if (II.isFilename()) |
254 | 4 | CreateExportCmdArgs.push_back(II.getFilename()); |
255 | | |
256 | 4 | CreateExportCmdArgs.push_back("--export-symbols"); |
257 | 4 | CreateExportCmdArgs.push_back("-X"); |
258 | 4 | if (IsArch32Bit) { |
259 | 2 | CreateExportCmdArgs.push_back("32"); |
260 | 2 | } else { |
261 | | // Must be 64-bit, otherwise asserted already. |
262 | 2 | CreateExportCmdArgs.push_back("64"); |
263 | 2 | } |
264 | | |
265 | 4 | auto ExpCommand = std::make_unique<Command>( |
266 | 4 | JA, *this, ResponseFileSupport::None(), CreateExportListExec, |
267 | 4 | CreateExportCmdArgs, Inputs, Output); |
268 | 4 | ExpCommand->setRedirectFiles( |
269 | 4 | {std::nullopt, std::string(ExportList), std::nullopt}); |
270 | 4 | C.addCommand(std::move(ExpCommand)); |
271 | 4 | CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-bE:") + ExportList)); |
272 | 4 | } |
273 | | |
274 | | // Add directory to library search path. |
275 | 129 | Args.AddAllArgs(CmdArgs, options::OPT_L); |
276 | 129 | if (!Args.hasArg(options::OPT_r)) { |
277 | 128 | ToolChain.AddFilePathLibArgs(Args, CmdArgs); |
278 | 128 | ToolChain.addProfileRTLibs(Args, CmdArgs); |
279 | | |
280 | 128 | if (getToolChain().ShouldLinkCXXStdlib(Args)) |
281 | 34 | getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); |
282 | | |
283 | 128 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { |
284 | 122 | AddRunTimeLibs(ToolChain, D, CmdArgs, Args); |
285 | | |
286 | | // Add OpenMP runtime if -fopenmp is specified. |
287 | 122 | if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, |
288 | 122 | options::OPT_fno_openmp, false)) { |
289 | 4 | switch (ToolChain.getDriver().getOpenMPRuntime(Args)) { |
290 | 1 | case Driver::OMPRT_OMP: |
291 | 1 | CmdArgs.push_back("-lomp"); |
292 | 1 | break; |
293 | 1 | case Driver::OMPRT_IOMP5: |
294 | 1 | CmdArgs.push_back("-liomp5"); |
295 | 1 | break; |
296 | 1 | case Driver::OMPRT_GOMP: |
297 | 1 | CmdArgs.push_back("-lgomp"); |
298 | 1 | break; |
299 | 1 | case Driver::OMPRT_Unknown: |
300 | | // Already diagnosed. |
301 | 1 | break; |
302 | 4 | } |
303 | 4 | } |
304 | | |
305 | | // Support POSIX threads if "-pthreads" or "-pthread" is present. |
306 | 122 | if (Args.hasArg(options::OPT_pthreads, options::OPT_pthread)) |
307 | 2 | CmdArgs.push_back("-lpthreads"); |
308 | | |
309 | 122 | if (D.CCCIsCXX()) |
310 | 36 | CmdArgs.push_back("-lm"); |
311 | | |
312 | 122 | CmdArgs.push_back("-lc"); |
313 | | |
314 | 122 | if (Args.hasArgNoClaim(options::OPT_p, options::OPT_pg)) { |
315 | 6 | CmdArgs.push_back(Args.MakeArgString((llvm::Twine("-L") + D.SysRoot) + |
316 | 6 | "/lib/profiled")); |
317 | 6 | CmdArgs.push_back(Args.MakeArgString((llvm::Twine("-L") + D.SysRoot) + |
318 | 6 | "/usr/lib/profiled")); |
319 | 6 | } |
320 | 122 | } |
321 | 128 | } |
322 | | |
323 | 129 | const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); |
324 | 129 | C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), |
325 | 129 | Exec, CmdArgs, Inputs, Output)); |
326 | 129 | } |
327 | | |
328 | | /// AIX - AIX tool chain which can call as(1) and ld(1) directly. |
329 | | AIX::AIX(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) |
330 | 265 | : ToolChain(D, Triple, Args) { |
331 | 265 | getProgramPaths().push_back(getDriver().getInstalledDir()); |
332 | 265 | if (getDriver().getInstalledDir() != getDriver().Dir) |
333 | 0 | getProgramPaths().push_back(getDriver().Dir); |
334 | | |
335 | 265 | ParseInlineAsmUsingAsmParser = Args.hasFlag( |
336 | 265 | options::OPT_fintegrated_as, options::OPT_fno_integrated_as, true); |
337 | 265 | getLibraryPaths().push_back(getDriver().SysRoot + "/usr/lib"); |
338 | 265 | } |
339 | | |
340 | | // Returns the effective header sysroot path to use. |
341 | | // This comes from either -isysroot or --sysroot. |
342 | | llvm::StringRef |
343 | 319 | AIX::GetHeaderSysroot(const llvm::opt::ArgList &DriverArgs) const { |
344 | 319 | if (DriverArgs.hasArg(options::OPT_isysroot)) |
345 | 0 | return DriverArgs.getLastArgValue(options::OPT_isysroot); |
346 | 319 | if (!getDriver().SysRoot.empty()) |
347 | 112 | return getDriver().SysRoot; |
348 | 207 | return "/"; |
349 | 319 | } |
350 | | |
351 | | void AIX::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
352 | 240 | ArgStringList &CC1Args) const { |
353 | | // Return if -nostdinc is specified as a driver option. |
354 | 240 | if (DriverArgs.hasArg(options::OPT_nostdinc)) |
355 | 4 | return; |
356 | | |
357 | 236 | llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); |
358 | 236 | const Driver &D = getDriver(); |
359 | | |
360 | 236 | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { |
361 | 232 | SmallString<128> P(D.ResourceDir); |
362 | | // Add the PowerPC intrinsic headers (<resource>/include/ppc_wrappers) |
363 | 232 | path::append(P, "include", "ppc_wrappers"); |
364 | 232 | addSystemInclude(DriverArgs, CC1Args, P); |
365 | | // Add the Clang builtin headers (<resource>/include) |
366 | 232 | addSystemInclude(DriverArgs, CC1Args, path::parent_path(P.str())); |
367 | 232 | } |
368 | | |
369 | | // Return if -nostdlibinc is specified as a driver option. |
370 | 236 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
371 | 4 | return; |
372 | | |
373 | | // Add <sysroot>/usr/include. |
374 | 232 | SmallString<128> UP(Sysroot); |
375 | 232 | path::append(UP, "/usr/include"); |
376 | 232 | addSystemInclude(DriverArgs, CC1Args, UP.str()); |
377 | 232 | } |
378 | | |
379 | | void AIX::AddClangCXXStdlibIncludeArgs( |
380 | | const llvm::opt::ArgList &DriverArgs, |
381 | 89 | llvm::opt::ArgStringList &CC1Args) const { |
382 | | |
383 | 89 | if (DriverArgs.hasArg(options::OPT_nostdinc) || |
384 | 89 | DriverArgs.hasArg(options::OPT_nostdincxx)87 || |
385 | 89 | DriverArgs.hasArg(options::OPT_nostdlibinc)85 ) |
386 | 6 | return; |
387 | | |
388 | 83 | switch (GetCXXStdlibType(DriverArgs)) { |
389 | 0 | case ToolChain::CST_Libstdcxx: |
390 | 0 | llvm::report_fatal_error( |
391 | 0 | "picking up libstdc++ headers is unimplemented on AIX"); |
392 | 83 | case ToolChain::CST_Libcxx: { |
393 | 83 | llvm::StringRef Sysroot = GetHeaderSysroot(DriverArgs); |
394 | 83 | SmallString<128> PathCPP(Sysroot); |
395 | 83 | llvm::sys::path::append(PathCPP, "opt/IBM/openxlCSDK", "include", "c++", |
396 | 83 | "v1"); |
397 | 83 | addSystemInclude(DriverArgs, CC1Args, PathCPP.str()); |
398 | | // Required in order to suppress conflicting C++ overloads in the system |
399 | | // libc headers that were used by XL C++. |
400 | 83 | CC1Args.push_back("-D__LIBC_NO_CPP_MATH_OVERLOADS__"); |
401 | 83 | return; |
402 | 0 | } |
403 | 83 | } |
404 | | |
405 | 0 | llvm_unreachable("Unexpected C++ library type; only libc++ is supported."); |
406 | 0 | } |
407 | | |
408 | | void AIX::AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, |
409 | 34 | llvm::opt::ArgStringList &CmdArgs) const { |
410 | 34 | switch (GetCXXStdlibType(Args)) { |
411 | 0 | case ToolChain::CST_Libstdcxx: |
412 | 0 | llvm::report_fatal_error("linking libstdc++ unimplemented on AIX"); |
413 | 34 | case ToolChain::CST_Libcxx: |
414 | 34 | CmdArgs.push_back("-lc++"); |
415 | 34 | if (Args.hasArg(options::OPT_fexperimental_library)) |
416 | 0 | CmdArgs.push_back("-lc++experimental"); |
417 | 34 | CmdArgs.push_back("-lc++abi"); |
418 | 34 | return; |
419 | 34 | } |
420 | | |
421 | 0 | llvm_unreachable("Unexpected C++ library type; only libc++ is supported."); |
422 | 0 | } |
423 | | |
424 | | void AIX::addClangTargetOptions( |
425 | | const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CC1Args, |
426 | 242 | Action::OffloadKind DeviceOffloadingKind) const { |
427 | 242 | Args.AddLastArg(CC1Args, options::OPT_mignore_xcoff_visibility); |
428 | 242 | Args.AddLastArg(CC1Args, options::OPT_mdefault_visibility_export_mapping_EQ); |
429 | 242 | Args.addOptInFlag(CC1Args, options::OPT_mxcoff_roptr, options::OPT_mno_xcoff_roptr); |
430 | | |
431 | 242 | if (Args.hasFlag(options::OPT_fxl_pragma_pack, |
432 | 242 | options::OPT_fno_xl_pragma_pack, true)) |
433 | 242 | CC1Args.push_back("-fxl-pragma-pack"); |
434 | 242 | } |
435 | | |
436 | | void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args, |
437 | 128 | llvm::opt::ArgStringList &CmdArgs) const { |
438 | 128 | if (needsProfileRT(Args)) { |
439 | | // Add linker option -u__llvm_profile_runtime to cause runtime |
440 | | // initialization to occur. |
441 | 7 | CmdArgs.push_back(Args.MakeArgString( |
442 | 7 | Twine("-u", llvm::getInstrProfRuntimeHookVarName()))); |
443 | | |
444 | 7 | if (const auto *A = |
445 | 7 | Args.getLastArgNoClaim(options::OPT_fprofile_update_EQ)) { |
446 | 3 | StringRef Val = A->getValue(); |
447 | 3 | if (Val == "atomic" || Val == "prefer-atomic"2 ) |
448 | 2 | CmdArgs.push_back("-latomic"); |
449 | 3 | } |
450 | 7 | } |
451 | | |
452 | 128 | ToolChain::addProfileRTLibs(Args, CmdArgs); |
453 | 128 | } |
454 | | |
455 | 89 | ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const { |
456 | 89 | return ToolChain::CST_Libcxx; |
457 | 89 | } |
458 | | |
459 | 124 | ToolChain::RuntimeLibType AIX::GetDefaultRuntimeLibType() const { |
460 | 124 | return ToolChain::RLT_CompilerRT; |
461 | 124 | } |
462 | | |
463 | 13 | auto AIX::buildAssembler() const -> Tool * { return new aix::Assembler(*this); } |
464 | | |
465 | 129 | auto AIX::buildLinker() const -> Tool * { return new aix::Linker(*this); } |