diff options
Diffstat (limited to 'clang/lib/Driver/ToolChains.cpp')
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 215 |
1 files changed, 87 insertions, 128 deletions
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 7370e623210..2d882eb5368 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -2555,122 +2555,108 @@ std::string MipsLLVMToolChain::getCompilerRT(const ArgList &Args, /// Hexagon Toolchain -std::string HexagonToolChain::GetGnuDir(const std::string &InstalledDir, - const ArgList &Args) const { - // Locate the rest of the toolchain ... - std::string GccToolchain = getGCCToolchainDir(Args); +std::string HexagonToolChain::getHexagonTargetDir( + const std::string &InstalledDir, + const SmallVectorImpl<std::string> &PrefixDirs) const { + std::string InstallRelDir; + const Driver &D = getDriver(); - if (!GccToolchain.empty()) - return GccToolchain; + // Locate the rest of the toolchain ... + for (auto &I : PrefixDirs) + if (D.getVFS().exists(I)) + return I; - std::string InstallRelDir = InstalledDir + "/../../gnu"; - if (getVFS().exists(InstallRelDir)) + if (getVFS().exists(InstallRelDir = InstalledDir + "/../target")) return InstallRelDir; - std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu"; + std::string PrefixRelDir = std::string(LLVM_PREFIX) + "/target"; if (getVFS().exists(PrefixRelDir)) return PrefixRelDir; return InstallRelDir; } -const char *HexagonToolChain::GetSmallDataThreshold(const ArgList &Args) { - Arg *A; - A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ, - options::OPT_msmall_data_threshold_EQ); - if (A) - return A->getValue(); +Optional<unsigned> HexagonToolChain::getSmallDataThreshold( + const ArgList &Args) { + StringRef Gn = ""; + if (Arg *A = Args.getLastArg(options::OPT_G, options::OPT_G_EQ, + options::OPT_msmall_data_threshold_EQ)) { + Gn = A->getValue(); + } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic, + options::OPT_fPIC)) { + Gn = "0"; + } - A = Args.getLastArg(options::OPT_shared, options::OPT_fpic, - options::OPT_fPIC); - if (A) - return "0"; + unsigned G; + if (!Gn.getAsInteger(10, G)) + return G; - return nullptr; + return None; } -bool HexagonToolChain::UsesG0(const char *smallDataThreshold) { - return smallDataThreshold && smallDataThreshold[0] == '0'; -} -static void GetHexagonLibraryPaths(const HexagonToolChain &TC, - const ArgList &Args, const std::string &Ver, - const std::string &MarchString, - const std::string &InstalledDir, - ToolChain::path_list *LibPaths) { - bool buildingLib = Args.hasArg(options::OPT_shared); +void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args, + ToolChain::path_list &LibPaths) const { + const Driver &D = getDriver(); //---------------------------------------------------------------------------- // -L Args //---------------------------------------------------------------------------- for (Arg *A : Args.filtered(options::OPT_L)) for (const char *Value : A->getValues()) - LibPaths->push_back(Value); + LibPaths.push_back(Value); //---------------------------------------------------------------------------- // Other standard paths //---------------------------------------------------------------------------- - const std::string MarchSuffix = "/" + MarchString; - const std::string G0Suffix = "/G0"; - const std::string MarchG0Suffix = MarchSuffix + G0Suffix; - const std::string RootDir = TC.GetGnuDir(InstalledDir, Args) + "/"; - - // lib/gcc/hexagon/... - std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/"; - if (buildingLib) { - LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix); - LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix); - } - LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix); - LibPaths->push_back(LibGCCHexagonDir + Ver); - - // lib/gcc/... - LibPaths->push_back(RootDir + "lib/gcc"); - - // hexagon/lib/... - std::string HexagonLibDir = RootDir + "hexagon/lib"; - if (buildingLib) { - LibPaths->push_back(HexagonLibDir + MarchG0Suffix); - LibPaths->push_back(HexagonLibDir + G0Suffix); + std::vector<std::string> RootDirs; + std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(), RootDirs.begin()); + + std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(), + D.PrefixDirs); + if (std::find(RootDirs.begin(), RootDirs.end(), TargetDir) == RootDirs.end()) + RootDirs.push_back(TargetDir); + + bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC); + // Assume G0 with -shared. + bool HasG0 = Args.hasArg(options::OPT_shared); + if (auto G = getSmallDataThreshold(Args)) + HasG0 = G.getValue() == 0; + + const std::string CpuVer = GetTargetCPUVersion(Args).str(); + for (auto &Dir : RootDirs) { + std::string LibDir = Dir + "/hexagon/lib"; + std::string LibDirCpu = LibDir + '/' + CpuVer; + if (HasG0) { + if (HasPIC) + LibPaths.push_back(LibDirCpu + "/G0/pic"); + LibPaths.push_back(LibDirCpu + "/G0"); + } + LibPaths.push_back(LibDirCpu); + LibPaths.push_back(LibDir); } - LibPaths->push_back(HexagonLibDir + MarchSuffix); - LibPaths->push_back(HexagonLibDir); } HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple, - const ArgList &Args) + const llvm::opt::ArgList &Args) : Linux(D, Triple, Args) { - const std::string InstalledDir(getDriver().getInstalledDir()); - const std::string GnuDir = GetGnuDir(InstalledDir, Args); + const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(), + D.PrefixDirs); // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to // program paths - const std::string BinDir(GnuDir + "/bin"); + const std::string BinDir(TargetDir + "/bin"); if (D.getVFS().exists(BinDir)) getProgramPaths().push_back(BinDir); - // Determine version of GCC libraries and headers to use. - const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon"); - std::error_code ec; - GCCVersion MaxVersion = GCCVersion::Parse("0.0.0"); - for (vfs::directory_iterator di = D.getVFS().dir_begin(HexagonDir, ec), de; - !ec && di != de; di = di.increment(ec)) { - GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->getName())); - if (MaxVersion < cv) - MaxVersion = cv; - } - GCCLibAndIncVersion = MaxVersion; - - ToolChain::path_list *LibPaths = &getFilePaths(); + ToolChain::path_list &LibPaths = getFilePaths(); // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets // 'elf' OS type, so the Linux paths are not appropriate. When we actually // support 'linux' we'll need to fix this up - LibPaths->clear(); - - GetHexagonLibraryPaths(*this, Args, GetGCCLibAndIncVersion(), - GetTargetCPU(Args), InstalledDir, LibPaths); + LibPaths.clear(); + getHexagonLibraryPaths(Args, LibPaths); } HexagonToolChain::~HexagonToolChain() {} @@ -2685,18 +2671,14 @@ Tool *HexagonToolChain::buildLinker() const { void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, ArgStringList &CC1Args) const { - const Driver &D = getDriver(); - if (DriverArgs.hasArg(options::OPT_nostdinc) || DriverArgs.hasArg(options::OPT_nostdlibinc)) return; - std::string Ver(GetGCCLibAndIncVersion()); - std::string GnuDir = GetGnuDir(D.InstalledDir, DriverArgs); - std::string HexagonDir(GnuDir + "/lib/gcc/hexagon/" + Ver); - addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include"); - addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed"); - addExternCSystemInclude(DriverArgs, CC1Args, GnuDir + "/hexagon/include"); + const Driver &D = getDriver(); + std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(), + D.PrefixDirs); + addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include"); } void HexagonToolChain::AddClangCXXStdlibIncludeArgs( @@ -2706,12 +2688,8 @@ void HexagonToolChain::AddClangCXXStdlibIncludeArgs( return; const Driver &D = getDriver(); - std::string Ver(GetGCCLibAndIncVersion()); - SmallString<128> IncludeDir(GetGnuDir(D.InstalledDir, DriverArgs)); - - llvm::sys::path::append(IncludeDir, "hexagon/include/c++/"); - llvm::sys::path::append(IncludeDir, Ver); - addSystemInclude(DriverArgs, CC1Args, IncludeDir); + std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs); + addSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include/c++"); } ToolChain::CXXStdlibType @@ -2721,53 +2699,34 @@ HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const { return ToolChain::CST_Libstdcxx; StringRef Value = A->getValue(); - if (Value != "libstdc++") { + if (Value != "libstdc++") getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args); - } return ToolChain::CST_Libstdcxx; } -static int getHexagonVersion(const ArgList &Args) { - Arg *A = Args.getLastArg(options::OPT_march_EQ, options::OPT_mcpu_EQ); - // Select the default CPU (v4) if none was given. - if (!A) - return 4; - - // FIXME: produce errors if we cannot parse the version. - StringRef WhichHexagon = A->getValue(); - if (WhichHexagon.startswith("hexagonv")) { - int Val; - if (!WhichHexagon.substr(sizeof("hexagonv") - 1).getAsInteger(10, Val)) - return Val; - } - if (WhichHexagon.startswith("v")) { - int Val; - if (!WhichHexagon.substr(1).getAsInteger(10, Val)) - return Val; - } - - // FIXME: should probably be an error. - return 4; +// +// Returns the default CPU for Hexagon. This is the default compilation target +// if no Hexagon processor is selected at the command-line. +// +const StringRef HexagonToolChain::GetDefaultCPU() { + return "hexagonv60"; } -StringRef HexagonToolChain::GetTargetCPU(const ArgList &Args) { - int V = getHexagonVersion(Args); - // FIXME: We don't support versions < 4. We should error on them. - switch (V) { - default: - llvm_unreachable("Unexpected version"); - case 5: - return "v5"; - case 4: - return "v4"; - case 3: - return "v3"; - case 2: - return "v2"; - case 1: - return "v1"; +const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) { + Arg *CpuArg = nullptr; + + for (auto &A : Args) { + if (A->getOption().matches(options::OPT_mcpu_EQ)) { + CpuArg = A; + A->claim(); + } } + + StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU(); + if (CPU.startswith("hexagon")) + return CPU.substr(sizeof("hexagon") - 1); + return CPU; } // End Hexagon |