[cfe-commits] r67038 - in /cfe/trunk: include/clang/Basic/DiagnosticDriverKinds.def include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/Driver.h lib/Driver/Driver.cpp lib/Driver/InputInfo.h tools/driver/driver.cpp
Daniel Dunbar
daniel at zuster.org
Sun Mar 15 23:56:51 PDT 2009
Author: ddunbar
Date: Mon Mar 16 01:56:51 2009
New Revision: 67038
URL: http://llvm.org/viewvc/llvm-project?rev=67038&view=rev
Log:
Driver: Implement majority tool binding logic.
- Still need code for determining proper output location.
- Doesn't work yet, of course, as the host isn't providing real
tool chains.
- Interface still has a few warts, but has gotten a nice bit of
polish during the rewrite.
Added:
cfe/trunk/lib/Driver/InputInfo.h
Modified:
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def
cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/lib/Driver/Driver.cpp
cfe/trunk/tools/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=67038&r1=67037&r2=67038&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.def Mon Mar 16 01:56:51 2009
@@ -28,8 +28,12 @@
"no input files")
DIAG(err_drv_use_of_Z_option, ERROR,
"unsupported use of internal gcc -Z option '%0'")
+DIAG(err_drv_output_argument_with_multiple_files, ERROR,
+ "cannot specify -o when generating multiple output files")
DIAG(warn_drv_input_file_unused, WARNING,
"%0: '%1' input file unused when '%2' is present")
DIAG(warn_drv_unused_argument, WARNING,
"argument unused during compilation: '%0'")
+DIAG(warn_drv_pipe_ignored_with_save_temps, WARNING,
+ "-pipe ignored because -save-temps specified")
Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=67038&r1=67037&r2=67038&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Mon Mar 16 01:56:51 2009
@@ -21,10 +21,14 @@
def err_drv_no_input_files : Error<"no input files">;
def err_drv_use_of_Z_option : Error<
"unsupported use of internal gcc -Z option '%0'">;
+def err_drv_output_argument_with_multiple_files : Error<
+ "cannot specify -o when generating multiple output files">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input file unused when '%2' is present">;
def warn_drv_unused_argument : Warning<
"argument unused during compilation: '%0'">;
+def warn_drv_pipe_ignored_with_save_temps : Warning<
+ "-pipe ignored because -save-temps specified">;
}
Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=67038&r1=67037&r2=67038&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Mon Mar 16 01:56:51 2009
@@ -27,7 +27,9 @@
class ArgList;
class Compilation;
class HostInfo;
+ class InputInfo;
class OptTable;
+ class PipedJob;
class ToolChain;
/// Driver - Encapsulate logic for constructing compilation processes
@@ -54,6 +56,9 @@
/// Default host triple.
std::string DefaultHostTriple;
+ /// Default name for linked images (e.g., "a.out").
+ std::string DefaultImageName;
+
/// Host information for the platform the driver is running as. This
/// will generally be the actual host platform, but not always.
HostInfo *Host;
@@ -95,6 +100,7 @@
public:
Driver(const char *_Name, const char *_Dir,
const char *_DefaultHostTriple,
+ const char *_DefaultImageName,
Diagnostic &_Diags);
~Driver();
@@ -186,6 +192,17 @@
Action *ConstructPhaseAction(const ArgList &Args, phases::ID Phase,
Action *Input) const;
+
+ /// BuildJobsForAction - Construct the jobs to perform for the
+ /// action \arg A.
+ void BuildJobsForAction(Compilation &C,
+ const Action *A,
+ const ToolChain *TC,
+ bool CanAcceptPipe,
+ bool AtTopLevel,
+ const char *LinkingOutput,
+ InputInfo &Result) 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=67038&r1=67037&r2=67038&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Mon Mar 16 01:56:51 2009
@@ -15,23 +15,30 @@
#include "clang/Driver/Compilation.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/HostInfo.h"
+#include "clang/Driver/Job.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Types.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
+#include "InputInfo.h"
+
#include <map>
using namespace clang::driver;
Driver::Driver(const char *_Name, const char *_Dir,
const char *_DefaultHostTriple,
+ const char *_DefaultImageName,
Diagnostic &_Diags)
: Opts(new OptTable()), Diags(_Diags),
Name(_Name), Dir(_Dir), DefaultHostTriple(_DefaultHostTriple),
+ DefaultImageName(_DefaultImageName),
Host(0),
CCCIsCXX(false), CCCEcho(false),
CCCNoClang(false), CCCNoClangCXX(false), CCCNoClangCPP(false),
@@ -567,8 +574,60 @@
return 0;
}
-void Driver::BuildJobs(Compilation &C,
- const ActionList &Actions) const {
+void Driver::BuildJobs(Compilation &C, const ActionList &Actions) const {
+ bool SaveTemps = C.getArgs().hasArg(options::OPT_save_temps);
+ bool UsePipes = C.getArgs().hasArg(options::OPT_pipe);
+
+ // -save-temps inhibits pipes.
+ if (SaveTemps && UsePipes) {
+ Diag(clang::diag::warn_drv_pipe_ignored_with_save_temps);
+ UsePipes = true;
+ }
+
+ Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o);
+
+ // It is an error to provide a -o option if we are making multiple
+ // output files.
+ if (FinalOutput) {
+ unsigned NumOutputs = 0;
+ for (ActionList::const_iterator it = Actions.begin(), ie = Actions.end();
+ it != ie; ++it)
+ if ((*it)->getType() != types::TY_Nothing)
+ ++NumOutputs;
+
+ if (NumOutputs > 1) {
+ Diag(clang::diag::err_drv_output_argument_with_multiple_files);
+ FinalOutput = 0;
+ }
+ }
+
+ for (ActionList::const_iterator it = Actions.begin(), ie = Actions.end();
+ it != ie; ++it) {
+ Action *A = *it;
+
+ // If we are linking an image for multiple archs then the linker
+ // wants -arch_multiple and -final_output <final image
+ // name>. Unfortunately, this doesn't fit in cleanly because we
+ // have to pass this information down.
+ //
+ // FIXME: This is a hack; find a cleaner way to integrate this
+ // into the process.
+ const char *LinkingOutput = 0;
+ if (isa<LinkJobAction>(A)) {
+ if (FinalOutput)
+ LinkingOutput = FinalOutput->getValue(C.getArgs());
+ else
+ LinkingOutput = DefaultImageName.c_str();
+ }
+
+ InputInfo II;
+ BuildJobsForAction(C,
+ A, DefaultToolChain,
+ /*CanAcceptPipe*/ true,
+ /*AtTopLevel*/ true,
+ /*LinkingOutput*/ LinkingOutput,
+ II);
+ }
// If there were no errors, warn about any unused arguments.
for (ArgList::const_iterator it = C.getArgs().begin(), ie = C.getArgs().end();
@@ -584,6 +643,91 @@
}
}
+void Driver::BuildJobsForAction(Compilation &C,
+ const Action *A,
+ const ToolChain *TC,
+ bool CanAcceptPipe,
+ bool AtTopLevel,
+ const char *LinkingOutput,
+ InputInfo &Result) const {
+ if (const InputAction *IA = dyn_cast<InputAction>(A)) {
+ const char *Name = IA->getInputArg().getValue(C.getArgs());
+ Result = InputInfo(Name, A->getType(), Name);
+ return;
+ }
+
+ if (const BindArchAction *BAA = dyn_cast<BindArchAction>(A)) {
+ const char *ArchName = BAA->getArchName();
+ BuildJobsForAction(C,
+ *BAA->begin(),
+ Host->getToolChain(C.getArgs(), ArchName),
+ CanAcceptPipe,
+ AtTopLevel,
+ LinkingOutput,
+ Result);
+ return;
+ }
+
+ const JobAction *JA = cast<JobAction>(A);
+ const Tool &T = TC->SelectTool(C, *JA);
+
+ // See if we should use an integrated preprocessor. We do so when we
+ // have exactly one input, since this is the only use case we care
+ // about (irrelevant since we don't support combine yet).
+ bool UseIntegratedCPP = false;
+ const ActionList *Inputs = &A->getInputs();
+ if (Inputs->size() == 1 && isa<PreprocessJobAction>(*Inputs->begin())) {
+ if (!C.getArgs().hasArg(options::OPT_no_integrated_cpp) &&
+ !C.getArgs().hasArg(options::OPT_traditional_cpp) &&
+ !C.getArgs().hasArg(options::OPT_save_temps) &&
+ T.hasIntegratedCPP()) {
+ UseIntegratedCPP = true;
+ Inputs = &(*Inputs)[0]->getInputs();
+ }
+ }
+
+ // Only use pipes when there is exactly one input.
+ bool TryToUsePipeInput = Inputs->size() == 1 && T.acceptsPipedInput();
+ llvm::SmallVector<InputInfo, 4> InputInfos;
+ for (ActionList::const_iterator it = Inputs->begin(), ie = Inputs->end();
+ it != ie; ++it) {
+ InputInfo II;
+ BuildJobsForAction(C, *it, TC, TryToUsePipeInput,
+ /*AtTopLevel*/false,
+ LinkingOutput,
+ II);
+ InputInfos.push_back(II);
+ }
+
+ // Determine if we should output to a pipe.
+ bool OutputToPipe = false;
+ if (CanAcceptPipe && T.canPipeOutput()) {
+ // Some actions default to writing to a pipe if they are the top
+ // level phase and there was no user override.
+ //
+ // FIXME: Is there a better way to handle this?
+ if (AtTopLevel) {
+ if (isa<PreprocessJobAction>(A) && !C.getArgs().hasArg(options::OPT_o))
+ OutputToPipe = true;
+ } else if (C.getArgs().hasArg(options::OPT_pipe))
+ OutputToPipe = true;
+ }
+
+ // Figure out where to put the job (pipes).
+ Job *Dest = &C.getJobs();
+ if (InputInfos[0].isPipe()) {
+ assert(InputInfos.size() == 1 && "Unexpected pipe with multiple inputs.");
+ Dest = &InputInfos[0].getPipe();
+ }
+
+ // Always use the first input as the base input.
+ const char *BaseInput = InputInfos[0].getBaseInput();
+ const char *Output = "foo";
+ // FIXME: Make the job.
+
+ Result = InputInfo(Output, A->getType(), BaseInput);
+}
+
llvm::sys::Path Driver::GetFilePath(const char *Name,
const ToolChain *TC) const {
// FIXME: Implement.
Added: cfe/trunk/lib/Driver/InputInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/InputInfo.h?rev=67038&view=auto
==============================================================================
--- cfe/trunk/lib/Driver/InputInfo.h (added)
+++ cfe/trunk/lib/Driver/InputInfo.h Mon Mar 16 01:56:51 2009
@@ -0,0 +1,57 @@
+//===--- InputInfo.h - Input Source & Type Information ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_DRIVER_INPUTINFO_H_
+#define CLANG_LIB_DRIVER_INPUTINFO_H_
+
+#include <cassert>
+
+namespace clang {
+namespace driver {
+ class PipedJob;
+
+/// InputInfo - Wrapper for information about an input source.
+class InputInfo {
+ union {
+ const char *Filename;
+ PipedJob *Pipe;
+ } Data;
+ bool IsPipe;
+ types::ID Type;
+ const char *BaseInput;
+
+public:
+ InputInfo() {}
+ InputInfo(const char *Filename, types::ID _Type, const char *_BaseInput)
+ : IsPipe(false), Type(_Type), BaseInput(_BaseInput) {
+ Data.Filename = Filename;
+ }
+ InputInfo(PipedJob *Pipe, types::ID _Type, const char *_BaseInput)
+ : IsPipe(true), Type(_Type), BaseInput(_BaseInput) {
+ Data.Pipe = Pipe;
+ }
+
+ bool isPipe() const { return IsPipe; }
+ types::ID getType() const { return Type; }
+ const char *getBaseInput() const { return BaseInput; }
+
+ const char *getInputFilename() const {
+ assert(!isPipe() && "Invalid accessor.");
+ return Data.Filename;
+ }
+ PipedJob &getPipe() const {
+ assert(isPipe() && "Invalid accessor.");
+ return *Data.Pipe;
+ }
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
Modified: cfe/trunk/tools/driver/driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/driver.cpp?rev=67038&r1=67037&r2=67038&view=diff
==============================================================================
--- cfe/trunk/tools/driver/driver.cpp (original)
+++ cfe/trunk/tools/driver/driver.cpp Mon Mar 16 01:56:51 2009
@@ -45,6 +45,7 @@
llvm::OwningPtr<Driver> TheDriver(new Driver(Path.getBasename().c_str(),
Path.getDirname().c_str(),
LLVM_HOSTTRIPLE,
+ "a.out",
Diags));
llvm::OwningPtr<Compilation> C(TheDriver->BuildCompilation(argc, argv));
More information about the cfe-commits
mailing list