13#include "clang/Config/config.h"
18#include "llvm/Config/llvm-config.h"
19#include "llvm/Option/ArgList.h"
20#include "llvm/Support/FileSystem.h"
21#include "llvm/Support/Path.h"
22#include "llvm/Support/VirtualFileSystem.h"
32std::string WebAssembly::getMultiarchTriple(
const Driver &
D,
33 const llvm::Triple &TargetTriple,
34 StringRef SysRoot)
const {
35 return (TargetTriple.getArchName() +
"-" +
36 TargetTriple.getOSAndEnvironmentName()).str();
41 if (
const Arg* A = Args.getLastArg(options::OPT_fuse_ld_EQ)) {
42 StringRef UseLinker = A->getValue();
43 if (!UseLinker.empty()) {
44 if (llvm::sys::path::is_absolute(UseLinker) &&
45 llvm::sys::fs::can_execute(UseLinker))
46 return std::string(UseLinker);
51 if (UseLinker ==
"lld") {
56 if (UseLinker !=
"ld")
58 << A->getAsString(Args);
68 return TargetTriple.isOSWASI() && TargetTriple.getOSName() !=
"wasip1" &&
69 TargetTriple.getOSName() !=
"wasi";
76 const char *LinkingOutput)
const {
79 const char *
Linker = Args.MakeArgString(getLinkerPath(Args));
80 ArgStringList CmdArgs;
82 CmdArgs.push_back(
"-m");
84 CmdArgs.push_back(
"wasm64");
86 CmdArgs.push_back(
"wasm32");
88 if (Args.hasArg(options::OPT_s))
89 CmdArgs.push_back(
"--strip-all");
95 if (llvm::sys::path::stem(
Linker).ends_with_insensitive(
96 "wasm-component-ld")) {
97 CmdArgs.push_back(
"--wasm-ld-path");
101 Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_u});
105 bool IsCommand =
true;
107 const char *Entry =
nullptr;
111 if (Args.hasArg(options::OPT_shared))
114 if (
const Arg *A = Args.getLastArg(options::OPT_mexec_model_EQ)) {
115 StringRef CM = A->getValue();
116 if (CM ==
"command") {
118 }
else if (CM ==
"reactor") {
122 << CM << A->getOption().getName();
135 Crt1 =
"crt1-command.o";
137 Crt1 =
"crt1-reactor.o";
138 Entry =
"_initialize";
141 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
144 CmdArgs.push_back(Args.MakeArgString(
"--entry"));
145 CmdArgs.push_back(Args.MakeArgString(Entry));
148 if (Args.hasArg(options::OPT_shared))
149 CmdArgs.push_back(Args.MakeArgString(
"-shared"));
153 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
157 if (Args.hasArg(options::OPT_pthread)) {
158 CmdArgs.push_back(
"-lpthread");
159 CmdArgs.push_back(
"--shared-memory");
162 CmdArgs.push_back(
"-lc");
168 CmdArgs.push_back(
"-o");
175 bool RunWasmOpt = Args.hasFlag(options::OPT_wasm_opt,
176 options::OPT_no_wasm_opt, WasmOptDefault);
180 std::string WasmOptPath;
181 if (RunWasmOpt && Args.getLastArg(options::OPT_O_Group)) {
183 if (WasmOptPath ==
"wasm-opt") {
188 if (!WasmOptPath.empty()) {
189 CmdArgs.push_back(
"--keep-section=target_features");
192 C.addCommand(std::make_unique<Command>(JA, *
this,
194 Linker, CmdArgs, Inputs, Output));
196 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
197 if (!WasmOptPath.empty()) {
198 StringRef OOpt =
"s";
199 if (A->getOption().matches(options::OPT_O4) ||
200 A->getOption().matches(options::OPT_Ofast))
202 else if (A->getOption().matches(options::OPT_O0))
204 else if (A->getOption().matches(options::OPT_O))
205 OOpt = A->getValue();
208 const char *WasmOpt = Args.MakeArgString(WasmOptPath);
209 ArgStringList OptArgs;
211 OptArgs.push_back(Args.MakeArgString(llvm::Twine(
"-O") + OOpt));
212 OptArgs.push_back(
"-o");
214 C.addCommand(std::make_unique<Command>(
227 return Dir +
"/llvm-lto/" LLVM_VERSION_STRING;
231 const llvm::opt::ArgList &Args)
234 assert(Triple.isArch32Bit() != Triple.isArch64Bit());
236 getProgramPaths().push_back(getDriver().Dir);
238 auto SysRoot = getDriver().SysRoot;
239 if (getTriple().getOS() == llvm::Triple::UnknownOS) {
244 getFilePaths().push_back(SysRoot +
"/lib");
246 const std::string MultiarchTriple =
247 getMultiarchTriple(getDriver(), Triple, SysRoot);
248 if (
D.isUsingLTO()) {
253 getFilePaths().push_back(Dir);
255 getFilePaths().push_back(SysRoot +
"/lib/" + MultiarchTriple);
259const char *WebAssembly::getDefaultLinker()
const {
261 return "wasm-component-ld";
265bool WebAssembly::IsMathErrnoDefault()
const {
return false; }
267bool WebAssembly::IsObjCNonFragileABIDefault()
const {
return true; }
269bool WebAssembly::UseObjCMixedDispatch()
const {
return true; }
271bool WebAssembly::isPICDefault()
const {
return false; }
273bool WebAssembly::isPIEDefault(
const llvm::opt::ArgList &Args)
const {
277bool WebAssembly::isPICDefaultForced()
const {
return false; }
279bool WebAssembly::hasBlocksRuntime()
const {
return false; }
282bool WebAssembly::SupportsProfiling()
const {
return false; }
284bool WebAssembly::HasNativeLLVMSupport()
const {
return true; }
286void WebAssembly::addClangTargetOptions(
const ArgList &DriverArgs,
287 ArgStringList &CC1Args,
289 if (!DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array,
290 options::OPT_fno_use_init_array,
true))
291 CC1Args.push_back(
"-fno-use-init-array");
294 if (DriverArgs.hasFlag(options::OPT_pthread, options::OPT_no_pthread,
296 if (DriverArgs.hasFlag(options::OPT_mno_atomics, options::OPT_matomics,
301 if (DriverArgs.hasFlag(options::OPT_mno_bulk_memory,
302 options::OPT_mbulk_memory,
false))
305 <<
"-mno-bulk-memory";
306 if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals,
307 options::OPT_mmutable_globals,
false))
310 <<
"-mno-mutable-globals";
311 if (DriverArgs.hasFlag(options::OPT_mno_sign_ext, options::OPT_msign_ext,
316 CC1Args.push_back(
"-target-feature");
317 CC1Args.push_back(
"+atomics");
318 CC1Args.push_back(
"-target-feature");
319 CC1Args.push_back(
"+bulk-memory");
320 CC1Args.push_back(
"-target-feature");
321 CC1Args.push_back(
"+mutable-globals");
322 CC1Args.push_back(
"-target-feature");
323 CC1Args.push_back(
"+sign-ext");
326 if (!DriverArgs.hasFlag(options::OPT_mmutable_globals,
327 options::OPT_mno_mutable_globals,
false)) {
330 llvm::Reloc::Model RelocationModel;
333 std::tie(RelocationModel, PICLevel, IsPIE) =
335 if (RelocationModel == llvm::Reloc::PIC_) {
336 if (DriverArgs.hasFlag(options::OPT_mno_mutable_globals,
337 options::OPT_mmutable_globals,
false)) {
340 <<
"-mno-mutable-globals";
342 CC1Args.push_back(
"-target-feature");
343 CC1Args.push_back(
"+mutable-globals");
347 if (DriverArgs.getLastArg(options::OPT_fwasm_exceptions)) {
349 if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
350 options::OPT_mexception_handing,
false))
352 <<
"-fwasm-exceptions"
353 <<
"-mno-exception-handling";
356 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
357 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions")
359 <<
"-fwasm-exceptions"
360 <<
"-mllvm -enable-emscripten-cxx-exceptions";
363 CC1Args.push_back(
"-target-feature");
364 CC1Args.push_back(
"+exception-handling");
366 CC1Args.push_back(
"-mllvm");
367 CC1Args.push_back(
"-wasm-enable-eh");
371 if (DriverArgs.hasFlag(options::OPT_mno_multivalue,
372 options::OPT_mmultivalue,
false)) {
374 <<
"-fwasm-exceptions" <<
"-mno-multivalue";
376 if (DriverArgs.hasFlag(options::OPT_mno_reference_types,
377 options::OPT_mreference_types,
false)) {
379 <<
"-fwasm-exceptions" <<
"-mno-reference-types";
381 CC1Args.push_back(
"-target-feature");
382 CC1Args.push_back(
"+multivalue");
383 CC1Args.push_back(
"-target-feature");
384 CC1Args.push_back(
"+reference-types");
387 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
388 StringRef Opt = A->getValue(0);
389 if (Opt.starts_with(
"-emscripten-cxx-exceptions-allowed")) {
392 bool EmEHArgExists =
false;
393 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
394 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions") {
395 EmEHArgExists =
true;
401 <<
"-mllvm -emscripten-cxx-exceptions-allowed"
402 <<
"-mllvm -enable-emscripten-cxx-exceptions";
406 StringRef FuncNamesStr = Opt.split(
'=').second;
408 FuncNamesStr.split(FuncNames,
',');
409 for (
auto Name : FuncNames) {
410 CC1Args.push_back(
"-mllvm");
411 CC1Args.push_back(DriverArgs.MakeArgString(
"--force-attribute=" + Name +
416 if (Opt.starts_with(
"-wasm-enable-sjlj")) {
419 if (DriverArgs.hasFlag(options::OPT_mno_exception_handing,
420 options::OPT_mexception_handing,
false))
422 <<
"-mllvm -wasm-enable-sjlj"
423 <<
"-mno-exception-handling";
427 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
428 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-cxx-exceptions")
430 <<
"-mllvm -wasm-enable-sjlj"
431 <<
"-mllvm -enable-emscripten-cxx-exceptions";
435 for (
const Arg *A : DriverArgs.filtered(options::OPT_mllvm)) {
436 if (StringRef(A->getValue(0)) ==
"-enable-emscripten-sjlj")
438 <<
"-mllvm -wasm-enable-sjlj"
439 <<
"-mllvm -enable-emscripten-sjlj";
442 CC1Args.push_back(
"-target-feature");
443 CC1Args.push_back(
"+exception-handling");
445 CC1Args.push_back(
"-exception-model=wasm");
449 if (DriverArgs.hasFlag(options::OPT_mno_multivalue,
450 options::OPT_mmultivalue,
false)) {
452 <<
"-mllvm -wasm-enable-sjlj" <<
"-mno-multivalue";
454 if (DriverArgs.hasFlag(options::OPT_mno_reference_types,
455 options::OPT_mreference_types,
false)) {
457 <<
"-mllvm -wasm-enable-sjlj" <<
"-mno-reference-types";
459 CC1Args.push_back(
"-target-feature");
460 CC1Args.push_back(
"+multivalue");
461 CC1Args.push_back(
"-target-feature");
462 CC1Args.push_back(
"+reference-types");
472WebAssembly::GetCXXStdlibType(
const ArgList &Args)
const {
473 if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
474 StringRef
Value = A->getValue();
475 if (
Value ==
"libc++")
477 else if (
Value ==
"libstdc++")
481 << A->getAsString(Args);
486void WebAssembly::AddClangSystemIncludeArgs(
const ArgList &DriverArgs,
487 ArgStringList &CC1Args)
const {
488 if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
493 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
495 llvm::sys::path::append(
P,
"include");
499 if (DriverArgs.hasArg(options::OPT_nostdlibinc))
503 StringRef CIncludeDirs(C_INCLUDE_DIRS);
504 if (CIncludeDirs !=
"") {
506 CIncludeDirs.split(dirs,
":");
507 for (StringRef dir : dirs) {
509 llvm::sys::path::is_absolute(dir) ?
"" : StringRef(
D.SysRoot);
516 const std::string MultiarchTriple =
517 getMultiarchTriple(D,
getTriple(),
D.SysRoot);
518 addSystemInclude(DriverArgs, CC1Args,
D.SysRoot +
"/include/" + MultiarchTriple);
523void WebAssembly::AddClangCXXStdlibIncludeArgs(
const ArgList &DriverArgs,
524 ArgStringList &CC1Args)
const {
526 if (DriverArgs.hasArg(options::OPT_nostdlibinc, options::OPT_nostdinc,
527 options::OPT_nostdincxx))
530 switch (GetCXXStdlibType(DriverArgs)) {
532 addLibCxxIncludePaths(DriverArgs, CC1Args);
535 addLibStdCXXIncludePaths(DriverArgs, CC1Args);
540void WebAssembly::AddCXXStdlibLibArgs(
const llvm::opt::ArgList &Args,
541 llvm::opt::ArgStringList &CmdArgs)
const {
543 switch (GetCXXStdlibType(Args)) {
545 CmdArgs.push_back(
"-lc++");
546 if (Args.hasArg(options::OPT_fexperimental_library))
547 CmdArgs.push_back(
"-lc++experimental");
548 CmdArgs.push_back(
"-lc++abi");
551 CmdArgs.push_back(
"-lstdc++");
559 Res |= SanitizerKind::Vptr | SanitizerKind::Leak | SanitizerKind::Address;
567Tool *WebAssembly::buildLinker()
const {
571void WebAssembly::addLibCxxIncludePaths(
572 const llvm::opt::ArgList &DriverArgs,
573 llvm::opt::ArgStringList &CC1Args)
const {
576 std::string LibPath = SysRoot +
"/include";
577 const std::string MultiarchTriple =
578 getMultiarchTriple(D,
getTriple(), SysRoot);
579 bool IsKnownOs = (
getTriple().getOS() != llvm::Triple::UnknownOS);
587 std::string TargetDir = LibPath +
"/" + MultiarchTriple +
"/c++/" + Version;
595void WebAssembly::addLibStdCXXIncludePaths(
596 const llvm::opt::ArgList &DriverArgs,
597 llvm::opt::ArgStringList &CC1Args)
const {
604 std::string LibPath = SysRoot +
"/include";
605 const std::string MultiarchTriple =
606 getMultiarchTriple(D,
getTriple(), SysRoot);
607 bool IsKnownOs = (
getTriple().getOS() != llvm::Triple::UnknownOS);
616 llvm::sys::path::append(
Path,
"c++");
617 for (llvm::vfs::directory_iterator LI =
getVFS().dir_begin(
Path, EC), LE;
618 !EC && LI !=
LE; LI = LI.increment(EC)) {
619 StringRef VersionText = llvm::sys::path::filename(LI->path());
620 if (VersionText[0] !=
'v') {
622 if (Version > MaxVersion)
623 MaxVersion = Version;
626 if (MaxVersion.
Major > 0)
627 Version = MaxVersion.
Text;
635 std::string TargetDir = LibPath +
"/c++/" + Version +
"/" + MultiarchTriple;
642 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()