summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/ToolChains.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/ToolChains.cpp')
-rw-r--r--clang/lib/Driver/ToolChains.cpp215
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
OpenPOWER on IntegriCloud