template <typename EntryType> struct SpecEntryTraits {
typedef EntryType DeclType;
- static DeclType *getMostRecentDecl(EntryType *D) {
- return D->getMostRecentDecl();
+ static DeclType *getDecl(EntryType *D) {
+ return D;
+ }
+ static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) {
+ return D->getTemplateArgs().asArray();
}
};
: SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
DeclType *operator*() const {
- return SETraits::getMostRecentDecl(&*this->I);
+ return SETraits::getDecl(&*this->I)->getMostRecentDecl();
}
DeclType *operator->() const { return **this; }
};
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
ArrayRef<TemplateArgument> Args, void *&InsertPos);
+ template <class Derived, class EntryType>
+ void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
+ EntryType *Entry, void *InsertPos);
+
struct CommonBase {
CommonBase() : InstantiatedFromMember(nullptr, false) { }
SpecEntryTraits<FunctionTemplateSpecializationInfo> {
typedef FunctionDecl DeclType;
- static DeclType *
- getMostRecentDecl(FunctionTemplateSpecializationInfo *I) {
- return I->Function->getMostRecentDecl();
+ static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
+ return I->Function;
+ }
+ static ArrayRef<TemplateArgument>
+ getTemplateArgs(FunctionTemplateSpecializationInfo *I) {
+ return I->TemplateArguments->asArray();
}
};
return Common;
}
-template <class EntryType>
-typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType*
+template<class EntryType>
+typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
RedeclarableTemplateDecl::findSpecializationImpl(
- llvm::FoldingSetVector<EntryType> &Specs,
- ArrayRef<TemplateArgument> Args,
- void *&InsertPos) {
+ llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
+ void *&InsertPos) {
typedef SpecEntryTraits<EntryType> SETraits;
llvm::FoldingSetNodeID ID;
EntryType::Profile(ID,Args, getASTContext());
EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
- return Entry ? SETraits::getMostRecentDecl(Entry) : nullptr;
+ return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
+}
+
+template<class Derived, class EntryType>
+void RedeclarableTemplateDecl::addSpecializationImpl(
+ llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
+ void *InsertPos) {
+ typedef SpecEntryTraits<EntryType> SETraits;
+ if (InsertPos) {
+#ifndef NDEBUG
+ void *CorrectInsertPos;
+ assert(!findSpecializationImpl(Specializations,
+ SETraits::getTemplateArgs(Entry),
+ CorrectInsertPos) &&
+ InsertPos == CorrectInsertPos &&
+ "given incorrect InsertPos for specialization");
+#endif
+ Specializations.InsertNode(Entry, InsertPos);
+ } else {
+ EntryType *Existing = Specializations.GetOrInsertNode(Entry);
+ (void)Existing;
+ assert(SETraits::getDecl(Existing)->isCanonicalDecl() &&
+ "non-canonical specialization?");
+ }
+
+ if (ASTMutationListener *L = getASTMutationListener())
+ L->AddedCXXTemplateSpecialization(cast<Derived>(this),
+ SETraits::getDecl(Entry));
}
/// \brief Generate the injected template arguments for the given template
void FunctionTemplateDecl::addSpecialization(
FunctionTemplateSpecializationInfo *Info, void *InsertPos) {
- if (InsertPos)
- getSpecializations().InsertNode(Info, InsertPos);
- else
- getSpecializations().GetOrInsertNode(Info);
- if (ASTMutationListener *L = getASTMutationListener())
- L->AddedCXXTemplateSpecialization(this, Info->Function);
+ addSpecializationImpl<FunctionTemplateDecl>(getSpecializations(), Info,
+ InsertPos);
}
ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() {
void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D,
void *InsertPos) {
- if (InsertPos)
- getSpecializations().InsertNode(D, InsertPos);
- else {
- ClassTemplateSpecializationDecl *Existing
- = getSpecializations().GetOrInsertNode(D);
- (void)Existing;
- assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
- }
- if (ASTMutationListener *L = getASTMutationListener())
- L->AddedCXXTemplateSpecialization(this, D);
+ addSpecializationImpl<ClassTemplateDecl>(getSpecializations(), D, InsertPos);
}
ClassTemplatePartialSpecializationDecl *
void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D,
void *InsertPos) {
- if (InsertPos)
- getSpecializations().InsertNode(D, InsertPos);
- else {
- VarTemplateSpecializationDecl *Existing =
- getSpecializations().GetOrInsertNode(D);
- (void)Existing;
- assert(Existing->isCanonicalDecl() && "Non-canonical specialization?");
- }
- if (ASTMutationListener *L = getASTMutationListener())
- L->AddedCXXTemplateSpecialization(this, D);
+ addSpecializationImpl<VarTemplateDecl>(getSpecializations(), D, InsertPos);
}
VarTemplatePartialSpecializationDecl *