TemplateArgumentLoc *ArgsAsWritten;
unsigned NumArgsAsWritten;
+ /// \brief Sequence number indicating when this class template partial
+ /// specialization was added to the set of partial specializations for
+ /// its owning class template.
+ unsigned SequenceNumber;
+
/// \brief The class template partial specialization from which this
/// class template partial specialization was instantiated.
///
TemplateArgumentListBuilder &Builder,
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
- ClassTemplatePartialSpecializationDecl *PrevDecl)
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
DC, L, SpecializedTemplate, Builder,
PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
- NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
+ NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
+ InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
TemplateArgumentListBuilder &Builder,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber);
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
return NumArgsAsWritten;
}
+ /// \brief Get the sequence number for this class template partial
+ /// specialization.
+ unsigned getSequenceNumber() const { return SequenceNumber; }
+
/// \brief Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
/// instantiated.
return CommonPtr->PartialSpecializations;
}
+ /// \brief Retrieve the partial specializations as an ordered list.
+ void getPartialSpecializations(
+ llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
+
/// \brief Find a class template partial specialization with the given
/// type T.
///
C.Deallocate((void*)this);
}
+void ClassTemplateDecl::getPartialSpecializations(
+ llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS) {
+ llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &PartialSpecs
+ = CommonPtr->PartialSpecializations;
+ PS.clear();
+ PS.resize(PartialSpecs.size());
+ for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
+ P = PartialSpecs.begin(), PEnd = PartialSpecs.end();
+ P != PEnd; ++P) {
+ assert(!PS[P->getSequenceNumber()]);
+ PS[P->getSequenceNumber()] = &*P;
+ }
+}
+
ClassTemplatePartialSpecializationDecl *
ClassTemplateDecl::findPartialSpecialization(QualType T) {
ASTContext &Context = getASTContext();
TemplateArgumentListBuilder &Builder,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl) {
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber) {
unsigned N = ArgInfos.size();
TemplateArgumentLoc *ClonedArgs = new (Context) TemplateArgumentLoc[N];
for (unsigned I = 0; I != N; ++I)
SpecializedTemplate,
Builder,
ClonedArgs, N,
- PrevDecl);
+ PrevDecl,
+ SequenceNumber);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
Context.getInjectedClassNameType(Result, CanonInjectedType);
// Create a new class template partial specialization declaration node.
ClassTemplatePartialSpecializationDecl *PrevPartial
= cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
+ unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber()
+ : ClassTemplate->getPartialSpecializations().size();
ClassTemplatePartialSpecializationDecl *Partial
= ClassTemplatePartialSpecializationDecl::Create(Context,
ClassTemplate->getDeclContext(),
Converted,
TemplateArgs,
CanonType,
- PrevPartial);
+ PrevPartial,
+ SequenceNumber);
SetNestedNameSpecifier(Partial, SS);
if (PrevPartial) {
typedef std::pair<ClassTemplatePartialSpecializationDecl *,
TemplateArgumentList *> MatchResult;
llvm::SmallVector<MatchResult, 4> Matched;
- for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
- Partial = Template->getPartialSpecializations().begin(),
- PartialEnd = Template->getPartialSpecializations().end();
- Partial != PartialEnd;
- ++Partial) {
+ llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
+ Template->getPartialSpecializations(PartialSpecs);
+ for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
+ ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
TemplateDeductionInfo Info(Context, PointOfInstantiation);
if (TemplateDeductionResult Result
- = DeduceTemplateArguments(&*Partial,
+ = DeduceTemplateArguments(Partial,
ClassTemplateSpec->getTemplateArgs(),
Info)) {
// FIXME: Store the failed-deduction information for use in
// diagnostics, later.
(void)Result;
} else {
- Matched.push_back(std::make_pair(&*Partial, Info.take()));
+ Matched.push_back(std::make_pair(Partial, Info.take()));
}
}
return 0;
}
-namespace {
- class SortDeclByLocation {
- SourceManager &SourceMgr;
-
- public:
- explicit SortDeclByLocation(SourceManager &SourceMgr)
- : SourceMgr(SourceMgr) { }
-
- bool operator()(const Decl *X, const Decl *Y) const {
- return SourceMgr.isBeforeInTranslationUnit(X->getLocation(),
- Y->getLocation());
- }
- };
-}
-
Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
bool isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
Owner->addDecl(Inst);
- // First, we sort the partial specializations by location, so
- // that we instantiate them in the order they were declared.
- llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
- for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
- P = D->getPartialSpecializations().begin(),
- PEnd = D->getPartialSpecializations().end();
- P != PEnd; ++P)
- PartialSpecs.push_back(&*P);
- std::sort(PartialSpecs.begin(), PartialSpecs.end(),
- SortDeclByLocation(SemaRef.SourceMgr));
-
// Instantiate all of the partial specializations of this member class
// template.
+ llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
+ D->getPartialSpecializations(PartialSpecs);
for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I)
InstantiateClassTemplatePartialSpecialization(Inst, PartialSpecs[I]);
Converted,
InstTemplateArgs,
CanonType,
- 0);
+ 0,
+ ClassTemplate->getPartialSpecializations().size());
// Substitute the nested name specifier, if any.
if (SubstQualifier(PartialSpec, InstPartialSpec))
return 0;