return ConvertArg(Arg, 0);
}
+// FIXME: This should not be a template, but
+// ClassTemplatePartialSpecializationDecl sadly does not derive from
+// TemplateDecl.
+template<typename TemplateDeclT>
+static Sema::TemplateDeductionResult ConvertDeducedTemplateArguments(
+ Sema &S, TemplateDeclT *Template,
+ SmallVectorImpl<DeducedTemplateArgument> &Deduced,
+ TemplateDeductionInfo &Info, SmallVectorImpl<TemplateArgument> &Builder,
+ LocalInstantiationScope *CurrentInstantiationScope = nullptr,
+ unsigned NumAlreadyConverted = 0, bool PartialOverloading = false) {
+ TemplateParameterList *TemplateParams = Template->getTemplateParameters();
+
+ for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
+ NamedDecl *Param = TemplateParams->getParam(I);
+
+ if (!Deduced[I].isNull()) {
+ if (I < NumAlreadyConverted) {
+ // We have already fully type-checked and converted this
+ // argument, because it was explicitly-specified. Just record the
+ // presence of this argument.
+ Builder.push_back(Deduced[I]);
+ // We may have had explicitly-specified template arguments for a
+ // template parameter pack (that may or may not have been extended
+ // via additional deduced arguments).
+ if (Param->isParameterPack() && CurrentInstantiationScope) {
+ if (CurrentInstantiationScope->getPartiallySubstitutedPack() ==
+ Param) {
+ // Forget the partially-substituted pack; its substitution is now
+ // complete.
+ CurrentInstantiationScope->ResetPartiallySubstitutedPack();
+ }
+ }
+ continue;
+ }
+
+ // We have deduced this argument, so it still needs to be
+ // checked and converted.
+ if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Template, Info,
+ isa<FunctionTemplateDecl>(Template),
+ Builder)) {
+ Info.Param = makeTemplateParameter(Param);
+ // FIXME: These template arguments are temporary. Free them!
+ Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+ return Sema::TDK_SubstitutionFailure;
+ }
+
+ continue;
+ }
+
+ // C++0x [temp.arg.explicit]p3:
+ // A trailing template parameter pack (14.5.3) not otherwise deduced will
+ // be deduced to an empty sequence of template arguments.
+ // FIXME: Where did the word "trailing" come from?
+ if (Param->isTemplateParameterPack()) {
+ // We may have had explicitly-specified template arguments for this
+ // template parameter pack. If so, our empty deduction extends the
+ // explicitly-specified set (C++0x [temp.arg.explicit]p9).
+ const TemplateArgument *ExplicitArgs;
+ unsigned NumExplicitArgs;
+ if (CurrentInstantiationScope &&
+ CurrentInstantiationScope->getPartiallySubstitutedPack(
+ &ExplicitArgs, &NumExplicitArgs) == Param) {
+ Builder.push_back(TemplateArgument(
+ llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs)));
+
+ // Forget the partially-substituted pack; its substitution is now
+ // complete.
+ CurrentInstantiationScope->ResetPartiallySubstitutedPack();
+ } else {
+ // Go through the motions of checking the empty argument pack against
+ // the parameter pack.
+ DeducedTemplateArgument DeducedPack(TemplateArgument::getEmptyPack());
+ if (ConvertDeducedTemplateArgument(
+ S, Param, DeducedPack, Template, Info,
+ isa<FunctionTemplateDecl>(Template), Builder)) {
+ Info.Param = makeTemplateParameter(Param);
+ // FIXME: These template arguments are temporary. Free them!
+ Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+ return Sema::TDK_SubstitutionFailure;
+ }
+ }
+ continue;
+ }
+
+ // Substitute into the default template argument, if available.
+ bool HasDefaultArg = false;
+ TemplateDecl *TD = dyn_cast<TemplateDecl>(Template);
+ if (!TD) {
+ assert(isa<ClassTemplatePartialSpecializationDecl>(Template));
+ return Sema::TDK_Incomplete;
+ }
+
+ TemplateArgumentLoc DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
+ TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param, Builder,
+ HasDefaultArg);
+
+ // If there was no default argument, deduction is incomplete.
+ if (DefArg.getArgument().isNull()) {
+ Info.Param = makeTemplateParameter(
+ const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+ Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+ if (PartialOverloading) break;
+
+ return HasDefaultArg ? Sema::TDK_SubstitutionFailure
+ : Sema::TDK_Incomplete;
+ }
+
+ // Check whether we can actually use the default argument.
+ if (S.CheckTemplateArgument(Param, DefArg, TD, TD->getLocation(),
+ TD->getSourceRange().getEnd(), 0, Builder,
+ Sema::CTAK_Specified)) {
+ Info.Param = makeTemplateParameter(
+ const_cast<NamedDecl *>(TemplateParams->getParam(I)));
+ // FIXME: These template arguments are temporary. Free them!
+ Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
+ return Sema::TDK_SubstitutionFailure;
+ }
+
+ // If we get here, we successfully used the default template argument.
+ }
+
+ return Sema::TDK_Success;
+}
+
/// Complete template argument deduction for a class template partial
/// specialization.
static Sema::TemplateDeductionResult
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
SmallVector<TemplateArgument, 4> Builder;
- TemplateParameterList *PartialParams = Partial->getTemplateParameters();
- for (unsigned I = 0, N = PartialParams->size(); I != N; ++I) {
- NamedDecl *Param = PartialParams->getParam(I);
- if (Deduced[I].isNull()) {
- Info.Param = makeTemplateParameter(Param);
- return Sema::TDK_Incomplete;
- }
-
- // We have deduced this argument, so it still needs to be
- // checked and converted.
- if (ConvertDeducedTemplateArgument(S, Param, Deduced[I],
- Partial, Info, false,
- Builder)) {
- Info.Param = makeTemplateParameter(Param);
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
- return Sema::TDK_SubstitutionFailure;
- }
- }
+ if (auto Result = ConvertDeducedTemplateArguments(S, Partial, Deduced,
+ Info, Builder))
+ return Result;
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
SmallVector<TemplateArgument, 4> Builder;
- TemplateParameterList *PartialParams = Partial->getTemplateParameters();
- for (unsigned I = 0, N = PartialParams->size(); I != N; ++I) {
- NamedDecl *Param = PartialParams->getParam(I);
- if (Deduced[I].isNull()) {
- Info.Param = makeTemplateParameter(Param);
- return Sema::TDK_Incomplete;
- }
-
- // We have deduced this argument, so it still needs to be
- // checked and converted.
- if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Partial,
- Info, false, Builder)) {
- Info.Param = makeTemplateParameter(Param);
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(S.Context, Builder));
- return Sema::TDK_SubstitutionFailure;
- }
- }
+ if (auto Result = ConvertDeducedTemplateArguments(S, Partial, Deduced,
+ Info, Builder))
+ return Result;
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList = TemplateArgumentList::CreateCopy(
TemplateDeductionInfo &Info,
SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs,
bool PartialOverloading) {
- TemplateParameterList *TemplateParams
- = FunctionTemplate->getTemplateParameters();
-
// Unevaluated SFINAE context.
EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated);
SFINAETrap Trap(*this);
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
SmallVector<TemplateArgument, 4> Builder;
- for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
- NamedDecl *Param = TemplateParams->getParam(I);
-
- if (!Deduced[I].isNull()) {
- if (I < NumExplicitlySpecified) {
- // We have already fully type-checked and converted this
- // argument, because it was explicitly-specified. Just record the
- // presence of this argument.
- Builder.push_back(Deduced[I]);
- // We may have had explicitly-specified template arguments for a
- // template parameter pack (that may or may not have been extended
- // via additional deduced arguments).
- if (Param->isParameterPack() && CurrentInstantiationScope) {
- if (CurrentInstantiationScope->getPartiallySubstitutedPack() ==
- Param) {
- // Forget the partially-substituted pack; its substitution is now
- // complete.
- CurrentInstantiationScope->ResetPartiallySubstitutedPack();
- }
- }
- continue;
- }
-
- // We have deduced this argument, so it still needs to be
- // checked and converted.
- if (ConvertDeducedTemplateArgument(*this, Param, Deduced[I],
- FunctionTemplate, Info,
- true, Builder)) {
- Info.Param = makeTemplateParameter(Param);
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
- return TDK_SubstitutionFailure;
- }
-
- continue;
- }
-
- // C++0x [temp.arg.explicit]p3:
- // A trailing template parameter pack (14.5.3) not otherwise deduced will
- // be deduced to an empty sequence of template arguments.
- // FIXME: Where did the word "trailing" come from?
- if (Param->isTemplateParameterPack()) {
- // We may have had explicitly-specified template arguments for this
- // template parameter pack. If so, our empty deduction extends the
- // explicitly-specified set (C++0x [temp.arg.explicit]p9).
- const TemplateArgument *ExplicitArgs;
- unsigned NumExplicitArgs;
- if (CurrentInstantiationScope &&
- CurrentInstantiationScope->getPartiallySubstitutedPack(&ExplicitArgs,
- &NumExplicitArgs)
- == Param) {
- Builder.push_back(TemplateArgument(
- llvm::makeArrayRef(ExplicitArgs, NumExplicitArgs)));
-
- // Forget the partially-substituted pack; its substitution is now
- // complete.
- CurrentInstantiationScope->ResetPartiallySubstitutedPack();
- } else {
- // Go through the motions of checking the empty argument pack against
- // the parameter pack.
- DeducedTemplateArgument DeducedPack(TemplateArgument::getEmptyPack());
- if (ConvertDeducedTemplateArgument(*this, Param, DeducedPack,
- FunctionTemplate, Info, true,
- Builder)) {
- Info.Param = makeTemplateParameter(Param);
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
- return TDK_SubstitutionFailure;
- }
- }
- continue;
- }
-
- // Substitute into the default template argument, if available.
- bool HasDefaultArg = false;
- TemplateArgumentLoc DefArg
- = SubstDefaultTemplateArgumentIfAvailable(FunctionTemplate,
- FunctionTemplate->getLocation(),
- FunctionTemplate->getSourceRange().getEnd(),
- Param,
- Builder, HasDefaultArg);
-
- // If there was no default argument, deduction is incomplete.
- if (DefArg.getArgument().isNull()) {
- Info.Param = makeTemplateParameter(
- const_cast<NamedDecl *>(TemplateParams->getParam(I)));
- Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
- if (PartialOverloading) break;
-
- return HasDefaultArg ? TDK_SubstitutionFailure : TDK_Incomplete;
- }
-
- // Check whether we can actually use the default argument.
- if (CheckTemplateArgument(Param, DefArg,
- FunctionTemplate,
- FunctionTemplate->getLocation(),
- FunctionTemplate->getSourceRange().getEnd(),
- 0, Builder,
- CTAK_Specified)) {
- Info.Param = makeTemplateParameter(
- const_cast<NamedDecl *>(TemplateParams->getParam(I)));
- // FIXME: These template arguments are temporary. Free them!
- Info.reset(TemplateArgumentList::CreateCopy(Context, Builder));
- return TDK_SubstitutionFailure;
- }
-
- // If we get here, we successfully used the default template argument.
- }
+ if (auto Result = ConvertDeducedTemplateArguments(
+ *this, FunctionTemplate, Deduced, Info, Builder,
+ CurrentInstantiationScope, NumExplicitlySpecified,
+ PartialOverloading))
+ return Result;
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *DeducedArgumentList