diff options
Diffstat (limited to 'clang/lib/Driver/ToolChain.cpp')
| -rw-r--r-- | clang/lib/Driver/ToolChain.cpp | 238 | 
1 files changed, 183 insertions, 55 deletions
| diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 3ebbd30195b3..b8c12fc9241a 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -68,8 +68,7 @@ static ToolChain::RTTIMode CalculateRTTIMode(const ArgList &Args,    }    // -frtti is default, except for the PS4 CPU. -  return (Triple.isPS4CPU() || Triple.isNVPTX()) ? ToolChain::RM_Disabled -                                                 : ToolChain::RM_Enabled; +  return (Triple.isPS4CPU()) ? ToolChain::RM_Disabled : ToolChain::RM_Enabled;  }  ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, @@ -169,7 +168,7 @@ static const DriverSuffix *FindDriverSuffix(StringRef ProgName, size_t &Pos) {  /// Normalize the program name from argv[0] by stripping the file extension if  /// present and lower-casing the string on Windows.  static std::string normalizeProgramName(llvm::StringRef Argv0) { -  std::string ProgName = llvm::sys::path::stem(Argv0); +  std::string ProgName = std::string(llvm::sys::path::stem(Argv0));  #ifdef _WIN32    // Transform to lowercase for case insensitive file systems.    std::transform(ProgName.begin(), ProgName.end(), ProgName.begin(), ::tolower); @@ -222,16 +221,21 @@ ToolChain::getTargetAndModeFromProgramName(StringRef PN) {    StringRef Prefix(ProgName);    Prefix = Prefix.slice(0, LastComponent);    std::string IgnoredError; -  bool IsRegistered = llvm::TargetRegistry::lookupTarget(Prefix, IgnoredError); -  return ParsedClangName{Prefix, ModeSuffix, DS->ModeFlag, IsRegistered}; +  bool IsRegistered = +      llvm::TargetRegistry::lookupTarget(std::string(Prefix), IgnoredError); +  return ParsedClangName{std::string(Prefix), ModeSuffix, DS->ModeFlag, +                         IsRegistered};  }  StringRef ToolChain::getDefaultUniversalArchName() const {    // In universal driver terms, the arch name accepted by -arch isn't exactly    // the same as the ones that appear in the triple. Roughly speaking, this is -  // an inverse of the darwin::getArchTypeForDarwinArchName() function, but the -  // only interesting special case is powerpc. +  // an inverse of the darwin::getArchTypeForDarwinArchName() function.    switch (Triple.getArch()) { +  case llvm::Triple::aarch64: +    return "arm64"; +  case llvm::Triple::aarch64_32: +    return "arm64_32";    case llvm::Triple::ppc:      return "ppc";    case llvm::Triple::ppc64: @@ -271,6 +275,10 @@ Tool *ToolChain::buildLinker() const {    llvm_unreachable("Linking is not supported by this toolchain");  } +Tool *ToolChain::buildStaticLibTool() const { +  llvm_unreachable("Creating static lib is not supported by this toolchain"); +} +  Tool *ToolChain::getAssemble() const {    if (!Assemble)      Assemble.reset(buildAssembler()); @@ -289,6 +297,12 @@ Tool *ToolChain::getLink() const {    return Link.get();  } +Tool *ToolChain::getStaticLibTool() const { +  if (!StaticLibTool) +    StaticLibTool.reset(buildStaticLibTool()); +  return StaticLibTool.get(); +} +  Tool *ToolChain::getIfsMerge() const {    if (!IfsMerge)      IfsMerge.reset(new tools::ifstool::Merger(*this)); @@ -318,6 +332,9 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const {    case Action::LinkJobClass:      return getLink(); +  case Action::StaticLibJobClass: +    return getStaticLibTool(); +    case Action::InputClass:    case Action::BindArchClass:    case Action::OffloadClass: @@ -386,11 +403,12 @@ std::string ToolChain::getCompilerRTPath() const {    } else {      llvm::sys::path::append(Path, "lib", getOSLibName());    } -  return Path.str(); +  return std::string(Path.str());  } -std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, -                                     FileType Type) const { +std::string ToolChain::getCompilerRTBasename(const ArgList &Args, +                                             StringRef Component, FileType Type, +                                             bool AddArch) const {    const llvm::Triple &TT = getTriple();    bool IsITANMSVCWindows =        TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment(); @@ -412,19 +430,33 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,      break;    } +  std::string ArchAndEnv; +  if (AddArch) { +    StringRef Arch = getArchNameForCompilerRTLib(*this, Args); +    const char *Env = TT.isAndroid() ? "-android" : ""; +    ArchAndEnv = ("-" + Arch + Env).str(); +  } +  return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str(); +} + +std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component, +                                     FileType Type) const { +  // Check for runtime files in the new layout without the architecture first. +  std::string CRTBasename = +      getCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);    for (const auto &LibPath : getLibraryPaths()) {      SmallString<128> P(LibPath); -    llvm::sys::path::append(P, Prefix + Twine("clang_rt.") + Component + Suffix); +    llvm::sys::path::append(P, CRTBasename);      if (getVFS().exists(P)) -      return P.str(); +      return std::string(P.str());    } -  StringRef Arch = getArchNameForCompilerRTLib(*this, Args); -  const char *Env = TT.isAndroid() ? "-android" : ""; +  // Fall back to the old expected compiler-rt name if the new one does not +  // exist. +  CRTBasename = getCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);    SmallString<128> Path(getCompilerRTPath()); -  llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" + -                                    Arch + Env + Suffix); -  return Path.str(); +  llvm::sys::path::append(Path, CRTBasename); +  return std::string(Path.str());  }  const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, @@ -441,13 +473,13 @@ Optional<std::string> ToolChain::getRuntimePath() const {    P.assign(D.ResourceDir);    llvm::sys::path::append(P, "lib", D.getTargetTriple());    if (getVFS().exists(P)) -    return llvm::Optional<std::string>(P.str()); +    return llvm::Optional<std::string>(std::string(P.str()));    // Second try the normalized triple.    P.assign(D.ResourceDir);    llvm::sys::path::append(P, "lib", Triple.str());    if (getVFS().exists(P)) -    return llvm::Optional<std::string>(P.str()); +    return llvm::Optional<std::string>(std::string(P.str()));    return None;  } @@ -459,13 +491,13 @@ Optional<std::string> ToolChain::getCXXStdlibPath() const {    P.assign(D.Dir);    llvm::sys::path::append(P, "..", "lib", D.getTargetTriple(), "c++");    if (getVFS().exists(P)) -    return llvm::Optional<std::string>(P.str()); +    return llvm::Optional<std::string>(std::string(P.str()));    // Second try the normalized triple.    P.assign(D.Dir);    llvm::sys::path::append(P, "..", "lib", Triple.str(), "c++");    if (getVFS().exists(P)) -    return llvm::Optional<std::string>(P.str()); +    return llvm::Optional<std::string>(std::string(P.str()));    return None;  } @@ -474,31 +506,27 @@ std::string ToolChain::getArchSpecificLibPath() const {    SmallString<128> Path(getDriver().ResourceDir);    llvm::sys::path::append(Path, "lib", getOSLibName(),                            llvm::Triple::getArchTypeName(getArch())); -  return Path.str(); +  return std::string(Path.str());  }  bool ToolChain::needsProfileRT(const ArgList &Args) {    if (Args.hasArg(options::OPT_noprofilelib))      return false; -  if (needsGCovInstrumentation(Args) || -      Args.hasArg(options::OPT_fprofile_generate) || -      Args.hasArg(options::OPT_fprofile_generate_EQ) || -      Args.hasArg(options::OPT_fcs_profile_generate) || -      Args.hasArg(options::OPT_fcs_profile_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_forder_file_instrumentation)) -    return true; - -  return false; +  return Args.hasArg(options::OPT_fprofile_generate) || +         Args.hasArg(options::OPT_fprofile_generate_EQ) || +         Args.hasArg(options::OPT_fcs_profile_generate) || +         Args.hasArg(options::OPT_fcs_profile_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_forder_file_instrumentation);  }  bool ToolChain::needsGCovInstrumentation(const llvm::opt::ArgList &Args) { -  return Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, -                      false) || -         Args.hasArg(options::OPT_coverage); +  return Args.hasArg(options::OPT_coverage) || +         Args.hasFlag(options::OPT_fprofile_arcs, options::OPT_fno_profile_arcs, +                      false);  }  Tool *ToolChain::SelectTool(const JobAction &JA) const { @@ -526,7 +554,7 @@ std::string ToolChain::GetLinkerPath() const {      // If we're passed what looks like an absolute path, don't attempt to      // second-guess that.      if (llvm::sys::fs::can_execute(UseLinker)) -      return UseLinker; +      return std::string(UseLinker);    } else if (UseLinker.empty() || UseLinker == "ld") {      // If we're passed -fuse-ld= with no argument, or with the argument ld,      // then use whatever the default system linker is. @@ -550,6 +578,11 @@ std::string ToolChain::GetLinkerPath() const {    return GetProgramPath(getDefaultLinker());  } +std::string ToolChain::GetStaticLibToolPath() const { +  // TODO: Add support for static lib archiving on Windows +  return GetProgramPath("llvm-ar"); +} +  types::ID ToolChain::LookupTypeForExtension(StringRef Ext) const {    types::ID id = types::lookupTypeForExtension(Ext); @@ -735,6 +768,10 @@ std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,    return ComputeLLVMTriple(Args, InputType);  } +std::string ToolChain::computeSysRoot() const { +  return D.SysRoot; +} +  void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,                                            ArgStringList &CC1Args) const {    // Each toolchain should provide the appropriate include flags. @@ -748,7 +785,8 @@ void ToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {}  void ToolChain::addProfileRTLibs(const llvm::opt::ArgList &Args,                                   llvm::opt::ArgStringList &CmdArgs) const { -  if (!needsProfileRT(Args)) return; +  if (!needsProfileRT(Args) && !needsGCovInstrumentation(Args)) +    return;    CmdArgs.push_back(getCompilerRTArgString(Args, "profile"));  } @@ -916,28 +954,35 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args,    CmdArgs.push_back("-lcc_kext");  } -bool ToolChain::AddFastMathRuntimeIfAvailable(const ArgList &Args, -                                              ArgStringList &CmdArgs) const { +bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, +                                           std::string &Path) const {    // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed    // (to keep the linker options consistent with gcc and clang itself).    if (!isOptimizationLevelFast(Args)) {      // Check if -ffast-math or -funsafe-math.      Arg *A = -        Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math, -                        options::OPT_funsafe_math_optimizations, -                        options::OPT_fno_unsafe_math_optimizations); +      Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math, +                      options::OPT_funsafe_math_optimizations, +                      options::OPT_fno_unsafe_math_optimizations);      if (!A || A->getOption().getID() == options::OPT_fno_fast_math ||          A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations)        return false;    }    // If crtfastmath.o exists add it to the arguments. -  std::string Path = GetFilePath("crtfastmath.o"); -  if (Path == "crtfastmath.o") // Not found. -    return false; +  Path = GetFilePath("crtfastmath.o"); +  return (Path != "crtfastmath.o"); // Not found. +} -  CmdArgs.push_back(Args.MakeArgString(Path)); -  return true; +bool ToolChain::addFastMathRuntimeIfAvailable(const ArgList &Args, +                                              ArgStringList &CmdArgs) const { +  std::string Path; +  if (isFastMathRuntimeAvailable(Args, Path)) { +    CmdArgs.push_back(Args.MakeArgString(Path)); +    return true; +  } + +  return false;  }  SanitizerMask ToolChain::getSupportedSanitizers() const { @@ -955,15 +1000,12 @@ SanitizerMask ToolChain::getSupportedSanitizers() const {    if (getTriple().getArch() == llvm::Triple::x86 ||        getTriple().getArch() == llvm::Triple::x86_64 ||        getTriple().getArch() == llvm::Triple::arm || -      getTriple().getArch() == llvm::Triple::aarch64 ||        getTriple().getArch() == llvm::Triple::wasm32 || -      getTriple().getArch() == llvm::Triple::wasm64) +      getTriple().getArch() == llvm::Triple::wasm64 || getTriple().isAArch64())      Res |= SanitizerKind::CFIICall; -  if (getTriple().getArch() == llvm::Triple::x86_64 || -      getTriple().getArch() == llvm::Triple::aarch64) +  if (getTriple().getArch() == llvm::Triple::x86_64 || getTriple().isAArch64())      Res |= SanitizerKind::ShadowCallStack; -  if (getTriple().getArch() == llvm::Triple::aarch64 || -      getTriple().getArch() == llvm::Triple::aarch64_be) +  if (getTriple().isAArch64())      Res |= SanitizerKind::MemTag;    return Res;  } @@ -971,6 +1013,9 @@ SanitizerMask ToolChain::getSupportedSanitizers() const {  void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,                                     ArgStringList &CC1Args) const {} +void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs, +                                  ArgStringList &CC1Args) const {} +  void ToolChain::AddIAMCUIncludeArgs(const ArgList &DriverArgs,                                      ArgStringList &CC1Args) const {} @@ -1094,3 +1139,86 @@ llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs(    delete DAL;    return nullptr;  } + +// TODO: Currently argument values separated by space e.g. +// -Xclang -mframe-pointer=no cannot be passed by -Xarch_. This should be +// fixed. +void ToolChain::TranslateXarchArgs( +    const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A, +    llvm::opt::DerivedArgList *DAL, +    SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { +  const OptTable &Opts = getDriver().getOpts(); +  unsigned ValuePos = 1; +  if (A->getOption().matches(options::OPT_Xarch_device) || +      A->getOption().matches(options::OPT_Xarch_host)) +    ValuePos = 0; + +  unsigned Index = Args.getBaseArgs().MakeIndex(A->getValue(ValuePos)); +  unsigned Prev = Index; +  std::unique_ptr<llvm::opt::Arg> XarchArg(Opts.ParseOneArg(Args, Index)); + +  // If the argument parsing failed or more than one argument was +  // consumed, the -Xarch_ argument's parameter tried to consume +  // extra arguments. Emit an error and ignore. +  // +  // We also want to disallow any options which would alter the +  // driver behavior; that isn't going to work in our model. We +  // use isDriverOption() as an approximation, although things +  // like -O4 are going to slip through. +  if (!XarchArg || Index > Prev + 1) { +    getDriver().Diag(diag::err_drv_invalid_Xarch_argument_with_args) +        << A->getAsString(Args); +    return; +  } else if (XarchArg->getOption().hasFlag(options::DriverOption)) { +    getDriver().Diag(diag::err_drv_invalid_Xarch_argument_isdriver) +        << A->getAsString(Args); +    return; +  } +  XarchArg->setBaseArg(A); +  A = XarchArg.release(); +  if (!AllocatedArgs) +    DAL->AddSynthesizedArg(A); +  else +    AllocatedArgs->push_back(A); +} + +llvm::opt::DerivedArgList *ToolChain::TranslateXarchArgs( +    const llvm::opt::DerivedArgList &Args, StringRef BoundArch, +    Action::OffloadKind OFK, +    SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const { +  DerivedArgList *DAL = new DerivedArgList(Args.getBaseArgs()); +  bool Modified = false; + +  bool IsGPU = OFK == Action::OFK_Cuda || OFK == Action::OFK_HIP; +  for (Arg *A : Args) { +    bool NeedTrans = false; +    bool Skip = false; +    if (A->getOption().matches(options::OPT_Xarch_device)) { +      NeedTrans = IsGPU; +      Skip = !IsGPU; +    } else if (A->getOption().matches(options::OPT_Xarch_host)) { +      NeedTrans = !IsGPU; +      Skip = IsGPU; +    } else if (A->getOption().matches(options::OPT_Xarch__) && IsGPU) { +      // Do not translate -Xarch_ options for non CUDA/HIP toolchain since +      // they may need special translation. +      // Skip this argument unless the architecture matches BoundArch +      if (BoundArch.empty() || A->getValue(0) != BoundArch) +        Skip = true; +      else +        NeedTrans = true; +    } +    if (NeedTrans || Skip) +      Modified = true; +    if (NeedTrans) +      TranslateXarchArgs(Args, A, DAL, AllocatedArgs); +    if (!Skip) +      DAL->append(A); +  } + +  if (Modified) +    return DAL; + +  delete DAL; +  return nullptr; +} | 
