void WebAssembly::addClangTargetOptions(const ArgList &DriverArgs, ArgStringList &CC1Args, Action::OffloadKind) const { if (DriverArgs.hasFlag(clang::driver::options::OPT_fuse_init_array, options::OPT_fno_use_init_array, true)) CC1Args.push_back("-fuse-init-array"); }
void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0, const char *Translation, bool Joined) const { for (arg_iterator it = filtered_begin(Id0), ie = filtered_end(); it != ie; ++it) { it->claim(); if (Joined) { Output.push_back(MakeArgString(llvm::StringRef(Translation) + it->getValue(*this, 0))); } else { Output.push_back(Translation); Output.push_back(it->getValue(*this, 0)); } } }
void NaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { // Check for -stdlib= flags. We only support libc++ but this consumes the arg // if the value is libc++, and emits an error for other values. GetCXXStdlibType(Args); CmdArgs.push_back("-lc++"); }
ToolChain::InvocationInfo ToolChain::constructInvocation(const MergeModuleJobAction &job, const JobContext &context) const { ArgStringList Arguments; if (context.OI.CompilerMode != OutputInfo::Mode::UpdateCode) Arguments.push_back("-frontend"); // We just want to emit a module, so pass -emit-module without any other // mode options. Arguments.push_back("-emit-module"); size_t origLen = Arguments.size(); (void)origLen; addInputsOfType(Arguments, context.Inputs, types::TY_SwiftModuleFile); addInputsOfType(Arguments, context.InputActions, types::TY_SwiftModuleFile); assert(Arguments.size() - origLen >= context.Inputs.size() + context.InputActions.size()); assert((Arguments.size() - origLen == context.Inputs.size() || !context.InputActions.empty()) && "every input to MergeModule must generate a swiftmodule"); // Tell all files to parse as library, which is necessary to load them as // serialized ASTs. Arguments.push_back("-parse-as-library"); addCommonFrontendArgs(*this, context.OI, context.Output, context.Args, Arguments); Arguments.push_back("-module-name"); Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName)); assert(context.Output.getPrimaryOutputType() == types::TY_SwiftModuleFile && "The MergeModule tool only produces swiftmodule files!"); const std::string &ObjCHeaderOutputPath = context.Output.getAdditionalOutputForType(types::TY_ObjCHeader); if (!ObjCHeaderOutputPath.empty()) { Arguments.push_back("-emit-objc-header-path"); Arguments.push_back(ObjCHeaderOutputPath.c_str()); } Arguments.push_back("-o"); Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); auto program = SWIFT_EXECUTABLE_NAME; if (context.OI.CompilerMode == OutputInfo::Mode::UpdateCode) program = SWIFT_UPDATE_NAME; return {program, Arguments}; }
static void addLinkSanitizerLibArgsForDarwin(const ArgList &Args, ArgStringList &Arguments, StringRef Sanitizer, const ToolChain &TC, bool shared = true) { // Sanitizer runtime libraries requires C++. Arguments.push_back("-lc++"); // Add explicit dependency on -lc++abi, as -lc++ doesn't re-export // all RTTI-related symbols that are used. Arguments.push_back("-lc++abi"); auto LibName = TC.sanitizerRuntimeLibName(Sanitizer, shared); TC.addLinkRuntimeLib(Args, Arguments, LibName); if (shared) addLinkRuntimeLibRPath(Args, Arguments, LibName, TC); }
void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, ArgStringList &CmdArgs) { // Force linking against the system libraries sanitizers depends on // (see PR15823 why this is necessary). CmdArgs.push_back("--no-as-needed"); // There's no libpthread or librt on RTEMS. if (TC.getTriple().getOS() != llvm::Triple::RTEMS) { CmdArgs.push_back("-lpthread"); CmdArgs.push_back("-lrt"); } CmdArgs.push_back("-lm"); // There's no libdl on FreeBSD or RTEMS. if (TC.getTriple().getOS() != llvm::Triple::FreeBSD && TC.getTriple().getOS() != llvm::Triple::NetBSD && TC.getTriple().getOS() != llvm::Triple::RTEMS) CmdArgs.push_back("-ldl"); }
void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { for (auto Arg : filtered(Id0, Id1, Id2)) { Arg->claim(); for (unsigned i = 0, e = Arg->getNumValues(); i != e; ++i) Output.push_back(Arg->getValue(i)); } }
ToolChain::InvocationInfo ToolChain::constructInvocation(const REPLJobAction &job, const JobContext &context) const { assert(context.Inputs.empty()); assert(context.InputActions.empty()); bool useLLDB; switch (job.getRequestedMode()) { case REPLJobAction::Mode::Integrated: useLLDB = false; break; case REPLJobAction::Mode::RequireLLDB: useLLDB = true; break; case REPLJobAction::Mode::PreferLLDB: useLLDB = !findProgramRelativeToSwift("lldb").empty(); break; } ArgStringList FrontendArgs; addCommonFrontendArgs(*this, context.OI, context.Output, context.Args, FrontendArgs); context.Args.AddAllArgs(FrontendArgs, options::OPT_l, options::OPT_framework, options::OPT_L); if (!useLLDB) { FrontendArgs.insert(FrontendArgs.begin(), {"-frontend", "-repl"}); FrontendArgs.push_back("-module-name"); FrontendArgs.push_back(context.Args.MakeArgString(context.OI.ModuleName)); return {SWIFT_EXECUTABLE_NAME, FrontendArgs}; } // Squash important frontend options into a single argument for LLDB. std::string SingleArg = "--repl="; { llvm::raw_string_ostream os(SingleArg); Job::printArguments(os, FrontendArgs); } ArgStringList Arguments; Arguments.push_back(context.Args.MakeArgString(std::move(SingleArg))); return {"lldb", Arguments}; }
// Should be called before we add system libraries (C++ ABI, libstdc++/libc++, // C runtime, etc). Returns true if sanitizer system deps need to be linked in. bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { SmallVector<StringRef, 4> SharedRuntimes, StaticRuntimes, NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols; collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes, NonWholeStaticRuntimes, HelperStaticRuntimes, RequiredSymbols); // Inject libfuzzer dependencies. if (TC.getSanitizerArgs().needsFuzzer() && !Args.hasArg(options::OPT_shared)) { addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true); if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx)) TC.AddCXXStdlibLibArgs(Args, CmdArgs); } for (auto RT : SharedRuntimes) addSanitizerRuntime(TC, Args, CmdArgs, RT, true, false); for (auto RT : HelperStaticRuntimes) addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true); bool AddExportDynamic = false; for (auto RT : StaticRuntimes) { addSanitizerRuntime(TC, Args, CmdArgs, RT, false, true); AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT); } for (auto RT : NonWholeStaticRuntimes) { addSanitizerRuntime(TC, Args, CmdArgs, RT, false, false); AddExportDynamic |= !addSanitizerDynamicList(TC, Args, CmdArgs, RT); } for (auto S : RequiredSymbols) { CmdArgs.push_back("-u"); CmdArgs.push_back(Args.MakeArgString(S)); } // If there is a static runtime with no dynamic list, force all the symbols // to be dynamic to be sure we export sanitizer interface functions. if (AddExportDynamic) CmdArgs.push_back("-export-dynamic"); const SanitizerArgs &SanArgs = TC.getSanitizerArgs(); if (SanArgs.hasCrossDsoCfi() && !AddExportDynamic) CmdArgs.push_back("-export-dynamic-symbol=__cfi_check"); return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty(); }
static void addInputsOfType(ArgStringList &Arguments, ArrayRef<const Job *> Jobs, types::ID InputType) { for (const Job *Cmd : Jobs) { auto &output = Cmd->getOutput().getAnyOutputForType(InputType); if (!output.empty()) Arguments.push_back(output.c_str()); } }
void MSP430ToolChain::addClangTargetOptions(const ArgList &DriverArgs, ArgStringList &CC1Args, Action::OffloadKind) const { CC1Args.push_back("-nostdsysteminc"); const auto *MCUArg = DriverArgs.getLastArg(options::OPT_mmcu_EQ); if (!MCUArg) return; const StringRef MCU = MCUArg->getValue(); if (MCU.startswith("msp430i")) { // 'i' should be in lower case as it's defined in TI MSP430-GCC headers CC1Args.push_back(DriverArgs.MakeArgString( "-D__MSP430i" + MCU.drop_front(7).upper() + "__")); } else { CC1Args.push_back(DriverArgs.MakeArgString("-D__" + MCU.upper() + "__")); } }
void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const { for (arg_iterator it = filtered_begin(Id0, Id1, Id2), ie = filtered_end(); it != ie; ++it) { (*it)->claim(); for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i) Output.push_back((*it)->getValue(*this, i)); } }
void HexagonToolChain::addClangTargetOptions(const ArgList &DriverArgs, ArgStringList &CC1Args, Action::OffloadKind) const { if (DriverArgs.hasArg(options::OPT_ffp_contract)) return; unsigned OptLevel = getOptimizationLevel(DriverArgs); if (OptLevel >= 3) CC1Args.push_back("-ffp-contract=fast"); }
void Arg::renderAsInput(const ArgList &Args, ArgStringList &Output) const { if (!getOption().hasNoOptAsInput()) { render(Args, Output); return; } for (unsigned i = 0, e = getNumValues(); i != e; ++i) Output.push_back(getValue(Args, i)); }
static void addInputsOfType(ArgStringList &Arguments, ArrayRef<const Action *> Inputs, types::ID InputType) { for (auto &Input : Inputs) { if (Input->getType() != InputType) continue; Arguments.push_back(cast<InputAction>(Input)->getInputArg().getValue()); } }
void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args, ArgStringList &CmdArgs, bool ObjCXXAutoRefCount) const { CXXStdlibType Type = GetCXXStdlibType(Args); // Header search paths are handled by the mass of goop in InitHeaderSearch. switch (Type) { case ToolChain::CST_Libcxx: if (ObjCXXAutoRefCount) CmdArgs.push_back("-fobjc-arc-cxxlib=libc++"); break; case ToolChain::CST_Libstdcxx: if (ObjCXXAutoRefCount) CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++"); break; } }
void tools::AddAssemblerKPIC(const ToolChain &ToolChain, const ArgList &Args, ArgStringList &CmdArgs) { llvm::Reloc::Model RelocationModel; unsigned PICLevel; bool IsPIE; std::tie(RelocationModel, PICLevel, IsPIE) = ParsePICArgs(ToolChain, Args); if (RelocationModel != llvm::Reloc::Static) CmdArgs.push_back("-KPIC"); }
void arm::appendEBLinkFlags(const ArgList &Args, ArgStringList &CmdArgs, const llvm::Triple &Triple) { if (Args.hasArg(options::OPT_r)) return; // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker // to generate BE-8 executables. if (arm::getARMSubArchVersionNumber(Triple) >= 7 || arm::isARMMProfile(Triple)) CmdArgs.push_back("--be8"); }
// Tries to use a file with the list of dynamic symbols that need to be exported // from the runtime library. Returns true if the file was found. static bool addSanitizerDynamicList(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, StringRef Sanitizer) { SmallString<128> SanRT(TC.getCompilerRT(Args, Sanitizer)); if (llvm::sys::fs::exists(SanRT + ".syms")) { CmdArgs.push_back(Args.MakeArgString("--dynamic-list=" + SanRT + ".syms")); return true; } return false; }
ToolChain::InvocationInfo ToolChain::constructInvocation(const GenerateDSYMJobAction &job, const JobContext &context) const { assert(context.Inputs.size() == 1); assert(context.InputActions.empty()); assert(context.Output.getPrimaryOutputType() == types::TY_dSYM); ArgStringList Arguments; StringRef inputPath = context.Inputs.front()->getOutput().getPrimaryOutputFilename(); Arguments.push_back(context.Args.MakeArgString(inputPath)); Arguments.push_back("-o"); Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); return {"dsymutil", Arguments}; }
void solaris::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { claimNoWarnArgs(Args); ArgStringList CmdArgs; Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); for (const auto &II : Inputs) CmdArgs.push_back(II.getFilename()); const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); }
void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const { // FIXME: Make fast. for (const_iterator it = begin(), ie = end(); it != ie; ++it) { const Arg *A = *it; if (A->getOption().matches(Id0)) { A->claim(); for (unsigned i = 0, e = A->getNumValues(); i != e; ++i) Output.push_back(A->getValue(*this, i)); } } }
static void addLinkSanitizerLibArgsForLinux(const ArgList &Args, ArgStringList &Arguments, StringRef Sanitizer, const ToolChain &TC) { TC.addLinkRuntimeLib(Args, Arguments, TC.sanitizerRuntimeLibName(Sanitizer)); // Code taken from // https://github.com/apple/swift-clang/blob/ab3cbe7/lib/Driver/Tools.cpp#L3264-L3276 // There's no libpthread or librt on RTEMS. if (TC.getTriple().getOS() != llvm::Triple::RTEMS) { Arguments.push_back("-lpthread"); Arguments.push_back("-lrt"); } Arguments.push_back("-lm"); // There's no libdl on FreeBSD or RTEMS. if (TC.getTriple().getOS() != llvm::Triple::FreeBSD && TC.getTriple().getOS() != llvm::Triple::RTEMS) Arguments.push_back("-ldl"); }
void XRayArgs::addArgs(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs, types::ID InputType) const { if (!XRayInstrument) return; CmdArgs.push_back(XRayInstrumentOption); if (XRayAlwaysEmitCustomEvents) CmdArgs.push_back("-fxray-always-emit-customevents"); if (XRayAlwaysEmitTypedEvents) CmdArgs.push_back("-fxray-always-emit-typedevents"); CmdArgs.push_back(Args.MakeArgString(Twine(XRayInstructionThresholdOption) + Twine(InstructionThreshold))); for (const auto &Always : AlwaysInstrumentFiles) { SmallString<64> AlwaysInstrumentOpt("-fxray-always-instrument="); AlwaysInstrumentOpt += Always; CmdArgs.push_back(Args.MakeArgString(AlwaysInstrumentOpt)); } for (const auto &Never : NeverInstrumentFiles) { SmallString<64> NeverInstrumentOpt("-fxray-never-instrument="); NeverInstrumentOpt += Never; CmdArgs.push_back(Args.MakeArgString(NeverInstrumentOpt)); } for (const auto &AttrFile : AttrListFiles) { SmallString<64> AttrListFileOpt("-fxray-attr-list="); AttrListFileOpt += AttrFile; CmdArgs.push_back(Args.MakeArgString(AttrListFileOpt)); } for (const auto &Dep : ExtraDeps) { SmallString<64> ExtraDepOpt("-fdepfile-entry="); ExtraDepOpt += Dep; CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt)); } for (const auto &Mode : Modes) { SmallString<64> ModeOpt("-fxray-modes="); ModeOpt += Mode; CmdArgs.push_back(Args.MakeArgString(ModeOpt)); } }
static void addPrimaryInputsOfType(ArgStringList &Arguments, ArrayRef<const Job *> Jobs, types::ID InputType) { for (const Job *Cmd : Jobs) { auto &outputInfo = Cmd->getOutput(); if (outputInfo.getPrimaryOutputType() == InputType) { for (const std::string &Output : outputInfo.getPrimaryOutputFilenames()) { Arguments.push_back(Output.c_str()); } } } }
ToolChain::InvocationInfo ToolChain::constructInvocation(const ModuleWrapJobAction &job, const JobContext &context) const { ArgStringList Arguments; Arguments.push_back("-modulewrap"); addInputsOfType(Arguments, context.Inputs, types::TY_SwiftModuleFile); addInputsOfType(Arguments, context.InputActions, types::TY_SwiftModuleFile); assert(Arguments.size() == 2 && "ModuleWrap expects exactly one merged swiftmodule as input"); assert(context.Output.getPrimaryOutputType() == types::TY_Object && "The -modulewrap mode only produces object files"); Arguments.push_back("-o"); Arguments.push_back( context.Args.MakeArgString(context.Output.getPrimaryOutputFilename())); return {SWIFT_EXECUTABLE_NAME, Arguments}; }
void Arg::render(const ArgList &Args, ArgStringList &Output) const { switch (getOption().getRenderStyle()) { case Option::RenderValuesStyle: for (unsigned i = 0, e = getNumValues(); i != e; ++i) Output.push_back(getValue(Args, i)); break; case Option::RenderCommaJoinedStyle: { llvm::SmallString<256> Res; llvm::raw_svector_ostream OS(Res); OS << getOption().getName(); for (unsigned i = 0, e = getNumValues(); i != e; ++i) { if (i) OS << ','; OS << getValue(Args, i); } Output.push_back(Args.MakeArgString(OS.str())); break; } case Option::RenderJoinedStyle: Output.push_back(Args.GetOrMakeJoinedArgString( getIndex(), getOption().getName(), getValue(Args, 0))); for (unsigned i = 1, e = getNumValues(); i != e; ++i) Output.push_back(getValue(Args, i)); break; case Option::RenderSeparateStyle: Output.push_back(getOption().getName().data()); for (unsigned i = 0, e = getNumValues(); i != e; ++i) Output.push_back(getValue(Args, i)); break; } }
void CudaInstallationDetector::AddCudaIncludeArgs( const ArgList &DriverArgs, ArgStringList &CC1Args) const { if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { // Add cuda_wrappers/* to our system include path. This lets us wrap // standard library headers. SmallString<128> P(D.ResourceDir); llvm::sys::path::append(P, "include"); llvm::sys::path::append(P, "cuda_wrappers"); CC1Args.push_back("-internal-isystem"); CC1Args.push_back(DriverArgs.MakeArgString(P)); } if (DriverArgs.hasArg(options::OPT_nocudainc)) return; if (!isValid()) { D.Diag(diag::err_drv_no_cuda_installation); return; } CC1Args.push_back("-internal-isystem"); CC1Args.push_back(DriverArgs.MakeArgString(getIncludePath())); CC1Args.push_back("-include"); CC1Args.push_back("__clang_cuda_runtime_wrapper.h"); }
void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const ArgList &Args, ArgStringList &CmdArgs, const JobAction &JA) { const Driver &D = TC.getDriver(); // Add extra linker input arguments which are not treated as inputs // (constructed via -Xarch_). Args.AddAllArgValues(CmdArgs, options::OPT_Zlinker_input); for (const auto &II : Inputs) { // If the current tool chain refers to an OpenMP offloading host, we should // ignore inputs that refer to OpenMP offloading devices - they will be // embedded according to a proper linker script. if (auto *IA = II.getAction()) if (JA.isHostOffloading(Action::OFK_OpenMP) && IA->isDeviceOffloading(Action::OFK_OpenMP)) continue; if (!TC.HasNativeLLVMSupport() && types::isLLVMIR(II.getType())) // Don't try to pass LLVM inputs unless we have native support. D.Diag(diag::err_drv_no_linker_llvm_support) << TC.getTripleString(); // Add filenames immediately. if (II.isFilename()) { CmdArgs.push_back(II.getFilename()); continue; } // Otherwise, this is a linker input argument. const Arg &A = II.getInputArg(); // Handle reserved library options. if (A.getOption().matches(options::OPT_Z_reserved_lib_stdcxx)) TC.AddCXXStdlibLibArgs(Args, CmdArgs); else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext)) TC.AddCCKextLibArgs(Args, CmdArgs); else if (A.getOption().matches(options::OPT_z)) { // Pass -z prefix for gcc linker compatibility. A.claim(); A.render(Args, CmdArgs); } else { A.renderAsInput(Args, CmdArgs); } } // LIBRARY_PATH - included following the user specified library paths. // and only supported on native toolchains. if (!TC.isCrossCompiling()) { addDirectoryList(Args, CmdArgs, "-L", "LIBRARY_PATH"); } }
void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { const ToolChain &ToolChain = getToolChain(); const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath()); ArgStringList CmdArgs; CmdArgs.push_back("-flavor"); CmdArgs.push_back("wasm"); if (Args.hasArg(options::OPT_s)) CmdArgs.push_back("--strip-all"); Args.AddAllArgs(CmdArgs, options::OPT_L); ToolChain.AddFilePathLibArgs(Args, CmdArgs); AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { if (ToolChain.ShouldLinkCXXStdlib(Args)) ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); if (Args.hasArg(options::OPT_pthread)) CmdArgs.push_back("-lpthread"); CmdArgs.push_back("-allow-undefined-file"); CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("wasm.syms"))); CmdArgs.push_back("-lc"); CmdArgs.push_back("-lcompiler_rt"); } CmdArgs.push_back("-o"); CmdArgs.push_back(Output.getFilename()); C.addCommand(llvm::make_unique<Command>(JA, *this, Linker, CmdArgs, Inputs)); }