Hi jvoung,

Add Tool and ToolChain support for clang to target the NaCl OS using the NaCl
SDK for x86-32, x86-64 and ARM.

Includes nacltools::Assemble and Link which are derived from gnutools. They
are similar to Linux but different enought that they warrant their own class.
Also includes a NaCl_TC in ToolChains derived from Generic_ELF with library
and include paths suitable for an SDK and independent of the system tools.

http://reviews.llvm.org/D8590

Files:
  lib/Basic/Targets.cpp
  lib/Driver/Driver.cpp
  lib/Driver/ToolChains.cpp
  lib/Driver/ToolChains.h
  lib/Driver/Tools.cpp
  lib/Driver/Tools.h
  lib/Frontend/InitHeaderSearch.cpp
  test/Driver/nacl-direct.c

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -713,8 +713,7 @@
     // RegParmMax is inherited from the underlying architecture
     this->LongDoubleFormat = &llvm::APFloat::IEEEdouble;
     if (Triple.getArch() == llvm::Triple::arm) {
-      this->DescriptionString =
-          "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128";
+      // Handled in ARM's setABI().
     } else if (Triple.getArch() == llvm::Triple::x86) {
       this->DescriptionString = "e-m:e-p:32:32-i64:64-n8:16:32-S128";
     } else if (Triple.getArch() == llvm::Triple::x86_64) {
@@ -3893,6 +3892,9 @@
                           "-a:0:32"
                           "-n32"
                           "-S64";
+    } else if (T.isOSNaCl()) {
+      assert(!BigEndian && "NaCl on ARM does not support big endian");
+      DescriptionString = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128";
     } else {
       DescriptionString =
           BigEndian ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
Index: lib/Driver/Driver.cpp
===================================================================
--- lib/Driver/Driver.cpp
+++ lib/Driver/Driver.cpp
@@ -2059,6 +2059,9 @@
       else
         TC = new toolchains::Linux(*this, Target, Args);
       break;
+    case llvm::Triple::NaCl:
+      TC = new toolchains::NaCl_TC(*this, Target, Args);
+      break;
     case llvm::Triple::Solaris:
       TC = new toolchains::Solaris(*this, Target, Args);
       break;
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -2084,7 +2084,8 @@
       getTriple().getArch() == llvm::Triple::aarch64_be ||
       (getTriple().getOS() == llvm::Triple::Linux &&
        (!V.isOlderThan(4, 7, 0) ||
-        getTriple().getEnvironment() == llvm::Triple::Android));
+        getTriple().getEnvironment() == llvm::Triple::Android)) ||
+      getTriple().getOS() == llvm::Triple::NaCl;
 
   if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
                          options::OPT_fno_use_init_array,
@@ -2307,6 +2308,157 @@
 }
 // End Hexagon
 
+/// NaCl Toolchain
+NaCl_TC::NaCl_TC(const Driver &D, const llvm::Triple &Triple,
+                 const ArgList &Args)
+  : Generic_ELF(D, Triple, Args) {
+
+  // Remove paths added by Generic_GCC. NaCl Toolchain cannot use the
+  // default paths, and must instead only use the paths provided
+  // with this toolchain based on architecture.
+  path_list& file_paths = getFilePaths();
+  path_list& prog_paths = getProgramPaths();
+
+  file_paths.clear();
+  prog_paths.clear();
+
+  // Path for library files (libc.a, ...)
+  std::string FilePath(getDriver().Dir + "/../");
+
+  // Path for tools (clang, ld, etc..)
+  std::string ProgPath(getDriver().Dir + "/../");
+
+  // Path for toolchain libraries (libgcc.a, ...)
+  std::string ToolPath(getDriver().ResourceDir + "/lib/");
+
+  switch(Triple.getArch()) {
+    case llvm::Triple::x86: {
+      file_paths.push_back(FilePath + "x86_64-nacl/lib32");
+      file_paths.push_back(FilePath + "x86_64-nacl/usr/lib32");
+      prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
+      file_paths.push_back(ToolPath + "i686-nacl");
+      break;
+    }
+    case llvm::Triple::x86_64: {
+      file_paths.push_back(FilePath + "x86_64-nacl/lib");
+      file_paths.push_back(FilePath + "x86_64-nacl/usr/lib");
+      prog_paths.push_back(ProgPath + "x86_64-nacl/bin");
+      file_paths.push_back(ToolPath + "x86_64-nacl");
+      break;
+    }
+    case llvm::Triple::arm: {
+      file_paths.push_back(FilePath + "arm-nacl/lib");
+      file_paths.push_back(FilePath + "arm-nacl/usr/lib");
+      prog_paths.push_back(ProgPath + "arm-nacl/bin");
+      file_paths.push_back(ToolPath + "arm-nacl");
+      break;
+    }
+    default:
+      break;
+  }
+
+  // Use provided linker, not system linker
+  Linker = GetProgramPath("ld");
+  NaClArmMacrosPath = GetFilePath("nacl-arm-macros.s");
+}
+
+void NaCl_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+                                        ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  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;
+
+  SmallString<128> P(D.Dir + "/../");
+  if (getTriple().getArch() == llvm::Triple::arm) {
+    llvm::sys::path::append(P, "arm-nacl/usr/include");
+  } else if (getTriple().getArch() == llvm::Triple::x86) {
+    llvm::sys::path::append(P, "x86_64-nacl/usr/include");
+  } else if (getTriple().getArch() == llvm::Triple::x86_64) {
+    llvm::sys::path::append(P, "x86_64-nacl/usr/include");
+  } else {
+    return;
+  }
+
+  addSystemInclude(DriverArgs, CC1Args, P.str());
+  llvm::sys::path::remove_filename(P);
+  llvm::sys::path::remove_filename(P);
+  llvm::sys::path::append(P, "include");
+  addSystemInclude(DriverArgs, CC1Args, P.str());
+}
+
+void NaCl_TC::AddCXXStdlibLibArgs(const ArgList &Args,
+                                    ArgStringList &CmdArgs) const {
+  // Allow and ignore -stdlib=libc++ without warning, but not libstdc++
+  GetCXXStdlibType(Args);
+  CmdArgs.push_back("-lc++");
+}
+
+void NaCl_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+                                          ArgStringList &CC1Args) const {
+  const Driver &D = getDriver();
+  if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+      DriverArgs.hasArg(options::OPT_nostdincxx))
+    return;
+
+  // Allow and ignore -stdlib=libc++ without warning, but not libstdc++
+  GetCXXStdlibType(DriverArgs);
+
+  if (getTriple().getArch() == llvm::Triple::arm) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "arm-nacl/include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  } else if (getTriple().getArch() == llvm::Triple::x86) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  } else if (getTriple().getArch() == llvm::Triple::x86_64) {
+    SmallString<128> P(D.Dir + "/../");
+    llvm::sys::path::append(P, "x86_64-nacl/include/c++/v1");
+    addSystemInclude(DriverArgs, CC1Args, P.str());
+  }
+}
+
+ToolChain::CXXStdlibType NaCl_TC::GetCXXStdlibType(const ArgList &Args) const {
+  if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
+    StringRef Value = A->getValue();
+    if (Value == "libc++")
+      return ToolChain::CST_Libcxx;
+    getDriver().Diag(diag::err_drv_invalid_stdlib_name)
+      << A->getAsString(Args);
+  }
+
+  return ToolChain::CST_Libcxx;
+}
+
+std::string NaCl_TC::ComputeEffectiveClangTriple(
+    const ArgList &Args, types::ID InputType) const {
+  llvm::Triple TheTriple(ComputeLLVMTriple(Args, InputType));
+  if (TheTriple.getArch() == llvm::Triple::arm &&
+      TheTriple.getEnvironment() == llvm::Triple::UnknownEnvironment)
+    TheTriple.setEnvironment(llvm::Triple::GNUEABIHF);
+  return TheTriple.getTriple();
+}
+
+Tool *NaCl_TC::buildLinker() const {
+  return new tools::nacltools::Link(*this);
+}
+
+Tool *NaCl_TC::buildAssembler() const {
+  if (getTriple().getArch() == llvm::Triple::arm)
+    return new tools::nacltools::AssembleARM(*this);
+  return new tools::gnutools::Assemble(*this);
+}
+// End NaCl
+
 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform
 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
 /// Currently does not support anything else but compilation.
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -692,6 +692,45 @@
   static StringRef GetTargetCPU(const llvm::opt::ArgList &Args);
 };
 
+class LLVM_LIBRARY_VISIBILITY NaCl_TC : public Generic_ELF {
+public:
+  NaCl_TC(const Driver &D, const llvm::Triple &Triple,
+          const llvm::opt::ArgList &Args);
+
+  void
+  AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                            llvm::opt::ArgStringList &CC1Args) const override;
+  void
+  AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+                               llvm::opt::ArgStringList &CC1Args) const override;
+
+  CXXStdlibType
+  GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+
+  void
+  AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
+                      llvm::opt::ArgStringList &CmdArgs) const override;
+
+  bool
+  IsIntegratedAssemblerDefault() const override { return false; }
+
+  // Get the path to the file containing NaCl's ARM macros. It lives in NaCl_TC
+  // because the AssembleARM tool needs a const char * that it can pass around
+  // and the toolchain outlives all the jobs.
+  const char *GetNaClArmMacrosPath() const { return NaClArmMacrosPath.c_str(); }
+
+  std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
+                                          types::ID InputType) const override;
+  std::string Linker;
+
+protected:
+  Tool *buildLinker() const override;
+  Tool *buildAssembler() const override;
+
+private:
+  std::string NaClArmMacrosPath;
+};
+
 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform
 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
 class LLVM_LIBRARY_VISIBILITY TCEToolChain : public ToolChain {
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -671,6 +671,10 @@
       }
       break;
 
+    case llvm::Triple::NaCl:
+      FloatABI = "hard";
+      break;
+
     default:
       switch(Triple.getEnvironment()) {
       case llvm::Triple::GNUEABIHF:
@@ -789,6 +793,8 @@
   } else if (Triple.isOSWindows()) {
     // FIXME: this is invalid for WindowsCE
     ABIName = "aapcs";
+  } else if (Triple.isOSNaCl()) {
+    ABIName = "aapcs-linux";
   } else {
     // Select the default based on the platform.
     switch(Triple.getEnvironment()) {
@@ -7838,6 +7844,168 @@
       llvm::make_unique<Command>(JA, *this, ToolChain.Linker.c_str(), CmdArgs));
 }
 
+
+// NaCl ARM assembly (inline or standalone) can be written with a set of macros
+// for the various SFI requirements like register masking. The assembly tool
+// inserts the file containing the macros as an input into all the assembly
+// jobs.
+void nacltools::AssembleARM::ConstructJob(Compilation &C, const JobAction &JA,
+                                       const InputInfo &Output,
+                                       const InputInfoList &Inputs,
+                                       const ArgList &Args,
+                                       const char *LinkingOutput) const {
+  const toolchains::NaCl_TC& ToolChain =
+    static_cast<const toolchains::NaCl_TC&>(getToolChain());
+  InputInfo NaClMacros(ToolChain.GetNaClArmMacrosPath(), types::TY_PP_Asm,
+                       "nacl-arm-macros.s");
+  InputInfoList NewInputs;
+  NewInputs.push_back(NaClMacros);
+  NewInputs.append(Inputs.begin(), Inputs.end());
+  gnutools::Assemble::ConstructJob(C, JA, Output, NewInputs, Args,
+                                   LinkingOutput);
+}
+
+
+// This is quite similar to gnutools::link::ConstructJob with changes that
+// we use static by default, do not yet support sanitizers or LTO, and a few
+// others. Eventually we can support more of that and hopefully migrate back
+// to gnutools::link
+void nacltools::Link::ConstructJob(Compilation &C, const JobAction &JA,
+                                  const InputInfo &Output,
+                                  const InputInfoList &Inputs,
+                                  const ArgList &Args,
+                                  const char *LinkingOutput) const {
+
+  const toolchains::NaCl_TC& ToolChain =
+    static_cast<const toolchains::NaCl_TC&>(getToolChain());
+  const Driver &D = ToolChain.getDriver();
+  const bool IsStatic =
+    !Args.hasArg(options::OPT_dynamic) &&
+    !Args.hasArg(options::OPT_shared);
+
+  ArgStringList CmdArgs;
+
+  // Silence warning for "clang -g foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_g_Group);
+  // and "clang -emit-llvm foo.o -o foo"
+  Args.ClaimAllArgs(options::OPT_emit_llvm);
+  // and for "clang -w foo.o -o foo". Other warning options are already
+  // handled somewhere else.
+  Args.ClaimAllArgs(options::OPT_w);
+
+  if (!D.SysRoot.empty())
+    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
+
+  if (Args.hasArg(options::OPT_rdynamic))
+    CmdArgs.push_back("-export-dynamic");
+
+  if (Args.hasArg(options::OPT_s))
+    CmdArgs.push_back("-s");
+
+  // NaCl_TC doesn't have ExtraOpts like Linux; the only relevant flag from
+  // there is --build-id, which we do want.
+  CmdArgs.push_back("--build-id");
+
+  if (!IsStatic)
+    CmdArgs.push_back("--eh-frame-hdr");
+
+  CmdArgs.push_back("-m");
+  if (ToolChain.getArch() == llvm::Triple::x86)
+    CmdArgs.push_back("elf_i386_nacl");
+  else if (ToolChain.getArch() == llvm::Triple::arm)
+    CmdArgs.push_back("armelf_nacl");
+  else
+    CmdArgs.push_back("elf_x86_64_nacl");
+
+  if (IsStatic)
+    CmdArgs.push_back("-static");
+  else if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back("-shared");
+
+  CmdArgs.push_back("-o");
+  CmdArgs.push_back(Output.getFilename());
+  if (!Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nostartfiles)) {
+    if (!Args.hasArg(options::OPT_shared))
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt1.o")));
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
+
+    const char *crtbegin;
+    if (IsStatic)
+      crtbegin = "crtbeginT.o";
+    else if (Args.hasArg(options::OPT_shared))
+      crtbegin = "crtbeginS.o";
+    else
+      crtbegin = "crtbegin.o";
+    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
+  }
+
+  Args.AddAllArgs(CmdArgs, options::OPT_L);
+  Args.AddAllArgs(CmdArgs, options::OPT_u);
+
+  const ToolChain::path_list Paths = ToolChain.getFilePaths();
+
+  for (const auto &Path : Paths)
+    CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + Path));
+
+  if (Args.hasArg(options::OPT_Z_Xlinker__no_demangle))
+    CmdArgs.push_back("--no-demangle");
+
+  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
+
+  if (D.CCCIsCXX() &&
+      !Args.hasArg(options::OPT_nostdlib) &&
+      !Args.hasArg(options::OPT_nodefaultlibs)) {
+    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+      !IsStatic;
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bstatic");
+    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+    if (OnlyLibstdcxxStatic)
+      CmdArgs.push_back("-Bdynamic");
+    CmdArgs.push_back("-lm");
+  }
+
+  if (!Args.hasArg(options::OPT_nostdlib)) {
+    if (!Args.hasArg(options::OPT_nodefaultlibs)) {
+      // Always use groups, since it has no effect on dynamic libraries.
+      CmdArgs.push_back("--start-group");
+      CmdArgs.push_back("-lc");
+      // libc++ and PPAPI programs always require libpthread, so just always
+      // include it in the group for C++.
+      if (Args.hasArg(options::OPT_pthread) ||
+          Args.hasArg(options::OPT_pthreads) ||
+          D.CCCIsCXX()) {
+        CmdArgs.push_back("-lpthread");
+      }
+
+      CmdArgs.push_back("-lgcc");
+      CmdArgs.push_back("--as-needed");
+      if (IsStatic)
+        CmdArgs.push_back("-lgcc_eh");
+      else
+        CmdArgs.push_back("-lgcc_s");
+      CmdArgs.push_back("--no-as-needed");
+      CmdArgs.push_back("--end-group");
+    }
+
+    if (!Args.hasArg(options::OPT_nostartfiles)) {
+      const char *crtend;
+      if (Args.hasArg(options::OPT_shared))
+        crtend = "crtendS.o";
+      else
+        crtend = "crtend.o";
+
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
+      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
+    }
+  }
+
+  C.addCommand(llvm::make_unique<Command>(JA, *this,
+                                          ToolChain.Linker.c_str(), CmdArgs));
+}
+
+
 void minix::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
                                    const InputInfo &Output,
                                    const InputInfoList &Inputs,
Index: lib/Driver/Tools.h
===================================================================
--- lib/Driver/Tools.h
+++ lib/Driver/Tools.h
@@ -491,6 +491,33 @@
                       const char *LinkingOutput) const override;
   };
 }
+
+namespace nacltools {
+  class LLVM_LIBRARY_VISIBILITY AssembleARM : public gnutools::Assemble  {
+  public:
+    AssembleARM(const ToolChain &TC) : gnutools::Assemble(TC) {}
+
+    void ConstructJob(Compilation &C, const JobAction &JA,
+                      const InputInfo &Output,
+                      const InputInfoList &Inputs,
+                      const llvm::opt::ArgList &TCArgs,
+                      const char *LinkingOutput) const override;
+  };
+  class LLVM_LIBRARY_VISIBILITY Link : public Tool  {
+  public:
+    Link(const ToolChain &TC) : Tool("NaCl::Link", "linker", 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;
+  };
+}
+
   /// minix -- Directly call GNU Binutils assembler and linker
 namespace minix {
   class LLVM_LIBRARY_VISIBILITY Assemble : public GnuTool  {
Index: lib/Frontend/InitHeaderSearch.cpp
===================================================================
--- lib/Frontend/InitHeaderSearch.cpp
+++ lib/Frontend/InitHeaderSearch.cpp
@@ -232,6 +232,7 @@
     case llvm::Triple::NetBSD:
     case llvm::Triple::OpenBSD:
     case llvm::Triple::Bitrig:
+    case llvm::Triple::NaCl:
       break;
     default:
       // FIXME: temporary hack: hard-coded paths.
@@ -352,6 +353,7 @@
   switch (os) {
   case llvm::Triple::CloudABI:
   case llvm::Triple::RTEMS:
+  case llvm::Triple::NaCl:
     break;
   default:
     AddPath("/usr/include", ExternCSystem, false);
Index: test/Driver/nacl-direct.c
===================================================================
--- /dev/null
+++ test/Driver/nacl-direct.c
@@ -0,0 +1,108 @@
+// Test clang changes for NaCl Support including:
+//    include paths, library paths, emulation, default static
+//
+// RUN: %clang -### -o %t.o %s 2>&1 \
+// RUN:     -target i686-unknown-nacl \
+// RUN:   | FileCheck --check-prefix=CHECK-I686 %s
+// CHECK-I686: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-I686: "-fuse-init-array"
+// CHECK-I686: "-target-cpu" "pentium4"
+// CHECK-I686: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-I686: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-I686: "-internal-isystem" "{{.*}}/../x86_64-nacl/usr/include"
+// CHECK-I686: "-internal-isystem" "{{.*}}/../x86_64-nacl/include"
+// CHECK-I686: /as" "--32"
+// CHECK-I686: /ld"
+// CHECK-I686: "--build-id"
+// CHECK-I686: "-m" "elf_i386_nacl"
+// CHECK-I686: "-static"
+// CHECK-I686: "-L{{.*}}/../x86_64-nacl/lib32"
+// CHECK-I686: "-L{{.*}}/../x86_64-nacl/usr/lib32"
+// CHECK-I686: "-L{{.*}}/../lib/clang/[[VER]]/lib/i686-nacl"
+// CHECK-I686-NOT: -lpthread
+//
+// RUN: %clang -### -o %t.o %s 2>&1 \
+// RUN:     -target x86_64-unknown-nacl \
+// RUN:   | FileCheck --check-prefix=CHECK-x86_64 %s
+// CHECK-x86_64: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-x86_64: "-fuse-init-array"
+// CHECK-x86_64: "-target-cpu" "x86-64"
+// CHECK-x86_64: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-x86_64: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-x86_64: "-internal-isystem" "{{.*}}/../x86_64-nacl/usr/include"
+// CHECK-x86_64: "-internal-isystem" "{{.*}}/../x86_64-nacl/include"
+// CHECK-x86_64: /as" "--64"
+// CHECK-x86_64: /ld"
+// CHECK-x86_64: "--build-id"
+// CHECK-x86_64: "-m" "elf_x86_64_nacl"
+// CHECK-x86_64: "-static"
+// CHECK-x86_64: "-L{{.*}}/../x86_64-nacl/lib"
+// CHECK-x86_64: "-L{{.*}}/../x86_64-nacl/usr/lib"
+// CHECK-x86_64: "-L{{.*}}/../lib/clang/[[VER]]/lib/x86_64-nacl"
+// CHECK-X86_64-NOT: -lpthread
+//
+// RUN: %clang -### -o %t.o %s 2>&1 \
+// RUN:     -target armv7a-unknown-nacl-gnueabihf \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM %s
+// CHECK-ARM: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-ARM: "-fuse-init-array"
+// CHECK-ARM: "-target-cpu" "cortex-a8"
+// CHECK-ARM: "-target-abi" "aapcs-linux"
+// CHECK-ARM: "-mfloat-abi" "hard"
+// CHECK-ARM: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-ARM: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-ARM: "-internal-isystem" "{{.*}}/../arm-nacl/usr/include"
+// CHECK-ARM: "-internal-isystem" "{{.*}}/../arm-nacl/include"
+// CHECK-ARM: /as"
+// CHECK-ARM: /ld"
+// CHECK-ARM: "--build-id"
+// CHECK-ARM: "-m" "armelf_nacl"
+// CHECK-ARM: "-static"
+// CHECK-ARM: "-L{{.*}}/../arm-nacl/lib"
+// CHECK-ARM: "-L{{.*}}/../arm-nacl/usr/lib"
+// CHECK-ARM: "-L{{.*}}/../lib/clang/[[VER]]/lib/arm-nacl"
+// CHECK-ARM-NOT: -lpthread
+
+// Check that even when the target arch is just "arm" (as will be the case when
+// it is inferred from the binary name) that we get the right ABI flags
+// RUN: %clang -### -o %t.o %s 2>&1 \
+// RUN:     -target arm-nacl \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM-NOV7 %s
+// CHECK-ARM-NOV7: "-triple" "armv7--nacl-gnueabihf"
+// CHECK-ARM-NOV7: "-target-abi" "aapcs-linux"
+// CHECK-ARM-NOV7: "-mfloat-abi" "hard"
+
+// Test clang c++ include dirs and link line when using clang++
+
+// RUN: %clangxx -### -o %t.o %s 2>&1 \
+// RUN:     -target armv7a-unknown-nacl-gnueabihf \
+// RUN:   | FileCheck --check-prefix=CHECK-ARM-CXX %s
+// CHECK-ARM-CXX: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-ARM-CXX: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-ARM-CXX: "-internal-isystem" "{{.*}}/../arm-nacl/include/c++/v1"
+// CHECK-ARM-CXX: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-ARM-CXX: "-internal-isystem" "{{.*}}/../arm-nacl/usr/include"
+// CHECK-ARM-CXX: "-internal-isystem" "{{.*}}/../arm-nacl/include"
+// CHECK-ARM-CXX: "-lpthread"
+
+// RUN: %clangxx -### -o %t.o %s 2>&1 \
+// RUN:     -target i686-unknown-nacl \
+// RUN:   | FileCheck --check-prefix=CHECK-I686-CXX %s
+// CHECK-I686-CXX: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-I686-CXX: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-I686-CXX: "-internal-isystem" "{{.*}}/../x86_64-nacl/include/c++/v1"
+// CHECK-I686-CXX: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-I686-CXX: "-internal-isystem" "{{.*}}/../x86_64-nacl/usr/include"
+// CHECK-I686-CXX: "-internal-isystem" "{{.*}}/../x86_64-nacl/include"
+// CHECK-I686-CXX: "-lpthread"
+
+// RUN: %clangxx -### -o %t.o %s 2>&1 \
+// RUN:     -target x86_64-unknown-nacl \
+// RUN:   | FileCheck --check-prefix=CHECK-x86_64-CXX %s
+// CHECK-x86_64-CXX: {{.*}}clang{{.*}}" "-cc1"
+// CHECK-x86_64-CXX: "-resource-dir" "{{.*}}/lib/clang/[[VER:[0-9.]+]]"
+// CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}/../x86_64-nacl/include/c++/v1"
+// CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}/../lib/clang/[[VER]]/include"
+// CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}/../x86_64-nacl/usr/include"
+// CHECK-x86_64-CXX: "-internal-isystem" "{{.*}}/../x86_64-nacl/include"
+// CHECK-x86_64-CXX: "-lpthread"
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to