[llvm-branch-commits] [clang] [clang] NFC: cleanup check template argument (PR #124668)
Matheus Izvekov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jan 28 12:27:58 PST 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/124668
>From db745bb131582139f29d471636cebeb78f25fb1c Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Mon, 27 Jan 2025 19:18:27 -0300
Subject: [PATCH] [clang] NFC: cleanup check template argument
---
clang/include/clang/Sema/Sema.h | 70 +++--
clang/lib/Sema/SemaLookup.cpp | 6 +-
clang/lib/Sema/SemaTemplate.cpp | 277 +++++++++---------
clang/lib/Sema/SemaTemplateDeduction.cpp | 208 +++++++------
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 47 +--
5 files changed, 307 insertions(+), 301 deletions(-)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 8a6dd4f6820bc7..6bffe5241e1694 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11651,6 +11651,33 @@ class Sema final : public SemaBase {
CTAK_DeducedFromArrayBound
};
+ struct CheckTemplateArgumentInfo {
+ explicit CheckTemplateArgumentInfo(bool PartialOrdering = false,
+ bool MatchingTTP = false)
+ : PartialOrdering(PartialOrdering), MatchingTTP(MatchingTTP) {}
+ CheckTemplateArgumentInfo(const CheckTemplateArgumentInfo &) = delete;
+ CheckTemplateArgumentInfo &
+ operator=(const CheckTemplateArgumentInfo &) = delete;
+
+ /// The checked, converted argument will be added to the
+ /// end of these vectors.
+ SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+
+ /// The check is being performed in the context of partial ordering.
+ bool PartialOrdering;
+
+ /// If true, assume these template arguments are
+ /// the injected template arguments for a template template parameter.
+ /// This will relax the requirement that all its possible uses are valid:
+ /// TTP checking is loose, and assumes that invalid uses will be diagnosed
+ /// during instantiation.
+ bool MatchingTTP;
+
+ /// Is set to true when, in the context of TTP matching, a pack parameter
+ /// matches non-pack arguments.
+ bool MatchedPackOnParmToNonPackOnArg;
+ };
+
/// Check that the given template argument corresponds to the given
/// template parameter.
///
@@ -11670,22 +11697,16 @@ class Sema final : public SemaBase {
/// \param ArgumentPackIndex The index into the argument pack where this
/// argument will be placed. Only valid if the parameter is a parameter pack.
///
- /// \param Converted The checked, converted argument will be added to the
- /// end of this small vector.
- ///
/// \param CTAK Describes how we arrived at this particular template argument:
/// explicitly written, deduced, etc.
///
/// \returns true on error, false otherwise.
- bool
- CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg,
- NamedDecl *Template, SourceLocation TemplateLoc,
- SourceLocation RAngleLoc, unsigned ArgumentPackIndex,
- SmallVectorImpl<TemplateArgument> &SugaredConverted,
- SmallVectorImpl<TemplateArgument> &CanonicalConverted,
- CheckTemplateArgumentKind CTAK, bool PartialOrdering,
- bool PartialOrderingTTP,
- bool *MatchedPackOnParmToNonPackOnArg);
+ bool CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &Arg,
+ NamedDecl *Template, SourceLocation TemplateLoc,
+ SourceLocation RAngleLoc,
+ unsigned ArgumentPackIndex,
+ CheckTemplateArgumentInfo &CTAI,
+ CheckTemplateArgumentKind CTAK);
/// Check that the given template arguments can be provided to
/// the given template, converting the arguments along the way.
@@ -11718,22 +11739,15 @@ class Sema final : public SemaBase {
/// \param DefaultArgs any default arguments from template specialization
/// deduction.
///
- /// \param PartialOrderingTTP If true, assume these template arguments are
- /// the injected template arguments for a template template parameter.
- /// This will relax the requirement that all its possible uses are valid:
- /// TTP checking is loose, and assumes that invalid uses will be diagnosed
- /// during instantiation.
- ///
/// \returns true if an error occurred, false otherwise.
- bool CheckTemplateArgumentList(
- TemplateDecl *Template, SourceLocation TemplateLoc,
- TemplateArgumentListInfo &TemplateArgs,
- const DefaultArguments &DefaultArgs, bool PartialTemplateArgs,
- SmallVectorImpl<TemplateArgument> &SugaredConverted,
- SmallVectorImpl<TemplateArgument> &CanonicalConverted,
- bool UpdateArgsWithConversions = true,
- bool *ConstraintsNotSatisfied = nullptr, bool PartialOrderingTTP = false,
- bool *MatchedPackOnParmToNonPackOnArg = nullptr);
+ bool CheckTemplateArgumentList(TemplateDecl *Template,
+ SourceLocation TemplateLoc,
+ TemplateArgumentListInfo &TemplateArgs,
+ const DefaultArguments &DefaultArgs,
+ bool PartialTemplateArgs,
+ CheckTemplateArgumentInfo &CTAI,
+ bool UpdateArgsWithConversions = true,
+ bool *ConstraintsNotSatisfied = nullptr);
bool CheckTemplateTypeArgument(
TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,
@@ -11758,7 +11772,7 @@ class Sema final : public SemaBase {
QualType InstantiatedParamType, Expr *Arg,
TemplateArgument &SugaredConverted,
TemplateArgument &CanonicalConverted,
- bool PartialOrderingTTP,
+ bool MatchingTTP,
CheckTemplateArgumentKind CTAK);
/// Check a template argument against its corresponding
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 641780fa072a54..0f5b7426e743e0 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -3721,13 +3721,11 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
// is a well-formed template argument for the template parameter.
if (StringLit) {
SFINAETrap Trap(*this);
- SmallVector<TemplateArgument, 1> SugaredChecked, CanonicalChecked;
+ CheckTemplateArgumentInfo CTAI;
TemplateArgumentLoc Arg(TemplateArgument(StringLit), StringLit);
if (CheckTemplateArgument(
Params->getParam(0), Arg, FD, R.getNameLoc(), R.getNameLoc(),
- 0, SugaredChecked, CanonicalChecked, CTAK_Specified,
- /*PartialOrdering=*/false, /*PartialOrderingTTP=*/false,
- /*MatchedPackOnParmToNonPackOnArg=*/nullptr) ||
+ /*ArgumentPackIndex=*/0, CTAI, CTAK_Specified) ||
Trap.hasErrorOccurred())
IsTemplate = false;
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index cb9d78734e6bbf..3944c4f67bab9a 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -38,6 +38,7 @@
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/SaveAndRestore.h"
#include <optional>
using namespace clang;
@@ -3497,10 +3498,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// Check that the template argument list is well-formed for this
// template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ CheckTemplateArgumentInfo CTAI;
if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
- DefaultArgs, false, SugaredConverted,
- CanonicalConverted,
+ DefaultArgs, /*PartialTemplateArgs=*/false,
+ CTAI,
/*UpdateArgsWithConversions=*/true))
return QualType();
@@ -3522,7 +3523,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// template type alias specializations apart.
MultiLevelTemplateArgumentList TemplateArgLists;
TemplateArgLists.addOuterTemplateArguments(
- Template, SugaredConverted,
+ Template, CTAI.SugaredConverted,
/*Final=*/!getLangOpts().RetainSubstTemplateTypeParmTypeAstNodes);
TemplateArgLists.addOuterRetainedLevels(
AliasTemplate->getTemplateParameters()->getDepth());
@@ -3582,11 +3583,11 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
return QualType();
}
} else if (auto *BTD = dyn_cast<BuiltinTemplateDecl>(Template)) {
- CanonType = checkBuiltinTemplateIdType(*this, BTD, SugaredConverted,
+ CanonType = checkBuiltinTemplateIdType(*this, BTD, CTAI.SugaredConverted,
TemplateLoc, TemplateArgs);
} else if (Name.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs, CanonicalConverted)) {
+ TemplateArgs, CTAI.CanonicalConverted)) {
// This class template specialization is a dependent
// type. Therefore, its canonical type is another class template
// specialization type that contains all of the converted
@@ -3595,7 +3596,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
//
// template<typename T, typename U = T> struct A;
CanonType = Context.getCanonicalTemplateSpecializationType(
- Name, CanonicalConverted);
+ Name, CTAI.CanonicalConverted);
// This might work out to be a current instantiation, in which
// case the canonical type needs to be the InjectedClassNameType.
@@ -3640,7 +3641,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// corresponds to these arguments.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *Decl =
- ClassTemplate->findSpecialization(CanonicalConverted, InsertPos);
+ ClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos);
if (!Decl) {
// This is the first time we have referenced this class template
// specialization. Create the canonical declaration and add it to
@@ -3649,7 +3650,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
Context, ClassTemplate->getTemplatedDecl()->getTagKind(),
ClassTemplate->getDeclContext(),
ClassTemplate->getTemplatedDecl()->getBeginLoc(),
- ClassTemplate->getLocation(), ClassTemplate, CanonicalConverted,
+ ClassTemplate->getLocation(), ClassTemplate, CTAI.CanonicalConverted,
nullptr);
ClassTemplate->AddSpecialization(Decl, InsertPos);
if (ClassTemplate->isOutOfLine())
@@ -3661,7 +3662,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
InstantiatingTemplate Inst(*this, TemplateLoc, Decl);
if (!Inst.isInvalid()) {
MultiLevelTemplateArgumentList TemplateArgLists(Template,
- CanonicalConverted,
+ CTAI.CanonicalConverted,
/*Final=*/false);
InstantiateAttrsForDecl(TemplateArgLists,
ClassTemplate->getTemplatedDecl(), Decl);
@@ -4183,10 +4184,10 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
// Check that the template argument list is well-formed for this
// template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ CheckTemplateArgumentInfo CTAI;
if (CheckTemplateArgumentList(VarTemplate, TemplateNameLoc, TemplateArgs,
- /*DefaultArgs=*/{}, false, SugaredConverted,
- CanonicalConverted,
+ /*DefaultArgs=*/{},
+ /*PartialTemplateArgs=*/false, CTAI,
/*UpdateArgsWithConversions=*/true))
return true;
@@ -4195,21 +4196,21 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
if (IsPartialSpecialization) {
if (CheckTemplatePartialSpecializationArgs(TemplateNameLoc, VarTemplate,
TemplateArgs.size(),
- CanonicalConverted))
+ CTAI.CanonicalConverted))
return true;
- // FIXME: Move these checks to CheckTemplatePartialSpecializationArgs so we
- // also do them during instantiation.
+ // FIXME: Move these checks to CheckTemplatePartialSpecializationArgs so
+ // we also do them during instantiation.
if (!Name.isDependent() &&
!TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs, CanonicalConverted)) {
+ TemplateArgs, CTAI.CanonicalConverted)) {
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
<< VarTemplate->getDeclName();
IsPartialSpecialization = false;
}
if (isSameAsPrimaryTemplate(VarTemplate->getTemplateParameters(),
- CanonicalConverted) &&
+ CTAI.CanonicalConverted) &&
(!Context.getLangOpts().CPlusPlus20 ||
!TemplateParams->hasAssociatedConstraints())) {
// C++ [temp.class.spec]p9b3:
@@ -4217,11 +4218,11 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
// -- The argument list of the specialization shall not be identical
// to the implicit argument list of the primary template.
Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template)
- << /*variable template*/ 1
- << /*is definition*/(SC != SC_Extern && !CurContext->isRecord())
- << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc));
- // FIXME: Recover from this by treating the declaration as a redeclaration
- // of the primary template.
+ << /*variable template*/ 1
+ << /*is definition*/ (SC != SC_Extern && !CurContext->isRecord())
+ << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc));
+ // FIXME: Recover from this by treating the declaration as a
+ // redeclaration of the primary template.
return true;
}
}
@@ -4231,9 +4232,10 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
if (IsPartialSpecialization)
PrevDecl = VarTemplate->findPartialSpecialization(
- CanonicalConverted, TemplateParams, InsertPos);
+ CTAI.CanonicalConverted, TemplateParams, InsertPos);
else
- PrevDecl = VarTemplate->findSpecialization(CanonicalConverted, InsertPos);
+ PrevDecl =
+ VarTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos);
VarTemplateSpecializationDecl *Specialization = nullptr;
@@ -4260,7 +4262,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
VarTemplatePartialSpecializationDecl::Create(
Context, VarTemplate->getDeclContext(), TemplateKWLoc,
TemplateNameLoc, TemplateParams, VarTemplate, DI->getType(), DI, SC,
- CanonicalConverted);
+ CTAI.CanonicalConverted);
Partial->setTemplateArgsAsWritten(TemplateArgs);
if (!PrevPartial)
@@ -4278,7 +4280,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
// this explicit specialization or friend declaration.
Specialization = VarTemplateSpecializationDecl::Create(
Context, VarTemplate->getDeclContext(), TemplateKWLoc, TemplateNameLoc,
- VarTemplate, DI->getType(), DI, SC, CanonicalConverted);
+ VarTemplate, DI->getType(), DI, SC, CTAI.CanonicalConverted);
Specialization->setTemplateArgsAsWritten(TemplateArgs);
if (!PrevDecl)
@@ -4350,25 +4352,25 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
assert(Template && "A variable template id without template?");
// Check that the template argument list is well-formed for this template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ CheckTemplateArgumentInfo CTAI;
if (CheckTemplateArgumentList(
Template, TemplateNameLoc,
const_cast<TemplateArgumentListInfo &>(TemplateArgs),
- /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted,
+ /*DefaultArgs=*/{}, /*PartialTemplateArgs=*/false, CTAI,
/*UpdateArgsWithConversions=*/true))
return true;
// Produce a placeholder value if the specialization is dependent.
if (Template->getDeclContext()->isDependentContext() ||
TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs, CanonicalConverted))
+ TemplateArgs, CTAI.CanonicalConverted))
return DeclResult();
// Find the variable template specialization declaration that
// corresponds to these arguments.
void *InsertPos = nullptr;
if (VarTemplateSpecializationDecl *Spec =
- Template->findSpecialization(CanonicalConverted, InsertPos)) {
+ Template->findSpecialization(CTAI.CanonicalConverted, InsertPos)) {
checkSpecializationReachability(TemplateNameLoc, Spec);
// If we already have a variable template specialization, return it.
return Spec;
@@ -4412,7 +4414,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
TemplateDeductionInfo Info(FailedCandidates.getLocation());
if (TemplateDeductionResult Result =
- DeduceTemplateArguments(Partial, SugaredConverted, Info);
+ DeduceTemplateArguments(Partial, CTAI.SugaredConverted, Info);
Result != TemplateDeductionResult::Success) {
// Store the failed-deduction information for use in diagnostics, later.
// TODO: Actually use the failed-deduction info?
@@ -4479,7 +4481,7 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
// FIXME: LateAttrs et al.?
VarTemplateSpecializationDecl *Decl = BuildVarTemplateInstantiation(
Template, InstantiationPattern, PartialSpecArgs, TemplateArgs,
- CanonicalConverted, TemplateNameLoc /*, LateAttrs, StartingScope*/);
+ CTAI.CanonicalConverted, TemplateNameLoc /*, LateAttrs, StartingScope*/);
if (!Decl)
return true;
@@ -4559,12 +4561,12 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
if (NamedConcept->isInvalidDecl())
return ExprError();
- llvm::SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ CheckTemplateArgumentInfo CTAI;
if (CheckTemplateArgumentList(
NamedConcept, ConceptNameInfo.getLoc(),
const_cast<TemplateArgumentListInfo &>(*TemplateArgs),
/*DefaultArgs=*/{},
- /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted,
+ /*PartialTemplateArgs=*/false, CTAI,
/*UpdateArgsWithConversions=*/false))
return ExprError();
@@ -4572,12 +4574,12 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
auto *CSD = ImplicitConceptSpecializationDecl::Create(
Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(),
- CanonicalConverted);
+ CTAI.CanonicalConverted);
ConstraintSatisfaction Satisfaction;
bool AreArgsDependent =
TemplateSpecializationType::anyDependentTemplateArguments(
- *TemplateArgs, CanonicalConverted);
- MultiLevelTemplateArgumentList MLTAL(NamedConcept, CanonicalConverted,
+ *TemplateArgs, CTAI.CanonicalConverted);
+ MultiLevelTemplateArgumentList MLTAL(NamedConcept, CTAI.CanonicalConverted,
/*Final=*/false);
LocalInstantiationScope Scope(*this);
@@ -5198,18 +5200,17 @@ convertTypeTemplateArgumentToTemplate(ASTContext &Context, TypeLoc TLoc) {
return TemplateArgumentLoc();
}
-bool Sema::CheckTemplateArgument(
- NamedDecl *Param, TemplateArgumentLoc &ArgLoc, NamedDecl *Template,
- SourceLocation TemplateLoc, SourceLocation RAngleLoc,
- unsigned ArgumentPackIndex,
- SmallVectorImpl<TemplateArgument> &SugaredConverted,
- SmallVectorImpl<TemplateArgument> &CanonicalConverted,
- CheckTemplateArgumentKind CTAK, bool PartialOrdering,
- bool PartialOrderingTTP, bool *MatchedPackOnParmToNonPackOnArg) {
+bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
+ NamedDecl *Template,
+ SourceLocation TemplateLoc,
+ SourceLocation RAngleLoc,
+ unsigned ArgumentPackIndex,
+ CheckTemplateArgumentInfo &CTAI,
+ CheckTemplateArgumentKind CTAK) {
// Check template type parameters.
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
- return CheckTemplateTypeArgument(TTP, ArgLoc, SugaredConverted,
- CanonicalConverted);
+ return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted,
+ CTAI.CanonicalConverted);
const TemplateArgument &Arg = ArgLoc.getArgument();
// Check non-type template parameters.
@@ -5226,12 +5227,12 @@ bool Sema::CheckTemplateArgument(
!Template->getDeclContext()->isDependentContext()) {
// Do substitution on the type of the non-type template parameter.
InstantiatingTemplate Inst(*this, TemplateLoc, Template, NTTP,
- SugaredConverted,
+ CTAI.SugaredConverted,
SourceRange(TemplateLoc, RAngleLoc));
if (Inst.isInvalid())
return true;
- MultiLevelTemplateArgumentList MLTAL(Template, SugaredConverted,
+ MultiLevelTemplateArgumentList MLTAL(Template, CTAI.SugaredConverted,
/*Final=*/true);
// If the parameter is a pack expansion, expand this slice of the pack.
if (auto *PET = NTTPType->getAs<PackExpansionType>()) {
@@ -5258,12 +5259,12 @@ bool Sema::CheckTemplateArgument(
unsigned CurSFINAEErrors = NumSFINAEErrors;
ExprResult Res =
CheckTemplateArgument(NTTP, NTTPType, E, SugaredResult,
- CanonicalResult, PartialOrderingTTP, CTAK);
+ CanonicalResult, CTAI.MatchingTTP, CTAK);
// If the current template argument causes an error, give up now.
if (Res.isInvalid() || CurSFINAEErrors < NumSFINAEErrors)
return nullptr;
- SugaredConverted.push_back(SugaredResult);
- CanonicalConverted.push_back(CanonicalResult);
+ CTAI.SugaredConverted.push_back(SugaredResult);
+ CTAI.CanonicalConverted.push_back(CanonicalResult);
return Res.get();
};
@@ -5343,8 +5344,8 @@ bool Sema::CheckTemplateArgument(
if (E.isInvalid())
return true;
- SugaredConverted.push_back(SugaredResult);
- CanonicalConverted.push_back(CanonicalResult);
+ CTAI.SugaredConverted.push_back(SugaredResult);
+ CTAI.CanonicalConverted.push_back(CanonicalResult);
break;
}
@@ -5402,16 +5403,16 @@ bool Sema::CheckTemplateArgument(
// Set up a template instantiation context.
LocalInstantiationScope Scope(*this);
InstantiatingTemplate Inst(*this, TemplateLoc, Template, TempParm,
- SugaredConverted,
+ CTAI.SugaredConverted,
SourceRange(TemplateLoc, RAngleLoc));
if (Inst.isInvalid())
return true;
- Params =
- SubstTemplateParams(Params, CurContext,
- MultiLevelTemplateArgumentList(
- Template, SugaredConverted, /*Final=*/true),
- /*EvaluateConstraints=*/false);
+ Params = SubstTemplateParams(
+ Params, CurContext,
+ MultiLevelTemplateArgumentList(Template, CTAI.SugaredConverted,
+ /*Final=*/true),
+ /*EvaluateConstraints=*/false);
if (!Params)
return true;
}
@@ -5433,12 +5434,14 @@ bool Sema::CheckTemplateArgument(
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
- if (CheckTemplateTemplateArgument(TempParm, Params, ArgLoc, PartialOrdering,
- MatchedPackOnParmToNonPackOnArg))
+ if (CheckTemplateTemplateArgument(TempParm, Params, ArgLoc,
+ CTAI.PartialOrdering,
+ &CTAI.MatchedPackOnParmToNonPackOnArg))
return true;
- SugaredConverted.push_back(Arg);
- CanonicalConverted.push_back(Context.getCanonicalTemplateArgument(Arg));
+ CTAI.SugaredConverted.push_back(Arg);
+ CTAI.CanonicalConverted.push_back(
+ Context.getCanonicalTemplateArgument(Arg));
break;
case TemplateArgument::Expression:
@@ -5503,11 +5506,8 @@ static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc,
bool Sema::CheckTemplateArgumentList(
TemplateDecl *Template, SourceLocation TemplateLoc,
TemplateArgumentListInfo &TemplateArgs, const DefaultArguments &DefaultArgs,
- bool PartialTemplateArgs,
- SmallVectorImpl<TemplateArgument> &SugaredConverted,
- SmallVectorImpl<TemplateArgument> &CanonicalConverted,
- bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied,
- bool PartialOrderingTTP, bool *MatchedPackOnParmToNonPackOnArg) {
+ bool PartialTemplateArgs, CheckTemplateArgumentInfo &CTAI,
+ bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied) {
if (ConstraintsNotSatisfied)
*ConstraintsNotSatisfied = false;
@@ -5544,8 +5544,8 @@ bool Sema::CheckTemplateArgumentList(
assert(Param + DefaultArgs.Args.size() <= ParamEnd);
// Default arguments from a DeducedTemplateName are already converted.
for (const TemplateArgument &DefArg : DefaultArgs.Args) {
- SugaredConverted.push_back(DefArg);
- CanonicalConverted.push_back(
+ CTAI.SugaredConverted.push_back(DefArg);
+ CTAI.CanonicalConverted.push_back(
Context.getCanonicalTemplateArgument(DefArg));
++Param;
}
@@ -5559,11 +5559,11 @@ bool Sema::CheckTemplateArgumentList(
if (*Expansions == SugaredArgumentPack.size()) {
// We're done with this parameter pack. Pack up its arguments and add
// them to the list.
- SugaredConverted.push_back(
+ CTAI.SugaredConverted.push_back(
TemplateArgument::CreatePackCopy(Context, SugaredArgumentPack));
SugaredArgumentPack.clear();
- CanonicalConverted.push_back(
+ CTAI.CanonicalConverted.push_back(
TemplateArgument::CreatePackCopy(Context, CanonicalArgumentPack));
CanonicalArgumentPack.clear();
@@ -5587,7 +5587,7 @@ bool Sema::CheckTemplateArgumentList(
!(*Param)->isTemplateParameterPack() || getExpandedPackSize(*Param);
bool ArgIsExpansion = ArgLoc.getArgument().isPackExpansion();
- if (ArgIsExpansion && PartialOrderingTTP) {
+ if (ArgIsExpansion && CTAI.MatchingTTP) {
SmallVector<TemplateArgument, 4> Args(ParamEnd - Param);
for (TemplateParameterList::iterator First = Param; Param != ParamEnd;
++Param) {
@@ -5597,31 +5597,30 @@ bool Sema::CheckTemplateArgumentList(
getExpandedPackSize(*Param))
Arg = Arg.getPackExpansionPattern();
TemplateArgumentLoc NewArgLoc(Arg, ArgLoc.getLocInfo());
- if (CheckTemplateArgument(
- *Param, NewArgLoc, Template, TemplateLoc, RAngleLoc,
- SugaredArgumentPack.size(), SugaredConverted,
- CanonicalConverted, CTAK_Specified, /*PartialOrdering=*/false,
- /*PartialOrderingTTP=*/true, MatchedPackOnParmToNonPackOnArg))
+ SaveAndRestore _1(CTAI.PartialOrdering, false);
+ SaveAndRestore _2(CTAI.MatchingTTP, true);
+ if (CheckTemplateArgument(*Param, NewArgLoc, Template, TemplateLoc,
+ RAngleLoc, SugaredArgumentPack.size(), CTAI,
+ CTAK_Specified))
return true;
Arg = NewArgLoc.getArgument();
- CanonicalConverted.back().setIsDefaulted(
+ CTAI.CanonicalConverted.back().setIsDefaulted(
clang::isSubstitutedDefaultArgument(Context, Arg, *Param,
- CanonicalConverted,
+ CTAI.CanonicalConverted,
Params->getDepth()));
}
ArgLoc =
TemplateArgumentLoc(TemplateArgument::CreatePackCopy(Context, Args),
ArgLoc.getLocInfo());
} else {
- if (CheckTemplateArgument(
- *Param, ArgLoc, Template, TemplateLoc, RAngleLoc,
- SugaredArgumentPack.size(), SugaredConverted,
- CanonicalConverted, CTAK_Specified, /*PartialOrdering=*/false,
- PartialOrderingTTP, MatchedPackOnParmToNonPackOnArg))
+ SaveAndRestore _1(CTAI.PartialOrdering, false);
+ if (CheckTemplateArgument(*Param, ArgLoc, Template, TemplateLoc,
+ RAngleLoc, SugaredArgumentPack.size(), CTAI,
+ CTAK_Specified))
return true;
- CanonicalConverted.back().setIsDefaulted(
+ CTAI.CanonicalConverted.back().setIsDefaulted(
clang::isSubstitutedDefaultArgument(Context, ArgLoc.getArgument(),
- *Param, CanonicalConverted,
+ *Param, CTAI.CanonicalConverted,
Params->getDepth()));
if (ArgIsExpansion && NonPackParameter) {
// CWG1430/CWG2686: we have a pack expansion as an argument to an
@@ -5641,28 +5640,28 @@ bool Sema::CheckTemplateArgumentList(
// We're now done with this argument.
++ArgIdx;
- if (ArgIsExpansion && (PartialOrderingTTP || NonPackParameter)) {
+ if (ArgIsExpansion && (CTAI.MatchingTTP || NonPackParameter)) {
// Directly convert the remaining arguments, because we don't know what
// parameters they'll match up with.
if (!SugaredArgumentPack.empty()) {
// If we were part way through filling in an expanded parameter pack,
// fall back to just producing individual arguments.
- SugaredConverted.insert(SugaredConverted.end(),
- SugaredArgumentPack.begin(),
- SugaredArgumentPack.end());
+ CTAI.SugaredConverted.insert(CTAI.SugaredConverted.end(),
+ SugaredArgumentPack.begin(),
+ SugaredArgumentPack.end());
SugaredArgumentPack.clear();
- CanonicalConverted.insert(CanonicalConverted.end(),
- CanonicalArgumentPack.begin(),
- CanonicalArgumentPack.end());
+ CTAI.CanonicalConverted.insert(CTAI.CanonicalConverted.end(),
+ CanonicalArgumentPack.begin(),
+ CanonicalArgumentPack.end());
CanonicalArgumentPack.clear();
}
while (ArgIdx < NumArgs) {
const TemplateArgument &Arg = NewArgs[ArgIdx].getArgument();
- SugaredConverted.push_back(Arg);
- CanonicalConverted.push_back(
+ CTAI.SugaredConverted.push_back(Arg);
+ CTAI.CanonicalConverted.push_back(
Context.getCanonicalTemplateArgument(Arg));
++ArgIdx;
}
@@ -5675,8 +5674,8 @@ bool Sema::CheckTemplateArgumentList(
// deduced argument and place it on the argument pack. Note that we
// stay on the same template parameter so that we can deduce more
// arguments.
- SugaredArgumentPack.push_back(SugaredConverted.pop_back_val());
- CanonicalArgumentPack.push_back(CanonicalConverted.pop_back_val());
+ SugaredArgumentPack.push_back(CTAI.SugaredConverted.pop_back_val());
+ CanonicalArgumentPack.push_back(CTAI.CanonicalConverted.pop_back_val());
} else {
// Move to the next template parameter.
++Param;
@@ -5687,9 +5686,9 @@ bool Sema::CheckTemplateArgumentList(
// If we're checking a partial template argument list, we're done.
if (PartialTemplateArgs) {
if ((*Param)->isTemplateParameterPack() && !SugaredArgumentPack.empty()) {
- SugaredConverted.push_back(
+ CTAI.SugaredConverted.push_back(
TemplateArgument::CreatePackCopy(Context, SugaredArgumentPack));
- CanonicalConverted.push_back(
+ CTAI.CanonicalConverted.push_back(
TemplateArgument::CreatePackCopy(Context, CanonicalArgumentPack));
}
return false;
@@ -5711,11 +5710,11 @@ bool Sema::CheckTemplateArgumentList(
return true;
}
- SugaredConverted.push_back(
+ CTAI.SugaredConverted.push_back(
TemplateArgument::CreatePackCopy(Context, SugaredArgumentPack));
SugaredArgumentPack.clear();
- CanonicalConverted.push_back(
+ CTAI.CanonicalConverted.push_back(
TemplateArgument::CreatePackCopy(Context, CanonicalArgumentPack));
CanonicalArgumentPack.clear();
@@ -5732,8 +5731,8 @@ bool Sema::CheckTemplateArgumentList(
// (when the template parameter was part of a nested template) into
// the default argument.
TemplateArgumentLoc Arg = SubstDefaultTemplateArgumentIfAvailable(
- Template, TemplateLoc, RAngleLoc, *Param, SugaredConverted,
- CanonicalConverted, HasDefaultArg);
+ Template, TemplateLoc, RAngleLoc, *Param, CTAI.SugaredConverted,
+ CTAI.CanonicalConverted, HasDefaultArg);
if (Arg.getArgument().isNull()) {
if (!HasDefaultArg) {
@@ -5756,21 +5755,21 @@ bool Sema::CheckTemplateArgumentList(
// template here, we just create this object to put a note into the
// context stack.
InstantiatingTemplate Inst(*this, RAngleLoc, Template, *Param,
- SugaredConverted,
+ CTAI.SugaredConverted,
SourceRange(TemplateLoc, RAngleLoc));
if (Inst.isInvalid())
return true;
+ SaveAndRestore _1(CTAI.PartialOrdering, false);
+ SaveAndRestore _2(CTAI.MatchingTTP, false);
+ SaveAndRestore _3(CTAI.MatchedPackOnParmToNonPackOnArg, {});
// Check the default template argument.
if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc, RAngleLoc, 0,
- SugaredConverted, CanonicalConverted,
- CTAK_Specified, /*PartialOrdering=*/false,
- /*PartialOrderingTTP=*/false,
- /*MatchedPackOnParmToNonPackOnArg=*/nullptr))
+ CTAI, CTAK_Specified))
return true;
- SugaredConverted.back().setIsDefaulted(true);
- CanonicalConverted.back().setIsDefaulted(true);
+ CTAI.SugaredConverted.back().setIsDefaulted(true);
+ CTAI.CanonicalConverted.back().setIsDefaulted(true);
// Core issue 150 (assumed resolution): if this is a template template
// parameter, keep track of the default template arguments from the
@@ -5787,14 +5786,15 @@ bool Sema::CheckTemplateArgumentList(
// pack expansions; they might be empty. This can happen even if
// PartialTemplateArgs is false (the list of arguments is complete but
// still dependent).
- if (PartialOrderingTTP ||
+ if (CTAI.MatchingTTP ||
(CurrentInstantiationScope &&
CurrentInstantiationScope->getPartiallySubstitutedPack())) {
while (ArgIdx < NumArgs &&
NewArgs[ArgIdx].getArgument().isPackExpansion()) {
const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument();
- SugaredConverted.push_back(Arg);
- CanonicalConverted.push_back(Context.getCanonicalTemplateArgument(Arg));
+ CTAI.SugaredConverted.push_back(Arg);
+ CTAI.CanonicalConverted.push_back(
+ Context.getCanonicalTemplateArgument(Arg));
}
}
@@ -5835,7 +5835,7 @@ bool Sema::CheckTemplateArgumentList(
CXXThisScopeRAII(*this, RD, ThisQuals, RD != nullptr);
MultiLevelTemplateArgumentList MLTAL = getTemplateInstantiationArgs(
- Template, NewContext, /*Final=*/false, CanonicalConverted,
+ Template, NewContext, /*Final=*/false, CTAI.CanonicalConverted,
/*RelativeToPrimary=*/true,
/*Pattern=*/nullptr,
/*ForConceptInstantiation=*/true);
@@ -8459,11 +8459,10 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
// Check that the template argument list is well-formed for this
// template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ CheckTemplateArgumentInfo CTAI;
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs,
/*DefaultArgs=*/{},
- /*PartialTemplateArgs=*/false, SugaredConverted,
- CanonicalConverted,
+ /*PartialTemplateArgs=*/false, CTAI,
/*UpdateArgsWithConversions=*/true))
return true;
@@ -8472,14 +8471,14 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
if (isPartialSpecialization) {
if (CheckTemplatePartialSpecializationArgs(TemplateNameLoc, ClassTemplate,
TemplateArgs.size(),
- CanonicalConverted))
+ CTAI.CanonicalConverted))
return true;
// FIXME: Move this to CheckTemplatePartialSpecializationArgs so we
// also do it during instantiation.
if (!Name.isDependent() &&
!TemplateSpecializationType::anyDependentTemplateArguments(
- TemplateArgs, CanonicalConverted)) {
+ TemplateArgs, CTAI.CanonicalConverted)) {
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
<< ClassTemplate->getDeclName();
isPartialSpecialization = false;
@@ -8492,9 +8491,10 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
if (isPartialSpecialization)
PrevDecl = ClassTemplate->findPartialSpecialization(
- CanonicalConverted, TemplateParams, InsertPos);
+ CTAI.CanonicalConverted, TemplateParams, InsertPos);
else
- PrevDecl = ClassTemplate->findSpecialization(CanonicalConverted, InsertPos);
+ PrevDecl =
+ ClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos);
ClassTemplateSpecializationDecl *Specialization = nullptr;
@@ -8513,7 +8513,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
// arguments of the class template partial specialization.
TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
CanonType = Context.getTemplateSpecializationType(CanonTemplate,
- CanonicalConverted);
+ CTAI.CanonicalConverted);
if (Context.hasSameType(CanonType,
ClassTemplate->getInjectedClassNameSpecialization()) &&
@@ -8543,7 +8543,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
ClassTemplatePartialSpecializationDecl *Partial =
ClassTemplatePartialSpecializationDecl::Create(
Context, Kind, DC, KWLoc, TemplateNameLoc, TemplateParams,
- ClassTemplate, CanonicalConverted, CanonType, PrevPartial);
+ ClassTemplate, CTAI.CanonicalConverted, CanonType, PrevPartial);
Partial->setTemplateArgsAsWritten(TemplateArgs);
SetNestedNameSpecifier(*this, Partial, SS);
if (TemplateParameterLists.size() > 1 && SS.isSet()) {
@@ -8566,7 +8566,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
// this explicit specialization or friend declaration.
Specialization = ClassTemplateSpecializationDecl::Create(
Context, Kind, DC, KWLoc, TemplateNameLoc, ClassTemplate,
- CanonicalConverted, PrevDecl);
+ CTAI.CanonicalConverted, PrevDecl);
Specialization->setTemplateArgsAsWritten(TemplateArgs);
SetNestedNameSpecifier(*this, Specialization, SS);
if (TemplateParameterLists.size() > 0) {
@@ -8579,8 +8579,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
if (CurContext->isDependentContext()) {
TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
- CanonType = Context.getTemplateSpecializationType(CanonTemplate,
- CanonicalConverted);
+ CanonType = Context.getTemplateSpecializationType(
+ CanonTemplate, CTAI.CanonicalConverted);
} else {
CanonType = Context.getTypeDeclType(Specialization);
}
@@ -9839,21 +9839,18 @@ DeclResult Sema::ActOnExplicitInstantiation(
// Check that the template argument list is well-formed for this
// template.
- bool PrimaryHasMatchedPackOnParmToNonPackOnArg = false;
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
- if (CheckTemplateArgumentList(
- ClassTemplate, TemplateNameLoc, TemplateArgs,
- /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted,
- /*UpdateArgsWithConversions=*/true,
- /*ConstraintsNotSatisfied=*/nullptr, /*PartialOrderingTTP=*/false,
- &PrimaryHasMatchedPackOnParmToNonPackOnArg))
+ CheckTemplateArgumentInfo CTAI;
+ if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs,
+ /*DefaultArgs=*/{}, false, CTAI,
+ /*UpdateArgsWithConversions=*/true,
+ /*ConstraintsNotSatisfied=*/nullptr))
return true;
// Find the class template specialization declaration that
// corresponds to these arguments.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *PrevDecl =
- ClassTemplate->findSpecialization(CanonicalConverted, InsertPos);
+ ClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos);
TemplateSpecializationKind PrevDecl_TSK
= PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
@@ -9912,7 +9909,7 @@ DeclResult Sema::ActOnExplicitInstantiation(
// this explicit specialization.
Specialization = ClassTemplateSpecializationDecl::Create(
Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc,
- ClassTemplate, CanonicalConverted, PrevDecl);
+ ClassTemplate, CTAI.CanonicalConverted, PrevDecl);
SetNestedNameSpecifier(*this, Specialization, SS);
// A MSInheritanceAttr attached to the previous declaration must be
@@ -9969,7 +9966,7 @@ DeclResult Sema::ActOnExplicitInstantiation(
if (!Def)
InstantiateClassTemplateSpecialization(
TemplateNameLoc, Specialization, TSK,
- /*Complain=*/true, PrimaryHasMatchedPackOnParmToNonPackOnArg);
+ /*Complain=*/true, CTAI.MatchedPackOnParmToNonPackOnArg);
else if (TSK == TSK_ExplicitInstantiationDefinition) {
MarkVTableUsed(TemplateNameLoc, Specialization, true);
Specialization->setPointOfInstantiation(Def->getPointOfInstantiation());
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 1e1fce10e7c017..137942f0c30bfe 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -53,6 +53,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/SaveAndRestore.h"
#include <algorithm>
#include <cassert>
#include <optional>
@@ -2957,11 +2958,11 @@ Sema::getIdentityTemplateArgumentLoc(NamedDecl *TemplateParm,
/// Convert the given deduced template argument and add it to the set of
/// fully-converted template arguments.
-static bool ConvertDeducedTemplateArgument(
- Sema &S, NamedDecl *Param, DeducedTemplateArgument Arg, NamedDecl *Template,
- TemplateDeductionInfo &Info, bool IsDeduced, bool PartialOrdering,
- SmallVectorImpl<TemplateArgument> &SugaredOutput,
- SmallVectorImpl<TemplateArgument> &CanonicalOutput) {
+static bool
+ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
+ DeducedTemplateArgument Arg, NamedDecl *Template,
+ TemplateDeductionInfo &Info, bool IsDeduced,
+ Sema::CheckTemplateArgumentInfo &CTAI) {
auto ConvertArg = [&](DeducedTemplateArgument Arg,
unsigned ArgumentPackIndex) {
// Convert the deduced template argument into a template
@@ -2970,19 +2971,17 @@ static bool ConvertDeducedTemplateArgument(
TemplateArgumentLoc ArgLoc = S.getTrivialTemplateArgumentLoc(
Arg, QualType(), Info.getLocation(), Param);
- bool MatchedPackOnParmToNonPackOnArg = false;
+ SaveAndRestore _1(CTAI.MatchingTTP, false);
+ SaveAndRestore _2(CTAI.MatchedPackOnParmToNonPackOnArg, false);
// Check the template argument, converting it as necessary.
auto Res = S.CheckTemplateArgument(
Param, ArgLoc, Template, Template->getLocation(),
- Template->getSourceRange().getEnd(), ArgumentPackIndex, SugaredOutput,
- CanonicalOutput,
+ Template->getSourceRange().getEnd(), ArgumentPackIndex, CTAI,
IsDeduced
? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound
: Sema::CTAK_Deduced)
- : Sema::CTAK_Specified,
- PartialOrdering, /*PartialOrderingTTP=*/false,
- &MatchedPackOnParmToNonPackOnArg);
- if (MatchedPackOnParmToNonPackOnArg)
+ : Sema::CTAK_Specified);
+ if (CTAI.MatchedPackOnParmToNonPackOnArg)
Info.setMatchedPackOnParmToNonPackOnArg();
return Res;
};
@@ -3014,20 +3013,21 @@ static bool ConvertDeducedTemplateArgument(
return true;
// Move the converted template argument into our argument pack.
- SugaredPackedArgsBuilder.push_back(SugaredOutput.pop_back_val());
- CanonicalPackedArgsBuilder.push_back(CanonicalOutput.pop_back_val());
+ SugaredPackedArgsBuilder.push_back(CTAI.SugaredConverted.pop_back_val());
+ CanonicalPackedArgsBuilder.push_back(
+ CTAI.CanonicalConverted.pop_back_val());
}
// If the pack is empty, we still need to substitute into the parameter
// itself, in case that substitution fails.
if (SugaredPackedArgsBuilder.empty()) {
LocalInstantiationScope Scope(S);
- MultiLevelTemplateArgumentList Args(Template, SugaredOutput,
+ MultiLevelTemplateArgumentList Args(Template, CTAI.SugaredConverted,
/*Final=*/true);
if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
- NTTP, SugaredOutput,
+ NTTP, CTAI.SugaredConverted,
Template->getSourceRange());
if (Inst.isInvalid() ||
S.SubstType(NTTP->getType(), Args, NTTP->getLocation(),
@@ -3035,7 +3035,7 @@ static bool ConvertDeducedTemplateArgument(
return true;
} else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) {
Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template,
- TTP, SugaredOutput,
+ TTP, CTAI.SugaredConverted,
Template->getSourceRange());
if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args))
return true;
@@ -3044,9 +3044,9 @@ static bool ConvertDeducedTemplateArgument(
}
// Create the resulting argument pack.
- SugaredOutput.push_back(
+ CTAI.SugaredConverted.push_back(
TemplateArgument::CreatePackCopy(S.Context, SugaredPackedArgsBuilder));
- CanonicalOutput.push_back(TemplateArgument::CreatePackCopy(
+ CTAI.CanonicalConverted.push_back(TemplateArgument::CreatePackCopy(
S.Context, CanonicalPackedArgsBuilder));
return false;
}
@@ -3065,9 +3065,7 @@ template <typename TemplateDeclT>
static TemplateDeductionResult ConvertDeducedTemplateArguments(
Sema &S, TemplateDeclT *Template, bool IsDeduced,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
- TemplateDeductionInfo &Info,
- SmallVectorImpl<TemplateArgument> &SugaredBuilder,
- SmallVectorImpl<TemplateArgument> &CanonicalBuilder, bool PartialOrdering,
+ TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI,
LocalInstantiationScope *CurrentInstantiationScope,
unsigned NumAlreadyConverted, bool *IsIncomplete) {
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
@@ -3102,8 +3100,8 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments(
// We have already fully type-checked and converted this
// argument, because it was explicitly-specified. Just record the
// presence of this argument.
- SugaredBuilder.push_back(Deduced[I]);
- CanonicalBuilder.push_back(
+ CTAI.SugaredConverted.push_back(Deduced[I]);
+ CTAI.CanonicalConverted.push_back(
S.Context.getCanonicalTemplateArgument(Deduced[I]));
continue;
}
@@ -3112,13 +3110,13 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments(
// We may have deduced this argument, so it still needs to be
// checked and converted.
if (ConvertDeducedTemplateArgument(S, Param, Deduced[I], Template, Info,
- IsDeduced, PartialOrdering,
- SugaredBuilder, CanonicalBuilder)) {
+ IsDeduced, CTAI)) {
Info.Param = makeTemplateParameter(Param);
// FIXME: These template arguments are temporary. Free them!
Info.reset(
- TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder),
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder));
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted),
+ TemplateArgumentList::CreateCopy(S.Context,
+ CTAI.CanonicalConverted));
return TemplateDeductionResult::SubstitutionFailure;
}
@@ -3132,8 +3130,8 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments(
// arguments.
if (IsIncomplete) {
*IsIncomplete = true;
- SugaredBuilder.push_back({});
- CanonicalBuilder.push_back({});
+ CTAI.SugaredConverted.push_back({});
+ CTAI.CanonicalConverted.push_back({});
continue;
}
@@ -3162,32 +3160,34 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments(
DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param,
- SugaredBuilder, CanonicalBuilder, HasDefaultArg);
+ CTAI.SugaredConverted, CTAI.CanonicalConverted, 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, SugaredBuilder),
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder));
+ Info.reset(
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted),
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted));
return HasDefaultArg ? TemplateDeductionResult::SubstitutionFailure
: TemplateDeductionResult::Incomplete;
}
+ SaveAndRestore _1(CTAI.PartialOrdering, false);
+ SaveAndRestore _2(CTAI.MatchingTTP, false);
+ SaveAndRestore _3(CTAI.MatchedPackOnParmToNonPackOnArg, false);
// Check whether we can actually use the default argument.
if (S.CheckTemplateArgument(
Param, DefArg, TD, TD->getLocation(), TD->getSourceRange().getEnd(),
- /*ArgumentPackIndex=*/0, SugaredBuilder, CanonicalBuilder,
- Sema::CTAK_Specified, /*PartialOrdering=*/false,
- /*PartialOrderingTTP=*/false,
- /*MatchedPackOnParmToNonPackOnArg=*/nullptr)) {
+ /*ArgumentPackIndex=*/0, CTAI, 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, SugaredBuilder),
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder));
+ Info.reset(
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted),
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted));
return TemplateDeductionResult::SubstitutionFailure;
}
@@ -3287,10 +3287,9 @@ FinishTemplateArgumentDeduction(
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
+ Sema::CheckTemplateArgumentInfo CTAI(IsPartialOrdering);
if (auto Result = ConvertDeducedTemplateArguments(
- S, Partial, IsPartialOrdering, Deduced, Info, SugaredBuilder,
- CanonicalBuilder, IsPartialOrdering,
+ S, Partial, IsPartialOrdering, Deduced, Info, CTAI,
/*CurrentInstantiationScope=*/nullptr, /*NumAlreadyConverted=*/0,
/*IsIncomplete=*/nullptr);
Result != TemplateDeductionResult::Success)
@@ -3298,9 +3297,9 @@ FinishTemplateArgumentDeduction(
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *SugaredDeducedArgumentList =
- TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder);
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted);
TemplateArgumentList *CanonicalDeducedArgumentList =
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder);
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted);
Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
@@ -3317,11 +3316,11 @@ FinishTemplateArgumentDeduction(
TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc,
PartialTemplArgInfo->RAngleLoc);
- if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(),
- MultiLevelTemplateArgumentList(Partial,
- SugaredBuilder,
- /*Final=*/true),
- InstArgs)) {
+ if (S.SubstTemplateArguments(
+ PartialTemplArgInfo->arguments(),
+ MultiLevelTemplateArgumentList(Partial, CTAI.SugaredConverted,
+ /*Final=*/true),
+ InstArgs)) {
unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx;
if (ParamIdx >= Partial->getTemplateParameters()->size())
ParamIdx = Partial->getTemplateParameters()->size() - 1;
@@ -3333,24 +3332,21 @@ FinishTemplateArgumentDeduction(
return TemplateDeductionResult::SubstitutionFailure;
}
- bool MatchedPackOnParmToNonPackOnArg = false;
bool ConstraintsNotSatisfied;
- SmallVector<TemplateArgument, 4> SugaredConvertedInstArgs,
- CanonicalConvertedInstArgs;
- if (S.CheckTemplateArgumentList(
- Template, Partial->getLocation(), InstArgs, /*DefaultArgs=*/{}, false,
- SugaredConvertedInstArgs, CanonicalConvertedInstArgs,
- /*UpdateArgsWithConversions=*/true, &ConstraintsNotSatisfied,
- /*PartialOrderingTTP=*/false, &MatchedPackOnParmToNonPackOnArg))
+ Sema::CheckTemplateArgumentInfo InstCTAI;
+ if (S.CheckTemplateArgumentList(Template, Partial->getLocation(), InstArgs,
+ /*DefaultArgs=*/{}, false, InstCTAI,
+ /*UpdateArgsWithConversions=*/true,
+ &ConstraintsNotSatisfied))
return ConstraintsNotSatisfied
? TemplateDeductionResult::ConstraintsNotSatisfied
: TemplateDeductionResult::SubstitutionFailure;
- if (MatchedPackOnParmToNonPackOnArg)
+ if (InstCTAI.MatchedPackOnParmToNonPackOnArg)
Info.setMatchedPackOnParmToNonPackOnArg();
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
- TemplateArgument InstArg = SugaredConvertedInstArgs.data()[I];
+ TemplateArgument InstArg = InstCTAI.SugaredConverted.data()[I];
if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg,
IsPartialOrdering)) {
Info.Param = makeTemplateParameter(TemplateParams->getParam(I));
@@ -3365,7 +3361,7 @@ FinishTemplateArgumentDeduction(
if (!IsPartialOrdering) {
if (auto Result = CheckDeducedArgumentConstraints(
- S, Partial, SugaredBuilder, CanonicalBuilder, Info);
+ S, Partial, CTAI.SugaredConverted, CTAI.CanonicalConverted, Info);
Result != TemplateDeductionResult::Success)
return Result;
}
@@ -3390,10 +3386,9 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
+ Sema::CheckTemplateArgumentInfo CTAI(PartialOrdering);
if (auto Result = ConvertDeducedTemplateArguments(
- S, Template, /*IsDeduced=*/PartialOrdering, Deduced, Info,
- SugaredBuilder, CanonicalBuilder, PartialOrdering,
+ S, Template, /*IsDeduced=*/PartialOrdering, Deduced, Info, CTAI,
/*CurrentInstantiationScope=*/nullptr,
/*NumAlreadyConverted=*/0U, /*IsIncomplete=*/nullptr);
Result != TemplateDeductionResult::Success)
@@ -3401,7 +3396,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// Check that we produced the correct argument list.
SmallVector<ArrayRef<TemplateArgument>, 4> PsStack{TemplateArgs},
- AsStack{CanonicalBuilder};
+ AsStack{CTAI.CanonicalConverted};
for (;;) {
auto take = [](SmallVectorImpl<ArrayRef<TemplateArgument>> &Stack)
-> std::tuple<ArrayRef<TemplateArgument> &, TemplateArgument> {
@@ -3458,7 +3453,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
if (!PartialOrdering) {
if (auto Result = CheckDeducedArgumentConstraints(
- S, Template, SugaredBuilder, CanonicalBuilder, Info);
+ S, Template, CTAI.SugaredConverted, CTAI.CanonicalConverted, Info);
Result != TemplateDeductionResult::Success)
return Result;
}
@@ -3482,17 +3477,16 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// C++ [temp.deduct.type]p2:
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
+ Sema::CheckTemplateArgumentInfo CTAI;
if (auto Result = ConvertDeducedTemplateArguments(
- S, TD, /*IsDeduced=*/false, Deduced, Info, SugaredBuilder,
- CanonicalBuilder, /*PartialOrdering=*/false,
+ S, TD, /*IsDeduced=*/false, Deduced, Info, CTAI,
/*CurrentInstantiationScope=*/nullptr, /*NumAlreadyConverted=*/0,
/*IsIncomplete=*/nullptr);
Result != TemplateDeductionResult::Success)
return Result;
- return ::CheckDeducedArgumentConstraints(S, TD, SugaredBuilder,
- CanonicalBuilder, Info);
+ return ::CheckDeducedArgumentConstraints(S, TD, CTAI.SugaredConverted,
+ CTAI.CanonicalConverted, Info);
}
/// Perform template argument deduction to determine whether the given template
@@ -3673,7 +3667,6 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
// declaration order of their corresponding template-parameters. The
// template argument list shall not specify more template-arguments than
// there are corresponding template-parameters.
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
// Enter a new template instantiation context where we check the
// explicitly-specified template arguments against this function template,
@@ -3685,12 +3678,13 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
if (Inst.isInvalid())
return TemplateDeductionResult::InstantiationDepth;
+ CheckTemplateArgumentInfo CTAI;
if (CheckTemplateArgumentList(FunctionTemplate, SourceLocation(),
- ExplicitTemplateArgs, /*DefaultArgs=*/{}, true,
- SugaredBuilder, CanonicalBuilder,
+ ExplicitTemplateArgs, /*DefaultArgs=*/{},
+ /*PartialTemplateArgs=*/true, CTAI,
/*UpdateArgsWithConversions=*/false) ||
Trap.hasErrorOccurred()) {
- unsigned Index = SugaredBuilder.size();
+ unsigned Index = CTAI.SugaredConverted.size();
if (Index >= TemplateParams->size())
return TemplateDeductionResult::SubstitutionFailure;
Info.Param = makeTemplateParameter(TemplateParams->getParam(Index));
@@ -3700,9 +3694,9 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
// Form the template argument list from the explicitly-specified
// template arguments.
TemplateArgumentList *SugaredExplicitArgumentList =
- TemplateArgumentList::CreateCopy(Context, SugaredBuilder);
+ TemplateArgumentList::CreateCopy(Context, CTAI.SugaredConverted);
TemplateArgumentList *CanonicalExplicitArgumentList =
- TemplateArgumentList::CreateCopy(Context, CanonicalBuilder);
+ TemplateArgumentList::CreateCopy(Context, CTAI.CanonicalConverted);
Info.setExplicitArgs(SugaredExplicitArgumentList,
CanonicalExplicitArgumentList);
@@ -3717,15 +3711,15 @@ TemplateDeductionResult Sema::SubstituteExplicitTemplateArguments(
// the explicit template arguments. They'll be used as part of deduction
// for this template parameter pack.
unsigned PartiallySubstitutedPackIndex = -1u;
- if (!SugaredBuilder.empty()) {
- const TemplateArgument &Arg = SugaredBuilder.back();
+ if (!CTAI.SugaredConverted.empty()) {
+ const TemplateArgument &Arg = CTAI.SugaredConverted.back();
if (Arg.getKind() == TemplateArgument::Pack) {
- auto *Param = TemplateParams->getParam(SugaredBuilder.size() - 1);
+ auto *Param = TemplateParams->getParam(CTAI.SugaredConverted.size() - 1);
// If this is a fully-saturated fixed-size pack, it should be
// fully-substituted, not partially-substituted.
std::optional<unsigned> Expansions = getExpandedPackSize(Param);
if (!Expansions || Arg.pack_size() < *Expansions) {
- PartiallySubstitutedPackIndex = SugaredBuilder.size() - 1;
+ PartiallySubstitutedPackIndex = CTAI.SugaredConverted.size() - 1;
CurrentInstantiationScope->SetPartiallySubstitutedPack(
Param, Arg.pack_begin(), Arg.pack_size());
}
@@ -4047,10 +4041,9 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
bool IsIncomplete = false;
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
+ CheckTemplateArgumentInfo CTAI(PartialOrdering);
if (auto Result = ConvertDeducedTemplateArguments(
- *this, FunctionTemplate, /*IsDeduced=*/true, Deduced, Info,
- SugaredBuilder, CanonicalBuilder, PartialOrdering,
+ *this, FunctionTemplate, /*IsDeduced=*/true, Deduced, Info, CTAI,
CurrentInstantiationScope, NumExplicitlySpecified,
PartialOverloading ? &IsIncomplete : nullptr);
Result != TemplateDeductionResult::Success)
@@ -4070,9 +4063,9 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *SugaredDeducedArgumentList =
- TemplateArgumentList::CreateCopy(Context, SugaredBuilder);
+ TemplateArgumentList::CreateCopy(Context, CTAI.SugaredConverted);
TemplateArgumentList *CanonicalDeducedArgumentList =
- TemplateArgumentList::CreateCopy(Context, CanonicalBuilder);
+ TemplateArgumentList::CreateCopy(Context, CTAI.CanonicalConverted);
Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
// Substitute the deduced template arguments into the function template
@@ -4133,13 +4126,13 @@ TemplateDeductionResult Sema::FinishTemplateArgumentDeduction(
// deduction fails.
if (!IsIncomplete) {
if (CheckInstantiatedFunctionTemplateConstraints(
- Info.getLocation(), Specialization, CanonicalBuilder,
+ Info.getLocation(), Specialization, CTAI.CanonicalConverted,
Info.AssociatedConstraintsSatisfaction))
return TemplateDeductionResult::MiscellaneousDeductionFailure;
if (!Info.AssociatedConstraintsSatisfaction.IsSatisfied) {
- Info.reset(Info.takeSugared(),
- TemplateArgumentList::CreateCopy(Context, CanonicalBuilder));
+ Info.reset(Info.takeSugared(), TemplateArgumentList::CreateCopy(
+ Context, CTAI.CanonicalConverted));
return TemplateDeductionResult::ConstraintsNotSatisfied;
}
}
@@ -5222,12 +5215,12 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
for (unsigned I = 0, C = TypeLoc.getNumArgs(); I != C; ++I)
TemplateArgs.addArgument(TypeLoc.getArgLoc(I));
- llvm::SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
- if (S.CheckTemplateArgumentList(
- Concept, SourceLocation(), TemplateArgs, /*DefaultArgs=*/{},
- /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted))
+ Sema::CheckTemplateArgumentInfo CTAI;
+ if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs,
+ /*DefaultArgs=*/{},
+ /*PartialTemplateArgs=*/false, CTAI))
return true;
- MultiLevelTemplateArgumentList MLTAL(Concept, CanonicalConverted,
+ MultiLevelTemplateArgumentList MLTAL(Concept, CTAI.CanonicalConverted,
/*Final=*/false);
// Build up an EvaluationContext with an ImplicitConceptSpecializationDecl so
// that the template arguments of the constraint can be preserved. For
@@ -5242,7 +5235,7 @@ static bool CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type,
S, Sema::ExpressionEvaluationContext::Unevaluated,
ImplicitConceptSpecializationDecl::Create(
S.getASTContext(), Concept->getDeclContext(), Concept->getLocation(),
- CanonicalConverted));
+ CTAI.CanonicalConverted));
if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()},
MLTAL, TypeLoc.getLocalSourceRange(),
Satisfaction))
@@ -5672,10 +5665,9 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// [...] or if any template argument remains neither deduced nor
// explicitly specified, template argument deduction fails.
bool IsIncomplete = false;
- SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder;
+ Sema::CheckTemplateArgumentInfo CTAI(/*PartialOrdering=*/true);
if (auto Result = ConvertDeducedTemplateArguments(
- S, FTD, /*IsDeduced=*/true, Deduced, Info, SugaredBuilder,
- CanonicalBuilder, /*PartialOrdering=*/true,
+ S, FTD, /*IsDeduced=*/true, Deduced, Info, CTAI,
/*CurrentInstantiationScope=*/nullptr,
/*NumAlreadyConverted=*/0, &IsIncomplete);
Result != TemplateDeductionResult::Success)
@@ -5683,9 +5675,9 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// Form the template argument list from the deduced template arguments.
TemplateArgumentList *SugaredDeducedArgumentList =
- TemplateArgumentList::CreateCopy(S.Context, SugaredBuilder);
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.SugaredConverted);
TemplateArgumentList *CanonicalDeducedArgumentList =
- TemplateArgumentList::CreateCopy(S.Context, CanonicalBuilder);
+ TemplateArgumentList::CreateCopy(S.Context, CTAI.CanonicalConverted);
Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
@@ -5694,7 +5686,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction(
// and equivalent to the parameter.
LocalInstantiationScope InstScope(S);
- if (auto TDR = CheckDeductionConsistency(S, FTD, SugaredBuilder);
+ if (auto TDR = CheckDeductionConsistency(S, FTD, CTAI.SugaredConverted);
TDR != TemplateDeductionResult::Success)
return TDR;
@@ -6571,13 +6563,17 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs(
// C++1z [temp.arg.template]p3:
// If the rewrite produces an invalid type, then P is not at least as
// specialized as A.
- SmallVector<TemplateArgument, 4> CanonicalPArgs;
- if (CheckTemplateArgumentList(
- AArg, ArgLoc, PArgList, DefaultArgs, false, PArgs, CanonicalPArgs,
- /*UpdateArgsWithConversions=*/true,
- /*ConstraintsNotSatisfied=*/nullptr,
- /*PartialOrderingTTP=*/true, MatchedPackOnParmToNonPackOnArg))
+ CheckTemplateArgumentInfo CTAI(
+ /*PartialOrdering=*/false, /*MatchingTTP=*/true);
+ CTAI.SugaredConverted = std::move(PArgs);
+ if (CheckTemplateArgumentList(AArg, ArgLoc, PArgList, DefaultArgs,
+ /*PartialTemplateArgs=*/false, CTAI,
+ /*UpdateArgsWithConversions=*/true,
+ /*ConstraintsNotSatisfied=*/nullptr))
return false;
+ PArgs = std::move(CTAI.SugaredConverted);
+ if (MatchedPackOnParmToNonPackOnArg)
+ *MatchedPackOnParmToNonPackOnArg |= CTAI.MatchedPackOnParmToNonPackOnArg;
}
// Determine whether P1 is at least as specialized as P2.
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 16a7049821a5c1..131f5c8ad1a09d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3957,10 +3957,10 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
// Check that the template argument list is well-formed for this
// class template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ Sema::CheckTemplateArgumentInfo CTAI;
if (SemaRef.CheckTemplateArgumentList(
InstClassTemplate, D->getLocation(), InstTemplateArgs,
- /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted,
+ /*DefaultArgs=*/{}, /*PartialTemplateArgs=*/false, CTAI,
/*UpdateArgsWithConversions=*/true))
return nullptr;
@@ -3968,7 +3968,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
// in the member template's set of class template explicit specializations.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *PrevDecl =
- InstClassTemplate->findSpecialization(CanonicalConverted, InsertPos);
+ InstClassTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos);
// Check whether we've already seen a conflicting instantiation of this
// declaration (for instance, if there was a prior implicit instantiation).
@@ -4006,7 +4006,8 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *InstD =
ClassTemplateSpecializationDecl::Create(
SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(),
- D->getLocation(), InstClassTemplate, CanonicalConverted, PrevDecl);
+ D->getLocation(), InstClassTemplate, CTAI.CanonicalConverted,
+ PrevDecl);
InstD->setTemplateArgsAsWritten(InstTemplateArgs);
// Add this partial specialization to the set of class template partial
@@ -4065,17 +4066,17 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
}
// Check that the template argument list is well-formed for this template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ Sema::CheckTemplateArgumentInfo CTAI;
if (SemaRef.CheckTemplateArgumentList(
InstVarTemplate, D->getLocation(), VarTemplateArgsInfo,
- /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted,
+ /*DefaultArgs=*/{}, /*PartialTemplateArgs=*/false, CTAI,
/*UpdateArgsWithConversions=*/true))
return nullptr;
// Check whether we've already seen a declaration of this specialization.
void *InsertPos = nullptr;
VarTemplateSpecializationDecl *PrevDecl =
- InstVarTemplate->findSpecialization(CanonicalConverted, InsertPos);
+ InstVarTemplate->findSpecialization(CTAI.CanonicalConverted, InsertPos);
// Check whether we've already seen a conflicting instantiation of this
// declaration (for instance, if there was a prior implicit instantiation).
@@ -4086,8 +4087,9 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
PrevDecl->getPointOfInstantiation(), Ignored))
return nullptr;
- return VisitVarTemplateSpecializationDecl(
- InstVarTemplate, D, VarTemplateArgsInfo, CanonicalConverted, PrevDecl);
+ return VisitVarTemplateSpecializationDecl(InstVarTemplate, D,
+ VarTemplateArgsInfo,
+ CTAI.CanonicalConverted, PrevDecl);
}
Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
@@ -4331,37 +4333,37 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Check that the template argument list is well-formed for this
// class template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ Sema::CheckTemplateArgumentInfo CTAI;
if (SemaRef.CheckTemplateArgumentList(
ClassTemplate, PartialSpec->getLocation(), InstTemplateArgs,
/*DefaultArgs=*/{},
- /*PartialTemplateArgs=*/false, SugaredConverted, CanonicalConverted))
+ /*PartialTemplateArgs=*/false, CTAI))
return nullptr;
// Check these arguments are valid for a template partial specialization.
if (SemaRef.CheckTemplatePartialSpecializationArgs(
PartialSpec->getLocation(), ClassTemplate, InstTemplateArgs.size(),
- CanonicalConverted))
+ CTAI.CanonicalConverted))
return nullptr;
// Figure out where to insert this class template partial specialization
// in the member template's set of class template partial specializations.
void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *PrevDecl =
- ClassTemplate->findPartialSpecialization(CanonicalConverted, InstParams,
- InsertPos);
+ ClassTemplate->findPartialSpecialization(CTAI.CanonicalConverted,
+ InstParams, InsertPos);
// Build the canonical type that describes the converted template
// arguments of the class template partial specialization.
QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
- TemplateName(ClassTemplate), CanonicalConverted);
+ TemplateName(ClassTemplate), CTAI.CanonicalConverted);
// Create the class template partial specialization declaration.
ClassTemplatePartialSpecializationDecl *InstPartialSpec =
ClassTemplatePartialSpecializationDecl::Create(
SemaRef.Context, PartialSpec->getTagKind(), Owner,
PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams,
- ClassTemplate, CanonicalConverted, CanonType,
+ ClassTemplate, CTAI.CanonicalConverted, CanonType,
/*PrevDecl=*/nullptr);
InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs);
@@ -4445,25 +4447,24 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
// Check that the template argument list is well-formed for this
// class template.
- SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted;
+ Sema::CheckTemplateArgumentInfo CTAI;
if (SemaRef.CheckTemplateArgumentList(VarTemplate, PartialSpec->getLocation(),
InstTemplateArgs, /*DefaultArgs=*/{},
- /*PartialTemplateArgs=*/false,
- SugaredConverted, CanonicalConverted))
+ /*PartialTemplateArgs=*/false, CTAI))
return nullptr;
// Check these arguments are valid for a template partial specialization.
if (SemaRef.CheckTemplatePartialSpecializationArgs(
PartialSpec->getLocation(), VarTemplate, InstTemplateArgs.size(),
- CanonicalConverted))
+ CTAI.CanonicalConverted))
return nullptr;
// Figure out where to insert this variable template partial specialization
// in the member template's set of variable template partial specializations.
void *InsertPos = nullptr;
VarTemplateSpecializationDecl *PrevDecl =
- VarTemplate->findPartialSpecialization(CanonicalConverted, InstParams,
- InsertPos);
+ VarTemplate->findPartialSpecialization(CTAI.CanonicalConverted,
+ InstParams, InsertPos);
// Do substitution on the type of the declaration
TypeSourceInfo *DI = SemaRef.SubstType(
@@ -4484,7 +4485,7 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
VarTemplatePartialSpecializationDecl::Create(
SemaRef.Context, Owner, PartialSpec->getInnerLocStart(),
PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(),
- DI, PartialSpec->getStorageClass(), CanonicalConverted);
+ DI, PartialSpec->getStorageClass(), CTAI.CanonicalConverted);
InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs);
More information about the llvm-branch-commits
mailing list