diff --git a/clang/examples/clang-interpreter/main.cpp b/clang/examples/clang-interpreter/main.cpp --- a/clang/examples/clang-interpreter/main.cpp +++ b/clang/examples/clang-interpreter/main.cpp @@ -130,7 +130,7 @@ T.setObjectFormat(llvm::Triple::ELF); #endif - Driver TheDriver(Path, T.str(), Diags); + Driver TheDriver(Path, Diags, nullptr, T.str()); TheDriver.setTitle("clang interpreter"); TheDriver.setCheckInputsExist(false); diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -283,9 +283,11 @@ static std::string GetResourcesPath(StringRef BinaryPath, StringRef CustomResourceDir = ""); - Driver(StringRef ClangExecutable, StringRef TargetTriple, - DiagnosticsEngine &Diags, - IntrusiveRefCntPtr VFS = nullptr); + /// If TargetTriple empty, it is deduced from ClangExecutable and falls back + /// to llvm::sys::getDefaultTriple() if deduction fails. + Driver(StringRef ClangExecutable, DiagnosticsEngine &Diags, + IntrusiveRefCntPtr VFS = nullptr, + StringRef TargetTriple = ""); /// @name Accessors /// @{ diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -70,6 +70,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" @@ -117,9 +118,9 @@ return P.str(); } -Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, - DiagnosticsEngine &Diags, - IntrusiveRefCntPtr VFS) +Driver::Driver(StringRef ClangExecutable, DiagnosticsEngine &Diags, + IntrusiveRefCntPtr VFS, + StringRef TargetTriple) : Opts(createDriverOptTable()), Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None), ClangExecutable(ClangExecutable), @@ -148,6 +149,15 @@ // Compute the path to the resource directory. ResourceDir = GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR); + + if (TargetTriple.empty()) { + ClangNameParts = + ToolChain::getTargetAndModeFromProgramName(ClangExecutable); + if (ClangNameParts.TargetIsValid) + this->TargetTriple = ClangNameParts.TargetPrefix; + else + this->TargetTriple = llvm::sys::getDefaultTargetTriple(); + } } void Driver::ParseDriverMode(StringRef ProgramName, diff --git a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp --- a/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ b/clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -44,8 +44,7 @@ Args.push_back("-fsyntax-only"); // FIXME: We shouldn't have to pass in the path info. - driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), - *Diags, VFS); + driver::Driver TheDriver(Args[0], *Diags, VFS); // Don't check that inputs exist, they may have been remapped. TheDriver.setCheckInputsExist(false); diff --git a/clang/lib/Tooling/CompilationDatabase.cpp b/clang/lib/Tooling/CompilationDatabase.cpp --- a/clang/lib/Tooling/CompilationDatabase.cpp +++ b/clang/lib/Tooling/CompilationDatabase.cpp @@ -271,8 +271,7 @@ // The clang executable path isn't required since the jobs the driver builds // will not be executed. std::unique_ptr NewDriver(new driver::Driver( - /* ClangExecutable= */ "", llvm::sys::getDefaultTargetTriple(), - Diagnostics)); + /* ClangExecutable= */ "", Diagnostics)); NewDriver->setCheckInputsExist(false); // This becomes the new argv[0]. The value is used to detect libc++ include diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -77,8 +77,7 @@ newDriver(DiagnosticsEngine *Diagnostics, const char *BinaryName, IntrusiveRefCntPtr VFS) { driver::Driver *CompilerDriver = - new driver::Driver(BinaryName, llvm::sys::getDefaultTargetTriple(), - *Diagnostics, std::move(VFS)); + new driver::Driver(BinaryName, *Diagnostics, std::move(VFS)); CompilerDriver->setTitle("clang_based_tool"); return CompilerDriver; } diff --git a/clang/tools/driver/cc1gen_reproducer_main.cpp b/clang/tools/driver/cc1gen_reproducer_main.cpp --- a/clang/tools/driver/cc1gen_reproducer_main.cpp +++ b/clang/tools/driver/cc1gen_reproducer_main.cpp @@ -118,7 +118,7 @@ IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, new IgnoringDiagConsumer()); ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false); - Driver TheDriver(Argv[0], llvm::sys::getDefaultTargetTriple(), Diags); + Driver TheDriver(Argv[0], Diags); TheDriver.setTargetAndMode(TargetAndMode); std::unique_ptr C(TheDriver.BuildCompilation(Argv)); diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -446,7 +446,7 @@ ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false); - Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags); + Driver TheDriver(Path, Diags); SetInstallDir(argv, TheDriver, CanonicalPrefixes); TheDriver.setTargetAndMode(TargetAndMode); diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp --- a/clang/unittests/Driver/ToolChainTest.cpp +++ b/clang/unittests/Driver/ToolChainTest.cpp @@ -16,6 +16,8 @@ #include "clang/Basic/LLVM.h" #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/Host.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/VirtualFileSystem.h" @@ -34,8 +36,8 @@ DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); IntrusiveRefCntPtr InMemoryFileSystem( new llvm::vfs::InMemoryFileSystem); - Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags, - InMemoryFileSystem); + Driver TheDriver("/bin/clang", Diags, InMemoryFileSystem, + "arm-linux-gnueabihf"); const char *EmptyFiles[] = { "foo.cpp", @@ -88,8 +90,8 @@ DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); IntrusiveRefCntPtr InMemoryFileSystem( new llvm::vfs::InMemoryFileSystem); - Driver TheDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, - InMemoryFileSystem); + Driver TheDriver("/home/test/bin/clang", Diags, InMemoryFileSystem, + "arm-linux-gnueabi"); const char *EmptyFiles[] = { "foo.cpp", "/home/test/lib/gcc/arm-linux-gnueabi/4.6.1/crtbegin.o", @@ -129,14 +131,14 @@ IntrusiveRefCntPtr InMemoryFileSystem( new llvm::vfs::InMemoryFileSystem); - Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, - InMemoryFileSystem); + Driver CCDriver("/home/test/bin/clang", Diags, InMemoryFileSystem, + "arm-linux-gnueabi"); CCDriver.setCheckInputsExist(false); - Driver CXXDriver("/home/test/bin/clang++", "arm-linux-gnueabi", Diags, - InMemoryFileSystem); + Driver CXXDriver("/home/test/bin/clang++", Diags, InMemoryFileSystem, + "arm-linux-gnueabi"); CXXDriver.setCheckInputsExist(false); - Driver CLDriver("/home/test/bin/clang-cl", "arm-linux-gnueabi", Diags, - InMemoryFileSystem); + Driver CLDriver("/home/test/bin/clang-cl", Diags, InMemoryFileSystem, + "arm-linux-gnueabi"); CLDriver.setCheckInputsExist(false); std::unique_ptr CC(CCDriver.BuildCompilation( @@ -158,7 +160,7 @@ struct TestDiagnosticConsumer : public DiagnosticConsumer {}; IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); - Driver TheDriver("/bin/clang", "arm-linux-gnueabihf", Diags); + Driver TheDriver("/bin/clang", Diags, nullptr, "arm-linux-gnueabihf"); std::unique_ptr C(TheDriver.BuildCompilation( {"-fsyntax-only", "-fan-unknown-option", "foo.cpp"})); EXPECT_TRUE(C); @@ -259,4 +261,46 @@ EXPECT_STREQ(Res.DriverMode, "--driver-mode=cl"); EXPECT_FALSE(Res.TargetIsValid); } + +TEST(ToolChainTest, TargetTripletDeduction) { + IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); + IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); + struct TestDiagnosticConsumer : public DiagnosticConsumer {}; + DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); + + // TargetTriple set + { + Driver TheDriver("/bin/x86_64-fuchsia-clang", Diags, nullptr, + "arm-linux-gnueabihf"); + std::unique_ptr C( + TheDriver.BuildCompilation({"-fsyntax-only", "foo.cpp"})); + EXPECT_TRUE(C); + EXPECT_EQ(C->getDefaultToolChain().ComputeEffectiveClangTriple( + llvm::opt::InputArgList{}), + "armv6kz-unknown-linux-gnueabihf"); + } + + // TargetTriple deduced from executable + { + Driver TheDriver("/bin/x86_64-fuchsia-clang", Diags); + std::unique_ptr C( + TheDriver.BuildCompilation({"-fsyntax-only", "foo.cpp"})); + EXPECT_TRUE(C); + EXPECT_EQ(C->getDefaultToolChain().ComputeEffectiveClangTriple( + llvm::opt::InputArgList{}), + "x86_64-unknown-linux-gnu"); + } + + // TargetTriple from default triplet + { + Driver TheDriver("clang", Diags); + std::unique_ptr C( + TheDriver.BuildCompilation({"-fsyntax-only", "foo.cpp"})); + EXPECT_TRUE(C); + EXPECT_EQ(C->getDefaultToolChain().ComputeEffectiveClangTriple( + llvm::opt::InputArgList{}), + llvm::sys::getDefaultTargetTriple()); + } +} + } // end anonymous namespace.