13#include "clang/Config/config.h"
18#include "llvm/Option/ArgList.h"
19#include "llvm/Support/FileSystem.h"
20#include "llvm/Support/Path.h"
21#include "llvm/Support/VirtualFileSystem.h"
31std::string WebAssembly::getMultiarchTriple(
const Driver &D,
32 const llvm::Triple &TargetTriple,
33 StringRef SysRoot)
const {
34 return (TargetTriple.getArchName() +
"-" +
35 TargetTriple.getOSAndEnvironmentName()).str();
40 if (
const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
41 StringRef UseLinker = A->getValue();
42 if (!UseLinker.empty()) {
43 if (llvm::sys::path::is_absolute(UseLinker) &&
44 llvm::sys::fs::can_execute(UseLinker))
45 return std::string(UseLinker);
50 if (UseLinker ==
"lld") {
55 if (UseLinker !=
"ld")
57 << A->getAsString(Args);
68 const char *LinkingOutput)
const {
71 const char *
Linker = Args.MakeArgString(getLinkerPath(Args));
72 ArgStringList CmdArgs;
74 CmdArgs.push_back(
"-m");
76 CmdArgs.push_back(
"wasm64");
78 CmdArgs.push_back(
"wasm32");
80 if (Args.hasArg(options::OPT_s))
81 CmdArgs.push_back(
"--strip-all");
87 if (llvm::sys::path::stem(
Linker).ends_with_insensitive(
88 "wasm-component-ld")) {
89 CmdArgs.push_back(
"--wasm-ld-path");
93 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});
97 bool IsCommand =
true;
99 const char *Entry =
nullptr;
103 if (Args.hasArg(options::OPT_shared))
106 if (
const Arg *A = Args.getLastArg(options::OPT_mexec_model_EQ)) {
107 StringRef CM = A->getValue();
108 if (CM ==
"command") {
110 }
else if (CM ==
"reactor") {
114 << CM << A->getOption().getName();
127 Crt1 =
"crt1-command.o";
129 Crt1 =
"crt1-reactor.o";
130 Entry =
"_initialize";
133 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
136 CmdArgs.push_back(Args.MakeArgString(
"--entry"));
137 CmdArgs.push_back(Args.MakeArgString(Entry));
140 if (Args.hasArg(options::OPT_shared))
141 CmdArgs.push_back(Args.MakeArgString(
"-shared"));
145 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
149 if (Args.hasArg(options::OPT_pthread)) {
150 CmdArgs.push_back(
"-lpthread");
151 CmdArgs.push_back(
"--shared-memory");
154 CmdArgs.push_back(
"-lc");
158 CmdArgs.push_back(
"-o");
162 std::string WasmOptPath;
163 if (Args.getLastArg(options::OPT_O_Group)) {
165 if (WasmOptPath ==
"wasm-opt") {
170 if (!WasmOptPath.empty()) {
171 CmdArgs.push_back(
"--keep-section=target_features");
174 C.addCommand(std::make_unique<Command>(JA, *
this,
176 Linker, CmdArgs, Inputs, Output));
178 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
179 if (!WasmOptPath.empty()) {
180 StringRef OOpt =
"s";
181 if (A->getOption().matches(options::OPT_O4) ||
182 A->getOption().matches(options::OPT_Ofast))
184 else if (A->getOption().matches(options::OPT_O0))
186 else if (A->getOption().matches(options::OPT_O))
187 OOpt = A->getValue();
190 const char *WasmOpt = Args.MakeArgString(WasmOptPath);
191 ArgStringList OptArgs;
193 OptArgs.push_back(Args.MakeArgString(llvm::Twine(
"-O") + OOpt));
194 OptArgs.push_back(
"-o");
196 C.addCommand(std::make_unique<Command>(
209 return Dir +
"/llvm-lto/" LLVM_VERSION_STRING;
213 const llvm::opt::ArgList &Args)
216 assert(Triple.isArch32Bit() != Triple.isArch64Bit());
218 getProgramPaths().push_back(getDriver().Dir);
220 auto SysRoot = getDriver().SysRoot;
221 if (getTriple().getOS() == llvm::Triple::UnknownOS) {
226 getFilePaths().push_back(SysRoot +
"/lib");
228 const std::string MultiarchTriple =
229 getMultiarchTriple(getDriver(), Triple, SysRoot);
235 getFilePaths().push_back(Dir);
237 getFilePaths().push_back(SysRoot +
"/lib/" + MultiarchTriple);
241const char *WebAssembly::getDefaultLinker()
const {
242 if (
getOS() ==
"wasip2")
243 return "wasm-component-ld";
247bool WebAssembly::IsMathErrnoDefault()
const {
return false; }
249bool WebAssembly::IsObjCNonFragileABIDefault()
const {
return true; }
251bool WebAssembly::UseObjCMixedDispatch()
const {
return true; }
253bool WebAssembly::isPICDefault()
const {
return false; }
255bool WebAssembly::isPIEDefault(
const llvm::opt::ArgList &Args)
const {
259bool WebAssembly::isPICDefaultForced()
const {
return false; }
261bool WebAssembly::hasBlocksRuntime()
const {
return false; }
264bool WebAssembly::SupportsProfiling()
const {
return false; }
266bool WebAssembly::HasNativeLLVMSupport()
const {
return true; }
268void WebAssembly::addClangTargetOptions(
const ArgList &DriverArgs,
269 ArgStringList &CC1Args,
271 if (!DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array,
272 options::OPT_fno_use_init_array,
true))
273 CC1Args.push_back(
"-fno-use-init-array");
276 if (DriverArgs.hasFlag(options::OPT_pthread, options::OPT_no_pthread,
278 if (DriverArgs.hasFlag(options::OPT_mno_atomics, options::OPT_matomics,
283 if (DriverArgs.hasFlag(options::OPT_mno_bulk_memory,
284 options::OPT_mbulk_memory,
false))
287 <<
"-mno-bulk-memory";
288 if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals,
289 options::OPT_mmutable_globals,
false))
292 <<
"-mno-mutable-globals";
293 if (DriverArgs.hasFlag(options::OPT_mno_sign_ext, options::OPT_msign_ext,
298 CC1Args.push_back(
"-target-feature");
299 CC1Args.push_back(
"+atomics");
300 CC1Args.push_back(
"-target-feature");
301 CC1Args.push_back(
"+bulk-memory");
302 CC1Args.push_back(
"-target-feature");
303 CC1Args.push_back(
"+mutable-globals");
304 CC1Args.push_back(
"-target-feature");
305 CC1Args.push_back(
"+sign-ext");
308 if (!DriverArgs.hasFlag(options::OPT_mmutable_globals,
309 options::OPT_mno_mutable_globals,
false)) {
312 llvm::Reloc::Model RelocationModel;
315 std::tie(RelocationModel, PICLevel, IsPIE) =
317 if (RelocationModel == llvm::Reloc::PIC_) {
318 if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals,
319 options::OPT_mmutable_globals,
false)) {
322 <<
"-mno-mutable-globals";
324 CC1Args.push_back(
"-target-feature");
325 CC1Args.push_back(
"+mutable-globals");
329 if (DriverArgs.getLastArg(options::OPT_fwasm_exceptions)) {
331 if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
332 options::OPT_mexception_handing,
false))
334 <<
"-fwasm-exceptions"
335 <<
"-mno-exception-handling";
338 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
339 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions")
341 <<
"-fwasm-exceptions"
342 <<
"-mllvm -enable-emscripten-cxx-exceptions";
345 CC1Args.push_back(
"-target-feature");
346 CC1Args.push_back(
"+exception-handling");
348 CC1Args.push_back(
"-mllvm");
349 CC1Args.push_back(
"-wasm-enable-eh");
352 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
353 StringRef Opt = A->getValue(0);
354 if (Opt.starts_with(
"-emscripten-cxx-exceptions-allowed")) {
357 bool EmEHArgExists =
false;
358 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
359 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions") {
360 EmEHArgExists =
true;
366 <<
"-mllvm -emscripten-cxx-exceptions-allowed"
367 <<
"-mllvm -enable-emscripten-cxx-exceptions";
371 StringRef FuncNamesStr = Opt.split(
'=').second;
373 FuncNamesStr.split(FuncNames,
',');
374 for (
auto Name : FuncNames) {
375 CC1Args.push_back(
"-mllvm");
376 CC1Args.push_back(DriverArgs.MakeArgString(
"--force-attribute=" + Name +
381 if (Opt.starts_with(
"-wasm-enable-sjlj")) {
384 if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
385 options::OPT_mexception_handing,
false))
387 <<
"-mllvm -wasm-enable-sjlj"
388 <<
"-mno-exception-handling";
392 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
393 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions")
395 <<
"-mllvm -wasm-enable-sjlj"
396 <<
"-mllvm -enable-emscripten-cxx-exceptions";
400 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
401 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-sjlj")
403 <<
"-mllvm -wasm-enable-sjlj"
404 <<
"-mllvm -enable-emscripten-sjlj";
407 CC1Args.push_back(
"-target-feature");
408 CC1Args.push_back(
"+exception-handling");
410 CC1Args.push_back(
"-exception-model=wasm");
420WebAssembly::GetCXXStdlibType(
const ArgList &Args)
const {
421 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
422 StringRef
Value = A->getValue();
423 if (
Value ==
"libc++")
425 else if (
Value ==
"libstdc++")
429 << A->getAsString(Args);
434void WebAssembly::AddClangSystemIncludeArgs(
const ArgList &DriverArgs,
435 ArgStringList &CC1Args)
const {
436 if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
441 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
443 llvm::sys::path::append(
P,
"include");
447 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
451 StringRef CIncludeDirs(C_INCLUDE_DIRS);
452 if (CIncludeDirs !=
"") {
454 CIncludeDirs.split(dirs,
":");
455 for (StringRef dir : dirs) {
457 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(D.
SysRoot);
464 const std::string MultiarchTriple =
471void WebAssembly::AddClangCXXStdlibIncludeArgs(
const ArgList &DriverArgs,
472 ArgStringList &CC1Args)
const {
474 if (DriverArgs.hasArg(options::OPT_nostdlibinc, options::OPT_nostdinc,
475 options::OPT_nostdincxx))
478 switch (GetCXXStdlibType(DriverArgs)) {
480 addLibCxxIncludePaths(DriverArgs, CC1Args);
483 addLibStdCXXIncludePaths(DriverArgs, CC1Args);
488void WebAssembly::AddCXXStdlibLibArgs(
const llvm::opt::ArgList &Args,
489 llvm::opt::ArgStringList &CmdArgs)
const {
491 switch (GetCXXStdlibType(Args)) {
493 CmdArgs.push_back(
"-lc++");
494 if (Args.hasArg(options::OPT_fexperimental_library))
495 CmdArgs.push_back(
"-lc++experimental");
496 CmdArgs.push_back(
"-lc++abi");
499 CmdArgs.push_back(
"-lstdc++");
507 Res |= SanitizerKind::Vptr | SanitizerKind::Leak | SanitizerKind::Address;
515Tool *WebAssembly::buildLinker()
const {
519void WebAssembly::addLibCxxIncludePaths(
520 const llvm::opt::ArgList &DriverArgs,
521 llvm::opt::ArgStringList &CC1Args)
const {
524 std::string LibPath = SysRoot +
"/include";
525 const std::string MultiarchTriple =
526 getMultiarchTriple(D,
getTriple(), SysRoot);
527 bool IsKnownOs = (
getTriple().getOS() != llvm::Triple::UnknownOS);
535 std::string TargetDir = LibPath +
"/" + MultiarchTriple +
"/c++/" + Version;
543void WebAssembly::addLibStdCXXIncludePaths(
544 const llvm::opt::ArgList &DriverArgs,
545 llvm::opt::ArgStringList &CC1Args)
const {
552 std::string LibPath = SysRoot +
"/include";
553 const std::string MultiarchTriple =
554 getMultiarchTriple(D,
getTriple(), SysRoot);
555 bool IsKnownOs = (
getTriple().getOS() != llvm::Triple::UnknownOS);
564 llvm::sys::path::append(Path,
"c++");
565 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(Path, EC), LE;
566 !EC && LI !=
LE; LI = LI.increment(EC)) {
567 StringRef VersionText = llvm::sys::path::filename(LI->path());
568 if (VersionText[0] !=
'v') {
570 if (Version > MaxVersion)
571 MaxVersion = Version;
574 if (MaxVersion.
Major > 0)
575 Version = MaxVersion.
Text;
583 std::string TargetDir = LibPath +
"/c++/" + Version +
"/" + MultiarchTriple;
590 addSystemInclude(DriverArgs, CC1Args, LibPath +
"/c++/" + Version +
"/backward");
Defines version macros and version-related utility functions for Clang.
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
DiagnosticBuilder Diag(unsigned DiagID) const
std::string ResourceDir
The path to the compiler resource directory.
bool isUsingLTO(bool IsOffload=false) const
Returns true if we are performing any kind of LTO.
bool LE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport AtFileCurCP()