diff options
Diffstat (limited to 'lib/Driver')
| -rw-r--r-- | lib/Driver/MinGWToolChain.cpp | 201 | ||||
| -rw-r--r-- | lib/Driver/ToolChain.cpp | 11 | ||||
| -rw-r--r-- | lib/Driver/ToolChains.h | 4 | ||||
| -rw-r--r-- | lib/Driver/Tools.cpp | 276 | ||||
| -rw-r--r-- | lib/Driver/Tools.h | 6 | 
5 files changed, 340 insertions, 158 deletions
diff --git a/lib/Driver/MinGWToolChain.cpp b/lib/Driver/MinGWToolChain.cpp index 197c19e91413..938440b08f60 100644 --- a/lib/Driver/MinGWToolChain.cpp +++ b/lib/Driver/MinGWToolChain.cpp @@ -20,12 +20,54 @@ using namespace clang::driver::toolchains;  using namespace clang;  using namespace llvm::opt; +namespace { +// Simplified from Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple. +bool findGccVersion(StringRef LibDir, std::string &GccLibDir, +                    std::string &Ver) { +  Generic_GCC::GCCVersion Version = Generic_GCC::GCCVersion::Parse("0.0.0"); +  std::error_code EC; +  for (llvm::sys::fs::directory_iterator LI(LibDir, EC), LE; !EC && LI != LE; +       LI = LI.increment(EC)) { +    StringRef VersionText = llvm::sys::path::filename(LI->path()); +    Generic_GCC::GCCVersion CandidateVersion = +        Generic_GCC::GCCVersion::Parse(VersionText); +    if (CandidateVersion.Major == -1) +      continue; +    if (CandidateVersion <= Version) +      continue; +    Ver = VersionText; +    GccLibDir = LI->path(); +  } +  return Ver.size(); +} +} + +void MinGW::findGccLibDir() { +  llvm::SmallVector<llvm::SmallString<32>, 2> Archs; +  Archs.emplace_back(getTriple().getArchName()); +  Archs[0] += "-w64-mingw32"; +  Archs.emplace_back("mingw32"); +  Arch = Archs[0].str(); +  // lib: Arch Linux, Ubuntu, Windows +  // lib64: openSUSE Linux +  for (StringRef CandidateLib : {"lib", "lib64"}) { +    for (StringRef CandidateArch : Archs) { +      llvm::SmallString<1024> LibDir(Base); +      llvm::sys::path::append(LibDir, CandidateLib, "gcc", CandidateArch); +      if (findGccVersion(LibDir, GccLibDir, Ver)) { +        Arch = CandidateArch; +        return; +      } +    } +  } +} +  MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)      : ToolChain(D, Triple, Args) {    getProgramPaths().push_back(getDriver().getInstalledDir()); -  llvm::SmallString<1024> LibDir; - +// In Windows there aren't any standard install locations, we search +// for gcc on the PATH. In Linux the base is always /usr.  #ifdef LLVM_ON_WIN32    if (getDriver().SysRoot.size())      Base = getDriver().SysRoot; @@ -35,45 +77,23 @@ MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)          llvm::sys::path::parent_path(GPPName.get()));    else      Base = llvm::sys::path::parent_path(getDriver().getInstalledDir()); -  Base += llvm::sys::path::get_separator(); -  LibDir = Base; -  llvm::sys::path::append(LibDir, "lib", "gcc");  #else    if (getDriver().SysRoot.size())      Base = getDriver().SysRoot;    else -    Base = "/usr/"; -  LibDir = Base; -  llvm::sys::path::append(LibDir, "lib64", "gcc"); +    Base = "/usr";  #endif -  LibDir += llvm::sys::path::get_separator(); - -  // First look for mingw-w64. -  Arch = getTriple().getArchName(); -  Arch += "-w64-mingw32"; -  std::error_code EC; -  llvm::sys::fs::directory_iterator MingW64Entry(LibDir + Arch, EC); -  if (!EC) { -    GccLibDir = MingW64Entry->path(); -    Ver = llvm::sys::path::filename(GccLibDir); -  } else { -    // If mingw-w64 not found, try looking for mingw.org. -    Arch = "mingw32"; -    llvm::sys::fs::directory_iterator MingwOrgEntry(LibDir + Arch, EC); -    if (!EC) -      GccLibDir = MingwOrgEntry->path(); -  } -  Arch += llvm::sys::path::get_separator(); +  Base += llvm::sys::path::get_separator(); +  findGccLibDir();    // GccLibDir must precede Base/lib so that the    // correct crtbegin.o ,cetend.o would be found.    getFilePaths().push_back(GccLibDir); +  getFilePaths().push_back( +      (Base + Arch + llvm::sys::path::get_separator() + "lib").str());    getFilePaths().push_back(Base + "lib"); -  getFilePaths().push_back(Base + Arch + "lib"); -#ifdef LLVM_ON_UNIX -  // For openSUSE. -  getFilePaths().push_back(Base + Arch + "sys-root/mingw/lib"); -#endif +  // openSUSE +  getFilePaths().push_back(Base + Arch + "/sys-root/mingw/lib");  }  bool MinGW::IsIntegratedAssemblerDefault() const { return true; } @@ -115,6 +135,58 @@ bool MinGW::UseSEHExceptions() const {    return getArch() == llvm::Triple::x86_64;  } +// Include directories for various hosts: + +// Windows, mingw.org +// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++ +// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\mingw32 +// c:\mingw\lib\gcc\mingw32\4.8.1\include\c++\backward +// c:\mingw\lib\gcc\mingw32\4.8.1\include +// c:\mingw\include +// c:\mingw\lib\gcc\mingw32\4.8.1\include-fixed +// c:\mingw\mingw32\include + +// Windows, mingw-w64 mingw-builds +// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include +// c:\mingw32\lib\gcc\i686-w64-mingw32\4.9.1\include-fixed +// c:\mingw32\i686-w64-mingw32\include +// c:\mingw32\i686-w64-mingw32\include\c++ +// c:\mingw32\i686-w64-mingw32\include\c++\i686-w64-mingw32 +// c:\mingw32\i686-w64-mingw32\include\c++\backward + +// Windows, mingw-w64 msys2 +// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include +// c:\msys64\mingw32\include +// c:\msys64\mingw32\lib\gcc\i686-w64-mingw32\4.9.2\include-fixed +// c:\msys64\mingw32\i686-w64-mingw32\include +// c:\msys64\mingw32\include\c++\4.9.2 +// c:\msys64\mingw32\include\c++\4.9.2\i686-w64-mingw32 +// c:\msys64\mingw32\include\c++\4.9.2\backward + +// openSUSE +// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++ +// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/x86_64-w64-mingw32 +// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include/c++/backward +// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include +// /usr/lib64/gcc/x86_64-w64-mingw32/5.1.0/include-fixed +// /usr/x86_64-w64-mingw32/sys-root/mingw/include + +// Arch Linux +// /usr/i686-w64-mingw32/include/c++/5.1.0 +// /usr/i686-w64-mingw32/include/c++/5.1.0/i686-w64-mingw32 +// /usr/i686-w64-mingw32/include/c++/5.1.0/backward +// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include +// /usr/lib/gcc/i686-w64-mingw32/5.1.0/include-fixed +// /usr/i686-w64-mingw32/include + +// Ubuntu +// /usr/include/c++/4.8 +// /usr/include/c++/4.8/x86_64-w64-mingw32 +// /usr/include/c++/4.8/backward +// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include +// /usr/lib/gcc/x86_64-w64-mingw32/4.8/include-fixed +// /usr/x86_64-w64-mingw32/include +  void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,                                        ArgStringList &CC1Args) const {    if (DriverArgs.hasArg(options::OPT_nostdinc)) @@ -129,17 +201,18 @@ void MinGW::AddClangSystemIncludeArgs(const ArgList &DriverArgs,    if (DriverArgs.hasArg(options::OPT_nostdlibinc))      return; -  llvm::SmallString<1024> IncludeDir(GccLibDir); -  llvm::sys::path::append(IncludeDir, "include"); -  addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); -  IncludeDir += "-fixed"; -#ifdef LLVM_ON_UNIX -  // For openSUSE. +  if (GetRuntimeLibType(DriverArgs) == ToolChain::RLT_Libgcc) { +    llvm::SmallString<1024> IncludeDir(GccLibDir); +    llvm::sys::path::append(IncludeDir, "include"); +    addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); +    IncludeDir += "-fixed"; +    // openSUSE +    addSystemInclude(DriverArgs, CC1Args, +                     Base + Arch + "/sys-root/mingw/include"); +    addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); +  }    addSystemInclude(DriverArgs, CC1Args, -                   "/usr/x86_64-w64-mingw32/sys-root/mingw/include"); -#endif -  addSystemInclude(DriverArgs, CC1Args, IncludeDir.c_str()); -  addSystemInclude(DriverArgs, CC1Args, Base + Arch + "include"); +                   Base + Arch + llvm::sys::path::get_separator() + "include");    addSystemInclude(DriverArgs, CC1Args, Base + "include");  } @@ -149,27 +222,29 @@ void MinGW::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,        DriverArgs.hasArg(options::OPT_nostdincxx))      return; -  // C++ includes may be found in several locations depending on distribution. -  // Windows -  // ------- -  // mingw-w64 mingw-builds: $sysroot/i686-w64-mingw32/include/c++. -  // mingw-w64 msys2:        $sysroot/include/c++/4.9.2 -  // mingw.org:              GccLibDir/include/c++ -  // -  // Linux -  // ----- -  // openSUSE:               GccLibDir/include/c++ -  llvm::SmallVector<llvm::SmallString<1024>, 3> CppIncludeBases; -  CppIncludeBases.emplace_back(Base); -  llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++"); -  CppIncludeBases.emplace_back(Base); -  llvm::sys::path::append(CppIncludeBases[1], "include", "c++", Ver); -  CppIncludeBases.emplace_back(GccLibDir); -  llvm::sys::path::append(CppIncludeBases[2], "include", "c++"); -  for (auto &CppIncludeBase : CppIncludeBases) { -    CppIncludeBase += llvm::sys::path::get_separator(); -    addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); -    addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch); -    addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); +  switch (GetCXXStdlibType(DriverArgs)) { +  case ToolChain::CST_Libcxx: +    addSystemInclude(DriverArgs, CC1Args, +                     Base + "include" + llvm::sys::path::get_separator() + +                         "c++" + llvm::sys::path::get_separator() + "v1"); +    break; + +  case ToolChain::CST_Libstdcxx: +    llvm::SmallVector<llvm::SmallString<1024>, 4> CppIncludeBases; +    CppIncludeBases.emplace_back(Base); +    llvm::sys::path::append(CppIncludeBases[0], Arch, "include", "c++"); +    CppIncludeBases.emplace_back(Base); +    llvm::sys::path::append(CppIncludeBases[1], Arch, "include", "c++", Ver); +    CppIncludeBases.emplace_back(Base); +    llvm::sys::path::append(CppIncludeBases[2], "include", "c++", Ver); +    CppIncludeBases.emplace_back(GccLibDir); +    llvm::sys::path::append(CppIncludeBases[3], "include", "c++"); +    for (auto &CppIncludeBase : CppIncludeBases) { +      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase); +      CppIncludeBase += llvm::sys::path::get_separator(); +      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + Arch); +      addSystemInclude(DriverArgs, CC1Args, CppIncludeBase + "backward"); +    } +    break;    }  } diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp index e6a1bc9685de..d40bb951e50a 100644 --- a/lib/Driver/ToolChain.cpp +++ b/lib/Driver/ToolChain.cpp @@ -305,12 +305,17 @@ std::string ToolChain::ComputeLLVMTriple(const ArgList &Args,      // Thumb2 is the default for V7 on Darwin.      //      // FIXME: Thumb should just be another -target-feaure, not in the triple. +    StringRef MCPU, MArch; +    if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) +      MCPU = A->getValue(); +    if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) +      MArch = A->getValue();      std::string CPU = Triple.isOSBinFormatMachO() -      ? tools::arm::getARMCPUForMArch(Args, Triple) -      : tools::arm::getARMTargetCPU(Args, Triple); +      ? tools::arm::getARMCPUForMArch(MArch, Triple) +      : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);      StringRef Suffix =         tools::arm::getLLVMArchSuffixForARM(CPU, -                                          tools::arm::getARMArch(Args, Triple)); +                                          tools::arm::getARMArch(MArch, Triple));      bool ThumbDefault = Suffix.startswith("v6m") || Suffix.startswith("v7m") ||        Suffix.startswith("v7em") ||        (Suffix.startswith("v7") && getTriple().isOSBinFormatMachO()); diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 327ff9b13b19..59eaade6b51c 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -29,7 +29,7 @@ namespace toolchains {  /// all subcommands; this relies on gcc translating the majority of  /// command line options.  class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain { -protected: +public:    /// \brief Struct to store and manipulate GCC versions.    ///    /// We rely on assumptions about the form and structure of GCC version @@ -147,6 +147,7 @@ protected:                                  bool NeedsBiarchSuffix = false);    }; +protected:    GCCInstallationDetector GCCInstallation;  public: @@ -556,6 +557,7 @@ private:    std::string Arch;    mutable std::unique_ptr<tools::gcc::Preprocessor> Preprocessor;    mutable std::unique_ptr<tools::gcc::Compiler> Compiler; +  void findGccLibDir();  };  class LLVM_LIBRARY_VISIBILITY OpenBSD : public Generic_ELF { diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 8c11992f1f82..19ebbb91ffc7 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -502,11 +502,46 @@ static bool isNoCommonDefault(const llvm::Triple &Triple) {    }  } +// ARM tools start. + +// Get SubArch (vN). +static int getARMSubArchVersionNumber(const llvm::Triple &Triple) { +  llvm::StringRef Arch = Triple.getArchName(); +  return llvm::ARMTargetParser::parseArchVersion(Arch); +} + +// True if M-profile. +static bool isARMMProfile(const llvm::Triple &Triple) { +  llvm::StringRef Arch = Triple.getArchName(); +  unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch); +  return Profile == llvm::ARM::PK_M; +} + +// Get Arch/CPU from args. +static void getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch, +                                  llvm::StringRef &CPU, bool FromAs = false) { +  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) +    CPU = A->getValue(); +  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) +    Arch = A->getValue(); +  if (!FromAs) +    return; + +  for (const Arg *A : +       Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { +    StringRef Value = A->getValue(); +    if (Value.startswith("-mcpu=")) +      CPU = Value.substr(6); +    if (Value.startswith("-march=")) +      Arch = Value.substr(7); +  } +} +  // Handle -mhwdiv=. +// FIXME: Use ARMTargetParser.  static void getARMHWDivFeatures(const Driver &D, const Arg *A, -                                const ArgList &Args, +                                const ArgList &Args, StringRef HWDiv,                                  std::vector<const char *> &Features) { -  StringRef HWDiv = A->getValue();    if (HWDiv == "arm") {      Features.push_back("+hwdiv-arm");      Features.push_back("-hwdiv"); @@ -525,23 +560,32 @@ static void getARMHWDivFeatures(const Driver &D, const Arg *A,  // Handle -mfpu=.  static void getARMFPUFeatures(const Driver &D, const Arg *A, -                              const ArgList &Args, +                              const ArgList &Args, StringRef FPU,                                std::vector<const char *> &Features) { -  StringRef FPU = A->getValue();    unsigned FPUID = llvm::ARMTargetParser::parseFPU(FPU);    if (!llvm::ARMTargetParser::getFPUFeatures(FPUID, Features))      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);  } -static int getARMSubArchVersionNumber(const llvm::Triple &Triple) { -  llvm::StringRef Arch = Triple.getArchName(); -  return llvm::ARMTargetParser::parseArchVersion(Arch); +// 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, +                             const llvm::Triple &Triple) { +  std::string MArch = arm::getARMArch(ArchName, Triple); +  if (llvm::ARMTargetParser::parseArch(MArch) == llvm::ARM::AK_INVALID) +    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);  } -static bool isARMMProfile(const llvm::Triple &Triple) { -  llvm::StringRef Arch = Triple.getArchName(); -  unsigned Profile = llvm::ARMTargetParser::parseArchProfile(Arch); -  return Profile == llvm::ARM::PK_M; +// 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, +                            const llvm::Triple &Triple) { +  std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple); +  std::string Arch = arm::getARMArch(ArchName, Triple); +  if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0) +    D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);  }  // Select the float ABI as determined by -msoft-float, -mhard-float, and @@ -641,6 +685,9 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,    bool KernelOrKext =        Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);    StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple); +  const Arg *WaCPU = nullptr, *WaFPU = nullptr; +  const Arg *WaHDiv = nullptr, *WaArch = nullptr; +    if (!ForAS) {      // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these      // yet (it uses the -mfloat-abi and -msoft-float options), and it is @@ -661,31 +708,75 @@ static void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,      // Use software floating point argument passing?      if (FloatABI != "hard")        Features.push_back("+soft-float-abi"); +  } else { +    // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down +    // to the assembler correctly. +    for (const Arg *A : +         Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) { +      StringRef Value = A->getValue(); +      if (Value.startswith("-mfpu=")) { +        WaFPU = A; +      } else if (Value.startswith("-mcpu=")) { +        WaCPU = A; +      } else if (Value.startswith("-mhwdiv=")) { +        WaHDiv = A; +      } else if (Value.startswith("-march=")) { +        WaArch = A; +      } +    }    } -  // Honor -mfpu=. -  if (const Arg *A = Args.getLastArg(options::OPT_mfpu_EQ)) -    getARMFPUFeatures(D, A, Args, Features); -  if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ)) -    getARMHWDivFeatures(D, A, Args, Features); - -  // 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. -  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { -    std::string Arch = arm::getARMArch(Args, Triple); -    if (llvm::ARMTargetParser::parseArch(Arch) == llvm::ARM::AK_INVALID) -      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); -  } - -  // We do a similar thing with -mcpu, but here things are complicated because -  // the only function we have to check if a cpu is valid is -  // getLLVMArchSuffixForARM which also needs an architecture. -  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { -    std::string CPU = arm::getARMTargetCPU(Args, Triple); -    std::string Arch = arm::getARMArch(Args, Triple); -    if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0) -      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args); +  // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=. +  const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ); +  if (WaFPU) { +    if (FPUArg) +      D.Diag(clang::diag::warn_drv_unused_argument) +          << FPUArg->getAsString(Args); +    getARMFPUFeatures(D, WaFPU, Args, StringRef(WaFPU->getValue()).substr(6), +                      Features); +  } else if (FPUArg) { +    getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features); +  } + +  // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=. +  const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ); +  if (WaHDiv) { +    if (HDivArg) +      D.Diag(clang::diag::warn_drv_unused_argument) +          << HDivArg->getAsString(Args); +    getARMHWDivFeatures(D, WaHDiv, Args, +                        StringRef(WaHDiv->getValue()).substr(8), Features); +  } else if (HDivArg) +    getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features); + +  // Check -march. ClangAs gives preference to -Wa,-march=. +  const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); +  StringRef ArchName; +  if (WaArch) { +    if (ArchArg) +      D.Diag(clang::diag::warn_drv_unused_argument) +          << ArchArg->getAsString(Args); +    ArchName = StringRef(WaArch->getValue()).substr(7); +    checkARMArchName(D, WaArch, Args, ArchName, Triple); +    // FIXME: Set Arch. +    D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args); +  } else if (ArchArg) { +    ArchName = ArchArg->getValue(); +    checkARMArchName(D, ArchArg, Args, ArchName, Triple); +  } + +  // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=. +  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ); +  StringRef CPUName; +  if (WaCPU) { +    if (CPUArg) +      D.Diag(clang::diag::warn_drv_unused_argument) +          << CPUArg->getAsString(Args); +    CPUName = StringRef(WaCPU->getValue()).substr(6); +    checkARMCPUName(D, WaCPU, Args, CPUName, ArchName, Triple); +  } else if (CPUArg) { +    CPUName = CPUArg->getValue(); +    checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, Triple);    }    // Setting -msoft-float effectively disables NEON because of the GCC @@ -836,6 +927,7 @@ void Clang::AddARMTargetArgs(const ArgList &Args, ArgStringList &CmdArgs,      CmdArgs.push_back("-arm-reserve-r9");    }  } +// ARM tools end.  /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are  /// targeting. @@ -1463,7 +1555,8 @@ static const char *getX86TargetCPU(const ArgList &Args,    }  } -static std::string getCPUName(const ArgList &Args, const llvm::Triple &T) { +static std::string getCPUName(const ArgList &Args, const llvm::Triple &T, +                              bool FromAs = false) {    switch (T.getArch()) {    default:      return ""; @@ -1475,9 +1568,11 @@ static std::string getCPUName(const ArgList &Args, const llvm::Triple &T) {    case llvm::Triple::arm:    case llvm::Triple::armeb:    case llvm::Triple::thumb: -  case llvm::Triple::thumbeb: -    return arm::getARMTargetCPU(Args, T); - +  case llvm::Triple::thumbeb: { +    StringRef MArch, MCPU; +    getARMArchCPUFromArgs(Args, MArch, MCPU, FromAs); +    return arm::getARMTargetCPU(MCPU, MArch, T); +  }    case llvm::Triple::mips:    case llvm::Triple::mipsel:    case llvm::Triple::mips64: @@ -2198,12 +2293,12 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,         Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {      A->claim(); -      for (const StringRef Value : A->getValues()) { -        if (TakeNextArg) { -          CmdArgs.push_back(Value.data()); -          TakeNextArg = false; -          continue; -        } +    for (const StringRef Value : A->getValues()) { +      if (TakeNextArg) { +        CmdArgs.push_back(Value.data()); +        TakeNextArg = false; +        continue; +      }        if (Value == "-force_cpusubtype_ALL") {          // Do nothing, this is the default and we don't support anything else. @@ -2227,6 +2322,9 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,            TakeNextArg = true;        } else if (Value.startswith("-gdwarf-")) {          CmdArgs.push_back(Value.data()); +      } else if (Value.startswith("-mcpu") || Value.startswith("-mfpu") || +                 Value.startswith("-mhwdiv") || Value.startswith("-march")) { +        // Do nothing, we'll validate it later.        } else {          D.Diag(diag::err_drv_unsupported_option_argument)              << A->getOption().getName() << Value; @@ -2243,8 +2341,7 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,  // Until ARM libraries are build separately, we have them all in one library  static StringRef getArchNameForCompilerRTLib(const ToolChain &TC) { -  if (TC.getTriple().isOSWindows() && -      !TC.getTriple().isWindowsItaniumEnvironment() && +  if (TC.getTriple().isWindowsMSVCEnvironment() &&        TC.getArch() == llvm::Triple::x86)      return "i386";    if (TC.getArch() == llvm::Triple::arm || TC.getArch() == llvm::Triple::armeb) @@ -2270,10 +2367,12 @@ SmallString<128> tools::getCompilerRT(const ToolChain &TC, StringRef Component,                          : "";    bool IsOSWindows = TC.getTriple().isOSWindows(); +  bool IsITANMSVCWindows = TC.getTriple().isWindowsMSVCEnvironment() || +                           TC.getTriple().isWindowsItaniumEnvironment();    StringRef Arch = getArchNameForCompilerRTLib(TC); -  const char *Prefix = IsOSWindows ? "" : "lib"; +  const char *Prefix = IsITANMSVCWindows ? "" : "lib";    const char *Suffix = -      Shared ? (IsOSWindows ? ".dll" : ".so") : (IsOSWindows ? ".lib" : ".a"); +      Shared ? (IsOSWindows ? ".dll" : ".so") : (IsITANMSVCWindows ? ".lib" : ".a");    SmallString<128> Path = getCompilerRTLibDir(TC);    llvm::sys::path::append(Path, Prefix + Twine("clang_rt.") + Component + "-" + @@ -2750,8 +2849,7 @@ static void addPGOAndCoverageFlags(Compilation &C, const Driver &D,    if (ProfileGenerateArg && ProfileUseArg)      D.Diag(diag::err_drv_argument_not_allowed_with) -        << ProfileGenerateArg->getSpelling() -        << ProfileUseArg->getSpelling(); +        << ProfileGenerateArg->getSpelling() << ProfileUseArg->getSpelling();    if (ProfileGenerateArg &&        ProfileGenerateArg->getOption().matches( @@ -2907,8 +3005,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,      assert((isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) &&             "Invalid action for clang tool."); -    if (JA.getType() == types::TY_LTO_IR || -        JA.getType() == types::TY_LTO_BC) { +    if (JA.getType() == types::TY_LTO_IR || JA.getType() == types::TY_LTO_BC) {        CmdArgs.push_back("-flto");      }      if (JA.getType() == types::TY_Nothing) { @@ -3434,7 +3531,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,    }    // Add the target cpu -  std::string CPU = getCPUName(Args, Triple); +  std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);    if (!CPU.empty()) {      CmdArgs.push_back("-target-cpu");      CmdArgs.push_back(Args.MakeArgString(CPU)); @@ -3952,9 +4049,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,    Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug);    Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug);    Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names); -  // AltiVec language extensions aren't relevant for assembling. -  if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) +  // AltiVec-like language extensions aren't relevant for assembling. +  if (!isa<PreprocessJobAction>(JA) || Output.getType() != types::TY_PP_Asm) {      Args.AddLastArg(CmdArgs, options::OPT_faltivec); +    Args.AddLastArg(CmdArgs, options::OPT_fzvector); +  }    Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);    Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type); @@ -3999,6 +4098,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,                                                         << "ppc/ppc64/ppc64le";    } +  // -fzvector is incompatible with -faltivec. +  if (Arg *A = Args.getLastArg(options::OPT_fzvector)) +    if (Args.hasArg(options::OPT_faltivec)) +      D.Diag(diag::err_drv_argument_not_allowed_with) << A->getAsString(Args) +                                                      << "-faltivec"; +    if (getToolChain().SupportsProfiling())      Args.AddLastArg(CmdArgs, options::OPT_pg); @@ -4234,8 +4339,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,        llvm::sys::path::append(Path, "modules");      } else if (Path.empty()) {        // No module path was provided: use the default. -      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, -                                             Path); +      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false, Path);        llvm::sys::path::append(Path, "org.llvm.clang.");        appendUserToPath(Path);        llvm::sys::path::append(Path, "ModuleCache"); @@ -5270,7 +5374,7 @@ void ClangAs::ConstructJob(Compilation &C, const JobAction &JA,    // Add the target cpu    const llvm::Triple Triple(TripleStr); -  std::string CPU = getCPUName(Args, Triple); +  std::string CPU = getCPUName(Args, Triple, /*FromAs*/ true);    if (!CPU.empty()) {      CmdArgs.push_back("-target-cpu");      CmdArgs.push_back(Args.MakeArgString(CPU)); @@ -5775,16 +5879,12 @@ void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,  }  // Hexagon tools end. -const std::string arm::getARMArch(const ArgList &Args, -                                  const llvm::Triple &Triple) { +const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {    std::string MArch; -  if (Arg *A = Args.getLastArg(options::OPT_march_EQ)) { -    // Otherwise, if we have -march= choose the base CPU for that arch. -    MArch = A->getValue(); -  } else { -    // Otherwise, use the Arch from the triple. +  if (!Arch.empty()) +    MArch = Arch; +  else      MArch = Triple.getArchName(); -  }    MArch = StringRef(MArch).lower();    // Handle -march=native. @@ -5805,9 +5905,8 @@ const std::string arm::getARMArch(const ArgList &Args,    return MArch;  }  /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting. -const char *arm::getARMCPUForMArch(const ArgList &Args, -                                   const llvm::Triple &Triple) { -  std::string MArch = getARMArch(Args, Triple); +const char *arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) { +  std::string MArch = getARMArch(Arch, Triple);    // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch    // here means an -march=native that we can't handle, so instead return no CPU.    if (MArch.empty()) @@ -5823,12 +5922,12 @@ const char *arm::getARMCPUForMArch(const ArgList &Args,  }  /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting. -std::string arm::getARMTargetCPU(const ArgList &Args, +std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,                                   const llvm::Triple &Triple) {    // FIXME: Warn on inconsistent use of -mcpu and -march.    // If we have -mcpu=, use that. -  if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) { -    std::string MCPU = StringRef(A->getValue()).lower(); +  if (!CPU.empty()) { +    std::string MCPU = StringRef(CPU).lower();      // Handle -mcpu=native.      if (MCPU == "native")        return llvm::sys::getHostCPUName(); @@ -5836,7 +5935,7 @@ std::string arm::getARMTargetCPU(const ArgList &Args,        return MCPU;    } -  return getARMCPUForMArch(Args, Triple); +  return getARMCPUForMArch(Arch, Triple);  }  /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular @@ -7335,8 +7434,11 @@ void netbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,    case llvm::Triple::armeb:    case llvm::Triple::thumb:    case llvm::Triple::thumbeb: { -    std::string MArch = arm::getARMTargetCPU(Args, getToolChain().getTriple()); -    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + MArch)); +    StringRef MArch, MCPU; +    getARMArchCPUFromArgs(Args, MArch, MCPU, /*FromAs*/ true); +    std::string Arch = +        arm::getARMTargetCPU(MCPU, MArch, getToolChain().getTriple()); +    CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch));      break;    } @@ -7816,6 +7918,7 @@ void gnutools::Assembler::ConstructJob(Compilation &C, const JobAction &JA,  static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,                        ArgStringList &CmdArgs, const ArgList &Args) {    bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android; +  bool isCygMing = Triple.isOSCygMing();    bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||                        Args.hasArg(options::OPT_static);    if (!D.CCCIsCXX()) @@ -7825,10 +7928,10 @@ static void AddLibgcc(const llvm::Triple &Triple, const Driver &D,      if (D.CCCIsCXX())        CmdArgs.push_back("-lgcc");    } else { -    if (!D.CCCIsCXX()) +    if (!D.CCCIsCXX() && !isCygMing)        CmdArgs.push_back("--as-needed");      CmdArgs.push_back("-lgcc_s"); -    if (!D.CCCIsCXX()) +    if (!D.CCCIsCXX() && !isCygMing)        CmdArgs.push_back("--no-as-needed");    } @@ -7863,13 +7966,15 @@ static std::string getLinuxDynamicLinker(const ArgList &Args,    else if (Arch == llvm::Triple::aarch64_be)      return "/lib/ld-linux-aarch64_be.so.1";    else if (Arch == llvm::Triple::arm || Arch == llvm::Triple::thumb) { -    if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) +    if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF || +        tools::arm::getARMFloatABI(ToolChain.getDriver(), Args, ToolChain.getTriple()) == "hard")        return "/lib/ld-linux-armhf.so.3";      else        return "/lib/ld-linux.so.3";    } else if (Arch == llvm::Triple::armeb || Arch == llvm::Triple::thumbeb) {      // TODO: check which dynamic linker name. -    if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF) +    if (ToolChain.getTriple().getEnvironment() == llvm::Triple::GNUEABIHF || +        tools::arm::getARMFloatABI(ToolChain.getDriver(), Args, ToolChain.getTriple()) == "hard")        return "/lib/ld-linux-armhf.so.3";      else        return "/lib/ld-linux.so.3"; @@ -8910,15 +9015,10 @@ void MinGW::Linker::AddLibGCC(const ArgList &Args,    if (Args.hasArg(options::OPT_mthreads))      CmdArgs.push_back("-lmingwthrd");    CmdArgs.push_back("-lmingw32"); -  if (Args.hasArg(options::OPT_shared) || -      Args.hasArg(options::OPT_shared_libgcc) || -      !Args.hasArg(options::OPT_static_libgcc)) { -    CmdArgs.push_back("-lgcc_s"); -    CmdArgs.push_back("-lgcc"); -  } else { -    CmdArgs.push_back("-lgcc"); -    CmdArgs.push_back("-lgcc_eh"); -  } + +  // Add libgcc or compiler-rt. +  AddRunTimeLibs(getToolChain(), getToolChain().getDriver(), CmdArgs, Args); +    CmdArgs.push_back("-lmoldname");    CmdArgs.push_back("-lmingwex");    CmdArgs.push_back("-lmsvcrt"); diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index 52ab731cbc46..651ddc8ff572 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -231,11 +231,11 @@ public:  } // end namespace hexagon.  namespace arm { -  std::string getARMTargetCPU(const llvm::opt::ArgList &Args, +  std::string getARMTargetCPU(StringRef CPU, StringRef Arch,                                const llvm::Triple &Triple); -  const std::string getARMArch(const llvm::opt::ArgList &Args, +  const std::string getARMArch(StringRef Arch,                                 const llvm::Triple &Triple); -  const char* getARMCPUForMArch(const llvm::opt::ArgList &Args, +  const char* getARMCPUForMArch(StringRef Arch,                                  const llvm::Triple &Triple);    const char* getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch);  | 
