[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