summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/Driver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Driver/Driver.cpp')
-rw-r--r--clang/lib/Driver/Driver.cpp50
1 files changed, 40 insertions, 10 deletions
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index f49e79046a6..a5910be5ece 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -21,6 +21,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
@@ -53,8 +54,8 @@ Driver::Driver(StringRef ClangExecutable,
DefaultImageName(DefaultImageName),
DriverTitle("clang LLVM compiler"),
CCPrintOptionsFilename(0), CCPrintHeadersFilename(0),
- CCLogDiagnosticsFilename(0), CCCIsCXX(false),
- CCCIsCPP(false),CCCEcho(false), CCCPrintBindings(false),
+ CCLogDiagnosticsFilename(0), Mode(GCCMode),
+ CCCEcho(false), CCCPrintBindings(false),
CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false),
CCGenDiagnostics(false), CCCGenericGCCName(""), CheckInputsExist(true),
CCCUsePCH(true), SuppressMissingInputWarning(false) {
@@ -81,6 +82,29 @@ Driver::~Driver() {
delete I->second;
}
+void Driver::ParseDriverMode(ArrayRef<const char *> Args) {
+ const std::string OptName =
+ getOpts().getOption(options::OPT_driver_mode).getPrefixedName();
+
+ for (size_t I = 0, E = Args.size(); I != E; ++I) {
+ const StringRef Arg = Args[I];
+ 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)
+ .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 *> ArgList) {
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
unsigned MissingArgIndex, MissingArgCount;
@@ -121,7 +145,7 @@ const {
phases::ID FinalPhase;
// -{E,M,MM} only run the preprocessor.
- if (CCCIsCPP ||
+ if (CCCIsCPP() ||
(PhaseArg = DAL.getLastArg(options::OPT_E)) ||
(PhaseArg = DAL.getLastArg(options::OPT_M, options::OPT_MM))) {
FinalPhase = phases::Preprocess;
@@ -249,6 +273,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(ArgList.slice(1));
+
// FIXME: What are we going to do with -V and -b?
// FIXME: This stuff needs to go into the Compilation, not the driver.
@@ -271,7 +299,6 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
CCCPrintOptions = Args->hasArg(options::OPT_ccc_print_options);
CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases);
CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings);
- CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx) || CCCIsCXX;
CCCEcho = Args->hasArg(options::OPT_ccc_echo);
if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name))
CCCGenericGCCName = A->getValue();
@@ -361,7 +388,7 @@ void Driver::generateCompilationDiagnostics(Compilation &C,
"crash backtrace, preprocessed source, and associated run script.";
// Suppress driver output and emit preprocessor output to temp file.
- CCCIsCPP = true;
+ Mode = CPPMode;
CCGenDiagnostics = true;
C.getArgs().AddFlagArg(0, Opts->getOption(options::OPT_frewrite_includes));
@@ -917,7 +944,7 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
//
// Otherwise emit an error but still use a valid type to avoid
// spurious errors (e.g., no inputs).
- if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP)
+ if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP())
Diag(clang::diag::err_drv_unknown_stdin_type);
Ty = types::TY_C;
} else {
@@ -929,7 +956,7 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
Ty = TC.LookupTypeForExtension(Ext + 1);
if (Ty == types::TY_INVALID) {
- if (CCCIsCPP)
+ if (CCCIsCPP())
Ty = types::TY_C;
else
Ty = types::TY_Object;
@@ -937,7 +964,7 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
// If the driver is invoked as C++ compiler (like clang++ or c++) it
// should autodetect some input files as C++ for g++ compatibility.
- if (CCCIsCXX) {
+ if (CCCIsCXX()) {
types::ID OldTy = Ty;
Ty = types::lookupCXXTypeForCType(Ty);
@@ -1001,7 +1028,7 @@ void Driver::BuildInputs(const ToolChain &TC, const DerivedArgList &Args,
}
}
}
- if (CCCIsCPP && Inputs.empty()) {
+ if (CCCIsCPP() && Inputs.empty()) {
// If called as standalone preprocessor, stdin is processed
// if no other input is present.
unsigned Index = Args.getBaseArgs().MakeIndex("-");
@@ -1052,7 +1079,7 @@ void Driver::BuildActions(const ToolChain &TC, const DerivedArgList &Args,
// Special case when final phase determined by binary name, rather than
// by a command-line argument with a corresponding Arg.
- if (CCCIsCPP)
+ if (CCCIsCPP())
Diag(clang::diag::warn_drv_input_file_unused_by_cpp)
<< InputArg->getAsString(Args)
<< getPhaseName(InitialPhase);
@@ -1257,6 +1284,9 @@ void Driver::BuildJobs(Compilation &C) const {
// Claim -### here.
(void) C.getArgs().hasArg(options::OPT__HASH_HASH_HASH);
+ // Claim --driver-mode, it was handled earlier.
+ (void) C.getArgs().hasArg(options::OPT_driver_mode);
+
for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end();
it != ie; ++it) {
Arg *A = *it;
OpenPOWER on IntegriCloud