[cfe-commits] r109870 - /cfe/trunk/include/clang/AST/DeclTemplate.h

Peter Collingbourne peter at pcc.me.uk
Fri Jul 30 10:09:11 PDT 2010


Author: pcc
Date: Fri Jul 30 12:09:11 2010
New Revision: 109870

URL: http://llvm.org/viewvc/llvm-project?rev=109870&view=rev
Log:
Add specialisation iterators for {Class,Function}TemplateDecl

This patch introduces the ClassTemplateDecl::spec_{begin,end}()
and FunctionTemplateDecl::{,partial_}spec_{begin,end}() member
functions as a public interface for iterating over the declarations'
specialisation sets.

Modified:
    cfe/trunk/include/clang/AST/DeclTemplate.h

Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=109870&r1=109869&r2=109870&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Fri Jul 30 12:09:11 2010
@@ -512,6 +512,49 @@
     }
   };
 
+  template <typename EntryType,
+            typename _SETraits = SpecEntryTraits<EntryType>,
+            typename _DeclType = typename _SETraits::DeclType>
+  class SpecIterator : public std::iterator<std::forward_iterator_tag,
+                                            _DeclType*, ptrdiff_t,
+                                            _DeclType*, _DeclType*> {
+    typedef _SETraits SETraits;
+    typedef _DeclType DeclType;
+
+    typedef typename llvm::FoldingSet<EntryType>::iterator SetIteratorType;
+
+    SetIteratorType SetIter;
+
+  public:
+    SpecIterator() : SetIter() {}
+    SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
+
+    DeclType *operator*() const {
+      return SETraits::getMostRecentDeclaration(&*SetIter);
+    }
+    DeclType *operator->() const { return **this; }
+
+    SpecIterator &operator++() { ++SetIter; return *this; }
+    SpecIterator operator++(int) {
+      SpecIterator tmp(*this);
+      ++(*this);
+      return tmp;
+    }
+
+    bool operator==(SpecIterator Other) const {
+      return SetIter == Other.SetIter;
+    }
+    bool operator!=(SpecIterator Other) const {
+      return SetIter != Other.SetIter;
+    }
+  };
+
+  template <typename EntryType>
+  SpecIterator<EntryType> makeSpecIterator(llvm::FoldingSet<EntryType> &Specs,
+                                           bool isEnd) {
+    return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
+  }
+
   template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
   findSpecializationImpl(llvm::FoldingSet<EntryType> &Specs,
                          const TemplateArgument *Args, unsigned NumArgs,
@@ -774,6 +817,16 @@
     return redeclarable_base::getInstantiatedFromMemberTemplate();
   }
 
+  typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
+
+  spec_iterator spec_begin() {
+    return makeSpecIterator(getSpecializations(), false);
+  }
+
+  spec_iterator spec_end() {
+    return makeSpecIterator(getSpecializations(), true);
+  }
+
   /// Create a template function node.
   static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
                                       SourceLocation L,
@@ -1679,6 +1732,27 @@
   /// \endcode
   QualType getInjectedClassNameSpecialization();
 
+  typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
+
+  spec_iterator spec_begin() {
+    return makeSpecIterator(getSpecializations(), false);
+  }
+
+  spec_iterator spec_end() {
+    return makeSpecIterator(getSpecializations(), true);
+  }
+
+  typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
+          partial_spec_iterator;
+
+  partial_spec_iterator partial_spec_begin() {
+    return makeSpecIterator(getPartialSpecializations(), false);
+  }
+
+  partial_spec_iterator partial_spec_end() {
+    return makeSpecIterator(getPartialSpecializations(), true);
+  }
+
   // Implement isa/cast/dyncast support
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classof(const ClassTemplateDecl *D) { return true; }





More information about the cfe-commits mailing list