diff options
-rw-r--r-- | include/clang/Basic/DiagnosticDriverKinds.def | 4 | ||||
-rw-r--r-- | include/clang/Driver/Driver.h | 19 | ||||
-rw-r--r-- | include/clang/Driver/Options.def | 2 | ||||
-rw-r--r-- | lib/Driver/Driver.cpp | 44 |
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"; |