[cfe-commits] r89860 - in /cfe/trunk: include/clang/Driver/ArgList.h include/clang/Driver/OptSpecifier.h lib/Driver/ArgList.cpp
Daniel Dunbar
daniel at zuster.org
Wed Nov 25 03:33:30 PST 2009
Author: ddunbar
Date: Wed Nov 25 05:33:30 2009
New Revision: 89860
URL: http://llvm.org/viewvc/llvm-project?rev=89860&view=rev
Log:
Add an arg_iterator, for iterating over a subset of arguments in an ArgList.
Modified:
cfe/trunk/include/clang/Driver/ArgList.h
cfe/trunk/include/clang/Driver/OptSpecifier.h
cfe/trunk/lib/Driver/ArgList.cpp
Modified: cfe/trunk/include/clang/Driver/ArgList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ArgList.h?rev=89860&r1=89859&r2=89860&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/ArgList.h (original)
+++ cfe/trunk/include/clang/Driver/ArgList.h Wed Nov 25 05:33:30 2009
@@ -25,8 +25,66 @@
namespace clang {
namespace driver {
class Arg;
+ class ArgList;
class Option;
+ /// arg_iterator - Iterates through arguments stored inside an ArgList.
+ class arg_iterator {
+ /// The current argument.
+ llvm::SmallVectorImpl<Arg*>::const_iterator Current;
+
+ /// The argument list we are iterating over.
+ const ArgList &Args;
+
+ /// Optional filters on the arguments which will be match. Most clients
+ /// should never want to iterate over arguments without filters, so we won't
+ /// bother to factor this into two separate iterator implementations.
+ //
+ // FIXME: Make efficient; the idea is to provide efficient iteration over
+ // all arguments which match a particular id and then just provide an
+ // iterator combinator which takes multiple iterators which can be
+ // efficiently compared and returns them in order.
+ OptSpecifier Id0, Id1, Id2;
+
+ void SkipToNextArg();
+
+ public:
+ typedef const Arg* value_type;
+ typedef const Arg* reference;
+ typedef const Arg* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ arg_iterator(llvm::SmallVectorImpl<Arg*>::const_iterator it,
+ const ArgList &_Args, OptSpecifier _Id0 = 0U,
+ OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
+ : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+ SkipToNextArg();
+ }
+
+ reference operator*() const { return *Current; }
+ pointer operator->() const { return *Current; }
+
+ arg_iterator &operator++() {
+ ++Current;
+ SkipToNextArg();
+ return *this;
+ }
+
+ arg_iterator operator++(int) {
+ arg_iterator tmp(*this);
+ ++(*this);
+ return tmp;
+ }
+
+ friend bool operator==(arg_iterator LHS, arg_iterator RHS) {
+ return LHS.Current == RHS.Current;
+ }
+ friend bool operator!=(arg_iterator LHS, arg_iterator RHS) {
+ return !(LHS == RHS);
+ }
+ };
+
/// ArgList - Ordered collection of driver arguments.
///
/// The ArgList class manages a list of Arg instances as well as
@@ -62,6 +120,10 @@
unsigned size() const { return Args.size(); }
+ /// @}
+ /// @name Arg Iteration
+ /// @{
+
iterator begin() { return Args.begin(); }
iterator end() { return Args.end(); }
@@ -74,6 +136,18 @@
const_reverse_iterator rbegin() const { return Args.rbegin(); }
const_reverse_iterator rend() const { return Args.rend(); }
+ arg_iterator filtered_begin(OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+ OptSpecifier Id2 = 0U) const {
+ return arg_iterator(Args.begin(), *this, Id0, Id1, Id2);
+ }
+ arg_iterator filtered_end() const {
+ return arg_iterator(Args.end(), *this);
+ }
+
+ /// @}
+ /// @name Arg Access
+ /// @{
+
/// hasArg - Does the arg list contain any option matching \arg Id.
///
/// \arg Claim Whether the argument should be claimed, if it exists.
@@ -115,17 +189,13 @@
void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
/// AddAllArgs - Render all arguments matching the given ids.
- void AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const;
void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1) const;
- void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1,
- OptSpecifier Id2) const;
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
/// AddAllArgValues - Render the argument values of all arguments
/// matching the given ids.
- void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const;
void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1) const;
+ OptSpecifier Id1 = 0U, OptSpecifier Id2 = 0U) const;
/// AddAllArgsTranslated - Render all the arguments matching the
/// given ids, but forced to separate args and using the provided
Modified: cfe/trunk/include/clang/Driver/OptSpecifier.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/OptSpecifier.h?rev=89860&r1=89859&r2=89860&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/OptSpecifier.h (original)
+++ cfe/trunk/include/clang/Driver/OptSpecifier.h Wed Nov 25 05:33:30 2009
@@ -22,9 +22,12 @@
explicit OptSpecifier(bool); // DO NOT IMPLEMENT
public:
+ OptSpecifier() : ID(0) {}
/*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
/*implicit*/ OptSpecifier(const Option *Opt);
+ bool isValid() const { return ID != 0; }
+
unsigned getID() const { return ID; }
bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
Modified: cfe/trunk/lib/Driver/ArgList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ArgList.cpp?rev=89860&r1=89859&r2=89860&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ArgList.cpp (original)
+++ cfe/trunk/lib/Driver/ArgList.cpp Wed Nov 25 05:33:30 2009
@@ -17,6 +17,23 @@
using namespace clang::driver;
+void arg_iterator::SkipToNextArg() {
+ for (; Current != Args.end(); ++Current) {
+ // Done if there are no filters.
+ if (!Id0.isValid())
+ break;
+
+ // Otherwise require a match.
+ const Option &O = (*Current)->getOption();
+ if (O.matches(Id0) ||
+ (Id1.isValid() && O.matches(Id1)) ||
+ (Id2.isValid() && O.matches(Id2)))
+ break;
+ }
+}
+
+//
+
ArgList::ArgList(arglist_type &_Args) : Args(_Args) {
}
@@ -98,95 +115,46 @@
}
}
-void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const {
- // FIXME: Make fast.
- for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().matches(Id0)) {
- A->claim();
- A->render(*this, Output);
- }
- }
-}
-
-void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1) const {
- // FIXME: Make fast.
- for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
- A->claim();
- A->render(*this, Output);
- }
- }
-}
-
void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
OptSpecifier Id1, OptSpecifier Id2) const {
- // FIXME: Make fast.
- for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().matches(Id0) || A->getOption().matches(Id1) ||
- A->getOption().matches(Id2)) {
- A->claim();
- A->render(*this, Output);
- }
- }
-}
-
-void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const {
- // FIXME: Make fast.
- for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().matches(Id0)) {
- A->claim();
- for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
- Output.push_back(A->getValue(*this, i));
- }
+ for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
+ ie = filtered_end(); it != ie; ++it) {
+ it->claim();
+ it->render(*this, Output);
}
}
void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
- OptSpecifier Id1) const {
- // FIXME: Make fast.
- for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().matches(Id0) || A->getOption().matches(Id1)) {
- A->claim();
- for (unsigned i = 0, e = A->getNumValues(); i != e; ++i)
- Output.push_back(A->getValue(*this, i));
- }
+ OptSpecifier Id1, OptSpecifier Id2) const {
+ for (arg_iterator it = filtered_begin(Id0, Id1, Id2),
+ ie = filtered_end(); it != ie; ++it) {
+ it->claim();
+ for (unsigned i = 0, e = it->getNumValues(); i != e; ++i)
+ Output.push_back(it->getValue(*this, i));
}
}
void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
const char *Translation,
bool Joined) const {
- // FIXME: Make fast.
- for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().matches(Id0)) {
- A->claim();
-
- if (Joined) {
- std::string Value = Translation;
- Value += A->getValue(*this, 0);
- Output.push_back(MakeArgString(Value.c_str()));
- } else {
- Output.push_back(Translation);
- Output.push_back(A->getValue(*this, 0));
- }
+ for (arg_iterator it = filtered_begin(Id0),
+ ie = filtered_end(); it != ie; ++it) {
+ it->claim();
+
+ if (Joined) {
+ Output.push_back(MakeArgString(llvm::StringRef(Translation) +
+ it->getValue(*this, 0)));
+ } else {
+ Output.push_back(Translation);
+ Output.push_back(it->getValue(*this, 0));
}
}
}
void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
- // FIXME: Make fast.
- for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
- const Arg *A = *it;
- if (A->getOption().matches(Id0))
- A->claim();
- }
+ for (arg_iterator it = filtered_begin(Id0),
+ ie = filtered_end(); it != ie; ++it)
+ it->claim();
}
const char *ArgList::MakeArgString(const llvm::Twine &T) const {
More information about the cfe-commits
mailing list