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);
67 return TargetTriple.isOSWASI() && TargetTriple.getOSName() !=
"wasip1" &&
68 TargetTriple.getOSName() !=
"wasi";
75 const char *LinkingOutput)
const {
78 const char *
Linker = Args.MakeArgString(getLinkerPath(Args));
79 ArgStringList CmdArgs;
81 CmdArgs.push_back(
"-m");
83 CmdArgs.push_back(
"wasm64");
85 CmdArgs.push_back(
"wasm32");
87 if (Args.hasArg(options::OPT_s))
88 CmdArgs.push_back(
"--strip-all");
94 if (llvm::sys::path::stem(
Linker).ends_with_insensitive(
95 "wasm-component-ld")) {
96 CmdArgs.push_back(
"--wasm-ld-path");
100 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});
104 bool IsCommand =
true;
106 const char *Entry =
nullptr;
110 if (Args.hasArg(options::OPT_shared))
113 if (
const Arg *A = Args.getLastArg(options::OPT_mexec_model_EQ)) {
114 StringRef CM = A->getValue();
115 if (CM ==
"command") {
117 }
else if (CM ==
"reactor") {
121 << CM << A->getOption().getName();
134 Crt1 =
"crt1-command.o";
136 Crt1 =
"crt1-reactor.o";
137 Entry =
"_initialize";
140 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
143 CmdArgs.push_back(Args.MakeArgString(
"--entry"));
144 CmdArgs.push_back(Args.MakeArgString(Entry));
147 if (Args.hasArg(options::OPT_shared))
148 CmdArgs.push_back(Args.MakeArgString(
"-shared"));
152 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
156 if (Args.hasArg(options::OPT_pthread)) {
157 CmdArgs.push_back(
"-lpthread");
158 CmdArgs.push_back(
"--shared-memory");
161 CmdArgs.push_back(
"-lc");
165 CmdArgs.push_back(
"-o");
172 bool RunWasmOpt = Args.hasFlag(options::OPT_wasm_opt,
173 options::OPT_no_wasm_opt, WasmOptDefault);
177 std::string WasmOptPath;
178 if (RunWasmOpt && Args.getLastArg(options::OPT_O_Group)) {
180 if (WasmOptPath ==
"wasm-opt") {
185 if (!WasmOptPath.empty()) {
186 CmdArgs.push_back(
"--keep-section=target_features");
189 C.addCommand(std::make_unique<Command>(JA, *
this,
191 Linker, CmdArgs, Inputs, Output));
193 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
194 if (!WasmOptPath.empty()) {
195 StringRef OOpt =
"s";
196 if (A->getOption().matches(options::OPT_O4) ||
197 A->getOption().matches(options::OPT_Ofast))
199 else if (A->getOption().matches(options::OPT_O0))
201 else if (A->getOption().matches(options::OPT_O))
202 OOpt = A->getValue();
205 const char *WasmOpt = Args.MakeArgString(WasmOptPath);
206 ArgStringList OptArgs;
208 OptArgs.push_back(Args.MakeArgString(llvm::Twine(
"-O") + OOpt));
209 OptArgs.push_back(
"-o");
211 C.addCommand(std::make_unique<Command>(
224 return Dir +
"/llvm-lto/" LLVM_VERSION_STRING;
228 const llvm::opt::ArgList &Args)
231 assert(Triple.isArch32Bit() != Triple.isArch64Bit());
233 getProgramPaths().push_back(getDriver().Dir);
235 auto SysRoot = getDriver().SysRoot;
236 if (getTriple().getOS() == llvm::Triple::UnknownOS) {
241 getFilePaths().push_back(SysRoot +
"/lib");
243 const std::string MultiarchTriple =
244 getMultiarchTriple(getDriver(), Triple, SysRoot);
245 if (
D.isUsingLTO()) {
250 getFilePaths().push_back(Dir);
252 getFilePaths().push_back(SysRoot +
"/lib/" + MultiarchTriple);
256const char *WebAssembly::getDefaultLinker()
const {
258 return "wasm-component-ld";
262bool WebAssembly::IsMathErrnoDefault()
const {
return false; }
264bool WebAssembly::IsObjCNonFragileABIDefault()
const {
return true; }
266bool WebAssembly::UseObjCMixedDispatch()
const {
return true; }
268bool WebAssembly::isPICDefault()
const {
return false; }
270bool WebAssembly::isPIEDefault(
const llvm::opt::ArgList &Args)
const {
274bool WebAssembly::isPICDefaultForced()
const {
return false; }
276bool WebAssembly::hasBlocksRuntime()
const {
return false; }
279bool WebAssembly::SupportsProfiling()
const {
return false; }
281bool WebAssembly::HasNativeLLVMSupport()
const {
return true; }
283void WebAssembly::addClangTargetOptions(
const ArgList &DriverArgs,
284 ArgStringList &CC1Args,
286 if (!DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array,
287 options::OPT_fno_use_init_array,
true))
288 CC1Args.push_back(
"-fno-use-init-array");
291 if (DriverArgs.hasFlag(options::OPT_pthread, options::OPT_no_pthread,
293 if (DriverArgs.hasFlag(options::OPT_mno_atomics, options::OPT_matomics,
298 if (DriverArgs.hasFlag(options::OPT_mno_bulk_memory,
299 options::OPT_mbulk_memory,
false))
302 <<
"-mno-bulk-memory";
303 if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals,
304 options::OPT_mmutable_globals,
false))
307 <<
"-mno-mutable-globals";
308 if (DriverArgs.hasFlag(options::OPT_mno_sign_ext, options::OPT_msign_ext,
313 CC1Args.push_back(
"-target-feature");
314 CC1Args.push_back(
"+atomics");
315 CC1Args.push_back(
"-target-feature");
316 CC1Args.push_back(
"+bulk-memory");
317 CC1Args.push_back(
"-target-feature");
318 CC1Args.push_back(
"+mutable-globals");
319 CC1Args.push_back(
"-target-feature");
320 CC1Args.push_back(
"+sign-ext");
323 if (!DriverArgs.hasFlag(options::OPT_mmutable_globals,
324 options::OPT_mno_mutable_globals,
false)) {
327 llvm::Reloc::Model RelocationModel;
330 std::tie(RelocationModel, PICLevel, IsPIE) =
332 if (RelocationModel == llvm::Reloc::PIC_) {
333 if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals,
334 options::OPT_mmutable_globals,
false)) {
337 <<
"-mno-mutable-globals";
339 CC1Args.push_back(
"-target-feature");
340 CC1Args.push_back(
"+mutable-globals");
344 if (DriverArgs.getLastArg(options::OPT_fwasm_exceptions)) {
346 if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
347 options::OPT_mexception_handing,
false))
349 <<
"-fwasm-exceptions"
350 <<
"-mno-exception-handling";
353 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
354 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions")
356 <<
"-fwasm-exceptions"
357 <<
"-mllvm -enable-emscripten-cxx-exceptions";
360 CC1Args.push_back(
"-target-feature");
361 CC1Args.push_back(
"+exception-handling");
363 CC1Args.push_back(
"-mllvm");
364 CC1Args.push_back(
"-wasm-enable-eh");
368 if (DriverArgs.hasFlag(options::OPT_mno_multivalue,
369 options::OPT_mmultivalue,
false)) {
371 <<
"-fwasm-exceptions" <<
"-mno-multivalue";
373 if (DriverArgs.hasFlag(options::OPT_mno_reference_types,
374 options::OPT_mreference_types,
false)) {
376 <<
"-fwasm-exceptions" <<
"-mno-reference-types";
378 CC1Args.push_back(
"-target-feature");
379 CC1Args.push_back(
"+multivalue");
380 CC1Args.push_back(
"-target-feature");
381 CC1Args.push_back(
"+reference-types");
384 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
385 StringRef Opt = A->getValue(0);
386 if (Opt.starts_with(
"-emscripten-cxx-exceptions-allowed")) {
389 bool EmEHArgExists =
false;
390 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
391 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions") {
392 EmEHArgExists =
true;
398 <<
"-mllvm -emscripten-cxx-exceptions-allowed"
399 <<
"-mllvm -enable-emscripten-cxx-exceptions";
403 StringRef FuncNamesStr = Opt.split(
'=').second;
405 FuncNamesStr.split(FuncNames,
',');
406 for (
auto Name : FuncNames) {
407 CC1Args.push_back(
"-mllvm");
408 CC1Args.push_back(DriverArgs.MakeArgString(
"--force-attribute=" + Name +
413 if (Opt.starts_with(
"-wasm-enable-sjlj")) {
416 if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
417 options::OPT_mexception_handing,
false))
419 <<
"-mllvm -wasm-enable-sjlj"
420 <<
"-mno-exception-handling";
424 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
425 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions")
427 <<
"-mllvm -wasm-enable-sjlj"
428 <<
"-mllvm -enable-emscripten-cxx-exceptions";
432 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
433 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-sjlj")
435 <<
"-mllvm -wasm-enable-sjlj"
436 <<
"-mllvm -enable-emscripten-sjlj";
439 CC1Args.push_back(
"-target-feature");
440 CC1Args.push_back(
"+exception-handling");
442 CC1Args.push_back(
"-exception-model=wasm");
446 if (DriverArgs.hasFlag(options::OPT_mno_multivalue,
447 options::OPT_mmultivalue,
false)) {
449 <<
"-mllvm -wasm-enable-sjlj" <<
"-mno-multivalue";
451 if (DriverArgs.hasFlag(options::OPT_mno_reference_types,
452 options::OPT_mreference_types,
false)) {
454 <<
"-mllvm -wasm-enable-sjlj" <<
"-mno-reference-types";
456 CC1Args.push_back(
"-target-feature");
457 CC1Args.push_back(
"+multivalue");
458 CC1Args.push_back(
"-target-feature");
459 CC1Args.push_back(
"+reference-types");
469WebAssembly::GetCXXStdlibType(
const ArgList &Args)
const {
470 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
471 StringRef
Value = A->getValue();
472 if (
Value ==
"libc++")
474 else if (
Value ==
"libstdc++")
478 << A->getAsString(Args);
483void WebAssembly::AddClangSystemIncludeArgs(
const ArgList &DriverArgs,
484 ArgStringList &CC1Args)
const {
485 if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
490 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
492 llvm::sys::path::append(
P,
"include");
496 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
500 StringRef CIncludeDirs(C_INCLUDE_DIRS);
501 if (CIncludeDirs !=
"") {
503 CIncludeDirs.split(dirs,
":");
504 for (StringRef dir : dirs) {
506 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(
D.SysRoot);
513 const std::string MultiarchTriple =
514 getMultiarchTriple(D,
getTriple(),
D.SysRoot);
515 addSystemInclude(DriverArgs, CC1Args,
D.SysRoot +
"/include/" + MultiarchTriple);
520void WebAssembly::AddClangCXXStdlibIncludeArgs(
const ArgList &DriverArgs,
521 ArgStringList &CC1Args)
const {
523 if (DriverArgs.hasArg(options::OPT_nostdlibinc, options::OPT_nostdinc,
524 options::OPT_nostdincxx))
527 switch (GetCXXStdlibType(DriverArgs)) {
529 addLibCxxIncludePaths(DriverArgs, CC1Args);
532 addLibStdCXXIncludePaths(DriverArgs, CC1Args);
537void WebAssembly::AddCXXStdlibLibArgs(
const llvm::opt::ArgList &Args,
538 llvm::opt::ArgStringList &CmdArgs)
const {
540 switch (GetCXXStdlibType(Args)) {
542 CmdArgs.push_back(
"-lc++");
543 if (Args.hasArg(options::OPT_fexperimental_library))
544 CmdArgs.push_back(
"-lc++experimental");
545 CmdArgs.push_back(
"-lc++abi");
548 CmdArgs.push_back(
"-lstdc++");
556 Res |= SanitizerKind::Vptr | SanitizerKind::Leak | SanitizerKind::Address;
564Tool *WebAssembly::buildLinker()
const {
568void WebAssembly::addLibCxxIncludePaths(
569 const llvm::opt::ArgList &DriverArgs,
570 llvm::opt::ArgStringList &CC1Args)
const {
573 std::string LibPath = SysRoot +
"/include";
574 const std::string MultiarchTriple =
575 getMultiarchTriple(D,
getTriple(), SysRoot);
576 bool IsKnownOs = (
getTriple().getOS() != llvm::Triple::UnknownOS);
584 std::string TargetDir = LibPath +
"/" + MultiarchTriple +
"/c++/" + Version;
592void WebAssembly::addLibStdCXXIncludePaths(
593 const llvm::opt::ArgList &DriverArgs,
594 llvm::opt::ArgStringList &CC1Args)
const {
601 std::string LibPath = SysRoot +
"/include";
602 const std::string MultiarchTriple =
603 getMultiarchTriple(D,
getTriple(), SysRoot);
604 bool IsKnownOs = (
getTriple().getOS() != llvm::Triple::UnknownOS);
613 llvm::sys::path::append(
Path,
"c++");
614 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(
Path, EC), LE;
615 !EC && LI !=
LE; LI = LI.increment(EC)) {
616 StringRef VersionText = llvm::sys::path::filename(LI->path());
617 if (VersionText[0] !=
'v') {
619 if (Version > MaxVersion)
620 MaxVersion = Version;
623 if (MaxVersion.
Major > 0)
624 Version = MaxVersion.
Text;
632 std::string TargetDir = LibPath +
"/c++/" + Version +
"/" + MultiarchTriple;
639 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...
DiagnosticBuilder Diag(unsigned DiagID) const
bool LE(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
static constexpr ResponseFileSupport AtFileCurCP()