kadircet created this revision. kadircet added a reviewer: sammccall. kadircet requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Also use it in other places that performed it on their own. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D106789 Files: clang/include/clang/Driver/Driver.h clang/lib/Driver/Driver.cpp clang/lib/Tooling/InterpolatingCompilationDatabase.cpp clang/tools/driver/driver.cpp
Index: clang/tools/driver/driver.cpp =================================================================== --- clang/tools/driver/driver.cpp +++ clang/tools/driver/driver.cpp @@ -360,7 +360,6 @@ return 1; llvm::InitializeAllTargets(); - auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Args[0]); llvm::BumpPtrAllocator A; llvm::StringSaver Saver(A); @@ -372,13 +371,8 @@ // have to manually search for a --driver-mode=cl argument the hard way. // Finally, our -cc1 tools don't care which tokenization mode we use because // response files written by clang will tokenize the same way in either mode. - bool ClangCLMode = false; - if (StringRef(TargetAndMode.DriverMode).equals("--driver-mode=cl") || - llvm::find_if(Args, [](const char *F) { - return F && strcmp(F, "--driver-mode=cl") == 0; - }) != Args.end()) { - ClangCLMode = true; - } + bool ClangCLMode = + getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1)).equals("cl"); enum { Default, POSIX, Windows } RSPQuoting = Default; for (const char *F : Args) { if (strcmp(F, "--rsp-quoting=posix") == 0) @@ -490,6 +484,7 @@ Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags); SetInstallDir(Args, TheDriver, CanonicalPrefixes); + auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Args[0]); TheDriver.setTargetAndMode(TargetAndMode); insertTargetAndModeArgs(TargetAndMode, Args, SavedStrings); Index: clang/lib/Tooling/InterpolatingCompilationDatabase.cpp =================================================================== --- clang/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ clang/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -43,9 +43,11 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/LangStandard.h" +#include "clang/Driver/Driver.h" #include "clang/Driver/Options.h" #include "clang/Driver/Types.h" #include "clang/Tooling/CompilationDatabase.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringExtras.h" @@ -134,8 +136,7 @@ bool ClangCLMode; TransferableCommand(CompileCommand C) - : Cmd(std::move(C)), Type(guessType(Cmd.Filename)), - ClangCLMode(checkIsCLMode(Cmd.CommandLine)) { + : Cmd(std::move(C)), Type(guessType(Cmd.Filename)) { std::vector<std::string> OldArgs = std::move(Cmd.CommandLine); Cmd.CommandLine.clear(); @@ -145,6 +146,10 @@ SmallVector<const char *, 16> TmpArgv; for (const std::string &S : OldArgs) TmpArgv.push_back(S.c_str()); + ClangCLMode = !TmpArgv.empty() && + driver::getDriverMode(TmpArgv.front(), + llvm::makeArrayRef(TmpArgv).slice(1)) + .equals("cl"); ArgList = {TmpArgv.begin(), TmpArgv.end()}; } @@ -246,19 +251,6 @@ } private: - // Determine whether the given command line is intended for the CL driver. - static bool checkIsCLMode(ArrayRef<std::string> CmdLine) { - // First look for --driver-mode. - for (StringRef S : llvm::reverse(CmdLine)) { - if (S.consume_front("--driver-mode=")) - return S == "cl"; - } - - // Otherwise just check the clang executable file name. - return !CmdLine.empty() && - llvm::sys::path::stem(CmdLine.front()).endswith_insensitive("cl"); - } - // Map the language from the --std flag to that of the -x flag. static types::ID toType(Language Lang) { switch (Lang) { Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -63,6 +63,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" @@ -168,28 +169,9 @@ ResourceDir = GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR); } -void Driver::ParseDriverMode(StringRef ProgramName, - ArrayRef<const char *> Args) { - if (ClangNameParts.isEmpty()) - ClangNameParts = ToolChain::getTargetAndModeFromProgramName(ProgramName); - setDriverModeFromOption(ClangNameParts.DriverMode); - - for (const char *ArgPtr : Args) { - // Ignore nullptrs, they are the response file's EOL markers. - if (ArgPtr == nullptr) - continue; - const StringRef Arg = ArgPtr; - setDriverModeFromOption(Arg); - } -} - -void Driver::setDriverModeFromOption(StringRef Opt) { +void Driver::setDriverMode(StringRef Value) { const std::string OptName = getOpts().getOption(options::OPT_driver_mode).getPrefixedName(); - if (!Opt.startswith(OptName)) - return; - StringRef Value = Opt.drop_front(OptName.size()); - if (auto M = llvm::StringSwitch<llvm::Optional<DriverMode>>(Value) .Case("gcc", GCCMode) .Case("g++", GXXMode) @@ -1031,7 +1013,7 @@ // We look for the driver mode option early, because the mode can affect // how other options are parsed. - ParseDriverMode(ClangExecutable, ArgList.slice(1)); + setDriverMode(getDriverMode(ClangExecutable, ArgList.slice(1))); // FIXME: What are we going to do with -V and -b? @@ -5573,3 +5555,19 @@ return true; return false; } + +llvm::StringRef clang::driver::getDriverMode(StringRef ProgName, + ArrayRef<const char *> Args) { + static const std::string OptName = + getDriverOptTable().getOption(options::OPT_driver_mode).getPrefixedName(); + llvm::StringRef Opt; + for (StringRef Arg : Args) { + if (!Arg.startswith(OptName)) + continue; + Opt = Arg; + break; + } + if (Opt.empty()) + Opt = ToolChain::getTargetAndModeFromProgramName(ProgName).DriverMode; + return Opt.consume_front(OptName) ? Opt : ""; +} Index: clang/include/clang/Driver/Driver.h =================================================================== --- clang/include/clang/Driver/Driver.h +++ clang/include/clang/Driver/Driver.h @@ -380,12 +380,6 @@ /// to determine if an error occurred. Compilation *BuildCompilation(ArrayRef<const char *> Args); - /// @name Driver Steps - /// @{ - - /// ParseDriverMode - Look for and handle the driver mode option in Args. - void ParseDriverMode(StringRef ProgramName, ArrayRef<const char *> Args); - /// ParseArgStrings - Parse the given list of strings into an /// ArgList. llvm::opt::InputArgList ParseArgStrings(ArrayRef<const char *> Args, @@ -584,9 +578,9 @@ /// \returns true, if error occurred while reading. bool readConfigFile(StringRef FileName); - /// Set the driver mode (cl, gcc, etc) from an option string of the form - /// --driver-mode=<mode>. - void setDriverModeFromOption(StringRef Opt); + /// Set the driver mode (cl, gcc, etc) from the value of the `--driver-mode` + /// option. + void setDriverMode(StringRef DriverModeValue); /// Parse the \p Args list for LTO options and record the type of LTO /// compilation based on which -f(no-)?lto(=.*)? option occurs last. @@ -646,6 +640,11 @@ /// \return True if the argument combination will end up generating remarks. bool willEmitRemarks(const llvm::opt::ArgList &Args); +/// Returns the driver mode option's value, i.e. `X` in `--driver-mode=X`. If \p +/// Args doesn't mention one explicitly, tries to deduce from `ProgName`. +/// Returns empty on failure. +llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef<const char *> Args); + } // end namespace driver } // end namespace clang
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits