On Tue, Jul 27, 2010 at 10:29:14PM +0300, Argyrios Kyrtzidis wrote: > On Jul 27, 2010, at 10:17 PM, Peter Collingbourne wrote: > > On Tue, Jul 27, 2010 at 10:00:24PM +0300, Argyrios Kyrtzidis wrote: > >> On Jul 27, 2010, at 9:55 PM, Peter Collingbourne wrote: > >>> Another possibility would be to expose an iterator > >>> specs_begin()..specs_end() over the set of specialisations. This way > >>> we don't need to copy the vector and the client still doesn't need > >>> to care how the specialisation list is stored. > >> > >> Sounds good. I'd suggest that the iterator is a class wrapping the > >> FoldingSet's iterator and making sure to return the latest redeclaration, > >> what do you think ? > > > > Agreed. For consistency we can also have the FunctionTemplateDecl's > > specialisation iterator produce FunctionDecls instead of > > FunctionTemplateSpecializationInfos. > > Yes, that'd be great.
Done, please see the attached patches. I also decided to include some refactoring for the find*Specialization member functions. OK to commit? Thanks, -- Peter
>From 2101e942bff98f165255fa0c42b39293ec025a60 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne <[email protected]> Date: Fri, 30 Jul 2010 14:12:05 +0100 Subject: [PATCH 1/3] Introduce RedeclarableTemplateDecl::SpecEntryTraits SpecEntryTraits describes how to obtain the most recent declaration of a specialisation from an entry in a specialisation FoldingSet. --- include/clang/AST/DeclTemplate.h | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index b26c569..341c802 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -504,6 +504,14 @@ class RedeclarableTemplateDecl : public TemplateDecl { } protected: + template <typename EntryType> struct SpecEntryTraits { + typedef EntryType DeclType; + + static DeclType *getMostRecentDeclaration(EntryType *D) { + return D->getMostRecentDeclaration(); + } + }; + struct CommonBase { CommonBase() : InstantiatedFromMember(0, false) { } @@ -677,6 +685,16 @@ public: } }; +template <> struct RedeclarableTemplateDecl:: +SpecEntryTraits<FunctionTemplateSpecializationInfo> { + typedef FunctionDecl DeclType; + + static DeclType * + getMostRecentDeclaration(FunctionTemplateSpecializationInfo *I) { + return I->Function->getMostRecentDeclaration(); + } +}; + /// Declaration of a template function. class FunctionTemplateDecl : public RedeclarableTemplateDecl, public RedeclarableTemplate<FunctionTemplateDecl> { -- 1.7.1
>From 14ba624982d4c7f5f662320b877c921262407a1f Mon Sep 17 00:00:00 2001 From: Peter Collingbourne <[email protected]> Date: Fri, 30 Jul 2010 14:14:08 +0100 Subject: [PATCH 2/3] Refactor find*Specialization functions using SpecEntryTraits This patch reimplements the find*Specialization family of member functions of {Class,Function}TemplateDecl in terms of a common implementation that uses SpecEntryTraits to obtain the most recent declaration. --- include/clang/AST/DeclTemplate.h | 5 +++++ lib/AST/DeclTemplate.cpp | 33 +++++++++++++++++---------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 341c802..0f25547 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -512,6 +512,11 @@ protected: } }; + template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType* + findSpecializationImpl(llvm::FoldingSet<EntryType> &Specs, + const TemplateArgument *Args, unsigned NumArgs, + void *&InsertPos); + struct CommonBase { CommonBase() : InstantiatedFromMember(0, false) { } diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 25df086..e69338a 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -126,6 +126,19 @@ RedeclarableTemplateDecl *RedeclarableTemplateDecl::getNextRedeclaration() { return Common ? Common->Latest : this; } +template <class EntryType> +typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType* +RedeclarableTemplateDecl::findSpecializationImpl( + llvm::FoldingSet<EntryType> &Specs, + const TemplateArgument *Args, unsigned NumArgs, + void *&InsertPos) { + typedef SpecEntryTraits<EntryType> SETraits; + llvm::FoldingSetNodeID ID; + EntryType::Profile(ID,Args,NumArgs, getASTContext()); + EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos); + return Entry ? SETraits::getMostRecentDeclaration(Entry) : 0; +} + //===----------------------------------------------------------------------===// // FunctionTemplateDecl Implementation //===----------------------------------------------------------------------===// @@ -152,11 +165,7 @@ RedeclarableTemplateDecl::CommonBase *FunctionTemplateDecl::newCommon() { FunctionDecl * FunctionTemplateDecl::findSpecialization(const TemplateArgument *Args, unsigned NumArgs, void *&InsertPos) { - llvm::FoldingSetNodeID ID; - FunctionTemplateSpecializationInfo::Profile(ID,Args,NumArgs, getASTContext()); - FunctionTemplateSpecializationInfo *Info - = getSpecializations().FindNodeOrInsertPos(ID, InsertPos); - return Info ? Info->Function->getMostRecentDeclaration() : 0; + return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); } //===----------------------------------------------------------------------===// @@ -188,23 +197,15 @@ RedeclarableTemplateDecl::CommonBase *ClassTemplateDecl::newCommon() { ClassTemplateSpecializationDecl * ClassTemplateDecl::findSpecialization(const TemplateArgument *Args, unsigned NumArgs, void *&InsertPos) { - llvm::FoldingSetNodeID ID; - ClassTemplateSpecializationDecl::Profile(ID, Args, NumArgs, getASTContext()); - ClassTemplateSpecializationDecl *D - = getSpecializations().FindNodeOrInsertPos(ID, InsertPos); - return D ? D->getMostRecentDeclaration() : 0; + return findSpecializationImpl(getSpecializations(), Args, NumArgs, InsertPos); } ClassTemplatePartialSpecializationDecl * ClassTemplateDecl::findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs, void *&InsertPos) { - llvm::FoldingSetNodeID ID; - ClassTemplatePartialSpecializationDecl::Profile(ID, Args, NumArgs, - getASTContext()); - ClassTemplatePartialSpecializationDecl *D - = getPartialSpecializations().FindNodeOrInsertPos(ID, InsertPos); - return D ? D->getMostRecentDeclaration() : 0; + return findSpecializationImpl(getPartialSpecializations(), Args, NumArgs, + InsertPos); } void ClassTemplateDecl::getPartialSpecializations( -- 1.7.1
>From d241ce39994419295bff8900bba242f5595c3066 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne <[email protected]> Date: Fri, 30 Jul 2010 14:15:28 +0100 Subject: [PATCH 3/3] 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. --- include/clang/AST/DeclTemplate.h | 74 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 74 insertions(+), 0 deletions(-) diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 0f25547..246a06f 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -512,6 +512,49 @@ protected: } }; + 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 @@ public: 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 @@ public: /// \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; } -- 1.7.1
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
