AlreadyInstantiating = !Inst.Entity ? false :
!SemaRef.InstantiatingSpecializations
- .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
+ .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
.second;
atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
}
auto &Active = SemaRef.CodeSynthesisContexts.back();
if (Active.Entity)
SemaRef.InstantiatingSpecializations.erase(
- std::make_pair(Active.Entity, Active.Kind));
+ {Active.Entity->getCanonicalDecl(), Active.Kind});
}
atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
/// Get the instantiation pattern to use to instantiate the definition of a
/// given ClassTemplateSpecializationDecl (either the pattern of the primary
/// template or of a partial specialization).
-static CXXRecordDecl *
+static ActionResult<CXXRecordDecl *>
getPatternForClassTemplateSpecialization(
Sema &S, SourceLocation PointOfInstantiation,
ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK, bool Complain) {
+ TemplateSpecializationKind TSK) {
Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec);
- if (Inst.isInvalid() || Inst.isAlreadyInstantiating())
- return nullptr;
+ if (Inst.isInvalid())
+ return {/*Invalid=*/true};
+ if (Inst.isAlreadyInstantiating())
+ return {/*Invalid=*/false};
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>
<< S.getTemplateArgumentBindingsText(
P->Partial->getTemplateParameters(), *P->Args);
- return nullptr;
+ return {/*Invalid=*/true};
}
}
if (ClassTemplateSpec->isInvalidDecl())
return true;
- CXXRecordDecl *Pattern = getPatternForClassTemplateSpecialization(
- *this, PointOfInstantiation, ClassTemplateSpec, TSK, Complain);
- if (!Pattern)
- return true;
+ ActionResult<CXXRecordDecl *> Pattern =
+ getPatternForClassTemplateSpecialization(*this, PointOfInstantiation,
+ ClassTemplateSpec, TSK);
+ if (!Pattern.isUsable())
+ return Pattern.isInvalid();
- return InstantiateClass(PointOfInstantiation, ClassTemplateSpec, Pattern,
- getTemplateInstantiationArgs(ClassTemplateSpec), TSK,
- Complain);
+ return InstantiateClass(
+ PointOfInstantiation, ClassTemplateSpec, Pattern.get(),
+ getTemplateInstantiationArgs(ClassTemplateSpec), TSK, Complain);
}
/// Instantiates the definitions of all of the member
// into a template instantiation for this specific function template
// specialization, which is not a SFINAE context, so that we diagnose any
// further errors in the declaration itself.
+ //
+ // FIXME: This is a hack.
typedef Sema::CodeSynthesisContext ActiveInstType;
ActiveInstType &ActiveInst = SemaRef.CodeSynthesisContexts.back();
if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution ||
assert(FunTmpl->getTemplatedDecl() == Tmpl &&
"Deduction from the wrong function template?");
(void) FunTmpl;
+ SemaRef.InstantiatingSpecializations.erase(
+ {ActiveInst.Entity->getCanonicalDecl(), ActiveInst.Kind});
atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst);
ActiveInst.Kind = ActiveInstType::TemplateInstantiation;
ActiveInst.Entity = New;