forked from OSchip/llvm-project
[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 llvm-svn: 278535
This commit is contained in:
parent
03878729fb
commit
aff19c3864
|
@ -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);
|
||||
|
|
|
@ -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(ArrayRef<const char *> ArgList) {
|
|||
|
||||
// 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?
|
||||
|
||||
|
|
|
@ -117,4 +117,29 @@ TEST(ToolChainTest, VFSGCCInstallationRelativeDir) {
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue