forked from OSchip/llvm-project
Driver: Basic argument parsing.
- Add Driver::ParseArgStrings. - Store values directly in CommaJoinedArg to support simple access. - Add FlagArg class. llvm-svn: 66142
This commit is contained in:
parent
359df7420f
commit
d02cb1dc2b
|
@ -18,6 +18,7 @@ using llvm::dyn_cast;
|
||||||
using llvm::dyn_cast_or_null;
|
using llvm::dyn_cast_or_null;
|
||||||
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
namespace driver {
|
namespace driver {
|
||||||
|
@ -34,7 +35,8 @@ namespace driver {
|
||||||
class Arg {
|
class Arg {
|
||||||
public:
|
public:
|
||||||
enum ArgClass {
|
enum ArgClass {
|
||||||
PositionalClass = 0,
|
FlagClass = 0,
|
||||||
|
PositionalClass,
|
||||||
JoinedClass,
|
JoinedClass,
|
||||||
SeparateClass,
|
SeparateClass,
|
||||||
CommaJoinedClass,
|
CommaJoinedClass,
|
||||||
|
@ -75,6 +77,22 @@ namespace driver {
|
||||||
void dump() const;
|
void dump() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// FlagArg - An argument with no value.
|
||||||
|
class FlagArg : public Arg {
|
||||||
|
public:
|
||||||
|
FlagArg(const Option *Opt, unsigned Index);
|
||||||
|
|
||||||
|
virtual void render(const ArgList &Args, ArgStringList &Output) const;
|
||||||
|
|
||||||
|
virtual unsigned getNumValues() const { return 0; }
|
||||||
|
virtual const char *getValue(const ArgList &Args, unsigned N) const;
|
||||||
|
|
||||||
|
static bool classof(const Arg *A) {
|
||||||
|
return A->getKind() == Arg::FlagClass;
|
||||||
|
}
|
||||||
|
static bool classof(const FlagArg *) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
/// PositionalArg - A simple positional argument.
|
/// PositionalArg - A simple positional argument.
|
||||||
class PositionalArg : public Arg {
|
class PositionalArg : public Arg {
|
||||||
public:
|
public:
|
||||||
|
@ -105,7 +123,7 @@ namespace driver {
|
||||||
static bool classof(const Arg *A) {
|
static bool classof(const Arg *A) {
|
||||||
return A->getKind() == Arg::JoinedClass;
|
return A->getKind() == Arg::JoinedClass;
|
||||||
}
|
}
|
||||||
static bool classof(const PositionalArg *) { return true; }
|
static bool classof(const JoinedArg *) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// SeparateArg - An argument where one or more values follow the
|
/// SeparateArg - An argument where one or more values follow the
|
||||||
|
@ -124,7 +142,7 @@ namespace driver {
|
||||||
static bool classof(const Arg *A) {
|
static bool classof(const Arg *A) {
|
||||||
return A->getKind() == Arg::SeparateClass;
|
return A->getKind() == Arg::SeparateClass;
|
||||||
}
|
}
|
||||||
static bool classof(const PositionalArg *) { return true; }
|
static bool classof(const SeparateArg *) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// CommaJoinedArg - An argument with multiple values joined by
|
/// CommaJoinedArg - An argument with multiple values joined by
|
||||||
|
@ -134,20 +152,20 @@ namespace driver {
|
||||||
/// separate arguments, which allows it to be used as a generic
|
/// separate arguments, which allows it to be used as a generic
|
||||||
/// mechanism for passing arguments through to tools.
|
/// mechanism for passing arguments through to tools.
|
||||||
class CommaJoinedArg : public Arg {
|
class CommaJoinedArg : public Arg {
|
||||||
unsigned NumValues;
|
std::vector<std::string> Values;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CommaJoinedArg(const Option *Opt, unsigned Index, unsigned NumValues);
|
CommaJoinedArg(const Option *Opt, unsigned Index, const char *Str);
|
||||||
|
|
||||||
virtual void render(const ArgList &Args, ArgStringList &Output) const;
|
virtual void render(const ArgList &Args, ArgStringList &Output) const;
|
||||||
|
|
||||||
virtual unsigned getNumValues() const { return NumValues; }
|
virtual unsigned getNumValues() const { return Values.size(); }
|
||||||
virtual const char *getValue(const ArgList &Args, unsigned N) const;
|
virtual const char *getValue(const ArgList &Args, unsigned N) const;
|
||||||
|
|
||||||
static bool classof(const Arg *A) {
|
static bool classof(const Arg *A) {
|
||||||
return A->getKind() == Arg::CommaJoinedClass;
|
return A->getKind() == Arg::CommaJoinedClass;
|
||||||
}
|
}
|
||||||
static bool classof(const PositionalArg *) { return true; }
|
static bool classof(const CommaJoinedArg *) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// JoinedAndSeparateArg - An argument with both joined and separate
|
/// JoinedAndSeparateArg - An argument with both joined and separate
|
||||||
|
@ -164,7 +182,7 @@ namespace driver {
|
||||||
static bool classof(const Arg *A) {
|
static bool classof(const Arg *A) {
|
||||||
return A->getKind() == Arg::JoinedAndSeparateClass;
|
return A->getKind() == Arg::JoinedAndSeparateClass;
|
||||||
}
|
}
|
||||||
static bool classof(const PositionalArg *) { return true; }
|
static bool classof(const JoinedAndSeparateArg *) { return true; }
|
||||||
};
|
};
|
||||||
} // end namespace driver
|
} // end namespace driver
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
namespace driver {
|
namespace driver {
|
||||||
|
class ArgList;
|
||||||
class Compilation;
|
class Compilation;
|
||||||
class OptTable;
|
class OptTable;
|
||||||
|
|
||||||
|
@ -20,6 +21,10 @@ namespace driver {
|
||||||
class Driver {
|
class Driver {
|
||||||
OptTable *Opts;
|
OptTable *Opts;
|
||||||
|
|
||||||
|
/// ParseArgStrings - Parse the given list of strings into an
|
||||||
|
/// ArgList.
|
||||||
|
ArgList *ParseArgStrings(const char **ArgBegin, const char **ArgEnd);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Driver();
|
Driver();
|
||||||
~Driver();
|
~Driver();
|
||||||
|
|
|
@ -55,3 +55,4 @@
|
||||||
OPTION(ArchOpt, Separate, "-arch", 0, 0, "", 0)
|
OPTION(ArchOpt, Separate, "-arch", 0, 0, "", 0)
|
||||||
OPTION(PassExitCodesFlag, Flag, "-pass-exit-codes", 0, 0, "", 0)
|
OPTION(PassExitCodesFlag, Flag, "-pass-exit-codes", 0, 0, "", 0)
|
||||||
OPTION(PrintFileNameOpt, Joined, "-print-file-name=", 0, 0, "", 0)
|
OPTION(PrintFileNameOpt, Joined, "-print-file-name=", 0, 0, "", 0)
|
||||||
|
OPTION(WpOpt, CommaJoined, "-Wp,", 0, 0, "", 0)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "clang/Driver/Arg.h"
|
#include "clang/Driver/Arg.h"
|
||||||
|
#include "clang/Driver/ArgList.h"
|
||||||
#include "clang/Driver/Option.h"
|
#include "clang/Driver/Option.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ void Arg::dump() const {
|
||||||
default:
|
default:
|
||||||
assert(0 && "Invalid kind");
|
assert(0 && "Invalid kind");
|
||||||
#define P(N) case N: llvm::errs() << #N; break
|
#define P(N) case N: llvm::errs() << #N; break
|
||||||
|
P(FlagClass);
|
||||||
P(PositionalClass);
|
P(PositionalClass);
|
||||||
P(JoinedClass);
|
P(JoinedClass);
|
||||||
P(SeparateClass);
|
P(SeparateClass);
|
||||||
|
@ -49,6 +51,19 @@ void Arg::dump() const {
|
||||||
llvm::errs().flush(); // FIXME
|
llvm::errs().flush(); // FIXME
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlagArg::FlagArg(const Option *Opt, unsigned Index)
|
||||||
|
: Arg(FlagClass, Opt, Index) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlagArg::render(const ArgList &Args, ArgStringList &Output) const {
|
||||||
|
assert(0 && "FIXME: Implement");
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *FlagArg::getValue(const ArgList &Args, unsigned N) const {
|
||||||
|
assert(0 && "Invalid index.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
PositionalArg::PositionalArg(const Option *Opt, unsigned Index)
|
PositionalArg::PositionalArg(const Option *Opt, unsigned Index)
|
||||||
: Arg(PositionalClass, Opt, Index) {
|
: Arg(PositionalClass, Opt, Index) {
|
||||||
}
|
}
|
||||||
|
@ -58,7 +73,8 @@ void PositionalArg::render(const ArgList &Args, ArgStringList &Output) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
|
const char *PositionalArg::getValue(const ArgList &Args, unsigned N) const {
|
||||||
assert(0 && "FIXME: Implement");
|
assert(N < getNumValues() && "Invalid index.");
|
||||||
|
return Args.getArgString(getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
JoinedArg::JoinedArg(const Option *Opt, unsigned Index)
|
JoinedArg::JoinedArg(const Option *Opt, unsigned Index)
|
||||||
|
@ -70,12 +86,28 @@ void JoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
|
const char *JoinedArg::getValue(const ArgList &Args, unsigned N) const {
|
||||||
assert(0 && "FIXME: Implement");
|
assert(N < getNumValues() && "Invalid index.");
|
||||||
|
// FIXME: Avoid strlen.
|
||||||
|
return Args.getArgString(getIndex()) + strlen(getOption().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index,
|
CommaJoinedArg::CommaJoinedArg(const Option *Opt, unsigned Index,
|
||||||
unsigned _NumValues)
|
const char *Str)
|
||||||
: Arg(CommaJoinedClass, Opt, Index), NumValues(_NumValues) {
|
: Arg(CommaJoinedClass, Opt, Index) {
|
||||||
|
const char *Prev = Str;
|
||||||
|
for (;; ++Str) {
|
||||||
|
char c = *Str;
|
||||||
|
|
||||||
|
if (!c) {
|
||||||
|
if (Prev != Str)
|
||||||
|
Values.push_back(std::string(Prev, Str));
|
||||||
|
break;
|
||||||
|
} else if (c == ',') {
|
||||||
|
if (Prev != Str)
|
||||||
|
Values.push_back(std::string(Prev, Str));
|
||||||
|
Prev = Str + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
|
void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
|
||||||
|
@ -83,7 +115,8 @@ void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CommaJoinedArg::getValue(const ArgList &Args, unsigned N) const {
|
const char *CommaJoinedArg::getValue(const ArgList &Args, unsigned N) const {
|
||||||
assert(0 && "FIXME: Implement");
|
assert(N < getNumValues() && "Invalid index.");
|
||||||
|
return Values[N].c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues)
|
SeparateArg::SeparateArg(const Option *Opt, unsigned Index, unsigned _NumValues)
|
||||||
|
@ -95,7 +128,8 @@ void SeparateArg::render(const ArgList &Args, ArgStringList &Output) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const {
|
const char *SeparateArg::getValue(const ArgList &Args, unsigned N) const {
|
||||||
assert(0 && "FIXME: Implement");
|
assert(N < getNumValues() && "Invalid index.");
|
||||||
|
return Args.getArgString(getIndex() + 1 + N);
|
||||||
}
|
}
|
||||||
|
|
||||||
JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index)
|
JoinedAndSeparateArg::JoinedAndSeparateArg(const Option *Opt, unsigned Index)
|
||||||
|
@ -109,5 +143,6 @@ void JoinedAndSeparateArg::render(const ArgList &Args,
|
||||||
|
|
||||||
const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
|
const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
|
||||||
unsigned N) const {
|
unsigned N) const {
|
||||||
|
assert(N < getNumValues() && "Invalid index.");
|
||||||
assert(0 && "FIXME: Implement");
|
assert(0 && "FIXME: Implement");
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
#include "clang/Driver/Arg.h"
|
#include "clang/Driver/Arg.h"
|
||||||
#include "clang/Driver/ArgList.h"
|
#include "clang/Driver/ArgList.h"
|
||||||
#include "clang/Driver/Compilation.h"
|
#include "clang/Driver/Compilation.h"
|
||||||
|
#include "clang/Driver/Option.h"
|
||||||
#include "clang/Driver/Options.h"
|
#include "clang/Driver/Options.h"
|
||||||
|
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
using namespace clang::driver;
|
using namespace clang::driver;
|
||||||
|
|
||||||
Driver::Driver() : Opts(new OptTable()) {
|
Driver::Driver() : Opts(new OptTable()) {
|
||||||
|
@ -23,6 +26,42 @@ Driver::~Driver() {
|
||||||
delete Opts;
|
delete Opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
Compilation *Driver::BuildCompilation(int argc, const char **argv) {
|
Compilation *Driver::BuildCompilation(int argc, const char **argv) {
|
||||||
|
ArgList *Args = ParseArgStrings(argv + 1, argv + argc);
|
||||||
|
|
||||||
|
// Hard coded to print-options behavior.
|
||||||
|
unsigned i = 0;
|
||||||
|
for (ArgList::iterator it = Args->begin(), ie = Args->end();
|
||||||
|
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";
|
||||||
|
|
||||||
|
llvm::errs().flush(); // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
return new Compilation();
|
return new Compilation();
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,7 @@ Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
|
||||||
if (strlen(getName()) != strlen(Args.getArgString(Index)))
|
if (strlen(getName()) != strlen(Args.getArgString(Index)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return new PositionalArg(this, Index++);
|
return new FlagArg(this, Index++);
|
||||||
}
|
}
|
||||||
|
|
||||||
JoinedOption::JoinedOption(options::ID ID, const char *Name,
|
JoinedOption::JoinedOption(options::ID ID, const char *Name,
|
||||||
|
@ -153,14 +153,7 @@ Arg *CommaJoinedOption::accept(const ArgList &Args, unsigned &Index) const {
|
||||||
// Get the suffix string.
|
// Get the suffix string.
|
||||||
// FIXME: Avoid strlen, and move to helper method?
|
// FIXME: Avoid strlen, and move to helper method?
|
||||||
const char *Suffix = Args.getArgString(Index) + strlen(getName());
|
const char *Suffix = Args.getArgString(Index) + strlen(getName());
|
||||||
const char *SuffixEnd = Suffix + strlen(Suffix);
|
return new CommaJoinedArg(this, Index++, Suffix);
|
||||||
|
|
||||||
// Degenerate case, exact match has no values.
|
|
||||||
if (Suffix == SuffixEnd)
|
|
||||||
return new CommaJoinedArg(this, Index++, 0);
|
|
||||||
|
|
||||||
return new CommaJoinedArg(this, Index++,
|
|
||||||
std::count(Suffix, SuffixEnd, ',') + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SeparateOption::SeparateOption(options::ID ID, const char *Name,
|
SeparateOption::SeparateOption(options::ID ID, const char *Name,
|
||||||
|
|
Loading…
Reference in New Issue