[cfe-commits] r66783 - in /cfe/trunk: include/clang/Driver/Action.h include/clang/Driver/Driver.h lib/Driver/Driver.cpp
Daniel Dunbar
daniel at zuster.org
Thu Mar 12 00:58:46 PDT 2009
Author: ddunbar
Date: Thu Mar 12 02:58:46 2009
New Revision: 66783
URL: http://llvm.org/viewvc/llvm-project?rev=66783&view=rev
Log:
Driver: Start sketching construction of abstract built actions.
Added:
cfe/trunk/include/clang/Driver/Action.h
Modified:
cfe/trunk/include/clang/Driver/Driver.h
cfe/trunk/lib/Driver/Driver.cpp
Added: cfe/trunk/include/clang/Driver/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Action.h?rev=66783&view=auto
==============================================================================
--- cfe/trunk/include/clang/Driver/Action.h (added)
+++ cfe/trunk/include/clang/Driver/Action.h Thu Mar 12 02:58:46 2009
@@ -0,0 +1,28 @@
+//===--- Action.h - Abstract compilation steps ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_DRIVER_ACTION_H_
+#define CLANG_DRIVER_ACTION_H_
+
+namespace clang {
+namespace driver {
+
+/// Action - Represent an abstract compilation step to perform.
+///
+/// An action represents an edge in the compilation graph; typically
+/// it is a job to transform an input using some tool.
+class Action {
+public:
+
+};
+
+} // end namespace driver
+} // end namespace clang
+
+#endif
Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=66783&r1=66782&r2=66783&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Thu Mar 12 02:58:46 2009
@@ -14,8 +14,14 @@
#include <set>
#include <string>
+namespace llvm {
+ template<typename T, unsigned N> class SmallVector;
+ class raw_ostream;
+}
+
namespace clang {
namespace driver {
+ class Action;
class ArgList;
class Compilation;
class HostInfo;
@@ -80,19 +86,39 @@
const char *_DefaultHostTriple);
~Driver();
-
const OptTable &getOpts() const { return *Opts; }
/// BuildCompilation - Construct a compilation object for a command
/// line argument vector.
Compilation *BuildCompilation(int argc, const char **argv);
- /// PrintOptions - Print the given list of arguments.
- void PrintOptions(const ArgList *Args);
+ /// PrintOptions - Print the list of arguments.
+ void PrintOptions(const ArgList &Args);
+
+ /// PrintActions - Print the list of actions.
+ void PrintActions(const llvm::SmallVector<Action*, 2> &Actions);
/// GetHostInfo - Construct a new host info object for the given
/// host triple.
static HostInfo *GetHostInfo(const char *HostTriple);
+
+ /// BuildUniversalActions - Construct the list of actions to perform
+ /// for the given arguments, which may require a universal build.
+ ///
+ /// \param Args - The input arguments.
+ /// \param Actions - The list to store the resulting actions onto.
+ void BuildUniversalActions(const ArgList &Args,
+ llvm::SmallVector<Action*, 2> &Actions);
+
+ /// BuildActions - Construct the list of actions to perform for the
+ /// given arguments, which are only done for a single architecture.
+ ///
+ /// \param Args - The input arguments.
+ /// \param Actions - The list to store the resulting actions onto.
+ void BuildActions(const ArgList &Args,
+ llvm::SmallVector<Action*, 2> &Actions);
+
+ llvm::raw_ostream &Diag(const char *Message) const;
};
} // end namespace driver
Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=66783&r1=66782&r2=66783&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Thu Mar 12 02:58:46 2009
@@ -9,14 +9,17 @@
#include "clang/Driver/Driver.h"
+#include "clang/Driver/Action.h"
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/HostInfo.h"
#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
+#include "clang/Driver/Types.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Path.h"
using namespace clang::driver;
Driver::Driver(const char *_Name, const char *_Dir,
@@ -41,8 +44,14 @@
while (Index < End) {
unsigned Prev = Index;
Arg *A = getOpts().ParseOneArg(*Args, Index, End);
- if (A)
+ if (A) {
+ if (A->getOption().isUnsupported()) {
+ Diag("unsupported option: ") << A->getOption().getName() << "\n";
+ continue;
+ }
+
Args->append(A);
+ }
assert(Index > Prev && "Parser failed to consume argument.");
}
@@ -53,7 +62,7 @@
Compilation *Driver::BuildCompilation(int argc, const char **argv) {
// FIXME: This stuff needs to go into the Compilation, not the
// driver.
- bool CCCPrintOptions = false, CCCPrintPhases = false;
+ bool CCCPrintOptions = false, CCCPrintActions = false;
const char **Start = argv + 1, **End = argv + argc;
const char *HostTriple = DefaultHostTriple.c_str();
@@ -70,7 +79,7 @@
if (!strcmp(Opt, "print-options")) {
CCCPrintOptions = true;
} else if (!strcmp(Opt, "print-phases")) {
- CCCPrintPhases = true;
+ CCCPrintActions = true;
} else if (!strcmp(Opt, "cxx")) {
CCCIsCXX = true;
} else if (!strcmp(Opt, "echo")) {
@@ -115,18 +124,32 @@
// FIXME: This behavior shouldn't be here.
if (CCCPrintOptions) {
- PrintOptions(Args);
+ PrintOptions(*Args);
exit(0);
}
-
+
+ // Construct the list of abstract actions to perform for this
+ // compilation.
+ llvm::SmallVector<Action*, 2> Actions;
+ if (Host->useDriverDriver())
+ BuildUniversalActions(*Args, Actions);
+ else
+ BuildActions(*Args, Actions);
+
+ // FIXME: This behavior shouldn't be here.
+ if (CCCPrintActions) {
+ PrintActions(Actions);
+ exit(0);
+ }
+
assert(0 && "FIXME: Implement");
return new Compilation();
}
-void Driver::PrintOptions(const ArgList *Args) {
+void Driver::PrintOptions(const ArgList &Args) {
unsigned i = 0;
- for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
+ for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
it != ie; ++it, ++i) {
Arg *A = *it;
llvm::errs() << "Option " << i << " - "
@@ -135,12 +158,112 @@
for (unsigned j = 0; j < A->getNumValues(); ++j) {
if (j)
llvm::errs() << ", ";
- llvm::errs() << '"' << A->getValue(*Args, j) << '"';
+ llvm::errs() << '"' << A->getValue(Args, j) << '"';
}
llvm::errs() << "}\n";
}
}
+void Driver::PrintActions(const llvm::SmallVector<Action*, 2> &Actions) {
+ llvm::errs() << "FIXME: Print actions.";
+}
+
+void Driver::BuildUniversalActions(const ArgList &Args,
+ llvm::SmallVector<Action*, 2> &Actions) {
+ // FIXME: Implement
+ BuildActions(Args, Actions);
+}
+
+void Driver::BuildActions(const ArgList &Args,
+ llvm::SmallVector<Action*, 2> &Actions) {
+ types::ID InputType = types::TY_INVALID;
+ Arg *InputTypeArg = 0;
+
+ llvm::SmallVector<std::pair<types::ID, const Arg*>, 16> Inputs;
+ for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
+ it != ie; ++it) {
+ Arg *A = *it;
+
+ if (isa<InputOption>(A->getOption())) {
+ const char *Value = A->getValue(Args);
+ types::ID Ty = types::TY_INVALID;
+
+ // Infer the input type if necessary.
+ if (!InputType) {
+ // stdin must be handled specially.
+ if (memcmp(Value, "-", 2) == 0) {
+ // If running with -E, treat as a C input (this changes the
+ // builtin macros, for example). This may be overridden by
+ // -ObjC below.
+ //
+ // Otherwise emit an error but still use a valid type to
+ // avoid spurious errors (e.g., no inputs).
+ if (!Args.hasArg(options::OPT_E))
+ Diag("-E or -x required when input is from standard input");
+ Ty = types::TY_C;
+ } else {
+ // Otherwise lookup by extension, and fallback to ObjectType
+ // if not found.
+ if (const char *Ext = strrchr(Value, '.'))
+ Ty = types::lookupTypeForExtension(Ext + 1);
+ if (Ty == types::TY_INVALID)
+ Ty = types::TY_Object;
+ }
+
+ // -ObjC and -ObjC++ override the default language, but only
+ // -for "source files". We just treat everything that isn't a
+ // -linker input as a source file.
+ //
+ // FIXME: Clean this up if we move the phase sequence into the
+ // type.
+ if (Ty != types::TY_Object) {
+ if (Args.hasArg(options::OPT_ObjC))
+ Ty = types::TY_ObjC;
+ else if (Args.hasArg(options::OPT_ObjCXX))
+ Ty = types::TY_ObjCXX;
+ }
+ } else {
+ assert(InputTypeArg && "InputType set w/o InputTypeArg");
+ InputTypeArg->claim();
+ Ty = InputType;
+ }
+
+ // Check that the file exists. It isn't clear this is worth
+ // doing, since the tool presumably does this anyway, and this
+ // just adds an extra stat to the equation, but this is gcc
+ // compatible.
+ if (memcmp(Value, "-", 2) != 0 && !llvm::sys::Path(Value).exists())
+ Diag("no such file or directory: ") << A->getValue(Args) << "\n";
+ else
+ Inputs.push_back(std::make_pair(Ty, A));
+
+ } else if (A->getOption().isLinkerInput()) {
+ // Just treat as object type, we could make a special type for
+ // this if necessary.
+ Inputs.push_back(std::make_pair(types::TY_Object, A));
+
+ } else if (A->getOption().getId() == options::OPT_x) {
+ InputTypeArg = A;
+ InputType = types::lookupTypeForTypeSpecifier(A->getValue(Args));
+
+ // Follow gcc behavior and treat as linker input for invalid -x
+ // options. Its not clear why we shouldn't just revert to
+ // unknown; but this isn't very important, we might as well be
+ // bug comatible.
+ if (!InputType) {
+ Diag("language not recognized: ") << A->getValue(Args) << "\n";
+ InputType = types::TY_Object;
+ }
+ }
+ }
+
+ for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
+ llvm::errs() << "input " << i << ": "
+ << Inputs[i].second->getValue(Args) << "\n";
+ }
+ exit(0);
+}
+
HostInfo *Driver::GetHostInfo(const char *Triple) {
// Dice into arch, platform, and OS. This matches
// arch,platform,os = '(.*?)-(.*?)-(.*?)'
@@ -163,3 +286,8 @@
return new UnknownHostInfo(Arch.c_str(), Platform.c_str(), OS.c_str());
}
+
+// FIXME: Migrate to a normal diagnostics client.
+llvm::raw_ostream &Driver::Diag(const char *Message) const {
+ return (llvm::errs() << Message);
+}
More information about the cfe-commits
mailing list