diff options
Diffstat (limited to 'lib/Driver')
| -rw-r--r-- | lib/Driver/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/Driver/Driver.cpp | 5 | ||||
| -rw-r--r-- | lib/Driver/SanitizerArgs.cpp | 12 | ||||
| -rw-r--r-- | lib/Driver/ToolChain.cpp | 6 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Arch/RISCV.cpp | 2 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Clang.cpp | 211 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Cuda.cpp | 12 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Cuda.h | 1 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Darwin.cpp | 73 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Darwin.h | 15 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Gnu.cpp | 6 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/Linux.cpp | 9 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/RISCV.cpp | 117 | ||||
| -rw-r--r-- | lib/Driver/ToolChains/RISCV.h | 57 | 
14 files changed, 369 insertions, 158 deletions
diff --git a/lib/Driver/CMakeLists.txt b/lib/Driver/CMakeLists.txt index 471ffe0f1b00..2b03c9f7001f 100644 --- a/lib/Driver/CMakeLists.txt +++ b/lib/Driver/CMakeLists.txt @@ -57,6 +57,7 @@ add_clang_library(clangDriver    ToolChains/NetBSD.cpp    ToolChains/OpenBSD.cpp    ToolChains/PS4CPU.cpp +  ToolChains/RISCV.cpp    ToolChains/Solaris.cpp    ToolChains/TCE.cpp    ToolChains/WebAssembly.cpp diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 1dfcacc75ea5..952a716cb6e6 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -37,6 +37,7 @@  #include "ToolChains/NetBSD.h"  #include "ToolChains/OpenBSD.h"  #include "ToolChains/PS4CPU.h" +#include "ToolChains/RISCV.h"  #include "ToolChains/Solaris.h"  #include "ToolChains/TCE.h"  #include "ToolChains/WebAssembly.h" @@ -4399,6 +4400,10 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,        case llvm::Triple::avr:          TC = llvm::make_unique<toolchains::AVRToolChain>(*this, Target, Args);          break; +      case llvm::Triple::riscv32: +      case llvm::Triple::riscv64: +        TC = llvm::make_unique<toolchains::RISCVToolChain>(*this, Target, Args); +        break;        default:          if (Target.getVendor() == llvm::Triple::Myriad)            TC = llvm::make_unique<toolchains::MyriadToolChain>(*this, Target, diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index bdc17d11c92b..5d3e31567ce6 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -27,22 +27,22 @@ using namespace clang::driver;  using namespace llvm::opt;  enum : SanitizerMask { -  NeedsUbsanRt = Undefined | Integer | Nullability | CFI, +  NeedsUbsanRt = Undefined | Integer | ImplicitConversion | Nullability | CFI,    NeedsUbsanCxxRt = Vptr | CFI,    NotAllowedWithTrap = Vptr,    NotAllowedWithMinimalRuntime = Vptr,    RequiresPIE = DataFlow | HWAddress | Scudo,    NeedsUnwindTables = Address | HWAddress | Thread | Memory | DataFlow,    SupportsCoverage = Address | HWAddress | KernelAddress | KernelHWAddress | -                     Memory | Leak | Undefined | Integer | Nullability | -                     DataFlow | Fuzzer | FuzzerNoLink, -  RecoverableByDefault = Undefined | Integer | Nullability, +                     Memory | Leak | Undefined | Integer | ImplicitConversion | +                     Nullability | DataFlow | Fuzzer | FuzzerNoLink, +  RecoverableByDefault = Undefined | Integer | ImplicitConversion | Nullability,    Unrecoverable = Unreachable | Return,    AlwaysRecoverable = KernelAddress | KernelHWAddress,    LegacyFsanitizeRecoverMask = Undefined | Integer,    NeedsLTO = CFI,    TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow | -                      Nullability | LocalBounds | CFI, +                      ImplicitConversion | Nullability | LocalBounds | CFI,    TrappingDefault = CFI,    CFIClasses =        CFIVCall | CFINVCall | CFIMFCall | CFIDerivedCast | CFIUnrelatedCast, @@ -321,7 +321,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,            D.Diag(diag::err_drv_argument_not_allowed_with)                << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);          } else { -          // The vptr sanitizer requires RTTI, but RTTI is disabled (by  +          // The vptr sanitizer requires RTTI, but RTTI is disabled (by            // default). Warn that the vptr sanitizer is being disabled.            D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);          } diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index d62ba1253348..cf3db34688df 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -564,7 +564,7 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,      StringRef Suffix =        tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);      bool IsMProfile = ARM::parseArchProfile(Suffix) == ARM::ProfileKind::M; -    bool ThumbDefault = IsMProfile || (ARM::parseArchVersion(Suffix) == 7 &&  +    bool ThumbDefault = IsMProfile || (ARM::parseArchVersion(Suffix) == 7 &&                                         getTriple().isOSBinFormatMachO());      // FIXME: this is invalid for WindowsCE      if (getTriple().isOSWindows()) @@ -803,8 +803,8 @@ SanitizerMask ToolChain::getSupportedSanitizers() const {    using namespace SanitizerKind;    SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) | -                      CFICastStrict | UnsignedIntegerOverflow | Nullability | -                      LocalBounds; +                      CFICastStrict | UnsignedIntegerOverflow | +                      ImplicitConversion | Nullability | LocalBounds;    if (getTriple().getArch() == llvm::Triple::x86 ||        getTriple().getArch() == llvm::Triple::x86_64 ||        getTriple().getArch() == llvm::Triple::arm || diff --git a/lib/Driver/ToolChains/Arch/RISCV.cpp b/lib/Driver/ToolChains/Arch/RISCV.cpp index 11ce8a1fd769..1321fedcec51 100644 --- a/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -279,7 +279,7 @@ void riscv::getRISCVTargetFeatures(const Driver &D, const ArgList &Args,      if (!getExtensionVersion(D, MArch, std::string(1, Baseline),                               Exts, Major, Minor))        return; -     +      // TODO: Use version number when setting target features      // and consume the underscore '_' that might follow. diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index eaff940a1c2b..8e9c4c6aecb8 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -919,34 +919,46 @@ static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs,    }  } +static bool checkDebugInfoOption(const Arg *A, const ArgList &Args, +                                 const Driver &D, const ToolChain &TC) { +  assert(A && "Expected non-nullptr argument."); +  if (TC.supportsDebugInfoOption(A)) +    return true; +  D.Diag(diag::warn_drv_unsupported_debug_info_opt_for_target) +      << A->getAsString(Args) << TC.getTripleString(); +  return false; +} +  static void RenderDebugInfoCompressionArgs(const ArgList &Args,                                             ArgStringList &CmdArgs, -                                           const Driver &D) { +                                           const Driver &D, +                                           const ToolChain &TC) {    const Arg *A = Args.getLastArg(options::OPT_gz, options::OPT_gz_EQ);    if (!A)      return; +  if (checkDebugInfoOption(A, Args, D, TC)) { +    if (A->getOption().getID() == options::OPT_gz) { +      if (llvm::zlib::isAvailable()) +        CmdArgs.push_back("-compress-debug-sections"); +      else +        D.Diag(diag::warn_debug_compression_unavailable); +      return; +    } -  if (A->getOption().getID() == options::OPT_gz) { -    if (llvm::zlib::isAvailable()) -      CmdArgs.push_back("-compress-debug-sections"); -    else -      D.Diag(diag::warn_debug_compression_unavailable); -    return; -  } - -  StringRef Value = A->getValue(); -  if (Value == "none") { -    CmdArgs.push_back("-compress-debug-sections=none"); -  } else if (Value == "zlib" || Value == "zlib-gnu") { -    if (llvm::zlib::isAvailable()) { -      CmdArgs.push_back( -          Args.MakeArgString("-compress-debug-sections=" + Twine(Value))); +    StringRef Value = A->getValue(); +    if (Value == "none") { +      CmdArgs.push_back("-compress-debug-sections=none"); +    } else if (Value == "zlib" || Value == "zlib-gnu") { +      if (llvm::zlib::isAvailable()) { +        CmdArgs.push_back( +            Args.MakeArgString("-compress-debug-sections=" + Twine(Value))); +      } else { +        D.Diag(diag::warn_debug_compression_unavailable); +      }      } else { -      D.Diag(diag::warn_debug_compression_unavailable); +      D.Diag(diag::err_drv_unsupported_option_argument) +          << A->getOption().getName() << Value;      } -  } else { -    D.Diag(diag::err_drv_unsupported_option_argument) -        << A->getOption().getName() << Value;    }  } @@ -2867,7 +2879,9 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,                                 codegenoptions::DebugInfoKind &DebugInfoKind,                                 const Arg *&SplitDWARFArg) {    if (Args.hasFlag(options::OPT_fdebug_info_for_profiling, -                   options::OPT_fno_debug_info_for_profiling, false)) +                   options::OPT_fno_debug_info_for_profiling, false) && +      checkDebugInfoOption( +          Args.getLastArg(options::OPT_fdebug_info_for_profiling), Args, D, TC))      CmdArgs.push_back("-fdebug-info-for-profiling");    // The 'g' groups options involve a somewhat intricate sequence of decisions @@ -2890,29 +2904,38 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,    SplitDWARFArg = Args.getLastArg(options::OPT_gsplit_dwarf); +  if (SplitDWARFArg && !checkDebugInfoOption(SplitDWARFArg, Args, D, TC)) { +    SplitDWARFArg = nullptr; +    SplitDWARFInlining = false; +  } +    if (const Arg *A = Args.getLastArg(options::OPT_g_Group)) { -    // If the last option explicitly specified a debug-info level, use it. -    if (A->getOption().matches(options::OPT_gN_Group)) { -      DebugInfoKind = DebugLevelToInfoKind(*A); -      // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses. -      // But -gsplit-dwarf is not a g_group option, hence we have to check the -      // order explicitly. If -gsplit-dwarf wins, we fix DebugInfoKind later. -      // This gets a bit more complicated if you've disabled inline info in the -      // skeleton CUs (SplitDWARFInlining) - then there's value in composing -      // split-dwarf and line-tables-only, so let those compose naturally in -      // that case. -      // And if you just turned off debug info, (-gsplit-dwarf -g0) - do that. -      if (SplitDWARFArg) { -        if (A->getIndex() > SplitDWARFArg->getIndex()) { -          if (DebugInfoKind == codegenoptions::NoDebugInfo || -              (DebugInfoKind == codegenoptions::DebugLineTablesOnly && -               SplitDWARFInlining)) -            SplitDWARFArg = nullptr; -        } else if (SplitDWARFInlining) -          DebugInfoKind = codegenoptions::NoDebugInfo; +    if (checkDebugInfoOption(A, Args, D, TC)) { +      // If the last option explicitly specified a debug-info level, use it. +      if (A->getOption().matches(options::OPT_gN_Group)) { +        DebugInfoKind = DebugLevelToInfoKind(*A); +        // If you say "-gsplit-dwarf -gline-tables-only", -gsplit-dwarf loses. +        // But -gsplit-dwarf is not a g_group option, hence we have to check the +        // order explicitly. If -gsplit-dwarf wins, we fix DebugInfoKind later. +        // This gets a bit more complicated if you've disabled inline info in +        // the skeleton CUs (SplitDWARFInlining) - then there's value in +        // composing split-dwarf and line-tables-only, so let those compose +        // naturally in that case. And if you just turned off debug info, +        // (-gsplit-dwarf -g0) - do that. +        if (SplitDWARFArg) { +          if (A->getIndex() > SplitDWARFArg->getIndex()) { +            if (DebugInfoKind == codegenoptions::NoDebugInfo || +                (DebugInfoKind == codegenoptions::DebugLineTablesOnly && +                 SplitDWARFInlining)) +              SplitDWARFArg = nullptr; +          } else if (SplitDWARFInlining) +            DebugInfoKind = codegenoptions::NoDebugInfo; +        } +      } else { +        // For any other 'g' option, use Limited. +        DebugInfoKind = codegenoptions::LimitedDebugInfo;        }      } else { -      // For any other 'g' option, use Limited.        DebugInfoKind = codegenoptions::LimitedDebugInfo;      }    } @@ -2920,39 +2943,50 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,    // If a debugger tuning argument appeared, remember it.    if (const Arg *A =            Args.getLastArg(options::OPT_gTune_Group, options::OPT_ggdbN_Group)) { -    if (A->getOption().matches(options::OPT_glldb)) -      DebuggerTuning = llvm::DebuggerKind::LLDB; -    else if (A->getOption().matches(options::OPT_gsce)) -      DebuggerTuning = llvm::DebuggerKind::SCE; -    else -      DebuggerTuning = llvm::DebuggerKind::GDB; +    if (checkDebugInfoOption(A, Args, D, TC)) { +      if (A->getOption().matches(options::OPT_glldb)) +        DebuggerTuning = llvm::DebuggerKind::LLDB; +      else if (A->getOption().matches(options::OPT_gsce)) +        DebuggerTuning = llvm::DebuggerKind::SCE; +      else +        DebuggerTuning = llvm::DebuggerKind::GDB; +    }    }    // If a -gdwarf argument appeared, remember it.    if (const Arg *A =            Args.getLastArg(options::OPT_gdwarf_2, options::OPT_gdwarf_3,                            options::OPT_gdwarf_4, options::OPT_gdwarf_5)) -    DWARFVersion = DwarfVersionNum(A->getSpelling()); +    if (checkDebugInfoOption(A, Args, D, TC)) +      DWARFVersion = DwarfVersionNum(A->getSpelling());    // Forward -gcodeview. EmitCodeView might have been set by CL-compatibility    // argument parsing.    if (EmitCodeView) { -    // DWARFVersion remains at 0 if no explicit choice was made. -    CmdArgs.push_back("-gcodeview"); -  } else if (DWARFVersion == 0 && -             DebugInfoKind != codegenoptions::NoDebugInfo) { -    DWARFVersion = TC.GetDefaultDwarfVersion(); +    if (const Arg *A = Args.getLastArg(options::OPT_gcodeview)) { +      EmitCodeView = checkDebugInfoOption(A, Args, D, TC); +      if (EmitCodeView) { +        // DWARFVersion remains at 0 if no explicit choice was made. +        CmdArgs.push_back("-gcodeview"); +      } +    }    } +  if (!EmitCodeView && DWARFVersion == 0 && +      DebugInfoKind != codegenoptions::NoDebugInfo) +    DWARFVersion = TC.GetDefaultDwarfVersion(); +    // We ignore flag -gstrict-dwarf for now.    // And we handle flag -grecord-gcc-switches later with DWARFDebugFlags.    Args.ClaimAllArgs(options::OPT_g_flags_Group); -  // Column info is included by default for everything except SCE and CodeView. -  // Clang doesn't track end columns, just starting columns, which, in theory, -  // is fine for CodeView (and PDB).  In practice, however, the Microsoft -  // debuggers don't handle missing end columns well, so it's better not to -  // include any column info. +  // Column info is included by default for everything except SCE and +  // CodeView. Clang doesn't track end columns, just starting columns, which, +  // in theory, is fine for CodeView (and PDB).  In practice, however, the +  // Microsoft debuggers don't handle missing end columns well, so it's better +  // not to include any column info. +  if (const Arg *A = Args.getLastArg(options::OPT_gcolumn_info)) +    (void)checkDebugInfoOption(A, Args, D, TC);    if (Args.hasFlag(options::OPT_gcolumn_info, options::OPT_gno_column_info,                     /*Default=*/!EmitCodeView &&                         DebuggerTuning != llvm::DebuggerKind::SCE)) @@ -2960,12 +2994,14 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,    // FIXME: Move backend command line options to the module.    // If -gline-tables-only is the last option it wins. -  if (DebugInfoKind != codegenoptions::DebugLineTablesOnly && -      Args.hasArg(options::OPT_gmodules)) { -    DebugInfoKind = codegenoptions::LimitedDebugInfo; -    CmdArgs.push_back("-dwarf-ext-refs"); -    CmdArgs.push_back("-fmodule-format=obj"); -  } +  if (const Arg *A = Args.getLastArg(options::OPT_gmodules)) +    if (checkDebugInfoOption(A, Args, D, TC)) { +      if (DebugInfoKind != codegenoptions::DebugLineTablesOnly) { +        DebugInfoKind = codegenoptions::LimitedDebugInfo; +        CmdArgs.push_back("-dwarf-ext-refs"); +        CmdArgs.push_back("-fmodule-format=obj"); +      } +    }    // -gsplit-dwarf should turn on -g and enable the backend dwarf    // splitting and extraction. @@ -2989,19 +3025,23 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,    bool NeedFullDebug = Args.hasFlag(options::OPT_fstandalone_debug,                                      options::OPT_fno_standalone_debug,                                      TC.GetDefaultStandaloneDebug()); +  if (const Arg *A = Args.getLastArg(options::OPT_fstandalone_debug)) +    (void)checkDebugInfoOption(A, Args, D, TC);    if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug)      DebugInfoKind = codegenoptions::FullDebugInfo; -  if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source, false)) { +  if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source, +                   false)) {      // Source embedding is a vendor extension to DWARF v5. By now we have      // checked if a DWARF version was stated explicitly, and have otherwise -    // fallen back to the target default, so if this is still not at least 5 we -    // emit an error. +    // fallen back to the target default, so if this is still not at least 5 +    // we emit an error. +    const Arg *A = Args.getLastArg(options::OPT_gembed_source);      if (DWARFVersion < 5)        D.Diag(diag::err_drv_argument_only_allowed_with) -          << Args.getLastArg(options::OPT_gembed_source)->getAsString(Args) -          << "-gdwarf-5"; -    CmdArgs.push_back("-gembed-source"); +          << A->getAsString(Args) << "-gdwarf-5"; +    else if (checkDebugInfoOption(A, Args, D, TC)) +      CmdArgs.push_back("-gembed-source");    }    RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DWARFVersion, @@ -3010,31 +3050,41 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,    // -fdebug-macro turns on macro debug info generation.    if (Args.hasFlag(options::OPT_fdebug_macro, options::OPT_fno_debug_macro,                     false)) -    CmdArgs.push_back("-debug-info-macro"); +    if (checkDebugInfoOption(Args.getLastArg(options::OPT_fdebug_macro), Args, +                             D, TC)) +      CmdArgs.push_back("-debug-info-macro");    // -ggnu-pubnames turns on gnu style pubnames in the backend.    if (Args.hasFlag(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames,                     false)) -    CmdArgs.push_back("-ggnu-pubnames"); +    if (checkDebugInfoOption(Args.getLastArg(options::OPT_ggnu_pubnames), Args, +                             D, TC)) +      CmdArgs.push_back("-ggnu-pubnames");    // -gdwarf-aranges turns on the emission of the aranges section in the    // backend.    // Always enabled for SCE tuning. -  if (Args.hasArg(options::OPT_gdwarf_aranges) || -      DebuggerTuning == llvm::DebuggerKind::SCE) { +  bool NeedAranges = DebuggerTuning == llvm::DebuggerKind::SCE; +  if (const Arg *A = Args.getLastArg(options::OPT_gdwarf_aranges)) +    NeedAranges = checkDebugInfoOption(A, Args, D, TC) || NeedAranges; +  if (NeedAranges) {      CmdArgs.push_back("-mllvm");      CmdArgs.push_back("-generate-arange-section");    }    if (Args.hasFlag(options::OPT_fdebug_types_section,                     options::OPT_fno_debug_types_section, false)) { -    if (!T.isOSBinFormatELF()) +    if (!T.isOSBinFormatELF()) {        D.Diag(diag::err_drv_unsupported_opt_for_target)            << Args.getLastArg(options::OPT_fdebug_types_section)                   ->getAsString(Args)            << T.getTriple(); -    CmdArgs.push_back("-mllvm"); -    CmdArgs.push_back("-generate-type-units"); +    } else if (checkDebugInfoOption( +                   Args.getLastArg(options::OPT_fdebug_types_section), Args, D, +                   TC)) { +      CmdArgs.push_back("-mllvm"); +      CmdArgs.push_back("-generate-type-units"); +    }    }    // Decide how to render forward declarations of template instantiations. @@ -3042,11 +3092,12 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,    if (DebuggerTuning == llvm::DebuggerKind::SCE)      CmdArgs.push_back("-debug-forward-template-params"); -  // Do we need to explicitly import anonymous namespaces into the parent scope? +  // Do we need to explicitly import anonymous namespaces into the parent +  // scope?    if (DebuggerTuning == llvm::DebuggerKind::SCE)      CmdArgs.push_back("-dwarf-explicit-import"); -  RenderDebugInfoCompressionArgs(Args, CmdArgs, D); +  RenderDebugInfoCompressionArgs(Args, CmdArgs, D, TC);  }  void Clang::ConstructJob(Compilation &C, const JobAction &JA, @@ -5388,7 +5439,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,    }    RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DwarfVersion,                            llvm::DebuggerKind::Default); -  RenderDebugInfoCompressionArgs(Args, CmdArgs, D); +  RenderDebugInfoCompressionArgs(Args, CmdArgs, D, getToolChain());    // Handle -fPIC et al -- the relocation-model affects the assembler diff --git a/lib/Driver/ToolChains/Cuda.cpp b/lib/Driver/ToolChains/Cuda.cpp index d17c4c39532a..7fb4ae4ea9cf 100644 --- a/lib/Driver/ToolChains/Cuda.cpp +++ b/lib/Driver/ToolChains/Cuda.cpp @@ -679,6 +679,18 @@ void CudaToolChain::addClangTargetOptions(    }  } +bool CudaToolChain::supportsDebugInfoOption(const llvm::opt::Arg *A) const { +  const Option &O = A->getOption(); +  return (O.matches(options::OPT_gN_Group) && +          !O.matches(options::OPT_gmodules)) || +         O.matches(options::OPT_g_Flag) || +         O.matches(options::OPT_ggdbN_Group) || O.matches(options::OPT_ggdb) || +         O.matches(options::OPT_gdwarf) || O.matches(options::OPT_gdwarf_2) || +         O.matches(options::OPT_gdwarf_3) || O.matches(options::OPT_gdwarf_4) || +         O.matches(options::OPT_gdwarf_5) || +         O.matches(options::OPT_gcolumn_info); +} +  void CudaToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,                                         ArgStringList &CC1Args) const {    // Check our CUDA version if we're going to include the CUDA headers. diff --git a/lib/Driver/ToolChains/Cuda.h b/lib/Driver/ToolChains/Cuda.h index 99d5a4a628ce..01580cb66920 100644 --- a/lib/Driver/ToolChains/Cuda.h +++ b/lib/Driver/ToolChains/Cuda.h @@ -158,6 +158,7 @@ public:    bool isPIEDefault() const override { return false; }    bool isPICDefaultForced() const override { return false; }    bool SupportsProfiling() const override { return false; } +  bool supportsDebugInfoOption(const llvm::opt::Arg *A) const override;    bool IsMathErrnoDefault() const override { return false; }    void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp index 95ec8d64c2c7..9205dd52de0b 100644 --- a/lib/Driver/ToolChains/Darwin.cpp +++ b/lib/Driver/ToolChains/Darwin.cpp @@ -916,26 +916,13 @@ unsigned DarwinClang::GetDefaultDwarfVersion() const {    return 4;  } -SmallString<128> MachO::runtimeLibDir(bool IsEmbedded) const { -  SmallString<128> Dir(getDriver().ResourceDir); -  llvm::sys::path::append( -      Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin"); -  return Dir; -} - -std::string Darwin::getFileNameForSanitizerLib(StringRef SanitizerName, -                                              bool Shared) const { -  return (Twine("libclang_rt.") + SanitizerName + "_" + -                      getOSLibraryNameSuffix() + -                      (Shared ? "_dynamic.dylib" : ".a")).str(); - -} -  void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,                                StringRef DarwinLibName,                                RuntimeLinkOptions Opts) const { +  SmallString<128> Dir(getDriver().ResourceDir); +  llvm::sys::path::append( +      Dir, "lib", (Opts & RLO_IsEmbedded) ? "macho_embedded" : "darwin"); -  SmallString<128> Dir = runtimeLibDir(Opts & RLO_IsEmbedded);    SmallString<128> P(Dir);    llvm::sys::path::append(P, DarwinLibName); @@ -1055,9 +1042,12 @@ void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,                                            StringRef Sanitizer,                                            bool Shared) const {    auto RLO = RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U)); -  std::string SanitizerRelFilename = -      getFileNameForSanitizerLib(Sanitizer, Shared); -  AddLinkRuntimeLib(Args, CmdArgs, SanitizerRelFilename, RLO); +  AddLinkRuntimeLib(Args, CmdArgs, +                    (Twine("libclang_rt.") + Sanitizer + "_" + +                     getOSLibraryNameSuffix() + +                     (Shared ? "_dynamic.dylib" : ".a")) +                        .str(), +                    RLO);  }  ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType( @@ -2295,43 +2285,24 @@ void Darwin::CheckObjCARC() const {  SanitizerMask Darwin::getSupportedSanitizers() const {    const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;    SanitizerMask Res = ToolChain::getSupportedSanitizers(); - -  { -    using namespace SanitizerKind; -    assert(!(Res & (Address | Leak | Fuzzer | FuzzerNoLink | Thread)) && -           "Sanitizer is already registered as supported"); -  } - -  if (sanitizerRuntimeExists("asan")) -    Res |= SanitizerKind::Address; -  if (sanitizerRuntimeExists("lsan")) -    Res |= SanitizerKind::Leak; -  if (sanitizerRuntimeExists("fuzzer", /*Shared=*/false)) { -    Res |= SanitizerKind::Fuzzer; -    Res |= SanitizerKind::FuzzerNoLink; -  } +  Res |= SanitizerKind::Address; +  Res |= SanitizerKind::Leak; +  Res |= SanitizerKind::Fuzzer; +  Res |= SanitizerKind::FuzzerNoLink;    Res |= SanitizerKind::Function; -  if (isTargetMacOS() && !isMacosxVersionLT(10, 9)) -    Res |= SanitizerKind::Vptr; -  if (isTargetMacOS()) +  if (isTargetMacOS()) { +    if (!isMacosxVersionLT(10, 9)) +      Res |= SanitizerKind::Vptr;      Res |= SanitizerKind::SafeStack; - -  if (sanitizerRuntimeExists("tsan") && IsX86_64 && -      (isTargetMacOS() || isTargetIOSSimulator() || isTargetTvOSSimulator())) -    Res |= SanitizerKind::Thread; - +    if (IsX86_64) +      Res |= SanitizerKind::Thread; +  } else if (isTargetIOSSimulator() || isTargetTvOSSimulator()) { +    if (IsX86_64) +      Res |= SanitizerKind::Thread; +  }    return Res;  }  void Darwin::printVerboseInfo(raw_ostream &OS) const {    CudaInstallation.print(OS);  } - -bool Darwin::sanitizerRuntimeExists(StringRef SanitizerName, -                                    bool Shared) const { -    std::string RelName = getFileNameForSanitizerLib(SanitizerName, Shared); -    SmallString<128> Dir = runtimeLibDir(); -    SmallString<128> AbsName(Dir); -    llvm::sys::path::append(AbsName, RelName); -    return getVFS().exists(AbsName); -} diff --git a/lib/Driver/ToolChains/Darwin.h b/lib/Driver/ToolChains/Darwin.h index eee6e966718b..87d553bd7e0b 100644 --- a/lib/Driver/ToolChains/Darwin.h +++ b/lib/Driver/ToolChains/Darwin.h @@ -130,9 +130,6 @@ protected:    Tool *buildLinker() const override;    Tool *getTool(Action::ActionClass AC) const override; -  /// \return Directory to find the runtime library in. -  SmallString<128> runtimeLibDir(bool IsEmbedded=false) const; -  private:    mutable std::unique_ptr<tools::darwin::Lipo> Lipo;    mutable std::unique_ptr<tools::darwin::Dsymutil> Dsymutil; @@ -254,6 +251,7 @@ public:    GetExceptionModel(const llvm::opt::ArgList &Args) const override {      return llvm::ExceptionHandling::None;    } +    /// }  }; @@ -422,11 +420,6 @@ protected:    StringRef getPlatformFamily() const;    StringRef getOSLibraryNameSuffix() const; -  /// \return Relative path to the filename for the library -  /// containing the sanitizer {@code SanitizerName}. -  std::string getFileNameForSanitizerLib(StringRef SanitizerName, -                                         bool Shared = true) const; -  public:    static StringRef getSDKName(StringRef isysroot); @@ -480,12 +473,6 @@ public:    SanitizerMask getSupportedSanitizers() const override;    void printVerboseInfo(raw_ostream &OS) const override; - -private: -  /// \return Whether the runtime corresponding to the given -  /// sanitizer exists in the toolchain. -  bool sanitizerRuntimeExists(StringRef SanitizerName, -                              bool Shared = true) const;  };  /// DarwinClang - The Darwin toolchain used by Clang. diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp index 2c83598f3d77..3755673250b2 100644 --- a/lib/Driver/ToolChains/Gnu.cpp +++ b/lib/Driver/ToolChains/Gnu.cpp @@ -1877,7 +1877,8 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(    static const char *const RISCV32LibDirs[] = {"/lib", "/lib32"};    static const char *const RISCVTriples[] = {"riscv32-unknown-linux-gnu", -                                             "riscv64-unknown-linux-gnu"}; +                                             "riscv64-unknown-linux-gnu", +                                             "riscv32-unknown-elf"};    static const char *const SPARCv8LibDirs[] = {"/lib32", "/lib"};    static const char *const SPARCv8Triples[] = {"sparc-linux-gnu", @@ -2188,7 +2189,8 @@ void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(        // this on Freescale triples, though, since some systems put a *lot* of        // files in that location, not just GCC installation data.        {CandidateTriple.str(), "..", -       TargetTriple.getVendor() == llvm::Triple::Freescale}, +       TargetTriple.getVendor() == llvm::Triple::Freescale || +       TargetTriple.getVendor() == llvm::Triple::OpenEmbedded},        // Natively multiarch systems sometimes put the GCC triple-specific        // directory within their multiarch lib directory, resulting in the diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp index d27f994d32ab..f8f36239180c 100644 --- a/lib/Driver/ToolChains/Linux.cpp +++ b/lib/Driver/ToolChains/Linux.cpp @@ -376,7 +376,14 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)    }    addPathIfExists(D, SysRoot + "/usr/lib/" + MultiarchTriple, Paths); -  addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths); +  // 64-bit OpenEmbedded sysroots may not have a /usr/lib dir. So they cannot +  // find /usr/lib64 as it is referenced as /usr/lib/../lib64. So we handle +  // this here. +  if (Triple.getVendor() == llvm::Triple::OpenEmbedded && +      Triple.isArch64Bit()) +    addPathIfExists(D, SysRoot + "/usr/" + OSLibDir, Paths); +  else +    addPathIfExists(D, SysRoot + "/usr/lib/../" + OSLibDir, Paths);    if (IsRISCV) {      StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple);      addPathIfExists(D, SysRoot + "/" + OSLibDir + "/" + ABIName, Paths); diff --git a/lib/Driver/ToolChains/RISCV.cpp b/lib/Driver/ToolChains/RISCV.cpp new file mode 100644 index 000000000000..31996fc588f1 --- /dev/null +++ b/lib/Driver/ToolChains/RISCV.cpp @@ -0,0 +1,117 @@ +//===--- RISCV.cpp - RISCV ToolChain Implementations ------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RISCV.h" +#include "CommonArgs.h" +#include "InputInfo.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +/// RISCV Toolchain +RISCVToolChain::RISCVToolChain(const Driver &D, const llvm::Triple &Triple, +                               const ArgList &Args) +    : Generic_ELF(D, Triple, Args) { +  GCCInstallation.init(Triple, Args); +  getFilePaths().push_back(D.SysRoot + "/lib"); +  if (GCCInstallation.isValid()) { +    getFilePaths().push_back(GCCInstallation.getInstallPath().str()); +    getProgramPaths().push_back( +        (GCCInstallation.getParentLibPath() + "/../bin").str()); +  } +} + +Tool *RISCVToolChain::buildLinker() const { +  return new tools::RISCV::Linker(*this); +} + +void RISCVToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, +                                               ArgStringList &CC1Args) const { +  if (DriverArgs.hasArg(options::OPT_nostdinc)) +    return; + +  if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) { +    SmallString<128> Dir(getDriver().SysRoot); +    llvm::sys::path::append(Dir, "include"); +    addSystemInclude(DriverArgs, CC1Args, Dir.str()); +  } +} + +void RISCVToolChain::addLibStdCxxIncludePaths( +    const llvm::opt::ArgList &DriverArgs, +    llvm::opt::ArgStringList &CC1Args) const { +  StringRef LibDir = GCCInstallation.getParentLibPath(); +  const GCCVersion &Version = GCCInstallation.getVersion(); +  StringRef TripleStr = GCCInstallation.getTriple().str(); +  const Multilib &Multilib = GCCInstallation.getMultilib(); +  addLibStdCXXIncludePaths( +      LibDir.str() + "/../" + TripleStr.str() + "/include/c++/" + Version.Text, +      "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args); +} + +void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, +                                 const InputInfo &Output, +                                 const InputInfoList &Inputs, +                                 const ArgList &Args, +                                 const char *LinkingOutput) const { +  const ToolChain &ToolChain = getToolChain(); +  const Driver &D = ToolChain.getDriver(); +  ArgStringList CmdArgs; + +  if (!D.SysRoot.empty()) +    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + +  std::string Linker = getToolChain().GetProgramPath(getShortName()); + +  bool WantCRTs = +      !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles); + +  if (WantCRTs) { +    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); +    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); +  } + +  Args.AddAllArgs(CmdArgs, options::OPT_L); +  ToolChain.AddFilePathLibArgs(Args, CmdArgs); +  Args.AddAllArgs(CmdArgs, +                  {options::OPT_T_Group, options::OPT_e, options::OPT_s, +                   options::OPT_t, options::OPT_Z_Flag, options::OPT_r}); + +  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); + +  // TODO: add C++ includes and libs if compiling C++. + +  if (!Args.hasArg(options::OPT_nostdlib) && +      !Args.hasArg(options::OPT_nodefaultlibs)) { +    if (ToolChain.ShouldLinkCXXStdlib(Args)) +      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); +    CmdArgs.push_back("--start-group"); +    CmdArgs.push_back("-lc"); +    CmdArgs.push_back("-lgloss"); +    CmdArgs.push_back("--end-group"); +    CmdArgs.push_back("-lgcc"); +  } + +  if (WantCRTs) +    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); + +  CmdArgs.push_back("-o"); +  CmdArgs.push_back(Output.getFilename()); +  C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker), +                                          CmdArgs, Inputs)); +} +// RISCV tools end. diff --git a/lib/Driver/ToolChains/RISCV.h b/lib/Driver/ToolChains/RISCV.h new file mode 100644 index 000000000000..6f59d84020d8 --- /dev/null +++ b/lib/Driver/ToolChains/RISCV.h @@ -0,0 +1,57 @@ +//===--- RISCV.h - RISCV ToolChain Implementations --------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_RISCV_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_RISCV_H + +#include "Gnu.h" +#include "clang/Driver/ToolChain.h" + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY RISCVToolChain : public Generic_ELF { +public: +  RISCVToolChain(const Driver &D, const llvm::Triple &Triple, +                 const llvm::opt::ArgList &Args); + +  bool IsIntegratedAssemblerDefault() const override { return true; } +  void +  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, +                            llvm::opt::ArgStringList &CC1Args) const override; +  void +  addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, +                           llvm::opt::ArgStringList &CC1Args) const override; + +protected: +  Tool *buildLinker() const override; +}; + +} // end namespace toolchains + +namespace tools { +namespace RISCV { +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: +  Linker(const ToolChain &TC) : GnuTool("RISCV::Linker", "ld", TC) {} +  bool hasIntegratedCPP() const override { return false; } +  bool isLinkJob() const override { return true; } +  void ConstructJob(Compilation &C, const JobAction &JA, +                    const InputInfo &Output, const InputInfoList &Inputs, +                    const llvm::opt::ArgList &TCArgs, +                    const char *LinkingOutput) const override; +}; +} // end namespace RISCV +} // end namespace tools + +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_RISCV_H  | 
