Author: zturner Date: Fri Aug 12 12:47:52 2016 New Revision: 278535 URL: http://llvm.org/viewvc/llvm-project?rev=278535&view=rev Log: [Driver] Set the default driver mode based on the executable.
Currently, if --driver-mode is not passed at all, it will default to GCC style driver. This is never an issue for clang because it manually constructs a --driver-mode option and passes it. However, we should still try to do as good as we can even if no --driver-mode is passed. LibTooling, for example, does not pass a --driver-mode option and while it could, it seems like we should still fallback to the best possible default we can. This is one of two steps necessary to get clang-tidy working on Windows. Reviewed By: rnk Differential Revision: https://reviews.llvm.org/D23454 Modified: cfe/trunk/include/clang/Driver/Driver.h cfe/trunk/lib/Driver/Driver.cpp cfe/trunk/unittests/Driver/ToolChainTest.cpp Modified: cfe/trunk/include/clang/Driver/Driver.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=278535&r1=278534&r2=278535&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Driver.h (original) +++ cfe/trunk/include/clang/Driver/Driver.h Fri Aug 12 12:47:52 2016 @@ -155,6 +155,9 @@ public: /// Whether the driver is just the preprocessor. bool CCCIsCPP() const { return Mode == CPPMode; } + /// Whether the driver should follow gcc like behavior. + bool CCCIsCC() const { return Mode == GCCMode; } + /// Whether the driver should follow cl.exe like behavior. bool IsCLMode() const { return Mode == CLMode; } @@ -291,7 +294,7 @@ public: /// @{ /// ParseDriverMode - Look for and handle the driver mode option in Args. - void ParseDriverMode(ArrayRef<const char *> Args); + void ParseDriverMode(StringRef ProgramName, ArrayRef<const char *> Args); /// ParseArgStrings - Parse the given list of strings into an /// ArgList. @@ -440,6 +443,10 @@ public: LTOKind getLTOMode() const { return LTOMode; } private: + /// Set the driver mode (cl, gcc, etc) from an option string of the form + /// --driver-mode=<mode>. + void setDriverModeFromOption(StringRef Opt); + /// Parse the \p Args list for LTO options and record the type of LTO /// compilation based on which -f(no-)?lto(=.*)? option occurs last. void setLTOMode(const llvm::opt::ArgList &Args); Modified: cfe/trunk/lib/Driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=278535&r1=278534&r2=278535&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Driver.cpp (original) +++ cfe/trunk/lib/Driver/Driver.cpp Fri Aug 12 12:47:52 2016 @@ -88,33 +88,41 @@ Driver::~Driver() { llvm::DeleteContainerSeconds(ToolChains); } -void Driver::ParseDriverMode(ArrayRef<const char *> Args) { - const std::string OptName = - getOpts().getOption(options::OPT_driver_mode).getPrefixedName(); +void Driver::ParseDriverMode(StringRef ProgramName, + ArrayRef<const char *> Args) { + auto Default = ToolChain::getTargetAndModeFromProgramName(ProgramName); + StringRef DefaultMode(Default.second); + setDriverModeFromOption(DefaultMode); for (const char *ArgPtr : Args) { // Ingore nullptrs, they are response file's EOL markers if (ArgPtr == nullptr) continue; const StringRef Arg = ArgPtr; - if (!Arg.startswith(OptName)) - continue; - - const StringRef Value = Arg.drop_front(OptName.size()); - const unsigned M = llvm::StringSwitch<unsigned>(Value) - .Case("gcc", GCCMode) - .Case("g++", GXXMode) - .Case("cpp", CPPMode) - .Case("cl", CLMode) - .Default(~0U); - - if (M != ~0U) - Mode = static_cast<DriverMode>(M); - else - Diag(diag::err_drv_unsupported_option_argument) << OptName << Value; + setDriverModeFromOption(Arg); } } +void Driver::setDriverModeFromOption(StringRef Opt) { + const std::string OptName = + getOpts().getOption(options::OPT_driver_mode).getPrefixedName(); + if (!Opt.startswith(OptName)) + return; + StringRef Value = Opt.drop_front(OptName.size()); + + const unsigned M = llvm::StringSwitch<unsigned>(Value) + .Case("gcc", GCCMode) + .Case("g++", GXXMode) + .Case("cpp", CPPMode) + .Case("cl", CLMode) + .Default(~0U); + + if (M != ~0U) + Mode = static_cast<DriverMode>(M); + else + Diag(diag::err_drv_unsupported_option_argument) << OptName << Value; +} + InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings) { llvm::PrettyStackTraceString CrashInfo("Command line argument parsing"); @@ -468,7 +476,7 @@ Compilation *Driver::BuildCompilation(Ar // We look for the driver mode option early, because the mode can affect // how other options are parsed. - ParseDriverMode(ArgList.slice(1)); + ParseDriverMode(ClangExecutable, ArgList.slice(1)); // FIXME: What are we going to do with -V and -b? Modified: cfe/trunk/unittests/Driver/ToolChainTest.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Driver/ToolChainTest.cpp?rev=278535&r1=278534&r2=278535&view=diff ============================================================================== --- cfe/trunk/unittests/Driver/ToolChainTest.cpp (original) +++ cfe/trunk/unittests/Driver/ToolChainTest.cpp Fri Aug 12 12:47:52 2016 @@ -117,4 +117,29 @@ TEST(ToolChainTest, VFSGCCInstallationRe S); } +TEST(ToolChainTest, DefaultDriverMode) { + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions(); + + IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); + struct TestDiagnosticConsumer : public DiagnosticConsumer {}; + DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer); + IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem( + new vfs::InMemoryFileSystem); + + Driver CCDriver("/home/test/bin/clang", "arm-linux-gnueabi", Diags, + InMemoryFileSystem); + Driver CXXDriver("/home/test/bin/clang++", "arm-linux-gnueabi", Diags, + InMemoryFileSystem); + Driver CLDriver("/home/test/bin/clang-cl", "arm-linux-gnueabi", Diags, + InMemoryFileSystem); + + std::unique_ptr<Compilation> CC(CCDriver.BuildCompilation({"foo.cpp"})); + std::unique_ptr<Compilation> CXX(CXXDriver.BuildCompilation({"foo.cpp"})); + std::unique_ptr<Compilation> CL(CLDriver.BuildCompilation({"foo.cpp"})); + + EXPECT_TRUE(CCDriver.CCCIsCC()); + EXPECT_TRUE(CXXDriver.CCCIsCXX()); + EXPECT_TRUE(CLDriver.IsCLMode()); +} + } // end anonymous namespace _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits