void msp430::getMSP430TargetFeatures(const Driver &D, const ArgList &Args, std::vector<StringRef> &Features) { const Arg *MCU = Args.getLastArg(options::OPT_mmcu_EQ); if (MCU && !isSupportedMCU(MCU->getValue())) { D.Diag(diag::err_drv_clang_unsupported) << MCU->getValue(); return; } const Arg *HWMultArg = Args.getLastArg(options::OPT_mhwmult_EQ); if (!MCU && !HWMultArg) return; StringRef HWMult = HWMultArg ? HWMultArg->getValue() : "auto"; StringRef SupportedHWMult = getSupportedHWMult(MCU); if (HWMult == "auto") { // 'auto' - deduce hw multiplier support based on mcu name provided. // If no mcu name is provided, assume no hw multiplier is supported. if (!MCU) D.Diag(clang::diag::warn_drv_msp430_hwmult_no_device); HWMult = SupportedHWMult; } if (HWMult == "none") { // 'none' - disable hw multiplier. Features.push_back("-hwmult16"); Features.push_back("-hwmult32"); Features.push_back("-hwmultf5"); return; } if (MCU && SupportedHWMult == "none") D.Diag(clang::diag::warn_drv_msp430_hwmult_unsupported) << HWMult; if (MCU && HWMult != SupportedHWMult) D.Diag(clang::diag::warn_drv_msp430_hwmult_mismatch) << SupportedHWMult << HWMult; if (HWMult == "16bit") { // '16bit' - for 16-bit only hw multiplier. Features.push_back("+hwmult16"); } else if (HWMult == "32bit") { // '32bit' - for 16/32-bit hw multiplier. Features.push_back("+hwmult32"); } else if (HWMult == "f5series") { // 'f5series' - for 16/32-bit hw multiplier supported by F5 series mcus. Features.push_back("+hwmultf5"); } else { D.Diag(clang::diag::err_drv_unsupported_option_argument) << HWMultArg->getAsString(Args) << HWMult; } }
MyriadToolChain::MyriadToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : Generic_ELF(D, Triple, Args) { // If a target of 'sparc-myriad-elf' is specified to clang, it wants to use // 'sparc-myriad--elf' (note the unknown OS) as the canonical triple. // This won't work to find gcc. Instead we give the installation detector an // extra triple, which is preferable to further hacks of the logic that at // present is based solely on getArch(). In particular, it would be wrong to // choose the myriad installation when targeting a non-myriad sparc install. switch (Triple.getArch()) { default: D.Diag(clang::diag::err_target_unsupported_arch) << Triple.getArchName() << "myriad"; case llvm::Triple::sparc: case llvm::Triple::sparcel: case llvm::Triple::shave: GCCInstallation.init(Triple, Args, {"sparc-myriad-elf"}); } if (GCCInstallation.isValid()) { // This directory contains crt{i,n,begin,end}.o as well as libgcc. // These files are tied to a particular version of gcc. SmallString<128> CompilerSupportDir(GCCInstallation.getInstallPath()); addPathIfExists(D, CompilerSupportDir, getFilePaths()); } // libstd++ and libc++ must both be found in this one place. addPathIfExists(D, D.Dir + "/../sparc-myriad-elf/lib", getFilePaths()); }
int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) { assert(A->getOption().matches(options::OPT_fsanitize_coverage) || A->getOption().matches(options::OPT_fno_sanitize_coverage)); int Features = 0; for (int i = 0, n = A->getNumValues(); i != n; ++i) { const char *Value = A->getValue(i); int F = llvm::StringSwitch<int>(Value) .Case("func", CoverageFunc) .Case("bb", CoverageBB) .Case("edge", CoverageEdge) .Case("indirect-calls", CoverageIndirCall) .Case("trace-bb", CoverageTraceBB) .Case("trace-cmp", CoverageTraceCmp) .Case("trace-div", CoverageTraceDiv) .Case("trace-gep", CoverageTraceGep) .Case("8bit-counters", Coverage8bitCounters) .Case("trace-pc", CoverageTracePC) .Default(0); if (F == 0) D.Diag(clang::diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; Features |= F; } return Features; }
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"); }
// Select the MIPS float ABI as determined by -msoft-float, -mhard-float, // and -mfloat-abi=. mips::FloatABI mips::getMipsFloatABI(const Driver &D, const ArgList &Args) { mips::FloatABI ABI = mips::FloatABI::Invalid; if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, options::OPT_mfloat_abi_EQ)) { if (A->getOption().matches(options::OPT_msoft_float)) ABI = mips::FloatABI::Soft; else if (A->getOption().matches(options::OPT_mhard_float)) ABI = mips::FloatABI::Hard; else { ABI = llvm::StringSwitch<mips::FloatABI>(A->getValue()) .Case("soft", mips::FloatABI::Soft) .Case("hard", mips::FloatABI::Hard) .Default(mips::FloatABI::Invalid); if (ABI == mips::FloatABI::Invalid && !StringRef(A->getValue()).empty()) { D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); ABI = mips::FloatABI::Hard; } } } // If unspecified, choose the default based on the platform. if (ABI == mips::FloatABI::Invalid) { // Assume "hard", because it's a default value used by gcc. // When we start to recognize specific target MIPS processors, // we will be able to select the default more correctly. ABI = mips::FloatABI::Hard; } assert(ABI != mips::FloatABI::Invalid && "must select an ABI"); return ABI; }
SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors) { assert((A->getOption().matches(options::OPT_fsanitize_EQ) || A->getOption().matches(options::OPT_fno_sanitize_EQ) || A->getOption().matches(options::OPT_fsanitize_recover_EQ) || A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) || A->getOption().matches(options::OPT_fsanitize_trap_EQ) || A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) && "Invalid argument in parseArgValues!"); SanitizerMask Kinds = 0; for (int i = 0, n = A->getNumValues(); i != n; ++i) { const char *Value = A->getValue(i); SanitizerMask Kind; // Special case: don't accept -fsanitize=all. if (A->getOption().matches(options::OPT_fsanitize_EQ) && 0 == strcmp("all", Value)) Kind = 0; else Kind = parseSanitizerValue(Value, /*AllowGroups=*/true); if (Kind) Kinds |= Kind; else if (DiagnoseErrors) D.Diag(clang::diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Value; } return Kinds; }
// Handle -mfpu=. static void getARMFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args, StringRef FPU, std::vector<StringRef> &Features) { unsigned FPUID = llvm::ARM::parseFPU(FPU); if (!llvm::ARM::getFPUFeatures(FPUID, Features)) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); }
// Handle -mhwdiv=. // FIXME: Use ARMTargetParser. static void getARMHWDivFeatures(const Driver &D, const Arg *A, const ArgList &Args, StringRef HWDiv, std::vector<StringRef> &Features) { unsigned HWDivID = llvm::ARM::parseHWDiv(HWDiv); if (!llvm::ARM::getHWDivFeatures(HWDivID, Features)) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); }
ppc::FloatABI ppc::getPPCFloatABI(const Driver &D, const ArgList &Args) { ppc::FloatABI ABI = ppc::FloatABI::Invalid; if (Arg *A = Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float, options::OPT_mfloat_abi_EQ)) { if (A->getOption().matches(options::OPT_msoft_float)) ABI = ppc::FloatABI::Soft; else if (A->getOption().matches(options::OPT_mhard_float)) ABI = ppc::FloatABI::Hard; else { ABI = llvm::StringSwitch<ppc::FloatABI>(A->getValue()) .Case("soft", ppc::FloatABI::Soft) .Case("hard", ppc::FloatABI::Hard) .Default(ppc::FloatABI::Invalid); if (ABI == ppc::FloatABI::Invalid && !StringRef(A->getValue()).empty()) { D.Diag(clang::diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args); ABI = ppc::FloatABI::Hard; } } } // If unspecified, choose the default based on the platform. if (ABI == ppc::FloatABI::Invalid) { ABI = ppc::FloatABI::Hard; } return ABI; }
static void handleHVXWarnings(const Driver &D, const ArgList &Args) { // Handle the unsupported values passed to mhvx-length. if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) { StringRef Val = A->getValue(); if (!Val.equals_lower("64b") && !Val.equals_lower("128b")) D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Val; } }
unsigned tools::getLTOParallelism(const ArgList &Args, const Driver &D) { unsigned Parallelism = 0; Arg *LtoJobsArg = Args.getLastArg(options::OPT_flto_jobs_EQ); if (LtoJobsArg && StringRef(LtoJobsArg->getValue()).getAsInteger(10, Parallelism)) D.Diag(diag::err_drv_invalid_int_value) << LtoJobsArg->getAsString(Args) << LtoJobsArg->getValue(); return Parallelism; }
ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, const ArgList &Args) : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)), CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) { if (Arg *A = Args.getLastArg(options::OPT_mthread_model)) if (!isThreadModelSupported(A->getValue())) D.Diag(diag::err_drv_invalid_thread_model_for_target) << A->getValue() << A->getAsString(Args); }
void aarch64::getAArch64TargetFeatures(const Driver &D, const ArgList &Args, std::vector<StringRef> &Features) { Arg *A; bool success = true; // Enable NEON by default. Features.push_back("+neon"); if ((A = Args.getLastArg(options::OPT_march_EQ))) success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features); else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features); else if (Args.hasArg(options::OPT_arch)) success = getAArch64ArchFeaturesFromMcpu(D, getAArch64TargetCPU(Args, A), Args, Features); if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))) success = getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features); else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ))) success = getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features); else if (success && Args.hasArg(options::OPT_arch)) success = getAArch64MicroArchFeaturesFromMcpu( D, getAArch64TargetCPU(Args, A), Args, Features); if (!success) D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); if (Args.getLastArg(options::OPT_mgeneral_regs_only)) { Features.push_back("-fp-armv8"); Features.push_back("-crypto"); Features.push_back("-neon"); } // En/disable crc if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) { if (A->getOption().matches(options::OPT_mcrc)) Features.push_back("+crc"); else Features.push_back("-crc"); } if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) if (A->getOption().matches(options::OPT_mno_unaligned_access)) Features.push_back("+strict-align"); if (Args.hasArg(options::OPT_ffixed_x18)) Features.push_back("+reserve-x18"); if (Args.hasArg(options::OPT_ffixed_x20)) Features.push_back("+reserve-x20"); if (Args.hasArg(options::OPT_mno_neg_immediates)) Features.push_back("+no-neg-immediates"); }
// Check -mcpu=. Needs ArchName to handle -mcpu=generic. static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args, llvm::StringRef CPUName, llvm::StringRef ArchName, std::vector<StringRef> &Features, const llvm::Triple &Triple) { std::pair<StringRef, StringRef> Split = CPUName.split("+"); std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); if (arm::getLLVMArchSuffixForARM(CPU, ArchName, Triple).empty() || (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); }
// Check if -march is valid by checking if it can be canonicalised and parsed. // getARMArch is used here instead of just checking the -march value in order // to handle -march=native correctly. static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args, llvm::StringRef ArchName, std::vector<StringRef> &Features, const llvm::Triple &Triple) { std::pair<StringRef, StringRef> Split = ArchName.split("+"); std::string MArch = arm::getARMArch(ArchName, Triple); if (llvm::ARM::parseArch(MArch) == llvm::ARM::ArchKind::INVALID || (Split.second.size() && !DecodeARMFeatures(D, Split.second, Features))) D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args); }
unsigned SanitizerArgs::parse(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors) { unsigned Kind = 0; for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) { if (unsigned K = parse(A->getValue(I))) Kind |= K; else if (DiagnoseErrors) D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << A->getValue(I); } return Kind; }
void CudaInstallationDetector::CheckCudaVersionSupportsArch( CudaArch Arch) const { if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN || ArchsWithBadVersion.count(Arch) > 0) return; auto MinVersion = MinVersionForCudaArch(Arch); auto MaxVersion = MaxVersionForCudaArch(Arch); if (Version < MinVersion || Version > MaxVersion) { ArchsWithBadVersion.insert(Arch); D.Diag(diag::err_drv_cuda_version_unsupported) << CudaArchToString(Arch) << CudaVersionToString(MinVersion) << CudaVersionToString(MaxVersion) << InstallPath << CudaVersionToString(Version); } }
// Decode AArch64 features from string like +[no]featureA+[no]featureB+... static bool DecodeAArch64Features(const Driver &D, StringRef text, std::vector<StringRef> &Features) { SmallVector<StringRef, 8> Split; text.split(Split, StringRef("+"), -1, false); for (StringRef Feature : Split) { StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature); if (!FeatureName.empty()) Features.push_back(FeatureName); else if (Feature == "neon" || Feature == "noneon") D.Diag(clang::diag::err_drv_no_neon_modifier); else return false; } return true; }
// Handle hvx target features explicitly. static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args, std::vector<StringRef> &Features, bool &HasHVX) { // Handle HVX warnings. handleHVXWarnings(D, Args); // Add the +hvx* features based on commandline flags. StringRef HVXFeature, HVXLength; StringRef Cpu(toolchains::HexagonToolChain::GetTargetCPUVersion(Args)); // Handle -mhvx, -mhvx=, -mno-hvx. if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx, options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ)) { if (A->getOption().matches(options::OPT_mno_hexagon_hvx)) return; if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) { HasHVX = true; HVXFeature = Cpu = A->getValue(); HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + HVXFeature.lower()); } else if (A->getOption().matches(options::OPT_mhexagon_hvx)) { HasHVX = true; HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + Cpu); } Features.push_back(HVXFeature); } // Handle -mhvx-length=. if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) { // These flags are valid only if HVX in enabled. if (!HasHVX) D.Diag(diag::err_drv_invalid_hvx_length); else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ)) HVXLength = A->getValue(); } // Default hvx-length based on Cpu. else if (HasHVX) HVXLength = getDefaultHvxLength(Cpu); if (!HVXLength.empty()) { HVXFeature = Args.MakeArgString(llvm::Twine("+hvx-length") + HVXLength.lower()); Features.push_back(HVXFeature); } }
static SanitizerMask parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args) { SanitizerMask TrapRemove = 0; // During the loop below, the accumulated set of // sanitizers disabled by the current sanitizer // argument or any argument after it. SanitizerMask TrappingKinds = 0; SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported); for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend(); I != E; ++I) { const auto *Arg = *I; if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) { Arg->claim(); SanitizerMask Add = parseArgValues(D, Arg, true); Add &= ~TrapRemove; if (SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) { SanitizerSet S; S.Mask = InvalidValues; D.Diag(diag::err_drv_unsupported_option_argument) << "-fsanitize-trap" << toString(S); } TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove; } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) { Arg->claim(); TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true)); } else if (Arg->getOption().matches( options::OPT_fsanitize_undefined_trap_on_error)) { Arg->claim(); TrappingKinds |= expandSanitizerGroups(UndefinedGroup & ~TrapRemove) & ~TrapRemove; } else if (Arg->getOption().matches( options::OPT_fno_sanitize_undefined_trap_on_error)) { Arg->claim(); TrapRemove |= expandSanitizerGroups(UndefinedGroup); } } // Apply default trapping behavior. TrappingKinds |= TrappingDefault & ~TrapRemove; return TrappingKinds; }
// Hexagon target features. void hexagon::getHexagonTargetFeatures(const Driver &D, const ArgList &Args, std::vector<StringRef> &Features) { handleTargetFeaturesGroup(Args, Features, options::OPT_m_hexagon_Features_Group); bool UseLongCalls = false; if (Arg *A = Args.getLastArg(options::OPT_mlong_calls, options::OPT_mno_long_calls)) { if (A->getOption().matches(options::OPT_mlong_calls)) UseLongCalls = true; } Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls"); bool HasHVX = false; handleHVXTargetFeatures(D, Args, Features, HasHVX); if (HexagonToolChain::isAutoHVXEnabled(Args) && !HasHVX) D.Diag(diag::warn_drv_vectorize_needs_hvx); }
bool SanitizerArgs::parse(const Driver &D, const llvm::opt::ArgList &Args, const llvm::opt::Arg *A, unsigned &Add, unsigned &Remove, bool DiagnoseErrors) { Add = 0; Remove = 0; const char *DeprecatedReplacement = 0; if (A->getOption().matches(options::OPT_faddress_sanitizer)) { Add = Address; DeprecatedReplacement = "-fsanitize=address"; } else if (A->getOption().matches(options::OPT_fno_address_sanitizer)) { Remove = Address; DeprecatedReplacement = "-fno-sanitize=address"; } else if (A->getOption().matches(options::OPT_fthread_sanitizer)) { Add = Thread; DeprecatedReplacement = "-fsanitize=thread"; } else if (A->getOption().matches(options::OPT_fno_thread_sanitizer)) { Remove = Thread; DeprecatedReplacement = "-fno-sanitize=thread"; } else if (A->getOption().matches(options::OPT_fcatch_undefined_behavior)) { Add = UndefinedTrap; DeprecatedReplacement = "-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error"; } else if (A->getOption().matches(options::OPT_fbounds_checking) || A->getOption().matches(options::OPT_fbounds_checking_EQ)) { Add = LocalBounds; DeprecatedReplacement = "-fsanitize=local-bounds"; } else if (A->getOption().matches(options::OPT_fsanitize_EQ)) { Add = parse(D, A, DiagnoseErrors); } else if (A->getOption().matches(options::OPT_fno_sanitize_EQ)) { Remove = parse(D, A, DiagnoseErrors); } else { // Flag is not relevant to sanitizers. return false; } // If this is a deprecated synonym, produce a warning directing users // towards the new spelling. if (DeprecatedReplacement && DiagnoseErrors) D.Diag(diag::warn_drv_deprecated_arg) << A->getAsString(Args) << DeprecatedReplacement; return true; }
void x86::getX86TargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, std::vector<StringRef> &Features) { // If -march=native, autodetect the feature list. if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_march_EQ)) { if (StringRef(A->getValue()) == "native") { llvm::StringMap<bool> HostFeatures; if (llvm::sys::getHostCPUFeatures(HostFeatures)) for (auto &F : HostFeatures) Features.push_back( Args.MakeArgString((F.second ? "+" : "-") + F.first())); } } if (Triple.getArchName() == "x86_64h") { // x86_64h implies quite a few of the more modern subtarget features // for Haswell class CPUs, but not all of them. Opt-out of a few. Features.push_back("-rdrnd"); Features.push_back("-aes"); Features.push_back("-pclmul"); Features.push_back("-rtm"); Features.push_back("-fsgsbase"); } const llvm::Triple::ArchType ArchType = Triple.getArch(); // Add features to be compatible with gcc for Android. if (Triple.isAndroid()) { if (ArchType == llvm::Triple::x86_64) { Features.push_back("+sse4.2"); Features.push_back("+popcnt"); } else Features.push_back("+ssse3"); } // Set features according to the -arch flag on MSVC. if (Arg *A = Args.getLastArg(options::OPT__SLASH_arch)) { StringRef Arch = A->getValue(); bool ArchUsed = false; // First, look for flags that are shared in x86 and x86-64. if (ArchType == llvm::Triple::x86_64 || ArchType == llvm::Triple::x86) { if (Arch == "AVX" || Arch == "AVX2") { ArchUsed = true; Features.push_back(Args.MakeArgString("+" + Arch.lower())); } } // Then, look for x86-specific flags. if (ArchType == llvm::Triple::x86) { if (Arch == "IA32") { ArchUsed = true; } else if (Arch == "SSE" || Arch == "SSE2") { ArchUsed = true; Features.push_back(Args.MakeArgString("+" + Arch.lower())); } } if (!ArchUsed) D.Diag(clang::diag::warn_drv_unused_argument) << A->getAsString(Args); } // Now add any that the user explicitly requested on the command line, // which may override the defaults. handleTargetFeaturesGroup(Args, Features, options::OPT_m_x86_Features_Group); }
SanitizerArgs::SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args) { clear(); unsigned AllKinds = 0; // All kinds of sanitizers that were turned on // at least once (possibly, disabled further). for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) { unsigned Add, Remove; if (!parse(D, Args, *I, Add, Remove, true)) continue; (*I)->claim(); Kind |= Add; Kind &= ~Remove; AllKinds |= Add; } UbsanTrapOnError = Args.hasArg(options::OPT_fcatch_undefined_behavior) || Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, options::OPT_fno_sanitize_undefined_trap_on_error, false); if (Args.hasArg(options::OPT_fcatch_undefined_behavior) && !Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, options::OPT_fno_sanitize_undefined_trap_on_error, true)) { D.Diag(diag::err_drv_argument_not_allowed_with) << "-fcatch-undefined-behavior" << "-fno-sanitize-undefined-trap-on-error"; } // Warn about undefined sanitizer options that require runtime support. if (UbsanTrapOnError && notAllowedWithTrap()) { if (Args.hasArg(options::OPT_fcatch_undefined_behavior)) D.Diag(diag::err_drv_argument_not_allowed_with) << lastArgumentForKind(D, Args, NotAllowedWithTrap) << "-fcatch-undefined-behavior"; else if (Args.hasFlag(options::OPT_fsanitize_undefined_trap_on_error, options::OPT_fno_sanitize_undefined_trap_on_error, false)) D.Diag(diag::err_drv_argument_not_allowed_with) << lastArgumentForKind(D, Args, NotAllowedWithTrap) << "-fsanitize-undefined-trap-on-error"; } // Only one runtime library can be used at once. bool NeedsAsan = needsAsanRt(); bool NeedsTsan = needsTsanRt(); bool NeedsMsan = needsMsanRt(); bool NeedsLsan = needsLeakDetection(); if (NeedsAsan && NeedsTsan) D.Diag(diag::err_drv_argument_not_allowed_with) << lastArgumentForKind(D, Args, NeedsAsanRt) << lastArgumentForKind(D, Args, NeedsTsanRt); if (NeedsAsan && NeedsMsan) D.Diag(diag::err_drv_argument_not_allowed_with) << lastArgumentForKind(D, Args, NeedsAsanRt) << lastArgumentForKind(D, Args, NeedsMsanRt); if (NeedsTsan && NeedsMsan) D.Diag(diag::err_drv_argument_not_allowed_with) << lastArgumentForKind(D, Args, NeedsTsanRt) << lastArgumentForKind(D, Args, NeedsMsanRt); if (NeedsLsan && NeedsTsan) D.Diag(diag::err_drv_argument_not_allowed_with) << lastArgumentForKind(D, Args, NeedsLeakDetection) << lastArgumentForKind(D, Args, NeedsTsanRt); if (NeedsLsan && NeedsMsan) D.Diag(diag::err_drv_argument_not_allowed_with) << lastArgumentForKind(D, Args, NeedsLeakDetection) << lastArgumentForKind(D, Args, NeedsMsanRt); // FIXME: Currenly -fsanitize=leak is silently ignored in the presence of // -fsanitize=address. Perhaps it should print an error, or perhaps // -f(-no)sanitize=leak should change whether leak detection is enabled by // default in ASan? // If -fsanitize contains extra features of ASan, it should also // explicitly contain -fsanitize=address (probably, turned off later in the // command line). if ((Kind & AddressFull) != 0 && (AllKinds & Address) == 0) D.Diag(diag::warn_drv_unused_sanitizer) << lastArgumentForKind(D, Args, AddressFull) << "-fsanitize=address"; // Parse -f(no-)sanitize-blacklist options. if (Arg *BLArg = Args.getLastArg(options::OPT_fsanitize_blacklist, options::OPT_fno_sanitize_blacklist)) { if (BLArg->getOption().matches(options::OPT_fsanitize_blacklist)) { std::string BLPath = BLArg->getValue(); if (llvm::sys::fs::exists(BLPath)) { // Validate the blacklist format. std::string BLError; llvm::OwningPtr<llvm::SpecialCaseList> SCL( llvm::SpecialCaseList::create(BLPath, BLError)); if (!SCL.get()) D.Diag(diag::err_drv_malformed_sanitizer_blacklist) << BLError; else BlacklistFile = BLPath; } else { D.Diag(diag::err_drv_no_such_file) << BLPath; } } } else { // If no -fsanitize-blacklist option is specified, try to look up for // blacklist in the resource directory. std::string BLPath; if (getDefaultBlacklistForKind(D, Kind, BLPath) && llvm::sys::fs::exists(BLPath)) BlacklistFile = BLPath; } // Parse -f(no-)sanitize-memory-track-origins options. if (NeedsMsan) MsanTrackOrigins = Args.hasFlag(options::OPT_fsanitize_memory_track_origins, options::OPT_fno_sanitize_memory_track_origins, /* Default */false); // Parse -f(no-)sanitize-address-zero-base-shadow options. if (NeedsAsan) { if (Arg *A = Args.getLastArg( options::OPT_fsanitize_address_zero_base_shadow, options::OPT_fno_sanitize_address_zero_base_shadow)) AsanZeroBaseShadow = A->getOption().matches( options::OPT_fsanitize_address_zero_base_shadow) ? AZBSK_On : AZBSK_Off; } }
void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple, const ArgList &Args, std::vector<StringRef> &Features) { StringRef CPUName; StringRef ABIName; getMipsCPUAndABI(Args, Triple, CPUName, ABIName); ABIName = getGnuCompatibleMipsABIName(ABIName); // Historically, PIC code for MIPS was associated with -mabicalls, a.k.a // SVR4 abicalls. Static code does not use SVR4 calling sequences. An ABI // extension was developed by Richard Sandiford & Code Sourcery to support // static code calling PIC code (CPIC). For O32 and N32 this means we have // several combinations of PIC/static and abicalls. Pure static, static // with the CPIC extension, and pure PIC code. // At final link time, O32 and N32 with CPIC will have another section // added to the binary which contains the stub functions to perform // any fixups required for PIC code. // For N64, the situation is more regular: code can either be static // (non-abicalls) or PIC (abicalls). GCC has traditionally picked PIC code // code for N64. Since Clang has already built the relocation model portion // of the commandline, we pick add +noabicalls feature in the N64 static // case. // The is another case to be accounted for: -msym32, which enforces that all // symbols have 32 bits in size. In this case, N64 can in theory use CPIC // but it is unsupported. // The combinations for N64 are: // a) Static without abicalls and 64bit symbols. // b) Static with abicalls and 32bit symbols. // c) PIC with abicalls and 64bit symbols. // For case (a) we need to add +noabicalls for N64. bool IsN64 = ABIName == "64"; bool NonPIC = false; Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC, options::OPT_fpic, options::OPT_fno_pic, options::OPT_fPIE, options::OPT_fno_PIE, options::OPT_fpie, options::OPT_fno_pie); if (LastPICArg) { Option O = LastPICArg->getOption(); NonPIC = (O.matches(options::OPT_fno_PIC) || O.matches(options::OPT_fno_pic) || O.matches(options::OPT_fno_PIE) || O.matches(options::OPT_fno_pie)); } if (IsN64 && NonPIC) Features.push_back("+noabicalls"); else AddTargetFeature(Args, Features, options::OPT_mno_abicalls, options::OPT_mabicalls, "noabicalls"); mips::FloatABI FloatABI = mips::getMipsFloatABI(D, Args); if (FloatABI == mips::FloatABI::Soft) { // FIXME: Note, this is a hack. We need to pass the selected float // mode to the MipsTargetInfoBase to define appropriate macros there. // Now it is the only method. Features.push_back("+soft-float"); } if (Arg *A = Args.getLastArg(options::OPT_mnan_EQ)) { StringRef Val = StringRef(A->getValue()); if (Val == "2008") { if (mips::getSupportedNanEncoding(CPUName) & mips::Nan2008) Features.push_back("+nan2008"); else { Features.push_back("-nan2008"); D.Diag(diag::warn_target_unsupported_nan2008) << CPUName; } } else if (Val == "legacy") { if (mips::getSupportedNanEncoding(CPUName) & mips::NanLegacy) Features.push_back("-nan2008"); else { Features.push_back("+nan2008"); D.Diag(diag::warn_target_unsupported_nanlegacy) << CPUName; } } else D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Val; } AddTargetFeature(Args, Features, options::OPT_msingle_float, options::OPT_mdouble_float, "single-float"); AddTargetFeature(Args, Features, options::OPT_mips16, options::OPT_mno_mips16, "mips16"); AddTargetFeature(Args, Features, options::OPT_mmicromips, options::OPT_mno_micromips, "micromips"); AddTargetFeature(Args, Features, options::OPT_mdsp, options::OPT_mno_dsp, "dsp"); AddTargetFeature(Args, Features, options::OPT_mdspr2, options::OPT_mno_dspr2, "dspr2"); AddTargetFeature(Args, Features, options::OPT_mmsa, options::OPT_mno_msa, "msa"); // Add the last -mfp32/-mfpxx/-mfp64, if none are given and the ABI is O32 // pass -mfpxx, or if none are given and fp64a is default, pass fp64 and // nooddspreg. if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx, options::OPT_mfp64)) { if (A->getOption().matches(options::OPT_mfp32)) Features.push_back("-fp64"); else if (A->getOption().matches(options::OPT_mfpxx)) { Features.push_back("+fpxx"); Features.push_back("+nooddspreg"); } else Features.push_back("+fp64"); } else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) { Features.push_back("+fpxx"); Features.push_back("+nooddspreg"); } else if (mips::isFP64ADefault(Triple, CPUName)) { Features.push_back("+fp64"); Features.push_back("+nooddspreg"); } AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg, options::OPT_modd_spreg, "nooddspreg"); AddTargetFeature(Args, Features, options::OPT_mno_madd4, options::OPT_mmadd4, "nomadd4"); AddTargetFeature(Args, Features, options::OPT_mlong_calls, options::OPT_mno_long_calls, "long-calls"); AddTargetFeature(Args, Features, options::OPT_mmt, options::OPT_mno_mt,"mt"); }
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"); } }