From: Peter Collingbourne Date: Fri, 30 Jul 2010 17:09:11 +0000 (+0000) Subject: Add specialisation iterators for {Class,Function}TemplateDecl X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9f339ba5b00256588d0d78786fff6d48ef073015;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@109870 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 0f25547675..246a06f963 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -512,6 +512,49 @@ protected: } }; + template , + typename _DeclType = typename _SETraits::DeclType> + class SpecIterator : public std::iterator { + typedef _SETraits SETraits; + typedef _DeclType DeclType; + + typedef typename llvm::FoldingSet::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 + SpecIterator makeSpecIterator(llvm::FoldingSet &Specs, + bool isEnd) { + return SpecIterator(isEnd ? Specs.end() : Specs.begin()); + } + template typename SpecEntryTraits::DeclType* findSpecializationImpl(llvm::FoldingSet &Specs, const TemplateArgument *Args, unsigned NumArgs, @@ -774,6 +817,16 @@ public: return redeclarable_base::getInstantiatedFromMemberTemplate(); } + typedef SpecIterator 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 @@ public: /// \endcode QualType getInjectedClassNameSpecialization(); + typedef SpecIterator spec_iterator; + + spec_iterator spec_begin() { + return makeSpecIterator(getSpecializations(), false); + } + + spec_iterator spec_end() { + return makeSpecIterator(getSpecializations(), true); + } + + typedef SpecIterator + 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; }