2009-03-02 19:59:07 +00:00
|
|
|
//===--- Driver.cpp - Clang GCC Compatible Driver -----------------------*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "clang/Driver/Driver.h"
|
|
|
|
|
2009-03-04 20:49:20 +00:00
|
|
|
#include "clang/Driver/Arg.h"
|
|
|
|
#include "clang/Driver/ArgList.h"
|
|
|
|
#include "clang/Driver/Compilation.h"
|
2009-03-05 06:38:47 +00:00
|
|
|
#include "clang/Driver/Option.h"
|
2009-03-04 20:49:20 +00:00
|
|
|
#include "clang/Driver/Options.h"
|
2009-03-05 06:38:47 +00:00
|
|
|
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2009-03-04 20:49:20 +00:00
|
|
|
using namespace clang::driver;
|
|
|
|
|
2009-03-10 20:52:46 +00:00
|
|
|
Driver::Driver(const char *_Name, const char *_Dir)
|
|
|
|
: Opts(new OptTable()),
|
|
|
|
Name(_Name), Dir(_Dir), Host(0),
|
|
|
|
CCCIsCXX(false), CCCEcho(false),
|
|
|
|
CCCNoClang(false), CCCNoClangCXX(false), CCCNoClangCPP(false)
|
|
|
|
{
|
2009-03-04 20:49:20 +00:00
|
|
|
|
2009-03-02 19:59:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Driver::~Driver() {
|
2009-03-04 20:49:20 +00:00
|
|
|
delete Opts;
|
2009-03-02 19:59:07 +00:00
|
|
|
}
|
|
|
|
|
2009-03-05 06:38:47 +00:00
|
|
|
ArgList *Driver::ParseArgStrings(const char **ArgBegin, const char **ArgEnd) {
|
|
|
|
ArgList *Args = new ArgList(ArgBegin, ArgEnd);
|
|
|
|
|
|
|
|
unsigned Index = 0, End = ArgEnd - ArgBegin;
|
|
|
|
while (Index < End) {
|
|
|
|
unsigned Prev = Index;
|
|
|
|
Arg *A = getOpts().ParseOneArg(*Args, Index, End);
|
|
|
|
if (A)
|
|
|
|
Args->append(A);
|
|
|
|
|
|
|
|
assert(Index > Prev && "Parser failed to consume argument.");
|
|
|
|
}
|
|
|
|
|
|
|
|
return Args;
|
|
|
|
}
|
|
|
|
|
2009-03-02 19:59:07 +00:00
|
|
|
Compilation *Driver::BuildCompilation(int argc, const char **argv) {
|
2009-03-10 20:52:46 +00:00
|
|
|
// FIXME: This stuff needs to go into the Compilation, not the
|
|
|
|
// driver.
|
|
|
|
bool CCCPrintOptions = false, CCCPrintPhases = false;
|
2009-03-05 06:38:47 +00:00
|
|
|
|
2009-03-10 20:52:46 +00:00
|
|
|
const char **Start = argv + 1, **End = argv + argc;
|
|
|
|
|
|
|
|
// Read -ccc args.
|
|
|
|
//
|
|
|
|
// FIXME: We need to figure out where this behavior should
|
|
|
|
// live. Most of it should be outside in the client; the parts that
|
|
|
|
// aren't should have proper options, either by introducing new ones
|
|
|
|
// or by overloading gcc ones like -V or -b.
|
|
|
|
for (; Start != End && memcmp(*Start, "-ccc-", 5) == 0; ++Start) {
|
|
|
|
const char *Opt = *Start + 5;
|
|
|
|
|
|
|
|
if (!strcmp(Opt, "print-options")) {
|
|
|
|
CCCPrintOptions = true;
|
|
|
|
} else if (!strcmp(Opt, "print-phases")) {
|
|
|
|
CCCPrintPhases = true;
|
|
|
|
} else if (!strcmp(Opt, "cxx")) {
|
|
|
|
CCCIsCXX = true;
|
|
|
|
} else if (!strcmp(Opt, "echo")) {
|
|
|
|
CCCEcho = true;
|
|
|
|
|
|
|
|
} else if (!strcmp(Opt, "no-clang")) {
|
|
|
|
CCCNoClang = true;
|
|
|
|
} else if (!strcmp(Opt, "no-clang-cxx")) {
|
|
|
|
CCCNoClangCXX = true;
|
|
|
|
} else if (!strcmp(Opt, "no-clang-cpp")) {
|
|
|
|
CCCNoClangCPP = true;
|
|
|
|
} else if (!strcmp(Opt, "clang-archs")) {
|
|
|
|
assert(Start+1 < End && "FIXME: -ccc- argument handling.");
|
|
|
|
const char *Cur = *++Start;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
const char *Next = strchr(Cur, ',');
|
|
|
|
|
|
|
|
if (Next) {
|
|
|
|
CCCClangArchs.insert(std::string(Cur, Next));
|
|
|
|
Cur = Next + 1;
|
|
|
|
} else {
|
|
|
|
CCCClangArchs.insert(std::string(Cur));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (!strcmp(Opt, "host-bits")) {
|
|
|
|
assert(Start+1 < End && "FIXME: -ccc- argument handling.");
|
|
|
|
HostBits = *++Start;
|
|
|
|
} else if (!strcmp(Opt, "host-machine")) {
|
|
|
|
assert(Start+1 < End && "FIXME: -ccc- argument handling.");
|
|
|
|
HostMachine = *++Start;
|
|
|
|
} else if (!strcmp(Opt, "host-release")) {
|
|
|
|
assert(Start+1 < End && "FIXME: -ccc- argument handling.");
|
|
|
|
HostRelease = *++Start;
|
|
|
|
} else if (!strcmp(Opt, "host-system")) {
|
|
|
|
assert(Start+1 < End && "FIXME: -ccc- argument handling.");
|
|
|
|
HostSystem = *++Start;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// FIXME: Error handling.
|
|
|
|
llvm::errs() << "invalid option: " << *Start << "\n";
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ArgList *Args = ParseArgStrings(Start, End);
|
|
|
|
|
|
|
|
// FIXME: This behavior shouldn't be here.
|
|
|
|
if (CCCPrintOptions) {
|
|
|
|
PrintOptions(Args);
|
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(0 && "FIXME: Implement");
|
|
|
|
|
|
|
|
return new Compilation();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Driver::PrintOptions(const ArgList *Args) {
|
2009-03-05 06:38:47 +00:00
|
|
|
unsigned i = 0;
|
2009-03-10 20:52:46 +00:00
|
|
|
for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
|
2009-03-05 06:38:47 +00:00
|
|
|
it != ie; ++it, ++i) {
|
|
|
|
Arg *A = *it;
|
|
|
|
llvm::errs() << "Option " << i << " - "
|
|
|
|
<< "Name: \"" << A->getOption().getName() << "\", "
|
|
|
|
<< "Values: {";
|
|
|
|
for (unsigned j = 0; j < A->getNumValues(); ++j) {
|
|
|
|
if (j)
|
|
|
|
llvm::errs() << ", ";
|
|
|
|
llvm::errs() << '"' << A->getValue(*Args, j) << '"';
|
|
|
|
}
|
|
|
|
llvm::errs() << "}\n";
|
|
|
|
}
|
2009-03-02 19:59:07 +00:00
|
|
|
}
|