forked from OSchip/llvm-project
Driver: Start sketching construction of abstract built actions.
llvm-svn: 66783
This commit is contained in:
parent
15adce4ea2
commit
1688f1a7e0
|
@ -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
|
|
@ -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 @@ public:
|
|||
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
|
||||
|
|
|
@ -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 @@ ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) {
|
|||
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 @@ ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) {
|
|||
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 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
|
|||
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 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) {
|
|||
|
||||
// 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 @@ void Driver::PrintOptions(const ArgList *Args) {
|
|||
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 @@ HostInfo *Driver::GetHostInfo(const char *Triple) {
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue