[clang] ce90b60 - [clang][Driver] Expose driver mode detection logic
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 27 05:55:28 PDT 2021
Author: Kadir Cetinkaya
Date: 2021-07-27T14:49:53+02:00
New Revision: ce90b60bd09da41c52006374a4715425122572ab
URL: https://github.com/llvm/llvm-project/commit/ce90b60bd09da41c52006374a4715425122572ab
DIFF: https://github.com/llvm/llvm-project/commit/ce90b60bd09da41c52006374a4715425122572ab.diff
LOG: [clang][Driver] Expose driver mode detection logic
Also use it in other places that performed it on their own.
Differential Revision: https://reviews.llvm.org/D106789
Added:
Modified:
clang/include/clang/Driver/Driver.h
clang/lib/Driver/Driver.cpp
clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
clang/tools/driver/driver.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 85810f0b568b6..da7e8386a151c 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -380,12 +380,6 @@ class Driver {
/// 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 @@ class Driver {
/// \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,16 @@ bool isOptimizationLevelFast(const llvm::opt::ArgList &Args);
/// \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.
+/// Common values are "gcc", "g++", "cpp", "cl" and "flang". Returned value need
+/// not be one of these.
+llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef<const char *> Args);
+
+/// Checks whether the value produced by getDriverMode is for CL mode.
+bool IsClangCL(StringRef DriverMode);
+
} // end namespace driver
} // end namespace clang
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index a06eb6ccc1b3c..5c323cb6ea23e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/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 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple,
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) {
- const std::string OptName =
+void Driver::setDriverMode(StringRef Value) {
+ static 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,10 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
// We look for the driver mode option early, because the mode can affect
// how other options are parsed.
- ParseDriverMode(ClangExecutable, ArgList.slice(1));
+
+ auto DriverMode = getDriverMode(ClangExecutable, ArgList.slice(1));
+ if (!DriverMode.empty())
+ setDriverMode(DriverMode);
// FIXME: What are we going to do with -V and -b?
@@ -5573,3 +5558,21 @@ bool clang::driver::willEmitRemarks(const ArgList &Args) {
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 : "";
+}
+
+bool driver::IsClangCL(StringRef DriverMode) { return DriverMode.equals("cl"); }
diff --git a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp b/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
index 650e510fb68ff..c1e25c41f7198 100644
--- a/clang/lib/Tooling/InterpolatingCompilationDatabase.cpp
+++ b/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 @@ struct TransferableCommand {
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,9 @@ struct TransferableCommand {
SmallVector<const char *, 16> TmpArgv;
for (const std::string &S : OldArgs)
TmpArgv.push_back(S.c_str());
+ ClangCLMode = !TmpArgv.empty() &&
+ driver::IsClangCL(driver::getDriverMode(
+ TmpArgv.front(), llvm::makeArrayRef(TmpArgv).slice(1)));
ArgList = {TmpArgv.begin(), TmpArgv.end()};
}
@@ -246,19 +250,6 @@ struct TransferableCommand {
}
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) {
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 9e3f51db21a9d..5a453429e79bf 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -360,7 +360,6 @@ int main(int Argc, const char **Argv) {
return 1;
llvm::InitializeAllTargets();
- auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Args[0]);
llvm::BumpPtrAllocator A;
llvm::StringSaver Saver(A);
@@ -372,13 +371,8 @@ int main(int Argc, const char **Argv) {
// 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 =
+ IsClangCL(getDriverMode(Args[0], llvm::makeArrayRef(Args).slice(1)));
enum { Default, POSIX, Windows } RSPQuoting = Default;
for (const char *F : Args) {
if (strcmp(F, "--rsp-quoting=posix") == 0)
@@ -490,6 +484,7 @@ int main(int Argc, const char **Argv) {
Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);
SetInstallDir(Args, TheDriver, CanonicalPrefixes);
+ auto TargetAndMode = ToolChain::getTargetAndModeFromProgramName(Args[0]);
TheDriver.setTargetAndMode(TargetAndMode);
insertTargetAndModeArgs(TargetAndMode, Args, SavedStrings);
More information about the cfe-commits
mailing list