aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-03-05 06:38:47 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-03-05 06:38:47 +0000
commit0648262df75d97b464c2be0ed867da3615659785 (patch)
tree1e1849d82dde933f81af038abce15e470f1dfcad
parentf27893a1a17dbde417dc7bccbbd25992c33215f9 (diff)
Driver: Basic argument parsing.
- Add Driver::ParseArgStrings. - Store values directly in CommaJoinedArg to support simple access. - Add FlagArg class. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66142 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Driver/Arg.h34
-rw-r--r--include/clang/Driver/Driver.h5
-rw-r--r--include/clang/Driver/Options.def1
-rw-r--r--lib/Driver/Arg.cpp47
-rw-r--r--lib/Driver/Driver.cpp39
-rw-r--r--lib/Driver/Option.cpp11
6 files changed, 114 insertions, 23 deletions
diff --git a/include/clang/Driver/Arg.h b/include/clang/Driver/Arg.h
index b558a84b89..ba72aac719 100644
--- a/include/clang/Driver/Arg.h
+++ b/include/clang/Driver/Arg.h
@@ -18,6 +18,7 @@ using llvm::dyn_cast;
using llvm::dyn_cast_or_null;
#include "Util.h"
+#include <vector>
namespace clang {
namespace driver {
@@ -34,7 +35,8 @@ namespace driver {
class Arg {
public:
enum ArgClass {
- PositionalClass = 0,
+ FlagClass = 0,
+ PositionalClass,
JoinedClass,
SeparateClass,
CommaJoinedClass,
@@ -75,6 +77,22 @@ namespace driver {
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.
class PositionalArg : public Arg {
public:
@@ -105,7 +123,7 @@ namespace driver {
static bool classof(const Arg *A) {
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
@@ -124,7 +142,7 @@ namespace driver {
static bool classof(const Arg *A) {
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
@@ -134,20 +152,20 @@ namespace driver {
/// separate arguments, which allows it to be used as a generic
/// mechanism for passing arguments through to tools.
class CommaJoinedArg : public Arg {
- unsigned NumValues;
+ std::vector<std::string> Values;
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 unsigned getNumValues() const { return NumValues; }
+ virtual unsigned getNumValues() const { return Values.size(); }
virtual const char *getValue(const ArgList &Args, unsigned N) const;
static bool classof(const Arg *A) {
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
@@ -164,7 +182,7 @@ namespace driver {
static bool classof(const Arg *A) {
return A->getKind() == Arg::JoinedAndSeparateClass;
}
- static bool classof(const PositionalArg *) { return true; }
+ static bool classof(const JoinedAndSeparateArg *) { return true; }
};
} // end namespace driver
} // end namespace clang
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index dc8c6c3d5d..dc30367c8b 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -12,6 +12,7 @@
namespace clang {
namespace driver {
+ class ArgList;
class Compilation;
class OptTable;
@@ -20,6 +21,10 @@ namespace driver {
class Driver {
OptTable *Opts;
+ /// ParseArgStrings - Parse the given list of strings into an
+ /// ArgList.
+ ArgList *ParseArgStrings(const char **ArgBegin, const char **ArgEnd);
+
public:
Driver();
~Driver();
diff --git a/include/clang/Driver/Options.def b/include/clang/Driver/Options.def
index 816678af6b..3c015622cd 100644
--- a/include/clang/Driver/Options.def
+++ b/include/clang/Driver/Options.def
@@ -55,3 +55,4 @@
OPTION(ArchOpt, Separate, "-arch", 0, 0, "", 0)
OPTION(PassExitCodesFlag, Flag, "-pass-exit-codes", 0, 0, "", 0)
OPTION(PrintFileNameOpt, Joined, "-print-file-name=", 0, 0, "", 0)
+OPTION(WpOpt, CommaJoined, "-Wp,", 0, 0, "", 0)
diff --git a/lib/Driver/Arg.cpp b/lib/Driver/Arg.cpp
index a4581d0e9e..52437e7772 100644
--- a/lib/Driver/Arg.cpp
+++ b/lib/Driver/Arg.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Arg.h"
+#include "clang/Driver/ArgList.h"
#include "clang/Driver/Option.h"
#include "llvm/Support/raw_ostream.h"
@@ -28,6 +29,7 @@ void Arg::dump() const {
default:
assert(0 && "Invalid kind");
#define P(N) case N: llvm::errs() << #N; break
+ P(FlagClass);
P(PositionalClass);
P(JoinedClass);
P(SeparateClass);
@@ -49,6 +51,19 @@ void Arg::dump() const {
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)
: 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 {
- assert(0 && "FIXME: Implement");
+ assert(N < getNumValues() && "Invalid index.");
+ return Args.getArgString(getIndex());
}
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 {
- 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,
- unsigned _NumValues)
- : Arg(CommaJoinedClass, Opt, Index), NumValues(_NumValues) {
+ const char *Str)
+ : 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 {
@@ -83,7 +115,8 @@ void CommaJoinedArg::render(const ArgList &Args, ArgStringList &Output) 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)
@@ -95,7 +128,8 @@ void SeparateArg::render(const ArgList &Args, ArgStringList &Output) 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)
@@ -109,5 +143,6 @@ void JoinedAndSeparateArg::render(const ArgList &Args,
const char *JoinedAndSeparateArg::getValue(const ArgList &Args,
unsigned N) const {
+ assert(N < getNumValues() && "Invalid index.");
assert(0 && "FIXME: Implement");
}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index d3c959499a..541a6d8eeb 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -12,7 +12,10 @@
#include "clang/Driver/Arg.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Option.h"
#include "clang/Driver/Options.h"
+
+#include "llvm/Support/raw_ostream.h"
using namespace clang::driver;
Driver::Driver() : Opts(new OptTable()) {
@@ -23,6 +26,42 @@ Driver::~Driver() {
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) {
+ 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();
}
diff --git a/lib/Driver/Option.cpp b/lib/Driver/Option.cpp
index 43d7e9e476..73cef25a55 100644
--- a/lib/Driver/Option.cpp
+++ b/lib/Driver/Option.cpp
@@ -127,7 +127,7 @@ Arg *FlagOption::accept(const ArgList &Args, unsigned &Index) const {
if (strlen(getName()) != strlen(Args.getArgString(Index)))
return 0;
- return new PositionalArg(this, Index++);
+ return new FlagArg(this, Index++);
}
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.
// FIXME: Avoid strlen, and move to helper method?
const char *Suffix = Args.getArgString(Index) + strlen(getName());
- const char *SuffixEnd = Suffix + strlen(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);
+ return new CommaJoinedArg(this, Index++, Suffix);
}
SeparateOption::SeparateOption(options::ID ID, const char *Name,