Index: lib/Driver/ToolChains.cpp |
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp |
index ebd4d4374b2ec37162d5eae034e2b2db91353559..cc40bd101fd749e116a7109ca0cc6bc86235dfc7 100644 |
--- a/lib/Driver/ToolChains.cpp |
+++ b/lib/Driver/ToolChains.cpp |
@@ -3712,3 +3712,145 @@ void XCore::AddCXXStdlibLibArgs(const ArgList &Args, |
ArgStringList &CmdArgs) const { |
// We don't output any lib args. This is handled by xcc. |
} |
+ |
+/// Generic_BC Toolchain |
+ |
+Generic_BC::Generic_BC(const Driver &D, const llvm::Triple &Triple, |
+ const ArgList &Args) |
+ : ToolChain(D, Triple, Args) { |
+ getProgramPaths().push_back(getDriver().getInstalledDir()); |
+ if (getDriver().getInstalledDir() != getDriver().Dir) |
+ getProgramPaths().push_back(getDriver().Dir); |
+} |
+ |
+/// PNaCl ToolChain |
+ |
+PNaClToolChain::PNaClToolChain(const Driver &D, const llvm::Triple &Triple, |
+ const ArgList &Args) |
+ : Generic_BC(D, Triple, Args) { |
+ std::string SysRoot = computeSysRoot(); |
+ |
+ getFilePaths().push_back(SysRoot + "/lib"); |
+ getFilePaths().push_back(SysRoot + "/usr/lib"); |
+ |
+ getFilePaths().push_back(D.ResourceDir + "/lib/le32-nacl"); |
+} |
+ |
+Tool *PNaClToolChain::buildLinker() const { |
+ return new tools::pnacltools::Link(*this); |
+} |
+ |
+Tool *PNaClToolChain::buildAssembler() const { |
+ llvm_unreachable("cannot build assembler"); |
+} |
+ |
+std::string PNaClToolChain::computeSysRoot() const { |
+ if (!getDriver().SysRoot.empty()) |
+ return getDriver().SysRoot; |
+ |
+ return getDriver().Dir + "/../le32-nacl"; |
+} |
+ |
+void PNaClToolChain::AddLinkRuntimeLibArgs(const ArgList &Args, |
+ ArgStringList &CmdArgs) const { |
+ CmdArgs.push_back("-lnacl"); |
+ CmdArgs.push_back("-lpnaclmm"); |
+} |
+ |
+ToolChain::CXXStdlibType PNaClToolChain::GetCXXStdlibType(const ArgList &Args) const { |
+ Arg *A = Args.getLastArg(options::OPT_stdlib_EQ); |
+ if (!A) |
+ return ToolChain::CST_Libcxx; |
+ |
+ StringRef Value = A->getValue(); |
+ if (Value != "libc++") { |
+ getDriver().Diag(diag::err_drv_invalid_stdlib_name) |
+ << A->getAsString(Args); |
+ } |
+ |
+ return ToolChain::CST_Libcxx; |
+} |
+ |
+void PNaClToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, |
+ ArgStringList &CC1Args) const { |
+ const Driver &D = getDriver(); |
+ std::string SysRoot = computeSysRoot(); |
+ |
+ if (DriverArgs.hasArg(options::OPT_nostdinc)) |
+ return; |
+ |
+ if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { |
+ SmallString<128> P(D.ResourceDir); |
+ llvm::sys::path::append(P, "include"); |
+ addSystemInclude(DriverArgs, CC1Args, P.str()); |
+ } |
+ |
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
+ return; |
+ |
+ // Check for configure-time C include directories. |
+ StringRef CIncludeDirs(C_INCLUDE_DIRS); |
+ if (CIncludeDirs != "") { |
+ SmallVector<StringRef, 5> dirs; |
+ CIncludeDirs.split(dirs, ":"); |
+ for (StringRef dir : dirs) { |
+ StringRef Prefix = |
+ llvm::sys::path::is_absolute(dir) ? StringRef(SysRoot) : ""; |
+ addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir); |
+ } |
+ return; |
+ } |
+ |
+ // Add an include of '/include' directly. This isn't provided by default by |
+ // system GCCs, but is often used with cross-compiling GCCs, and harmless to |
+ // add even when Clang is acting as-if it were a system compiler. |
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); |
+ |
+ addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); |
+} |
+ |
+void PNaClToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, |
+ ArgStringList &CC1Args) const { |
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) || |
+ DriverArgs.hasArg(options::OPT_nostdincxx)) |
+ return; |
+ |
+ // Check for -stdlib= flags. We only support libc++ but this consumes the arg |
+ // if the value is libc++, and emits an error for other values. |
+ GetCXXStdlibType(DriverArgs); |
+ |
+ const std::string LibCXXIncludePathCandidates[] = { |
+ // The primary location is within the Clang installation. |
+ getDriver().Dir + "/../include/c++/v1", |
+ |
+ // We also check the system as for a long time this is the only place Clang looked. |
+ getDriver().SysRoot + "/usr/include/c++/v1" |
+ }; |
+ for (const auto &IncludePath : LibCXXIncludePathCandidates) { |
+ if (!llvm::sys::fs::exists(IncludePath)) |
+ continue; |
+ // Add the first candidate that exists. |
+ addSystemInclude(DriverArgs, CC1Args, IncludePath); |
+ break; |
+ } |
+ return; |
+} |
+ |
+void PNaClToolChain::AddCXXStdlibLibArgs(const ArgList &Args, |
+ ArgStringList &CmdArgs) const { |
+ switch (GetCXXStdlibType(Args)) { |
+ case ToolChain::CST_Libcxx: |
+ CmdArgs.push_back("-lc++"); |
+ break; |
+ case ToolChain::CST_Libstdcxx: |
+ break; |
+ } |
+} |
+ |
+void PNaClToolChain::addClangTargetOptions(const ArgList &DriverArgs, |
+ ArgStringList &CC1Args) const { |
+ if (DriverArgs.hasFlag(options::OPT_fuse_init_array, |
+ options::OPT_fno_use_init_array, |
+ getTriple().getOS() == llvm::Triple::NaCl)) |
+ CC1Args.push_back("-fuse-init-array"); |
+} |