bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, const ArgList &Args, bool IsOffloadingHost, bool GompNeedsRT) { if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ, options::OPT_fno_openmp, false)) return false; switch (TC.getDriver().getOpenMPRuntime(Args)) { case Driver::OMPRT_OMP: CmdArgs.push_back("-lomp"); break; case Driver::OMPRT_GOMP: CmdArgs.push_back("-lgomp"); if (GompNeedsRT) CmdArgs.push_back("-lrt"); break; case Driver::OMPRT_IOMP5: CmdArgs.push_back("-liomp5"); break; case Driver::OMPRT_Unknown: // Already diagnosed. return false; } if (IsOffloadingHost) CmdArgs.push_back("-lomptarget"); addArchSpecificRPath(TC, Args, CmdArgs); return true; }
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"); }
std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, types::ID InputType) const { switch (getTriple().getArch()) { default: return getTripleString(); case llvm::Triple::arm: case llvm::Triple::thumb: { // FIXME: Factor into subclasses. llvm::Triple Triple = getTriple(); // Thumb2 is the default for V7 on Darwin. // // FIXME: Thumb should just be another -target-feaure, not in the triple. StringRef Suffix = getLLVMArchSuffixForARM(getARMTargetCPU(Args, Triple)); bool ThumbDefault = (Suffix == "v7" && getTriple().isOSDarwin()); std::string ArchName = "arm"; // Assembly files should start in ARM mode. if (InputType != types::TY_PP_Asm && Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) ArchName = "thumb"; Triple.setArchName(ArchName + Suffix.str()); return Triple.getTriple(); } } }
bool ToolChain::needsProfileRT(const ArgList &Args) { if (Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, false) || Args.hasArg(options::OPT_fprofile_generate) || Args.hasArg(options::OPT_fprofile_generate_EQ) || Args.hasArg(options::OPT_fprofile_instr_generate) || Args.hasArg(options::OPT_fprofile_instr_generate_EQ) || Args.hasArg(options::OPT_fcreate_profile) || Args.hasArg(options::OPT_coverage)) return true; return false; }
std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, types::ID InputType) const { switch (getTriple().getArch()) { default: return getTripleString(); case llvm::Triple::x86_64: { llvm::Triple Triple = getTriple(); if (!Triple.isOSBinFormatMachO()) return getTripleString(); if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { // x86_64h goes in the triple. Other -march options just use the // vanilla triple we already have. StringRef MArch = A->getValue(); if (MArch == "x86_64h") Triple.setArchName(MArch); } return Triple.getTriple(); } case llvm::Triple::arm: case llvm::Triple::thumb: { // FIXME: Factor into subclasses. llvm::Triple Triple = getTriple(); // Thumb2 is the default for V7 on Darwin. // // FIXME: Thumb should just be another -target-feaure, not in the triple. StringRef Suffix = Triple.isOSBinFormatMachO() ? tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMCPUForMArch(Args, Triple)) : tools::arm::getLLVMArchSuffixForARM(tools::arm::getARMTargetCPU(Args, Triple)); bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") || Suffix.startswith("v7em") || (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO()); std::string ArchName = "arm"; // Assembly files should start in ARM mode. if (InputType != types::TY_PP_Asm && Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) ArchName = "thumb"; Triple.setArchName(ArchName + Suffix.str()); return Triple.getTriple(); } } }
void DarwinGCC::AddLinkRuntimeLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { // Note that this routine is only used for targetting OS X. // Derived from libgcc and lib specs but refactored. if (Args.hasArg(options::OPT_static)) { CmdArgs.push_back("-lgcc_static"); } else { if (Args.hasArg(options::OPT_static_libgcc)) { CmdArgs.push_back("-lgcc_eh"); } else if (Args.hasArg(options::OPT_miphoneos_version_min_EQ)) { // Derived from darwin_iphoneos_libgcc spec. if (isTargetIPhoneOS()) { CmdArgs.push_back("-lgcc_s.1"); } else { CmdArgs.push_back("-lgcc_s.10.5"); } } else if (Args.hasArg(options::OPT_shared_libgcc) || Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions) || Args.hasArg(options::OPT_fgnu_runtime)) { // FIXME: This is probably broken on 10.3? if (isMacosxVersionLT(10, 5)) CmdArgs.push_back("-lgcc_s.10.4"); else if (isMacosxVersionLT(10, 6)) CmdArgs.push_back("-lgcc_s.10.5"); } else { if (isMacosxVersionLT(10, 3, 9)) ; // Do nothing. else if (isMacosxVersionLT(10, 5)) CmdArgs.push_back("-lgcc_s.10.4"); else if (isMacosxVersionLT(10, 6)) CmdArgs.push_back("-lgcc_s.10.5"); } if (isTargetIPhoneOS() || isMacosxVersionLT(10, 6)) { CmdArgs.push_back("-lgcc"); CmdArgs.push_back("-lSystem"); } else { CmdArgs.push_back("-lSystem"); CmdArgs.push_back("-lgcc"); } } }
static DebugInfoKind mustEmitDebugInfo(const ArgList &Args) { Arg *A = Args.getLastArg(options::OPT_O_Group); if (Args.hasFlag(options::OPT_cuda_noopt_device_debug, options::OPT_no_cuda_noopt_device_debug, !A || A->getOption().matches(options::OPT_O0))) { if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { const Option &Opt = A->getOption(); if (Opt.matches(options::OPT_gN_Group)) { if (Opt.matches(options::OPT_g0) || Opt.matches(options::OPT_ggdb0)) return NoDebug; if (Opt.matches(options::OPT_gline_tables_only) || Opt.matches(options::OPT_ggdb1)) return LineTableOnly; } return FullDebug; } } return NoDebug; }
static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, DiagnosticEngine &Diags, const FrontendOptions &FrontendOpts) { using namespace options; /// FIXME: Remove this flag when void subscripts are implemented. /// This is used to guard preemptive testing for the fix-it. if (Args.hasArg(OPT_fix_string_substring_conversion)) { Opts.FixStringToSubstringConversions = true; } if (auto A = Args.getLastArg(OPT_swift_version)) { auto vers = version::Version::parseVersionString( A->getValue(), SourceLoc(), &Diags); bool isValid = false; if (vers.hasValue()) { if (auto effectiveVers = vers.getValue().getEffectiveLanguageVersion()) { Opts.EffectiveLanguageVersion = effectiveVers.getValue(); isValid = true; } } if (!isValid) diagnoseSwiftVersion(vers, A, Args, Diags); } Opts.AttachCommentsToDecls |= Args.hasArg(OPT_dump_api_path); Opts.UseMalloc |= Args.hasArg(OPT_use_malloc); Opts.DiagnosticsEditorMode |= Args.hasArg(OPT_diagnostics_editor_mode, OPT_serialize_diagnostics_path); Opts.EnableExperimentalPropertyBehaviors |= Args.hasArg(OPT_enable_experimental_property_behaviors); if (auto A = Args.getLastArg(OPT_enable_deserialization_recovery, OPT_disable_deserialization_recovery)) { Opts.EnableDeserializationRecovery = A->getOption().matches(OPT_enable_deserialization_recovery); } Opts.DisableAvailabilityChecking |= Args.hasArg(OPT_disable_availability_checking); Opts.DisableTsanInoutInstrumentation |= Args.hasArg(OPT_disable_tsan_inout_instrumentation); if (FrontendOpts.InputKind == InputFileKind::IFK_SIL) Opts.DisableAvailabilityChecking = true; if (auto A = Args.getLastArg(OPT_enable_access_control, OPT_disable_access_control)) { Opts.EnableAccessControl = A->getOption().matches(OPT_enable_access_control); } if (auto A = Args.getLastArg(OPT_disable_typo_correction, OPT_typo_correction_limit)) { if (A->getOption().matches(OPT_disable_typo_correction)) Opts.TypoCorrectionLimit = 0; else { unsigned limit; if (StringRef(A->getValue()).getAsInteger(10, limit)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.TypoCorrectionLimit = limit; } } Opts.CodeCompleteInitsInPostfixExpr |= Args.hasArg(OPT_code_complete_inits_in_postfix_expr); Opts.CodeCompleteCallPatternHeuristics |= Args.hasArg(OPT_code_complete_call_pattern_heuristics); if (auto A = Args.getLastArg(OPT_enable_target_os_checking, OPT_disable_target_os_checking)) { Opts.EnableTargetOSChecking = A->getOption().matches(OPT_enable_target_os_checking); } Opts.EnableASTScopeLookup |= Args.hasArg(OPT_enable_astscope_lookup); Opts.DebugConstraintSolver |= Args.hasArg(OPT_debug_constraints); Opts.IterativeTypeChecker |= Args.hasArg(OPT_iterative_type_checker); Opts.NamedLazyMemberLoading &= !Args.hasArg(OPT_disable_named_lazy_member_loading); Opts.DebugGenericSignatures |= Args.hasArg(OPT_debug_generic_signatures); if (Args.hasArg(OPT_verify_syntax_tree)) { Opts.BuildSyntaxTree = true; Opts.VerifySyntaxTree = true; } Opts.DebuggerSupport |= Args.hasArg(OPT_debugger_support); if (Opts.DebuggerSupport) Opts.EnableDollarIdentifiers = true; Opts.Playground |= Args.hasArg(OPT_playground); Opts.InferImportAsMember |= Args.hasArg(OPT_enable_infer_import_as_member); Opts.EnableThrowWithoutTry |= Args.hasArg(OPT_enable_throw_without_try); if (auto A = Args.getLastArg(OPT_enable_objc_attr_requires_foundation_module, OPT_disable_objc_attr_requires_foundation_module)) { Opts.EnableObjCAttrRequiresFoundation = A->getOption().matches(OPT_enable_objc_attr_requires_foundation_module); } if (auto A = Args.getLastArg(OPT_enable_testable_attr_requires_testable_module, OPT_disable_testable_attr_requires_testable_module)) { Opts.EnableTestableAttrRequiresTestableModule = A->getOption().matches(OPT_enable_testable_attr_requires_testable_module); } if (const Arg *A = Args.getLastArg(OPT_debug_constraints_attempt)) { unsigned attempt; if (StringRef(A->getValue()).getAsInteger(10, attempt)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.DebugConstraintSolverAttempt = attempt; } if (const Arg *A = Args.getLastArg(OPT_debug_forbid_typecheck_prefix)) { Opts.DebugForbidTypecheckPrefix = A->getValue(); } if (const Arg *A = Args.getLastArg(OPT_solver_memory_threshold)) { unsigned threshold; if (StringRef(A->getValue()).getAsInteger(10, threshold)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.SolverMemoryThreshold = threshold; } if (const Arg *A = Args.getLastArg(OPT_solver_shrink_unsolved_threshold)) { unsigned threshold; if (StringRef(A->getValue()).getAsInteger(10, threshold)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.SolverShrinkUnsolvedThreshold = threshold; } if (const Arg *A = Args.getLastArg(OPT_value_recursion_threshold)) { unsigned threshold; if (StringRef(A->getValue()).getAsInteger(10, threshold)) { Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, A->getAsString(Args), A->getValue()); return true; } Opts.MaxCircularityDepth = threshold; } for (const Arg *A : Args.filtered(OPT_D)) { Opts.addCustomConditionalCompilationFlag(A->getValue()); } Opts.EnableAppExtensionRestrictions |= Args.hasArg(OPT_enable_app_extension); Opts.EnableSwift3ObjCInference = Args.hasFlag(OPT_enable_swift3_objc_inference, OPT_disable_swift3_objc_inference, Opts.isSwiftVersion3()); if (Opts.EnableSwift3ObjCInference) { if (const Arg *A = Args.getLastArg( OPT_warn_swift3_objc_inference_minimal, OPT_warn_swift3_objc_inference_complete)) { if (A->getOption().getID() == OPT_warn_swift3_objc_inference_minimal) Opts.WarnSwift3ObjCInference = Swift3ObjCInferenceWarnings::Minimal; else Opts.WarnSwift3ObjCInference = Swift3ObjCInferenceWarnings::Complete; } } Opts.EnableNSKeyedArchiverDiagnostics = Args.hasFlag(OPT_enable_nskeyedarchiver_diagnostics, OPT_disable_nskeyedarchiver_diagnostics, Opts.EnableNSKeyedArchiverDiagnostics); Opts.EnableNonFrozenEnumExhaustivityDiagnostics = Args.hasFlag(OPT_enable_nonfrozen_enum_exhaustivity_diagnostics, OPT_disable_nonfrozen_enum_exhaustivity_diagnostics, Opts.isSwiftVersionAtLeast(5)); if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) Opts.OptimizationRemarkPassedPattern = generateOptimizationRemarkRegex(Diags, Args, A); if (Arg *A = Args.getLastArg(OPT_Rpass_missed_EQ)) Opts.OptimizationRemarkMissedPattern = generateOptimizationRemarkRegex(Diags, Args, A); llvm::Triple Target = Opts.Target; StringRef TargetArg; if (const Arg *A = Args.getLastArg(OPT_target)) { Target = llvm::Triple(A->getValue()); TargetArg = A->getValue(); } Opts.EnableObjCInterop = Args.hasFlag(OPT_enable_objc_interop, OPT_disable_objc_interop, Target.isOSDarwin()); Opts.EnableSILOpaqueValues |= Args.hasArg(OPT_enable_sil_opaque_values); Opts.EnableKeyPathResilience |= Args.hasArg(OPT_enable_key_path_resilience); #if SWIFT_DARWIN_ENABLE_STABLE_ABI_BIT Opts.UseDarwinPreStableABIBit = false; #else Opts.UseDarwinPreStableABIBit = true; #endif // Must be processed after any other language options that could affect // platform conditions. bool UnsupportedOS, UnsupportedArch; std::tie(UnsupportedOS, UnsupportedArch) = Opts.setTarget(Target); SmallVector<StringRef, 3> TargetComponents; TargetArg.split(TargetComponents, "-"); if (UnsupportedArch) { auto TargetArgArch = TargetComponents.size() ? TargetComponents[0] : ""; Diags.diagnose(SourceLoc(), diag::error_unsupported_target_arch, TargetArgArch); } if (UnsupportedOS) { auto TargetArgOS = TargetComponents.size() > 2 ? TargetComponents[2] : ""; Diags.diagnose(SourceLoc(), diag::error_unsupported_target_os, TargetArgOS); } return UnsupportedOS || UnsupportedArch; }
std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, types::ID InputType) const { switch (getTriple().getArch()) { default: return getTripleString(); case llvm::Triple::x86_64: { llvm::Triple Triple = getTriple(); if (!Triple.isOSBinFormatMachO()) return getTripleString(); if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { // x86_64h goes in the triple. Other -march options just use the // vanilla triple we already have. StringRef MArch = A->getValue(); if (MArch == "x86_64h") Triple.setArchName(MArch); } return Triple.getTriple(); } case llvm::Triple::aarch64: { llvm::Triple Triple = getTriple(); if (!Triple.isOSBinFormatMachO()) return getTripleString(); // FIXME: older versions of ld64 expect the "arm64" component in the actual // triple string and query it to determine whether an LTO file can be // handled. Remove this when we don't care any more. Triple.setArchName("arm64"); return Triple.getTriple(); } case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: { // FIXME: Factor into subclasses. llvm::Triple Triple = getTriple(); bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb || getTriple().getArch() == llvm::Triple::thumbeb; // Handle pseudo-target flags '-mlittle-endian'/'-EL' and // '-mbig-endian'/'-EB'. if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, options::OPT_mbig_endian)) { IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); } // Thumb2 is the default for V7 on Darwin. // // FIXME: Thumb should just be another -target-feaure, not in the triple. StringRef MCPU, MArch; if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) MCPU = A->getValue(); if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) MArch = A->getValue(); std::string CPU = Triple.isOSBinFormatMachO() ? tools::arm::getARMCPUForMArch(MArch, Triple).str() : tools::arm::getARMTargetCPU(MCPU, MArch, Triple); StringRef Suffix = tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple); bool IsMProfile = ARM::parseArchProfile(Suffix) == ARM::PK_M; bool ThumbDefault = IsMProfile || (ARM::parseArchVersion(Suffix) == 7 && getTriple().isOSBinFormatMachO()); // FIXME: this is invalid for WindowsCE if (getTriple().isOSWindows()) ThumbDefault = true; std::string ArchName; if (IsBigEndian) ArchName = "armeb"; else ArchName = "arm"; // Assembly files should start in ARM mode, unless arch is M-profile. if ((InputType != types::TY_PP_Asm && Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault)) || IsMProfile) { if (IsBigEndian) ArchName = "thumbeb"; else ArchName = "thumb"; } Triple.setArchName(ArchName + Suffix.str()); return Triple.getTriple(); } } }
void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { const auto &TC = static_cast<const toolchains::CudaToolChain &>(getToolChain()); assert(TC.getTriple().isNVPTX() && "Wrong platform"); StringRef GPUArchName; // If this is an OpenMP action we need to extract the device architecture // from the -march=arch option. This option may come from -Xopenmp-target // flag or the default value. if (JA.isDeviceOffloading(Action::OFK_OpenMP)) { GPUArchName = Args.getLastArgValue(options::OPT_march_EQ); assert(!GPUArchName.empty() && "Must have an architecture passed in."); } else GPUArchName = JA.getOffloadingArch(); // Obtain architecture from the action. CudaArch gpu_arch = StringToCudaArch(GPUArchName); assert(gpu_arch != CudaArch::UNKNOWN && "Device action expected to have an architecture."); // Check that our installation's ptxas supports gpu_arch. if (!Args.hasArg(options::OPT_no_cuda_version_check)) { TC.CudaInstallation.CheckCudaVersionSupportsArch(gpu_arch); } ArgStringList CmdArgs; CmdArgs.push_back(TC.getTriple().isArch64Bit() ? "-m64" : "-m32"); if (Args.hasFlag(options::OPT_cuda_noopt_device_debug, options::OPT_no_cuda_noopt_device_debug, false)) { // ptxas does not accept -g option if optimization is enabled, so // we ignore the compiler's -O* options if we want debug info. CmdArgs.push_back("-g"); CmdArgs.push_back("--dont-merge-basicblocks"); CmdArgs.push_back("--return-at-end"); } else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { // Map the -O we received to -O{0,1,2,3}. // // TODO: Perhaps we should map host -O2 to ptxas -O3. -O3 is ptxas's // default, so it may correspond more closely to the spirit of clang -O2. // -O3 seems like the least-bad option when -Osomething is specified to // clang but it isn't handled below. StringRef OOpt = "3"; if (A->getOption().matches(options::OPT_O4) || A->getOption().matches(options::OPT_Ofast)) OOpt = "3"; else if (A->getOption().matches(options::OPT_O0)) OOpt = "0"; else if (A->getOption().matches(options::OPT_O)) { // -Os, -Oz, and -O(anything else) map to -O2, for lack of better options. OOpt = llvm::StringSwitch<const char *>(A->getValue()) .Case("1", "1") .Case("2", "2") .Case("3", "3") .Case("s", "2") .Case("z", "2") .Default("2"); } CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-O") + OOpt)); } else { // If no -O was passed, pass -O0 to ptxas -- no opt flag should correspond // to no optimizations, but ptxas's default is -O3. CmdArgs.push_back("-O0"); } // Pass -v to ptxas if it was passed to the driver. if (Args.hasArg(options::OPT_v)) CmdArgs.push_back("-v"); CmdArgs.push_back("--gpu-name"); CmdArgs.push_back(Args.MakeArgString(CudaArchToString(gpu_arch))); CmdArgs.push_back("--output-file"); CmdArgs.push_back(Args.MakeArgString(TC.getInputFilename(Output))); for (const auto& II : Inputs) CmdArgs.push_back(Args.MakeArgString(II.getFilename())); for (const auto& A : Args.getAllArgValues(options::OPT_Xcuda_ptxas)) CmdArgs.push_back(Args.MakeArgString(A)); // In OpenMP we need to generate relocatable code. if (JA.isOffloading(Action::OFK_OpenMP) && Args.hasFlag(options::OPT_fopenmp_relocatable_target, options::OPT_fnoopenmp_relocatable_target, /*Default=*/ true)) CmdArgs.push_back("-c"); const char *Exec; if (Arg *A = Args.getLastArg(options::OPT_ptxas_path_EQ)) Exec = A->getValue(); else Exec = Args.MakeArgString(TC.GetProgramPath("ptxas")); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); }
std::string ToolChain::ComputeLLVMTriple(const ArgList &Args, types::ID InputType) const { switch (getTriple().getArch()) { default: return getTripleString(); case llvm::Triple::x86_64: { llvm::Triple Triple = getTriple(); if (!Triple.isOSBinFormatMachO()) return getTripleString(); if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { // x86_64h goes in the triple. Other -march options just use the // vanilla triple we already have. StringRef MArch = A->getValue(); if (MArch == "x86_64h") Triple.setArchName(MArch); } return Triple.getTriple(); } case llvm::Triple::aarch64: { llvm::Triple Triple = getTriple(); if (!Triple.isOSBinFormatMachO()) return getTripleString(); // FIXME: older versions of ld64 expect the "arm64" component in the actual // triple string and query it to determine whether an LTO file can be // handled. Remove this when we don't care any more. Triple.setArchName("arm64"); return Triple.getTriple(); } case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::thumb: case llvm::Triple::thumbeb: { // FIXME: Factor into subclasses. llvm::Triple Triple = getTriple(); bool IsBigEndian = getTriple().getArch() == llvm::Triple::armeb || getTriple().getArch() == llvm::Triple::thumbeb; // Handle pseudo-target flags '-mlittle-endian'/'-EL' and // '-mbig-endian'/'-EB'. if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian, options::OPT_mbig_endian)) { IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian); } // Thumb2 is the default for V7 on Darwin. // // FIXME: Thumb should just be another -target-feaure, not in the triple. StringRef MCPU, MArch; if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) MCPU = A->getValue(); if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) MArch = A->getValue(); std::string CPU = Triple.isOSBinFormatMachO() ? tools::arm::getARMCPUForMArch(MArch, Triple).str() : tools::arm::getARMTargetCPU(MCPU, MArch, Triple); StringRef Suffix = tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple); bool IsMProfile = ARM::parseArchProfile(Suffix) == ARM::ProfileKind::M; bool ThumbDefault = IsMProfile || (ARM::parseArchVersion(Suffix) == 7 && getTriple().isOSBinFormatMachO()); // FIXME: this is invalid for WindowsCE if (getTriple().isOSWindows()) ThumbDefault = true; std::string ArchName; if (IsBigEndian) ArchName = "armeb"; else ArchName = "arm"; // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for // M-Class CPUs/architecture variants, which is not supported. bool ARMModeRequested = !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault); if (IsMProfile && ARMModeRequested) { if (!MCPU.empty()) getDriver().Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM"; else getDriver().Diag(diag::err_arch_unsupported_isa) << tools::arm::getARMArch(MArch, getTriple()) << "ARM"; } // Check to see if an explicit choice to use thumb has been made via // -mthumb. For assembler files we must check for -mthumb in the options // passed to the assembler via -Wa or -Xassembler. bool IsThumb = false; if (InputType != types::TY_PP_Asm) IsThumb = Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault); else { // Ideally we would check for these flags in // CollectArgsForIntegratedAssembler but we can't change the ArchName at // that point. There is no assembler equivalent of -mno-thumb, -marm, or // -mno-arm. for (const auto *A : Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { for (StringRef Value : A->getValues()) { if (Value == "-mthumb") IsThumb = true; } } } // Assembly files should start in ARM mode, unless arch is M-profile, or // -mthumb has been passed explicitly to the assembler. Windows is always // thumb. if (IsThumb || IsMProfile || getTriple().isOSWindows()) { if (IsBigEndian) ArchName = "thumbeb"; else ArchName = "thumb"; } Triple.setArchName(ArchName + Suffix.str()); return Triple.getTriple(); } } }
void tools::AddGoldPlugin(const ToolChain &ToolChain, const ArgList &Args, ArgStringList &CmdArgs, bool IsThinLTO, const Driver &D) { // Tell the linker to load the plugin. This has to come before AddLinkerInputs // as gold requires -plugin to come before any -plugin-opt that -Wl might // forward. CmdArgs.push_back("-plugin"); #if defined(LLVM_ON_WIN32) const char *Suffix = ".dll"; #elif defined(__APPLE__) const char *Suffix = ".dylib"; #else const char *Suffix = ".so"; #endif SmallString<1024> Plugin; llvm::sys::path::native(Twine(ToolChain.getDriver().Dir) + "/../lib" CLANG_LIBDIR_SUFFIX "/LLVMgold" + Suffix, Plugin); CmdArgs.push_back(Args.MakeArgString(Plugin)); // Try to pass driver level flags relevant to LTO code generation down to // the plugin. // Handle flags for selecting CPU variants. std::string CPU = getCPUName(Args, ToolChain.getTriple()); if (!CPU.empty()) CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=mcpu=") + CPU)); if (Arg *A = Args.getLastArg(options::OPT_O_Group)) { StringRef OOpt; if (A->getOption().matches(options::OPT_O4) || A->getOption().matches(options::OPT_Ofast)) OOpt = "3"; else if (A->getOption().matches(options::OPT_O)) OOpt = A->getValue(); else if (A->getOption().matches(options::OPT_O0)) OOpt = "0"; if (!OOpt.empty()) CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=O") + OOpt)); } if (IsThinLTO) CmdArgs.push_back("-plugin-opt=thinlto"); if (unsigned Parallelism = getLTOParallelism(Args, D)) CmdArgs.push_back(Args.MakeArgString(Twine("-plugin-opt=jobs=") + llvm::to_string(Parallelism))); // If an explicit debugger tuning argument appeared, pass it along. if (Arg *A = Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) { if (A->getOption().matches(options::OPT_glldb)) CmdArgs.push_back("-plugin-opt=-debugger-tune=lldb"); else if (A->getOption().matches(options::OPT_gsce)) CmdArgs.push_back("-plugin-opt=-debugger-tune=sce"); else CmdArgs.push_back("-plugin-opt=-debugger-tune=gdb"); } bool UseSeparateSections = isUseSeparateSections(ToolChain.getEffectiveTriple()); if (Args.hasFlag(options::OPT_ffunction_sections, options::OPT_fno_function_sections, UseSeparateSections)) { CmdArgs.push_back("-plugin-opt=-function-sections"); } if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections, UseSeparateSections)) { CmdArgs.push_back("-plugin-opt=-data-sections"); } if (Arg *A = getLastProfileSampleUseArg(Args)) { StringRef FName = A->getValue(); if (!llvm::sys::fs::exists(FName)) D.Diag(diag::err_drv_no_such_file) << FName; else CmdArgs.push_back( Args.MakeArgString(Twine("-plugin-opt=sample-profile=") + FName)); } // Need this flag to turn on new pass manager via Gold plugin. if (Args.hasFlag(options::OPT_fexperimental_new_pass_manager, options::OPT_fno_experimental_new_pass_manager, /* Default */ false)) { CmdArgs.push_back("-plugin-opt=new-pass-manager"); } }
/// \brief Determine whether Objective-C automated reference counting is /// enabled. bool tools::isObjCAutoRefCount(const ArgList &Args) { return Args.hasFlag(options::OPT_fobjc_arc, options::OPT_fno_objc_arc, false); }
XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { const Driver &D = TC.getDriver(); const llvm::Triple &Triple = TC.getTriple(); if (Args.hasFlag(options::OPT_fxray_instrument, options::OPT_fnoxray_instrument, false)) { if (Triple.getOS() == llvm::Triple::Linux) { switch (Triple.getArch()) { case llvm::Triple::x86_64: case llvm::Triple::arm: case llvm::Triple::aarch64: case llvm::Triple::ppc64le: case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: break; default: D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } } else if (Triple.getOS() == llvm::Triple::FreeBSD || Triple.getOS() == llvm::Triple::OpenBSD || Triple.getOS() == llvm::Triple::NetBSD) { if (Triple.getArch() != llvm::Triple::x86_64) { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } } else { D.Diag(diag::err_drv_clang_unsupported) << (std::string(XRayInstrumentOption) + " on " + Triple.str()); } XRayInstrument = true; if (const Arg *A = Args.getLastArg(options::OPT_fxray_instruction_threshold_, options::OPT_fxray_instruction_threshold_EQ)) { StringRef S = A->getValue(); if (S.getAsInteger(0, InstructionThreshold) || InstructionThreshold < 0) D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S; } // By default, the back-end will not emit the lowering for XRay customevent // calls if the function is not instrumented. In the future we will change // this default to be the reverse, but in the meantime we're going to // introduce the new functionality behind a flag. if (Args.hasFlag(options::OPT_fxray_always_emit_customevents, options::OPT_fnoxray_always_emit_customevents, false)) XRayAlwaysEmitCustomEvents = true; if (Args.hasFlag(options::OPT_fxray_always_emit_typedevents, options::OPT_fnoxray_always_emit_typedevents, false)) XRayAlwaysEmitTypedEvents = true; if (!Args.hasFlag(options::OPT_fxray_link_deps, options::OPT_fnoxray_link_deps, true)) XRayRT = false; auto Bundles = Args.getAllArgValues(options::OPT_fxray_instrumentation_bundle); if (Bundles.empty()) InstrumentationBundle.Mask = XRayInstrKind::All; else for (const auto &B : Bundles) { llvm::SmallVector<StringRef, 2> BundleParts; llvm::SplitString(B, BundleParts, ","); for (const auto &P : BundleParts) { // TODO: Automate the generation of the string case table. auto Valid = llvm::StringSwitch<bool>(P) .Cases("none", "all", "function", "custom", true) .Default(false); if (!Valid) { D.Diag(clang::diag::err_drv_invalid_value) << "-fxray-instrumentation-bundle=" << P; continue; } auto Mask = parseXRayInstrValue(P); if (Mask == XRayInstrKind::None) { InstrumentationBundle.clear(); break; } InstrumentationBundle.Mask |= Mask; } } // Validate the always/never attribute files. We also make sure that they // are treated as actual dependencies. for (const auto &Filename : Args.getAllArgValues(options::OPT_fxray_always_instrument)) { if (llvm::sys::fs::exists(Filename)) { AlwaysInstrumentFiles.push_back(Filename); ExtraDeps.push_back(Filename); } else D.Diag(clang::diag::err_drv_no_such_file) << Filename; } for (const auto &Filename : Args.getAllArgValues(options::OPT_fxray_never_instrument)) { if (llvm::sys::fs::exists(Filename)) { NeverInstrumentFiles.push_back(Filename); ExtraDeps.push_back(Filename); } else D.Diag(clang::diag::err_drv_no_such_file) << Filename; } for (const auto &Filename : Args.getAllArgValues(options::OPT_fxray_attr_list)) { if (llvm::sys::fs::exists(Filename)) { AttrListFiles.push_back(Filename); ExtraDeps.push_back(Filename); } else D.Diag(clang::diag::err_drv_no_such_file) << Filename; } // Get the list of modes we want to support. auto SpecifiedModes = Args.getAllArgValues(options::OPT_fxray_modes); if (SpecifiedModes.empty()) llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); else for (const auto &Arg : SpecifiedModes) { // Parse CSV values for -fxray-modes=... llvm::SmallVector<StringRef, 2> ModeParts; llvm::SplitString(Arg, ModeParts, ","); for (const auto &M : ModeParts) if (M == "none") Modes.clear(); else if (M == "all") llvm::copy(XRaySupportedModes, std::back_inserter(Modes)); else Modes.push_back(M); } // Then we want to sort and unique the modes we've collected. llvm::sort(Modes.begin(), Modes.end()); Modes.erase(std::unique(Modes.begin(), Modes.end()), Modes.end()); } }
void Fuchsia::addClangTargetOptions(const ArgList &DriverArgs, ArgStringList &CC1Args) const { if (DriverArgs.hasFlag(options::OPT_fuse_init_array, options::OPT_fno_use_init_array, true)) CC1Args.push_back("-fuse-init-array"); }