aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.def4
-rw-r--r--include/clang/Driver/Driver.h19
-rw-r--r--include/clang/Driver/Options.def2
-rw-r--r--lib/Driver/Driver.cpp44
4 files changed, 67 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticDriverKinds.def b/include/clang/Basic/DiagnosticDriverKinds.def
index 47332b6d19..e832504bfa 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.def
+++ b/include/clang/Basic/DiagnosticDriverKinds.def
@@ -24,3 +24,7 @@ DIAG(err_drv_invalid_opt_with_multiple_archs, ERROR,
"option '%0' cannot be used with multiple -arch options")
DIAG(err_drv_invalid_output_with_multiple_archs, ERROR,
"cannot use '%0' output with multiple -arch options")
+DIAG(err_drv_no_input_files, ERROR,
+ "no input files")
+DIAG(err_drv_use_of_Z_option, ERROR,
+ "unsupported use of internal gcc -Z option '%0'")
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index dc1814cb6d..44b5d57600 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -29,6 +29,25 @@ namespace driver {
/// Driver - Encapsulate logic for constructing compilation processes
/// from a set of gcc-driver-like command line arguments.
class Driver {
+ /// PhaseOrder - Ordered values for successive stages in the
+ /// compilation process which interact with user options.
+ enum PhaseOrder {
+ /// Nothing.
+ NoPhaseOrder = 0,
+
+ /// Only run the preprocessor.
+ PreprocessPhaseOrder,
+
+ /// Only run the preprocessor and compiler.
+ CompilePhaseOrder,
+
+ /// Only run the preprocessor, compiler, and assembler.
+ AssemblePhaseOrder,
+
+ /// Run everything.
+ PostAssemblePhaseOrder
+ };
+
OptTable *Opts;
Diagnostic &Diags;
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index b35f56fecf..e9833a6420 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -111,7 +111,7 @@ OPTION("--bootclasspath=", _bootclasspath_EQ, Joined, INVALID, fbootclasspath_EQ
OPTION("--bootclasspath", _bootclasspath, Separate, INVALID, fbootclasspath_EQ, "J", 0)
OPTION("--classpath=", _classpath_EQ, Joined, INVALID, fclasspath_EQ, "", 0)
OPTION("--classpath", _classpath, Separate, INVALID, fclasspath_EQ, "J", 0)
-OPTION("--combine", _combine, Flag, INVALID, combine, "", 0)
+OPTION("--combine", _combine, Flag, INVALID, combine, "u", 0)
OPTION("--comments-in-macros", _comments_in_macros, Flag, INVALID, CC, "", 0)
OPTION("--comments", _comments, Flag, INVALID, C, "", 0)
OPTION("--compile", _compile, Flag, INVALID, c, "", 0)
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 4ceeb77c15..204436abba 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -244,7 +244,9 @@ void Driver::BuildUniversalActions(ArgList &Args, ActionList &Actions) {
void Driver::BuildActions(ArgList &Args, ActionList &Actions) {
types::ID InputType = types::TY_INVALID;
Arg *InputTypeArg = 0;
-
+
+ // Start by constructing the list of inputs and their types.
+
llvm::SmallVector<std::pair<types::ID, const Arg*>, 16> Inputs;
for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
it != ie; ++it) {
@@ -323,6 +325,46 @@ void Driver::BuildActions(ArgList &Args, ActionList &Actions) {
}
}
+ if (Inputs.empty()) {
+ Diag(clang::diag::err_drv_no_input_files);
+ return;
+ }
+
+ // Determine which compilation mode we are in. We look for options
+ // which affect the phase, starting with the earliest phases, and
+ // record which option we used to determine the final phase.
+ Arg *FinalPhaseOpt = 0;
+ PhaseOrder FinalPhase;
+
+ // -{E,M,MM} only run the preprocessor.
+ if ((FinalPhaseOpt = Args.getLastArg(options::OPT_E)) ||
+ (FinalPhaseOpt = Args.getLastArg(options::OPT_M)) ||
+ (FinalPhaseOpt = Args.getLastArg(options::OPT_MM))) {
+ FinalPhase = PreprocessPhaseOrder;
+
+ // -{-analyze,fsyntax-only,S} only run up to the compiler.
+ } else if ((FinalPhaseOpt = Args.getLastArg(options::OPT__analyze)) ||
+ (FinalPhaseOpt = Args.getLastArg(options::OPT_fsyntax_only)) ||
+ (FinalPhaseOpt = Args.getLastArg(options::OPT_S))) {
+ FinalPhase = CompilePhaseOrder;
+
+ // -c only runs up to the assembler.
+ } else if ((FinalPhaseOpt = Args.getLastArg(options::OPT_c))) {
+ FinalPhase = AssemblePhaseOrder;
+
+ // Otherwise do everything.
+ } else
+ FinalPhase = PostAssemblePhaseOrder;
+
+ if (FinalPhaseOpt)
+ FinalPhaseOpt->claim();
+
+ // Reject -Z* at the top level, these options should never have been
+ // exposed by gcc.
+ if (Arg *A = Args.getLastArg(options::OPT_Z))
+ Diag(clang::diag::err_drv_use_of_Z_option) << A->getValue(Args);
+
+ // FIXME: This is just debugging code.
for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
llvm::errs() << "input " << i << ": "
<< Inputs[i].second->getValue(Args) << "\n";