示例#1
0
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;
  }
}
示例#2
0
文件: Myriad.cpp 项目: davidlt/root
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());
}
示例#3
0
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;
}
示例#4
0
文件: Cuda.cpp 项目: Bekenn/clang
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");
}
示例#5
0
// 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;
}
示例#7
0
文件: ARM.cpp 项目: JaredCJR/clang
// 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);
}
示例#8
0
文件: ARM.cpp 项目: JaredCJR/clang
// 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);
}
示例#9
0
文件: PPC.cpp 项目: Teemperor/clang
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;
}
示例#10
0
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;
  }
}
示例#11
0
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;
}
示例#12
0
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);
}
示例#13
0
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");
}
示例#14
0
文件: ARM.cpp 项目: JaredCJR/clang
// 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);
}
示例#15
0
文件: ARM.cpp 项目: JaredCJR/clang
// 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);
}
示例#16
0
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;
}
示例#17
0
文件: Cuda.cpp 项目: Bekenn/clang
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);
  }
}
示例#18
0
// 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;
}
示例#19
0
// 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);
  }
}
示例#20
0
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;
}
示例#21
0
// 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);
}
示例#22
0
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;
}
示例#23
0
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);
}
示例#24
0
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;
  }
}
示例#25
0
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");
}
示例#26
0
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");
  }

}