forked from OSchip/llvm-project
Add an arg_iterator, for iterating over a subset of arguments in an ArgList.
llvm-svn: 89860
This commit is contained in:
parent
b7f1babb73
commit
b8c2f7d950
|
@ -25,8 +25,66 @@ namespace llvm {
|
|||
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 @@ namespace driver {
|
|||
|
||||
unsigned size() const { return Args.size(); }
|
||||
|
||||
/// @}
|
||||
/// @name Arg Iteration
|
||||
/// @{
|
||||
|
||||
iterator begin() { return Args.begin(); }
|
||||
iterator end() { return Args.end(); }
|
||||
|
||||
|
@ -74,6 +136,18 @@ namespace driver {
|
|||
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 @@ namespace driver {
|
|||
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
|
||||
|
|
|
@ -22,9 +22,12 @@ namespace driver {
|
|||
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(); }
|
||||
|
|
|
@ -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::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
for (arg_iterator it = filtered_begin(Id0),
|
||||
ie = filtered_end(); it != ie; ++it) {
|
||||
it->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));
|
||||
}
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue