[cfe-commits] r66885 - in /cfe/trunk: include/clang/Basic/DiagnosticDriverKinds.def include/clang/Driver/Driver.h lib/Driver/Driver.cpp
Daniel Dunbar
daniel at zuster.org
Fri Mar 13 04:38:43 PDT 2009
Author: ddunbar
Date: Fri Mar 13 06:38:42 2009
New Revision: 66885
URL: http://llvm.org/viewvc/llvm-project?rev=66885&view=rev
Log:
Driver: Complete "pipelining" (building the list of abstract actions
to perform). Still doesn't do anything interesting.
- This code came out much cleaner than in ccc with the reworked
phases & mapping of types to lists of compilation steps (phases) to
perform.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/lib/Driver/Driver.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def?rev=66885&r1=66884&r2=66885&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def Fri Mar 13 06:38:42 2009
@@ -28,3 +28,6 @@
"no input files")
DIAG(err_drv_use_of_Z_option, ERROR,
"unsupported use of internal gcc -Z option '%0'")
+
+DIAG(warn_drv_input_file_unused, WARNING,
+ "%0: '%1' input file unused when '%2' is present")
Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=66885&r1=66884&r2=66885&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Fri Mar 13 06:38:42 2009
@@ -12,6 +12,7 @@
#include "clang/Basic/Diagnostic.h"
+#include "clang/Driver/Phases.h"
#include "clang/Driver/Util.h"
#include "llvm/System/Path.h" // FIXME: Kill when CompilationInfo
@@ -32,25 +33,6 @@
/// 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;
@@ -184,6 +166,12 @@
/// invocation.
bool HandleImmediateArgs(const ArgList &Args);
+ /// ConstructAction - Construct the appropriate action to do for
+ /// \arg Phase on the \arg Input, taking in to account arguments
+ /// like -fsyntax-only or --analyze.
+ Action *ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
+ Action *Input) const;
+
/// GetHostInfo - Construct a new host info object for the given
/// host triple.
static HostInfo *GetHostInfo(const char *HostTriple);
Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=66885&r1=66884&r2=66885&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Fri Mar 13 06:38:42 2009
@@ -43,6 +43,8 @@
ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) {
ArgList *Args = new ArgList(ArgBegin, ArgEnd);
+ // FIXME: Handle '@' args (or at least error on them).
+
unsigned Index = 0, End = ArgEnd - ArgBegin;
while (Index < End) {
// gcc's handling of empty arguments doesn't make
@@ -393,43 +395,122 @@
// 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;
+ Arg *FinalPhaseArg = 0;
+ phases::ID 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;
+ if ((FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
+ (FinalPhaseArg = Args.getLastArg(options::OPT_M)) ||
+ (FinalPhaseArg = Args.getLastArg(options::OPT_MM))) {
+ FinalPhase = phases::Preprocess;
// -{-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;
+ } else if ((FinalPhaseArg = Args.getLastArg(options::OPT__analyze)) ||
+ (FinalPhaseArg = Args.getLastArg(options::OPT_fsyntax_only)) ||
+ (FinalPhaseArg = Args.getLastArg(options::OPT_S))) {
+ FinalPhase = phases::Compile;
// -c only runs up to the assembler.
- } else if ((FinalPhaseOpt = Args.getLastArg(options::OPT_c))) {
- FinalPhase = AssemblePhaseOrder;
+ } else if ((FinalPhaseArg = Args.getLastArg(options::OPT_c))) {
+ FinalPhase = phases::Assemble;
// Otherwise do everything.
} else
- FinalPhase = PostAssemblePhaseOrder;
+ FinalPhase = phases::Link;
- if (FinalPhaseOpt)
- FinalPhaseOpt->claim();
+ if (FinalPhaseArg)
+ FinalPhaseArg->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.
+ // Construct the actions to perform.
+ ActionList LinkerInputs;
for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
- llvm::errs() << "input " << i << ": "
- << Inputs[i].second->getValue(Args) << "\n";
+ types::ID InputType = Inputs[i].first;
+ const Arg *InputArg = Inputs[i].second;
+
+ unsigned NumSteps = types::getNumCompilationPhases(InputType);
+ assert(NumSteps && "Invalid number of steps!");
+
+ // If the first step comes after the final phase we are doing as
+ // part of this compilation, warn the user about it.
+ phases::ID InitialPhase = types::getCompilationPhase(InputType, 0);
+ if (InitialPhase > FinalPhase) {
+ Diag(clang::diag::warn_drv_input_file_unused)
+ << InputArg->getValue(Args)
+ << getPhaseName(InitialPhase)
+ << FinalPhaseArg->getOption().getName();
+ continue;
+ }
+
+ // Build the pipeline for this file.
+ Action *Current = new InputAction(*InputArg, InputType);
+ for (unsigned i = 0; i != NumSteps; ++i) {
+ phases::ID Phase = types::getCompilationPhase(InputType, i);
+
+ // We are done if this step is past what the user requested.
+ if (Phase > FinalPhase)
+ break;
+
+ // Queue linker inputs.
+ if (Phase == phases::Link) {
+ assert(i + 1 == NumSteps && "linking must be final compilation step.");
+ LinkerInputs.push_back(Current);
+ Current = 0;
+ break;
+ }
+
+ // Otherwise construct the appropriate action.
+ Current = ConstructPhaseAction(Args, Phase, Current);
+ if (Current->getType() == types::TY_Nothing)
+ break;
+ }
+
+ // If we ended with something, add to the output list.
+ if (Current)
+ Actions.push_back(Current);
+ }
+
+ // Add a link action if necessary.
+ if (!LinkerInputs.empty())
+ Actions.push_back(new LinkJobAction(LinkerInputs, types::TY_Image));
+}
+
+Action *Driver::ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
+ Action *Input) const {
+ // Build the appropriate action.
+ switch (Phase) {
+ case phases::Link: assert(0 && "link action invalid here.");
+ case phases::Preprocess: {
+ types::ID OutputTy = types::getPreprocessedType(Input->getType());
+ assert(OutputTy != types::TY_INVALID &&
+ "Cannot preprocess this input type!");
+ return new PreprocessJobAction(Input, OutputTy);
+ }
+ case phases::Precompile:
+ return new PrecompileJobAction(Input, types::TY_PCH);
+ case phases::Compile: {
+ if (Args.hasArg(options::OPT_fsyntax_only)) {
+ return new CompileJobAction(Input, types::TY_Nothing);
+ } else if (Args.hasArg(options::OPT__analyze)) {
+ return new AnalyzeJobAction(Input, types::TY_Plist);
+ } else if (Args.hasArg(options::OPT_emit_llvm)) {
+ types::ID Output =
+ Args.hasArg(options::OPT_S) ? types::TY_LLVMAsm : types::TY_LLVMBC;
+ return new CompileJobAction(Input, Output);
+ } else {
+ return new CompileJobAction(Input, types::TY_PP_Asm);
+ }
+ }
+ case phases::Assemble:
+ return new AssembleJobAction(Input, types::TY_Object);
}
- exit(0);
+
+ assert(0 && "invalid phase in ConstructPhaseAction");
+ return 0;
}
llvm::sys::Path Driver::GetFilePath(const char *Name) const {
More information about the cfe-commits
mailing list